This commit is contained in:
planetbeing 2008-05-21 06:59:40 -07:00
Родитель 555107697c
Коммит 545e8f92f0
32 изменённых файлов: 8939 добавлений и 8939 удалений

Просмотреть файл

@ -1,27 +1,27 @@
DMGOBJS=dmg.o base64.o resources.o checksum.o udif.o partition.o io.o filevault.o dmgfile.o dmglib.o zlib-1.2.3/libz.a openssl-0.9.8g/libcrypto.a
HFSOBJS=../hfs/volume.o ../hfs/btree.o ../hfs/extents.o ../hfs/rawfile.o ../hfs/catalog.o ../hfs/flatfile.o ../hfs/utility.o ../hfs/fastunicodecompare.o ../hfs/abstractfile.o
CFLAGS=-D_FILE_OFFSET_BITS=64 -DHAVE_CRYPT
LIBRARIES=`if $(CC) win32test.c -o /dev/null 2>/dev/null ; then echo ""; else echo "-lgdi32"; fi`
all: dmg
dmg: $(DMGOBJS) $(HFSOBJS)
$(CC) $(CFLAGS) $(DMGOBJS) $(HFSOBJS) $(LIBRARIES) -o dmg
%.o: %.c dmg.h filevault.h dmgfile.h
$(CC) $(CFLAGS) -Izlib-1.2.3 -Iopenssl-0.9.8g/include -c $< -o $@
zlib-1.2.3/Makefile:
cd zlib-1.2.3; ./configure
zlib-1.2.3/libz.a: zlib-1.2.3/Makefile
cd zlib-1.2.3; make
DMGOBJS=dmg.o base64.o resources.o checksum.o udif.o partition.o io.o filevault.o dmgfile.o dmglib.o zlib-1.2.3/libz.a openssl-0.9.8g/libcrypto.a
HFSOBJS=../hfs/volume.o ../hfs/btree.o ../hfs/extents.o ../hfs/rawfile.o ../hfs/catalog.o ../hfs/flatfile.o ../hfs/utility.o ../hfs/fastunicodecompare.o ../hfs/abstractfile.o
CFLAGS=-D_FILE_OFFSET_BITS=64 -DHAVE_CRYPT
LIBRARIES=`if $(CC) win32test.c -o /dev/null 2>/dev/null ; then echo ""; else echo "-lgdi32"; fi`
all: dmg
dmg: $(DMGOBJS) $(HFSOBJS)
$(CC) $(CFLAGS) $(DMGOBJS) $(HFSOBJS) $(LIBRARIES) -o dmg
%.o: %.c dmg.h filevault.h dmgfile.h
$(CC) $(CFLAGS) -Izlib-1.2.3 -Iopenssl-0.9.8g/include -c $< -o $@
zlib-1.2.3/Makefile:
cd zlib-1.2.3; ./configure
zlib-1.2.3/libz.a: zlib-1.2.3/Makefile
cd zlib-1.2.3; make
openssl-0.9.8g/libcrypto.a:
touch openssl-0.9.8g/Makefile
cd openssl-0.9.8g/crypto; make
clean:
-rm *.o
-rm dmg
-rm dmg.exe
touch openssl-0.9.8g/Makefile
cd openssl-0.9.8g/crypto; make
clean:
-rm *.o
-rm dmg
-rm dmg.exe

Просмотреть файл

@ -1,183 +1,183 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "dmg.h"
unsigned char* decodeBase64(char* toDecode, size_t* dataLength) {
uint8_t buffer[4];
uint8_t charsInBuffer;
unsigned char* curChar;
unsigned char* decodeBuffer;
unsigned int decodeLoc;
unsigned int decodeBufferSize;
uint8_t bytesToDrop;
curChar = (unsigned char*) toDecode;
charsInBuffer = 0;
decodeBufferSize = 100;
decodeLoc = 0;
decodeBuffer = (unsigned char*) malloc(decodeBufferSize);
bytesToDrop = 0;
while((*curChar) != '\0') {
if((*curChar) >= 'A' && (*curChar) <= 'Z') {
buffer[charsInBuffer] = (*curChar) - 'A';
charsInBuffer++;
}
if((*curChar) >= 'a' && (*curChar) <= 'z') {
buffer[charsInBuffer] = ((*curChar) - 'a') + ('Z' - 'A' + 1);
charsInBuffer++;
}
if((*curChar) >= '0' && (*curChar) <= '9') {
buffer[charsInBuffer] = ((*curChar) - '0') + ('Z' - 'A' + 1) + ('z' - 'a' + 1);
charsInBuffer++;
}
if((*curChar) == '+') {
buffer[charsInBuffer] = ('Z' - 'A' + 1) + ('z' - 'a' + 1) + ('9' - '0' + 1);
charsInBuffer++;
}
if((*curChar) == '/') {
buffer[charsInBuffer] = ('Z' - 'A' + 1) + ('z' - 'a' + 1) + ('9' - '0' + 1) + 1;
charsInBuffer++;
}
if((*curChar) == '=') {
bytesToDrop++;
}
if(charsInBuffer == 4) {
charsInBuffer = 0;
if((decodeLoc + 3) >= decodeBufferSize) {
decodeBufferSize <<= 1;
decodeBuffer = (unsigned char*) realloc(decodeBuffer, decodeBufferSize);
}
decodeBuffer[decodeLoc] = ((buffer[0] << 2) & 0xFC) + ((buffer[1] >> 4) & 0x3F);
decodeBuffer[decodeLoc + 1] = ((buffer[1] << 4) & 0xF0) + ((buffer[2] >> 2) & 0x0F);
decodeBuffer[decodeLoc + 2] = ((buffer[2] << 6) & 0xC0) + (buffer[3] & 0x3F);
decodeLoc += 3;
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = 0;
}
curChar++;
}
if(bytesToDrop != 0) {
if((decodeLoc + 3) >= decodeBufferSize) {
decodeBufferSize <<= 1;
decodeBuffer = (unsigned char*) realloc(decodeBuffer, decodeBufferSize);
}
decodeBuffer[decodeLoc] = ((buffer[0] << 2) & 0xFC) | ((buffer[1] >> 4) & 0x3F);
if(bytesToDrop <= 2)
decodeBuffer[decodeLoc + 1] = ((buffer[1] << 4) & 0xF0) | ((buffer[2] >> 2) & 0x0F);
if(bytesToDrop <= 1)
decodeBuffer[decodeLoc + 2] = ((buffer[2] << 6) & 0xC0) | (buffer[3] & 0x3F);
*dataLength = decodeLoc + 3 - bytesToDrop;
} else {
*dataLength = decodeLoc;
}
return decodeBuffer;
}
void writeBase64(AbstractFile* file, unsigned char* data, size_t dataLength, int tabLength, int width) {
char* buffer;
buffer = convertBase64(data, dataLength, tabLength, width);
file->write(file, buffer, strlen(buffer));
free(buffer);
}
#define CHECK_BUFFER_SIZE() \
if(pos == bufferSize) { \
bufferSize <<= 1; \
buffer = (unsigned char*) realloc(buffer, bufferSize); \
}
#define CHECK_LINE_END_STRING() \
CHECK_BUFFER_SIZE() \
if(width == lineLength) { \
buffer[pos++] = '\n'; \
CHECK_BUFFER_SIZE() \
for(j = 0; j < tabLength; j++) { \
buffer[pos++] = '\t'; \
CHECK_BUFFER_SIZE() \
} \
lineLength = 0; \
} else { \
lineLength++; \
}
char* convertBase64(unsigned char* data, size_t dataLength, int tabLength, int width) {
const char* dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned char* buffer;
size_t pos;
size_t bufferSize;
int i, j;
int lineLength;
bufferSize = 100;
buffer = (unsigned char*) malloc(bufferSize);
pos = 0;
lineLength = 0;
for(i = 0; i < tabLength; i++) {
CHECK_BUFFER_SIZE()
buffer[pos++] = '\t';
}
i = 0;
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "dmg.h"
unsigned char* decodeBase64(char* toDecode, size_t* dataLength) {
uint8_t buffer[4];
uint8_t charsInBuffer;
unsigned char* curChar;
unsigned char* decodeBuffer;
unsigned int decodeLoc;
unsigned int decodeBufferSize;
uint8_t bytesToDrop;
curChar = (unsigned char*) toDecode;
charsInBuffer = 0;
decodeBufferSize = 100;
decodeLoc = 0;
decodeBuffer = (unsigned char*) malloc(decodeBufferSize);
bytesToDrop = 0;
while((*curChar) != '\0') {
if((*curChar) >= 'A' && (*curChar) <= 'Z') {
buffer[charsInBuffer] = (*curChar) - 'A';
charsInBuffer++;
}
if((*curChar) >= 'a' && (*curChar) <= 'z') {
buffer[charsInBuffer] = ((*curChar) - 'a') + ('Z' - 'A' + 1);
charsInBuffer++;
}
if((*curChar) >= '0' && (*curChar) <= '9') {
buffer[charsInBuffer] = ((*curChar) - '0') + ('Z' - 'A' + 1) + ('z' - 'a' + 1);
charsInBuffer++;
}
if((*curChar) == '+') {
buffer[charsInBuffer] = ('Z' - 'A' + 1) + ('z' - 'a' + 1) + ('9' - '0' + 1);
charsInBuffer++;
}
if((*curChar) == '/') {
buffer[charsInBuffer] = ('Z' - 'A' + 1) + ('z' - 'a' + 1) + ('9' - '0' + 1) + 1;
charsInBuffer++;
}
if((*curChar) == '=') {
bytesToDrop++;
}
if(charsInBuffer == 4) {
charsInBuffer = 0;
if((decodeLoc + 3) >= decodeBufferSize) {
decodeBufferSize <<= 1;
decodeBuffer = (unsigned char*) realloc(decodeBuffer, decodeBufferSize);
}
decodeBuffer[decodeLoc] = ((buffer[0] << 2) & 0xFC) + ((buffer[1] >> 4) & 0x3F);
decodeBuffer[decodeLoc + 1] = ((buffer[1] << 4) & 0xF0) + ((buffer[2] >> 2) & 0x0F);
decodeBuffer[decodeLoc + 2] = ((buffer[2] << 6) & 0xC0) + (buffer[3] & 0x3F);
decodeLoc += 3;
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = 0;
}
curChar++;
}
if(bytesToDrop != 0) {
if((decodeLoc + 3) >= decodeBufferSize) {
decodeBufferSize <<= 1;
decodeBuffer = (unsigned char*) realloc(decodeBuffer, decodeBufferSize);
}
decodeBuffer[decodeLoc] = ((buffer[0] << 2) & 0xFC) | ((buffer[1] >> 4) & 0x3F);
if(bytesToDrop <= 2)
decodeBuffer[decodeLoc + 1] = ((buffer[1] << 4) & 0xF0) | ((buffer[2] >> 2) & 0x0F);
if(bytesToDrop <= 1)
decodeBuffer[decodeLoc + 2] = ((buffer[2] << 6) & 0xC0) | (buffer[3] & 0x3F);
*dataLength = decodeLoc + 3 - bytesToDrop;
} else {
*dataLength = decodeLoc;
}
return decodeBuffer;
}
void writeBase64(AbstractFile* file, unsigned char* data, size_t dataLength, int tabLength, int width) {
char* buffer;
buffer = convertBase64(data, dataLength, tabLength, width);
file->write(file, buffer, strlen(buffer));
free(buffer);
}
#define CHECK_BUFFER_SIZE() \
if(pos == bufferSize) { \
bufferSize <<= 1; \
buffer = (unsigned char*) realloc(buffer, bufferSize); \
}
#define CHECK_LINE_END_STRING() \
CHECK_BUFFER_SIZE() \
if(width == lineLength) { \
buffer[pos++] = '\n'; \
CHECK_BUFFER_SIZE() \
for(j = 0; j < tabLength; j++) { \
buffer[pos++] = '\t'; \
CHECK_BUFFER_SIZE() \
} \
lineLength = 0; \
} else { \
lineLength++; \
}
char* convertBase64(unsigned char* data, size_t dataLength, int tabLength, int width) {
const char* dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned char* buffer;
size_t pos;
size_t bufferSize;
int i, j;
int lineLength;
bufferSize = 100;
buffer = (unsigned char*) malloc(bufferSize);
pos = 0;
lineLength = 0;
for(i = 0; i < tabLength; i++) {
CHECK_BUFFER_SIZE()
buffer[pos++] = '\t';
}
i = 0;
while(dataLength >= 3) {
dataLength -= 3;
buffer[pos++] = dictionary[(data[i] >> 2) & 0x3F];
CHECK_LINE_END_STRING();
buffer[pos++] = dictionary[(((data[i] << 4) & 0x30) | ((data[i+1] >> 4) & 0x0F)) & 0x3F];
CHECK_LINE_END_STRING();
buffer[pos++] = dictionary[(((data[i+1] << 2) & 0x3C) | ((data[i+2] >> 6) & 0x03)) & 0x03F];
CHECK_LINE_END_STRING();
buffer[pos++] = dictionary[data[i+2] & 0x3F];
CHECK_LINE_END_STRING();
i += 3;
}
if(dataLength == 2) {
buffer[pos++] = dictionary[(data[i] >> 2) & 0x3F];
CHECK_LINE_END_STRING();
buffer[pos++] = dictionary[(((data[i] << 4) & 0x30) | ((data[i+1] >> 4) & 0x0F)) & 0x3F];
CHECK_LINE_END_STRING();
buffer[pos++] = dictionary[(data[i+1] << 2) & 0x3C];
CHECK_LINE_END_STRING();
buffer[pos++] = '=';
} else if(dataLength == 1) {
buffer[pos++] = dictionary[(data[i] >> 2) & 0x3F];
CHECK_LINE_END_STRING();
buffer[pos++] = dictionary[(data[i] << 4) & 0x30];
CHECK_LINE_END_STRING();
buffer[pos++] = '=';
CHECK_LINE_END_STRING();
buffer[pos++] = '=';
}
CHECK_BUFFER_SIZE();
buffer[pos++] = '\n';
CHECK_BUFFER_SIZE();
buffer[pos++] = '\0';
return (char*) buffer;
}
dataLength -= 3;
buffer[pos++] = dictionary[(data[i] >> 2) & 0x3F];
CHECK_LINE_END_STRING();
buffer[pos++] = dictionary[(((data[i] << 4) & 0x30) | ((data[i+1] >> 4) & 0x0F)) & 0x3F];
CHECK_LINE_END_STRING();
buffer[pos++] = dictionary[(((data[i+1] << 2) & 0x3C) | ((data[i+2] >> 6) & 0x03)) & 0x03F];
CHECK_LINE_END_STRING();
buffer[pos++] = dictionary[data[i+2] & 0x3F];
CHECK_LINE_END_STRING();
i += 3;
}
if(dataLength == 2) {
buffer[pos++] = dictionary[(data[i] >> 2) & 0x3F];
CHECK_LINE_END_STRING();
buffer[pos++] = dictionary[(((data[i] << 4) & 0x30) | ((data[i+1] >> 4) & 0x0F)) & 0x3F];
CHECK_LINE_END_STRING();
buffer[pos++] = dictionary[(data[i+1] << 2) & 0x3C];
CHECK_LINE_END_STRING();
buffer[pos++] = '=';
} else if(dataLength == 1) {
buffer[pos++] = dictionary[(data[i] >> 2) & 0x3F];
CHECK_LINE_END_STRING();
buffer[pos++] = dictionary[(data[i] << 4) & 0x30];
CHECK_LINE_END_STRING();
buffer[pos++] = '=';
CHECK_LINE_END_STRING();
buffer[pos++] = '=';
}
CHECK_BUFFER_SIZE();
buffer[pos++] = '\n';
CHECK_BUFFER_SIZE();
buffer[pos++] = '\0';
return (char*) buffer;
}

Просмотреть файл

@ -1,313 +1,313 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "dmg.h"
void BlockSHA1CRC(void* token, const unsigned char* data, size_t len) {
ChecksumToken* ckSumToken;
ckSumToken = (ChecksumToken*) token;
MKBlockChecksum(&(ckSumToken->block), data, len);
CRC32Checksum(&(ckSumToken->crc), data, len);
SHA1Update(&(ckSumToken->sha1), data, len);
}
void BlockCRC(void* token, const unsigned char* data, size_t len) {
ChecksumToken* ckSumToken;
ckSumToken = (ChecksumToken*) token;
MKBlockChecksum(&(ckSumToken->block), data, len);
CRC32Checksum(&(ckSumToken->crc), data, len);
}
void CRCProxy(void* token, const unsigned char* data, size_t len) {
ChecksumToken* ckSumToken;
ckSumToken = (ChecksumToken*) token;
CRC32Checksum(&(ckSumToken->crc), data, len);
}
/*
*
* MediaKit block checksumming reverse-engineered from Leopard MediaKit framework
*
*/
uint32_t MKBlockChecksum(uint32_t* ckSum, const unsigned char* data, size_t len) {
uint32_t* curDWordPtr;
uint32_t curDWord;
uint32_t myCkSum;
myCkSum = *ckSum;
if(data) {
curDWordPtr = (uint32_t*) data;
while(curDWordPtr < (uint32_t*)(&data[len & 0xFFFFFFFC])) {
curDWord = *curDWordPtr;
FLIPENDIAN(curDWord);
myCkSum = curDWord + ((myCkSum >> 31) | (myCkSum << 1));
curDWordPtr++;
}
}
*ckSum = myCkSum;
return myCkSum;
}
/*
* CRC32 code ripped off (and adapted) from the zlib-1.1.3 distribution by Jean-loup Gailly and Mark Adler.
*
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*
*/
/* ========================================================================
* Table of CRC-32's of all single-byte values (made by make_crc_table)
*/
static uint64_t crc_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8l, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
/* ========================================================================= */
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
#define DO2(buf) DO1(buf); DO1(buf);
#define DO4(buf) DO2(buf); DO2(buf);
#define DO8(buf) DO4(buf); DO4(buf);
/* ========================================================================= */
uint32_t CRC32Checksum(uint32_t* ckSum, const unsigned char *buf, size_t len)
{
uint32_t crc;
crc = *ckSum;
if (buf == NULL) return crc;
crc = crc ^ 0xffffffffL;
while (len >= 8)
{
DO8(buf);
len -= 8;
}
if (len)
{
do {
DO1(buf);
} while (--len);
}
crc = crc ^ 0xffffffffL;
*ckSum = crc;
return crc;
}
/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
Test Vectors (from FIPS PUB 180-1)
"abc"
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
#define SHA1HANDSOFF * Copies data before messing with it.
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
#define blk0(i) ((endianness == IS_LITTLE_ENDIAN) ? (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF)) : block->l[i])
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1Transform(unsigned long state[5], const unsigned char buffer[64])
{
unsigned long a, b, c, d, e;
typedef union {
unsigned char c[64];
unsigned long l[16];
} CHAR64LONG16;
CHAR64LONG16* block;
#ifdef SHA1HANDSOFF
static unsigned char workspace[64];
block = (CHAR64LONG16*)workspace;
memcpy(block, buffer, 64);
#else
block = (CHAR64LONG16*)buffer;
#endif
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
}
/* SHA1Init - Initialize new context */
void SHA1Init(SHA1_CTX* context)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len)
{
unsigned int i, j;
j = (context->count[0] >> 3) & 63;
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
context->count[1] += (len >> 29);
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
SHA1Transform(context->state, &data[i]);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
{
unsigned long i, j;
unsigned char finalcount[8];
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
SHA1Update(context, (unsigned char *)"\200", 1);
while ((context->count[0] & 504) != 448) {
SHA1Update(context, (unsigned char *)"\0", 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++) {
digest[i] = (unsigned char)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
/* Wipe variables */
i = j = 0;
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(&finalcount, 0, 8);
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
SHA1Transform(context->state, context->buffer);
#endif
}
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "dmg.h"
void BlockSHA1CRC(void* token, const unsigned char* data, size_t len) {
ChecksumToken* ckSumToken;
ckSumToken = (ChecksumToken*) token;
MKBlockChecksum(&(ckSumToken->block), data, len);
CRC32Checksum(&(ckSumToken->crc), data, len);
SHA1Update(&(ckSumToken->sha1), data, len);
}
void BlockCRC(void* token, const unsigned char* data, size_t len) {
ChecksumToken* ckSumToken;
ckSumToken = (ChecksumToken*) token;
MKBlockChecksum(&(ckSumToken->block), data, len);
CRC32Checksum(&(ckSumToken->crc), data, len);
}
void CRCProxy(void* token, const unsigned char* data, size_t len) {
ChecksumToken* ckSumToken;
ckSumToken = (ChecksumToken*) token;
CRC32Checksum(&(ckSumToken->crc), data, len);
}
/*
*
* MediaKit block checksumming reverse-engineered from Leopard MediaKit framework
*
*/
uint32_t MKBlockChecksum(uint32_t* ckSum, const unsigned char* data, size_t len) {
uint32_t* curDWordPtr;
uint32_t curDWord;
uint32_t myCkSum;
myCkSum = *ckSum;
if(data) {
curDWordPtr = (uint32_t*) data;
while(curDWordPtr < (uint32_t*)(&data[len & 0xFFFFFFFC])) {
curDWord = *curDWordPtr;
FLIPENDIAN(curDWord);
myCkSum = curDWord + ((myCkSum >> 31) | (myCkSum << 1));
curDWordPtr++;
}
}
*ckSum = myCkSum;
return myCkSum;
}
/*
* CRC32 code ripped off (and adapted) from the zlib-1.1.3 distribution by Jean-loup Gailly and Mark Adler.
*
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*
*/
/* ========================================================================
* Table of CRC-32's of all single-byte values (made by make_crc_table)
*/
static uint64_t crc_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8l, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
/* ========================================================================= */
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
#define DO2(buf) DO1(buf); DO1(buf);
#define DO4(buf) DO2(buf); DO2(buf);
#define DO8(buf) DO4(buf); DO4(buf);
/* ========================================================================= */
uint32_t CRC32Checksum(uint32_t* ckSum, const unsigned char *buf, size_t len)
{
uint32_t crc;
crc = *ckSum;
if (buf == NULL) return crc;
crc = crc ^ 0xffffffffL;
while (len >= 8)
{
DO8(buf);
len -= 8;
}
if (len)
{
do {
DO1(buf);
} while (--len);
}
crc = crc ^ 0xffffffffL;
*ckSum = crc;
return crc;
}
/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
Test Vectors (from FIPS PUB 180-1)
"abc"
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
#define SHA1HANDSOFF * Copies data before messing with it.
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
#define blk0(i) ((endianness == IS_LITTLE_ENDIAN) ? (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF)) : block->l[i])
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1Transform(unsigned long state[5], const unsigned char buffer[64])
{
unsigned long a, b, c, d, e;
typedef union {
unsigned char c[64];
unsigned long l[16];
} CHAR64LONG16;
CHAR64LONG16* block;
#ifdef SHA1HANDSOFF
static unsigned char workspace[64];
block = (CHAR64LONG16*)workspace;
memcpy(block, buffer, 64);
#else
block = (CHAR64LONG16*)buffer;
#endif
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
}
/* SHA1Init - Initialize new context */
void SHA1Init(SHA1_CTX* context)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len)
{
unsigned int i, j;
j = (context->count[0] >> 3) & 63;
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
context->count[1] += (len >> 29);
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
SHA1Transform(context->state, &data[i]);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
{
unsigned long i, j;
unsigned char finalcount[8];
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
SHA1Update(context, (unsigned char *)"\200", 1);
while ((context->count[0] & 504) != 448) {
SHA1Update(context, (unsigned char *)"\0", 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++) {
digest[i] = (unsigned char)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
/* Wipe variables */
i = j = 0;
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(&finalcount, 0, 8);
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
SHA1Transform(context->state, context->buffer);
#endif
}

166
dmg/dmg.c
Просмотреть файл

@ -1,83 +1,83 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "dmg.h"
#include "filevault.h"
char endianness;
void TestByteOrder()
{
short int word = 0x0001;
char *byte = (char *) &word;
endianness = byte[0] ? IS_LITTLE_ENDIAN : IS_BIG_ENDIAN;
}
int buildInOut(const char* source, const char* dest, AbstractFile** in, AbstractFile** out) {
*in = createAbstractFileFromFile(fopen(source, "rb"));
if(!(*in)) {
printf("cannot open source: %s\n", source);
return FALSE;
}
*out = createAbstractFileFromFile(fopen(dest, "wb"));
if(!(*out)) {
(*in)->close(*in);
printf("cannot open destination: %s\n", dest);
return FALSE;
}
return TRUE;
}
int main(int argc, char* argv[]) {
int partNum;
AbstractFile* in;
AbstractFile* out;
int hasKey;
TestByteOrder();
if(argc < 4) {
printf("usage: %s [extract|build|iso|dmg] <in> <out> (-k <key>) (partition)\n", argv[0]);
return 0;
}
if(!buildInOut(argv[2], argv[3], &in, &out)) {
return FALSE;
}
hasKey = FALSE;
if(argc > 5) {
if(strcmp(argv[4], "-k") == 0) {
in = createAbstractFileFromFileVault(in, argv[5]);
hasKey = TRUE;
}
}
if(strcmp(argv[1], "extract") == 0) {
partNum = -1;
if(hasKey) {
if(argc > 6) {
sscanf(argv[6], "%d", &partNum);
}
} else {
if(argc > 4) {
sscanf(argv[4], "%d", &partNum);
}
}
extractDmg(in, out, partNum);
} else if(strcmp(argv[1], "build") == 0) {
buildDmg(in, out);
} else if(strcmp(argv[1], "iso") == 0) {
convertToISO(in, out);
} else if(strcmp(argv[1], "dmg") == 0) {
convertToDMG(in, out);
}
return 0;
}
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "dmg.h"
#include "filevault.h"
char endianness;
void TestByteOrder()
{
short int word = 0x0001;
char *byte = (char *) &word;
endianness = byte[0] ? IS_LITTLE_ENDIAN : IS_BIG_ENDIAN;
}
int buildInOut(const char* source, const char* dest, AbstractFile** in, AbstractFile** out) {
*in = createAbstractFileFromFile(fopen(source, "rb"));
if(!(*in)) {
printf("cannot open source: %s\n", source);
return FALSE;
}
*out = createAbstractFileFromFile(fopen(dest, "wb"));
if(!(*out)) {
(*in)->close(*in);
printf("cannot open destination: %s\n", dest);
return FALSE;
}
return TRUE;
}
int main(int argc, char* argv[]) {
int partNum;
AbstractFile* in;
AbstractFile* out;
int hasKey;
TestByteOrder();
if(argc < 4) {
printf("usage: %s [extract|build|iso|dmg] <in> <out> (-k <key>) (partition)\n", argv[0]);
return 0;
}
if(!buildInOut(argv[2], argv[3], &in, &out)) {
return FALSE;
}
hasKey = FALSE;
if(argc > 5) {
if(strcmp(argv[4], "-k") == 0) {
in = createAbstractFileFromFileVault(in, argv[5]);
hasKey = TRUE;
}
}
if(strcmp(argv[1], "extract") == 0) {
partNum = -1;
if(hasKey) {
if(argc > 6) {
sscanf(argv[6], "%d", &partNum);
}
} else {
if(argc > 4) {
sscanf(argv[4], "%d", &partNum);
}
}
extractDmg(in, out, partNum);
} else if(strcmp(argv[1], "build") == 0) {
buildDmg(in, out);
} else if(strcmp(argv[1], "iso") == 0) {
convertToISO(in, out);
} else if(strcmp(argv[1], "dmg") == 0) {
convertToDMG(in, out);
}
return 0;
}

672
dmg/dmg.h
Просмотреть файл

@ -1,343 +1,343 @@
#ifndef DMG_H
#define DMG_H
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#ifndef DMG_H
#define DMG_H
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include "../hfs/hfsplus.h"
#include "../hfs/abstractfile.h"
#define CHECKSUM_CRC32 0x00000002
#define CHECKSUM_MKBLOCK 0x0002
#define CHECKSUM_NONE 0x0000
#define BLOCK_ZLIB 0x80000005
#define BLOCK_RAW 0x00000001
#define BLOCK_IGNORE 0x00000002
#define BLOCK_COMMENT 0x7FFFFFFE
#define BLOCK_TERMINATOR 0xFFFFFFFF
#define SECTOR_SIZE 512
#define DRIVER_DESCRIPTOR_SIGNATURE 0x4552
#define APPLE_PARTITION_MAP_SIGNATURE 0x504D
#define UDIF_BLOCK_SIGNATURE 0x6D697368
#define KOLY_SIGNATURE 0x6B6F6C79
#define HFSX_SIGNATURE 0x4858
#define ATTRIBUTE_HDIUTIL 0x0050
#define HFSX_VOLUME_TYPE "Apple_HFSX"
#define DDM_SIZE 0x1
#define PARTITION_SIZE 0x3f
#define ATAPI_SIZE 0x8
#define FREE_SIZE 0xa
#define EXTRA_SIZE (DDM_SIZE + PARTITION_SIZE + ATAPI_SIZE + FREE_SIZE)
#define DDM_OFFSET 0x0
#define PARTITION_OFFSET (DDM_SIZE)
#define ATAPI_OFFSET (DDM_SIZE + PARTITION_SIZE)
#define USER_OFFSET (DDM_SIZE + PARTITION_SIZE + ATAPI_SIZE)
#define BOOTCODE_DMMY 0x444D4D59
#define BOOTCODE_GOON 0x676F6F6E
enum {
kUDIFFlagsFlattened = 1
};
enum {
kUDIFDeviceImageType = 1,
kUDIFPartitionImageType = 2
};
typedef struct {
uint32_t type;
uint32_t size;
uint32_t data[0x20];
} __attribute__((__packed__)) UDIFChecksum;
typedef struct {
uint32_t data1; /* smallest */
uint32_t data2;
uint32_t data3;
uint32_t data4; /* largest */
} __attribute__((__packed__)) UDIFID;
typedef struct {
uint32_t fUDIFSignature;
uint32_t fUDIFVersion;
uint32_t fUDIFHeaderSize;
uint32_t fUDIFFlags;
uint64_t fUDIFRunningDataForkOffset;
uint64_t fUDIFDataForkOffset;
uint64_t fUDIFDataForkLength;
uint64_t fUDIFRsrcForkOffset;
uint64_t fUDIFRsrcForkLength;
uint32_t fUDIFSegmentNumber;
uint32_t fUDIFSegmentCount;
UDIFID fUDIFSegmentID; /* a 128-bit number like a GUID, but does not seem to be a OSF GUID, since it doesn't have the proper versioning byte */
UDIFChecksum fUDIFDataForkChecksum;
uint64_t fUDIFXMLOffset;
uint64_t fUDIFXMLLength;
uint8_t reserved1[0x78]; /* this is actually the perfect amount of space to store every thing in this struct until the checksum */
UDIFChecksum fUDIFMasterChecksum;
uint32_t fUDIFImageVariant;
uint64_t fUDIFSectorCount;
uint32_t reserved2;
uint32_t reserved3;
uint32_t reserved4;
} __attribute__((__packed__)) UDIFResourceFile;
typedef struct {
uint32_t type;
uint32_t reserved;
uint64_t sectorStart;
uint64_t sectorCount;
uint64_t compOffset;
uint64_t compLength;
} __attribute__((__packed__)) BLKXRun;
typedef struct {
uint16_t version; /* set to 5 */
uint32_t isHFS; /* first dword of v53(ImageInfoRec): Set to 1 if it's a HFS or HFS+ partition -- duh. */
uint32_t unknown1; /* second dword of v53: seems to be garbage if it's HFS+, stuff related to HFS embedded if it's that*/
uint8_t dataLen; /* length of data that proceeds, comes right before the data in ImageInfoRec. Always set to 0 for HFS, HFS+ */
uint8_t data[255]; /* other data from v53, dataLen + 1 bytes, the rest NULL filled... a string? Not set for HFS, HFS+ */
uint32_t unknown2; /* 8 bytes before volumeModified in v53, seems to be always set to 0 for HFS, HFS+ */
uint32_t unknown3; /* 4 bytes before volumeModified in v53, seems to be always set to 0 for HFS, HFS+ */
uint32_t volumeModified; /* offset 272 in v53 */
uint32_t unknown4; /* always seems to be 0 for UDIF */
uint16_t volumeSignature; /* HX in our case */
uint16_t sizePresent; /* always set to 1 */
} __attribute__((__packed__)) SizeResource;
typedef struct {
uint16_t version; /* set to 1 */
uint32_t type; /* set to 0x2 for MKBlockChecksum */
uint32_t checksum;
} __attribute__((__packed__)) CSumResource;
typedef struct NSizResource {
char isVolume;
unsigned char* sha1Digest;
uint32_t blockChecksum2;
uint32_t bytes;
uint32_t modifyDate;
uint32_t partitionNumber;
uint32_t version;
uint32_t volumeSignature;
struct NSizResource* next;
} NSizResource;
#define DDM_DESCRIPTOR 0xFFFFFFFF
#define ENTIRE_DEVICE_DESCRIPTOR 0xFFFFFFFE
typedef struct {
uint32_t fUDIFBlocksSignature;
uint32_t infoVersion;
uint64_t firstSectorNumber;
uint64_t sectorCount;
uint64_t dataStart;
uint32_t decompressBufferRequested;
uint32_t blocksDescriptor;
uint32_t reserved1;
uint32_t reserved2;
uint32_t reserved3;
uint32_t reserved4;
uint32_t reserved5;
uint32_t reserved6;
UDIFChecksum checksum;
uint32_t blocksRunCount;
BLKXRun runs[0];
} __attribute__((__packed__)) BLKXTable;
typedef struct {
uint32_t ddBlock;
uint16_t ddSize;
uint16_t ddType;
} __attribute__((__packed__)) DriverDescriptor;
typedef struct {
uint16_t pmSig;
uint16_t pmSigPad;
uint32_t pmMapBlkCnt;
uint32_t pmPyPartStart;
uint32_t pmPartBlkCnt;
unsigned char pmPartName[32];
unsigned char pmParType[32];
uint32_t pmLgDataStart;
uint32_t pmDataCnt;
uint32_t pmPartStatus;
uint32_t pmLgBootStart;
uint32_t pmBootSize;
uint32_t pmBootAddr;
uint32_t pmBootAddr2;
uint32_t pmBootEntry;
uint32_t pmBootEntry2;
uint32_t pmBootCksum;
unsigned char pmProcessor[16];
uint32_t bootCode;
uint16_t pmPad[186];
} __attribute__((__packed__)) Partition;
typedef struct {
uint16_t sbSig;
uint16_t sbBlkSize;
uint32_t sbBlkCount;
uint16_t sbDevType;
uint16_t sbDevId;
uint32_t sbData;
uint16_t sbDrvrCount;
uint32_t ddBlock;
uint16_t ddSize;
uint16_t ddType;
DriverDescriptor ddPad[0];
} __attribute__((__packed__)) DriverDescriptorRecord;
typedef struct ResourceData {
uint32_t attributes;
unsigned char* data;
size_t dataLength;
int id;
unsigned char* name;
struct ResourceData* next;
} ResourceData;
typedef void (*FlipDataFunc)(unsigned char* data, char out);
typedef void (*ChecksumFunc)(void* ckSum, const unsigned char* data, size_t len);
typedef struct ResourceKey {
unsigned char* key;
ResourceData* data;
struct ResourceKey* next;
FlipDataFunc flipData;
} ResourceKey;
typedef struct {
unsigned long state[5];
unsigned long count[2];
unsigned char buffer[64];
} SHA1_CTX;
typedef struct {
uint32_t block;
uint32_t crc;
SHA1_CTX sha1;
} ChecksumToken;
static inline uint32_t readUInt32(AbstractFile* file) {
uint32_t data;
ASSERT(file->read(file, &data, sizeof(data)) == sizeof(data), "fread");
FLIPENDIAN(data);
return data;
}
static inline void writeUInt32(AbstractFile* file, uint32_t data) {
FLIPENDIAN(data);
ASSERT(file->write(file, &data, sizeof(data)) == sizeof(data), "fwrite");
}
static inline uint32_t readUInt64(AbstractFile* file) {
uint64_t data;
ASSERT(file->read(file, &data, sizeof(data)) == sizeof(data), "fread");
FLIPENDIAN(data);
return data;
}
static inline void writeUInt64(AbstractFile* file, uint64_t data) {
FLIPENDIAN(data);
ASSERT(file->write(file, &data, sizeof(data)) == sizeof(data), "fwrite");
}
#include "../hfs/abstractfile.h"
#define CHECKSUM_CRC32 0x00000002
#define CHECKSUM_MKBLOCK 0x0002
#define CHECKSUM_NONE 0x0000
#define BLOCK_ZLIB 0x80000005
#define BLOCK_RAW 0x00000001
#define BLOCK_IGNORE 0x00000002
#define BLOCK_COMMENT 0x7FFFFFFE
#define BLOCK_TERMINATOR 0xFFFFFFFF
#define SECTOR_SIZE 512
#define DRIVER_DESCRIPTOR_SIGNATURE 0x4552
#define APPLE_PARTITION_MAP_SIGNATURE 0x504D
#define UDIF_BLOCK_SIGNATURE 0x6D697368
#define KOLY_SIGNATURE 0x6B6F6C79
#define HFSX_SIGNATURE 0x4858
#define ATTRIBUTE_HDIUTIL 0x0050
#define HFSX_VOLUME_TYPE "Apple_HFSX"
#define DDM_SIZE 0x1
#define PARTITION_SIZE 0x3f
#define ATAPI_SIZE 0x8
#define FREE_SIZE 0xa
#define EXTRA_SIZE (DDM_SIZE + PARTITION_SIZE + ATAPI_SIZE + FREE_SIZE)
#define DDM_OFFSET 0x0
#define PARTITION_OFFSET (DDM_SIZE)
#define ATAPI_OFFSET (DDM_SIZE + PARTITION_SIZE)
#define USER_OFFSET (DDM_SIZE + PARTITION_SIZE + ATAPI_SIZE)
#define BOOTCODE_DMMY 0x444D4D59
#define BOOTCODE_GOON 0x676F6F6E
enum {
kUDIFFlagsFlattened = 1
};
enum {
kUDIFDeviceImageType = 1,
kUDIFPartitionImageType = 2
};
typedef struct {
uint32_t type;
uint32_t size;
uint32_t data[0x20];
} __attribute__((__packed__)) UDIFChecksum;
typedef struct {
uint32_t data1; /* smallest */
uint32_t data2;
uint32_t data3;
uint32_t data4; /* largest */
} __attribute__((__packed__)) UDIFID;
typedef struct {
uint32_t fUDIFSignature;
uint32_t fUDIFVersion;
uint32_t fUDIFHeaderSize;
uint32_t fUDIFFlags;
uint64_t fUDIFRunningDataForkOffset;
uint64_t fUDIFDataForkOffset;
uint64_t fUDIFDataForkLength;
uint64_t fUDIFRsrcForkOffset;
uint64_t fUDIFRsrcForkLength;
uint32_t fUDIFSegmentNumber;
uint32_t fUDIFSegmentCount;
UDIFID fUDIFSegmentID; /* a 128-bit number like a GUID, but does not seem to be a OSF GUID, since it doesn't have the proper versioning byte */
UDIFChecksum fUDIFDataForkChecksum;
uint64_t fUDIFXMLOffset;
uint64_t fUDIFXMLLength;
uint8_t reserved1[0x78]; /* this is actually the perfect amount of space to store every thing in this struct until the checksum */
UDIFChecksum fUDIFMasterChecksum;
uint32_t fUDIFImageVariant;
uint64_t fUDIFSectorCount;
uint32_t reserved2;
uint32_t reserved3;
uint32_t reserved4;
} __attribute__((__packed__)) UDIFResourceFile;
typedef struct {
uint32_t type;
uint32_t reserved;
uint64_t sectorStart;
uint64_t sectorCount;
uint64_t compOffset;
uint64_t compLength;
} __attribute__((__packed__)) BLKXRun;
typedef struct {
uint16_t version; /* set to 5 */
uint32_t isHFS; /* first dword of v53(ImageInfoRec): Set to 1 if it's a HFS or HFS+ partition -- duh. */
uint32_t unknown1; /* second dword of v53: seems to be garbage if it's HFS+, stuff related to HFS embedded if it's that*/
uint8_t dataLen; /* length of data that proceeds, comes right before the data in ImageInfoRec. Always set to 0 for HFS, HFS+ */
uint8_t data[255]; /* other data from v53, dataLen + 1 bytes, the rest NULL filled... a string? Not set for HFS, HFS+ */
uint32_t unknown2; /* 8 bytes before volumeModified in v53, seems to be always set to 0 for HFS, HFS+ */
uint32_t unknown3; /* 4 bytes before volumeModified in v53, seems to be always set to 0 for HFS, HFS+ */
uint32_t volumeModified; /* offset 272 in v53 */
uint32_t unknown4; /* always seems to be 0 for UDIF */
uint16_t volumeSignature; /* HX in our case */
uint16_t sizePresent; /* always set to 1 */
} __attribute__((__packed__)) SizeResource;
typedef struct {
uint16_t version; /* set to 1 */
uint32_t type; /* set to 0x2 for MKBlockChecksum */
uint32_t checksum;
} __attribute__((__packed__)) CSumResource;
typedef struct NSizResource {
char isVolume;
unsigned char* sha1Digest;
uint32_t blockChecksum2;
uint32_t bytes;
uint32_t modifyDate;
uint32_t partitionNumber;
uint32_t version;
uint32_t volumeSignature;
struct NSizResource* next;
} NSizResource;
#define DDM_DESCRIPTOR 0xFFFFFFFF
#define ENTIRE_DEVICE_DESCRIPTOR 0xFFFFFFFE
typedef struct {
uint32_t fUDIFBlocksSignature;
uint32_t infoVersion;
uint64_t firstSectorNumber;
uint64_t sectorCount;
uint64_t dataStart;
uint32_t decompressBufferRequested;
uint32_t blocksDescriptor;
uint32_t reserved1;
uint32_t reserved2;
uint32_t reserved3;
uint32_t reserved4;
uint32_t reserved5;
uint32_t reserved6;
UDIFChecksum checksum;
uint32_t blocksRunCount;
BLKXRun runs[0];
} __attribute__((__packed__)) BLKXTable;
typedef struct {
uint32_t ddBlock;
uint16_t ddSize;
uint16_t ddType;
} __attribute__((__packed__)) DriverDescriptor;
typedef struct {
uint16_t pmSig;
uint16_t pmSigPad;
uint32_t pmMapBlkCnt;
uint32_t pmPyPartStart;
uint32_t pmPartBlkCnt;
unsigned char pmPartName[32];
unsigned char pmParType[32];
uint32_t pmLgDataStart;
uint32_t pmDataCnt;
uint32_t pmPartStatus;
uint32_t pmLgBootStart;
uint32_t pmBootSize;
uint32_t pmBootAddr;
uint32_t pmBootAddr2;
uint32_t pmBootEntry;
uint32_t pmBootEntry2;
uint32_t pmBootCksum;
unsigned char pmProcessor[16];
uint32_t bootCode;
uint16_t pmPad[186];
} __attribute__((__packed__)) Partition;
typedef struct {
uint16_t sbSig;
uint16_t sbBlkSize;
uint32_t sbBlkCount;
uint16_t sbDevType;
uint16_t sbDevId;
uint32_t sbData;
uint16_t sbDrvrCount;
uint32_t ddBlock;
uint16_t ddSize;
uint16_t ddType;
DriverDescriptor ddPad[0];
} __attribute__((__packed__)) DriverDescriptorRecord;
typedef struct ResourceData {
uint32_t attributes;
unsigned char* data;
size_t dataLength;
int id;
unsigned char* name;
struct ResourceData* next;
} ResourceData;
typedef void (*FlipDataFunc)(unsigned char* data, char out);
typedef void (*ChecksumFunc)(void* ckSum, const unsigned char* data, size_t len);
typedef struct ResourceKey {
unsigned char* key;
ResourceData* data;
struct ResourceKey* next;
FlipDataFunc flipData;
} ResourceKey;
typedef struct {
unsigned long state[5];
unsigned long count[2];
unsigned char buffer[64];
} SHA1_CTX;
typedef struct {
uint32_t block;
uint32_t crc;
SHA1_CTX sha1;
} ChecksumToken;
static inline uint32_t readUInt32(AbstractFile* file) {
uint32_t data;
ASSERT(file->read(file, &data, sizeof(data)) == sizeof(data), "fread");
FLIPENDIAN(data);
return data;
}
static inline void writeUInt32(AbstractFile* file, uint32_t data) {
FLIPENDIAN(data);
ASSERT(file->write(file, &data, sizeof(data)) == sizeof(data), "fwrite");
}
static inline uint32_t readUInt64(AbstractFile* file) {
uint64_t data;
ASSERT(file->read(file, &data, sizeof(data)) == sizeof(data), "fread");
FLIPENDIAN(data);
return data;
}
static inline void writeUInt64(AbstractFile* file, uint64_t data) {
FLIPENDIAN(data);
ASSERT(file->write(file, &data, sizeof(data)) == sizeof(data), "fwrite");
}
#ifdef __cplusplus
extern "C" {
#endif
unsigned char* decodeBase64(char* toDecode, size_t* dataLength);
void writeBase64(AbstractFile* file, unsigned char* data, size_t dataLength, int tabLength, int width);
char* convertBase64(unsigned char* data, size_t dataLength, int tabLength, int width);
uint32_t CRC32Checksum(uint32_t* crc, const unsigned char *buf, size_t len);
uint32_t MKBlockChecksum(uint32_t* ckSum, const unsigned char* data, size_t len);
void BlockSHA1CRC(void* token, const unsigned char* data, size_t len);
void BlockCRC(void* token, const unsigned char* data, size_t len);
void CRCProxy(void* token, const unsigned char* data, size_t len);
void SHA1Transform(unsigned long state[5], const unsigned char buffer[64]);
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len);
void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
void flipUDIFChecksum(UDIFChecksum* o, char out);
void readUDIFChecksum(AbstractFile* file, UDIFChecksum* o);
void writeUDIFChecksum(AbstractFile* file, UDIFChecksum* o);
void readUDIFID(AbstractFile* file, UDIFID* o);
void writeUDIFID(AbstractFile* file, UDIFID* o);
void readUDIFResourceFile(AbstractFile* file, UDIFResourceFile* o);
void writeUDIFResourceFile(AbstractFile* file, UDIFResourceFile* o);
ResourceKey* readResources(AbstractFile* file, UDIFResourceFile* resourceFile);
void writeResources(AbstractFile* file, ResourceKey* resources);
void releaseResources(ResourceKey* resources);
NSizResource* readNSiz(ResourceKey* resources);
ResourceKey* writeNSiz(NSizResource* nSiz);
void releaseNSiz(NSizResource* nSiz);
extern const char* plistHeader;
extern const char* plistFooter;
ResourceKey* getResourceByKey(ResourceKey* resources, const char* key);
ResourceData* getDataByID(ResourceKey* resource, int id);
ResourceKey* insertData(ResourceKey* resources, const char* key, int id, const char* name, const char* data, size_t dataLength, uint32_t attributes);
ResourceKey* makePlst();
ResourceKey* makeSize(HFSPlusVolumeHeader* volumeHeader);
void flipDriverDescriptorRecord(DriverDescriptorRecord* record, char out);
void flipPartition(Partition* partition, char out);
void flipPartitionMultiple(Partition* partition, char multiple, char out);
void readDriverDescriptorMap(AbstractFile* file, ResourceKey* resources);
DriverDescriptorRecord* createDriverDescriptorMap(uint32_t numSectors);
void writeDriverDescriptorMap(AbstractFile* file, DriverDescriptorRecord* DDM, ChecksumFunc dataForkChecksum, void* dataForkToken, ResourceKey **resources);
void readApplePartitionMap(AbstractFile* file, ResourceKey* resources);
Partition* createApplePartitionMap(uint32_t numSectors, const char* volumeType);
void writeApplePartitionMap(AbstractFile* file, Partition* partitions, ChecksumFunc dataForkChecksum, void* dataForkToken, ResourceKey **resources, NSizResource** nsizIn);
void writeATAPI(AbstractFile* file, ChecksumFunc dataForkChecksum, void* dataForkToken, ResourceKey **resources, NSizResource** nsizIn);
void writeFreePartition(AbstractFile* outFile, uint32_t numSectors, ResourceKey** resources);
void extractBLKX(AbstractFile* in, AbstractFile* out, BLKXTable* blkx);
BLKXTable* insertBLKX(AbstractFile* out, AbstractFile* in, uint32_t firstSectorNumber, uint32_t numSectors, uint32_t blocksDescriptor,
uint32_t checksumType, ChecksumFunc uncompressedChk, void* uncompressedChkToken, ChecksumFunc compressedChk,
void* compressedChkToken, Volume* volume);
int extractDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, int partNum);
int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut);
int convertToISO(AbstractFile* abstractIn, AbstractFile* abstractOut);
int convertToDMG(AbstractFile* abstractIn, AbstractFile* abstractOut);
#endif
unsigned char* decodeBase64(char* toDecode, size_t* dataLength);
void writeBase64(AbstractFile* file, unsigned char* data, size_t dataLength, int tabLength, int width);
char* convertBase64(unsigned char* data, size_t dataLength, int tabLength, int width);
uint32_t CRC32Checksum(uint32_t* crc, const unsigned char *buf, size_t len);
uint32_t MKBlockChecksum(uint32_t* ckSum, const unsigned char* data, size_t len);
void BlockSHA1CRC(void* token, const unsigned char* data, size_t len);
void BlockCRC(void* token, const unsigned char* data, size_t len);
void CRCProxy(void* token, const unsigned char* data, size_t len);
void SHA1Transform(unsigned long state[5], const unsigned char buffer[64]);
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len);
void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
void flipUDIFChecksum(UDIFChecksum* o, char out);
void readUDIFChecksum(AbstractFile* file, UDIFChecksum* o);
void writeUDIFChecksum(AbstractFile* file, UDIFChecksum* o);
void readUDIFID(AbstractFile* file, UDIFID* o);
void writeUDIFID(AbstractFile* file, UDIFID* o);
void readUDIFResourceFile(AbstractFile* file, UDIFResourceFile* o);
void writeUDIFResourceFile(AbstractFile* file, UDIFResourceFile* o);
ResourceKey* readResources(AbstractFile* file, UDIFResourceFile* resourceFile);
void writeResources(AbstractFile* file, ResourceKey* resources);
void releaseResources(ResourceKey* resources);
NSizResource* readNSiz(ResourceKey* resources);
ResourceKey* writeNSiz(NSizResource* nSiz);
void releaseNSiz(NSizResource* nSiz);
extern const char* plistHeader;
extern const char* plistFooter;
ResourceKey* getResourceByKey(ResourceKey* resources, const char* key);
ResourceData* getDataByID(ResourceKey* resource, int id);
ResourceKey* insertData(ResourceKey* resources, const char* key, int id, const char* name, const char* data, size_t dataLength, uint32_t attributes);
ResourceKey* makePlst();
ResourceKey* makeSize(HFSPlusVolumeHeader* volumeHeader);
void flipDriverDescriptorRecord(DriverDescriptorRecord* record, char out);
void flipPartition(Partition* partition, char out);
void flipPartitionMultiple(Partition* partition, char multiple, char out);
void readDriverDescriptorMap(AbstractFile* file, ResourceKey* resources);
DriverDescriptorRecord* createDriverDescriptorMap(uint32_t numSectors);
void writeDriverDescriptorMap(AbstractFile* file, DriverDescriptorRecord* DDM, ChecksumFunc dataForkChecksum, void* dataForkToken, ResourceKey **resources);
void readApplePartitionMap(AbstractFile* file, ResourceKey* resources);
Partition* createApplePartitionMap(uint32_t numSectors, const char* volumeType);
void writeApplePartitionMap(AbstractFile* file, Partition* partitions, ChecksumFunc dataForkChecksum, void* dataForkToken, ResourceKey **resources, NSizResource** nsizIn);
void writeATAPI(AbstractFile* file, ChecksumFunc dataForkChecksum, void* dataForkToken, ResourceKey **resources, NSizResource** nsizIn);
void writeFreePartition(AbstractFile* outFile, uint32_t numSectors, ResourceKey** resources);
void extractBLKX(AbstractFile* in, AbstractFile* out, BLKXTable* blkx);
BLKXTable* insertBLKX(AbstractFile* out, AbstractFile* in, uint32_t firstSectorNumber, uint32_t numSectors, uint32_t blocksDescriptor,
uint32_t checksumType, ChecksumFunc uncompressedChk, void* uncompressedChkToken, ChecksumFunc compressedChk,
void* compressedChkToken, Volume* volume);
int extractDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, int partNum);
int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut);
int convertToISO(AbstractFile* abstractIn, AbstractFile* abstractOut);
int convertToDMG(AbstractFile* abstractIn, AbstractFile* abstractOut);
#ifdef __cplusplus
}
#endif
#endif
#endif

Просмотреть файл

@ -1,236 +1,236 @@
/*
* dmgfile.c
* libdmg-hfsplus
*/
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#include "dmg.h"
#include "dmgfile.h"
static void cacheRun(DMG* dmg, BLKXTable* blkx, int run) {
size_t bufferSize;
z_stream strm;
void* inBuffer;
int ret;
size_t have;
if(dmg->runData) {
free(dmg->runData);
}
bufferSize = SECTOR_SIZE * blkx->decompressBufferRequested;
dmg->runData = (void*) malloc(bufferSize);
inBuffer = (void*) malloc(bufferSize);
memset(dmg->runData, 0, bufferSize);
ASSERT(dmg->dmg->seek(dmg->dmg, blkx->dataStart + blkx->runs[run].compOffset) == 0, "fseeko");
switch(blkx->runs[run].type) {
case BLOCK_ZLIB:
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ASSERT(inflateInit(&strm) == Z_OK, "inflateInit");
ASSERT((strm.avail_in = dmg->dmg->read(dmg->dmg, inBuffer, blkx->runs[run].compLength)) == blkx->runs[run].compLength, "fread");
strm.next_in = (unsigned char*) inBuffer;
do {
strm.avail_out = bufferSize;
strm.next_out = (unsigned char*) dmg->runData;
ASSERT((ret = inflate(&strm, Z_NO_FLUSH)) != Z_STREAM_ERROR, "inflate/Z_STREAM_ERROR");
if(ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_STREAM_END) {
ASSERT(FALSE, "inflate");
}
have = bufferSize - strm.avail_out;
} while (strm.avail_out == 0);
ASSERT(inflateEnd(&strm) == Z_OK, "inflateEnd");
break;
case BLOCK_RAW:
ASSERT((have = dmg->dmg->read(dmg->dmg, dmg->runData, blkx->runs[run].compLength)) == blkx->runs[run].compLength, "fread");
break;
case BLOCK_IGNORE:
break;
case BLOCK_COMMENT:
break;
case BLOCK_TERMINATOR:
break;
default:
break;
}
dmg->runStart = (blkx->runs[run].sectorStart + blkx->firstSectorNumber) * SECTOR_SIZE;
dmg->runEnd = dmg->runStart + (blkx->runs[run].sectorCount * SECTOR_SIZE);
}
static void cacheOffset(DMG* dmg, off_t location) {
int i;
int j;
uint64_t sector;
sector = (uint64_t)(location / SECTOR_SIZE);
for(i = 0; i < dmg->numBLKX; i++) {
if(sector >= dmg->blkx[i]->firstSectorNumber && sector < (dmg->blkx[i]->firstSectorNumber + dmg->blkx[i]->sectorCount)) {
for(j = 0; j < dmg->blkx[i]->blocksRunCount; j++) {
if(sector >= (dmg->blkx[i]->firstSectorNumber + dmg->blkx[i]->runs[j].sectorStart) &&
sector < (dmg->blkx[i]->firstSectorNumber + dmg->blkx[i]->runs[j].sectorStart + dmg->blkx[i]->runs[j].sectorCount)) {
cacheRun(dmg, dmg->blkx[i], j);
}
}
}
}
}
static int dmgFileRead(io_func* io, off_t location, size_t size, void *buffer) {
DMG* dmg;
size_t toRead;
dmg = (DMG*) io->data;
location += dmg->offset;
if(size == 0) {
return TRUE;
}
if(location < dmg->runStart || location >= dmg->runEnd) {
cacheOffset(dmg, location);
}
if((location + size) > dmg->runEnd) {
toRead = dmg->runEnd - location;
} else {
toRead = size;
}
memcpy(buffer, (void*)((uint8_t*)dmg->runData + (uint32_t)(location - dmg->runStart)), toRead);
size -= toRead;
location += toRead;
buffer = (void*)((uint8_t*)buffer + toRead);
if(size > 0) {
return dmgFileRead(io, location, size, buffer);
} else {
return TRUE;
}
}
static int dmgFileWrite(io_func* io, off_t location, size_t size, void *buffer) {
fprintf(stderr, "Error: writing to DMGs is not supported (impossible to achieve with compressed images and retain asr multicast ordering).\n");
return FALSE;
}
static void closeDmgFile(io_func* io) {
DMG* dmg;
dmg = (DMG*) io->data;
if(dmg->runData) {
free(dmg->runData);
}
free(dmg->blkx);
releaseResources(dmg->resources);
dmg->dmg->close(dmg->dmg);
free(dmg);
free(io);
}
io_func* openDmgFile(AbstractFile* abstractIn) {
off_t fileLength;
UDIFResourceFile resourceFile;
DMG* dmg;
ResourceData* blkx;
ResourceData* curData;
int i;
io_func* toReturn;
if(abstractIn == NULL) {
return NULL;
}
fileLength = abstractIn->getLength(abstractIn);
abstractIn->seek(abstractIn, fileLength - sizeof(UDIFResourceFile));
readUDIFResourceFile(abstractIn, &resourceFile);
dmg = (DMG*) malloc(sizeof(DMG));
dmg->dmg = abstractIn;
dmg->resources = readResources(abstractIn, &resourceFile);
dmg->numBLKX = 0;
blkx = (getResourceByKey(dmg->resources, "blkx"))->data;
curData = blkx;
while(curData != NULL) {
dmg->numBLKX++;
curData = curData->next;
}
dmg->blkx = (BLKXTable**) malloc(sizeof(BLKXTable*) * dmg->numBLKX);
i = 0;
while(blkx != NULL) {
dmg->blkx[i] = (BLKXTable*)(blkx->data);
i++;
blkx = blkx->next;
}
dmg->offset = 0;
dmg->runData = NULL;
cacheOffset(dmg, 0);
toReturn = (io_func*) malloc(sizeof(io_func));
toReturn->data = dmg;
toReturn->read = &dmgFileRead;
toReturn->write = &dmgFileWrite;
toReturn->close = &closeDmgFile;
return toReturn;
}
io_func* openDmgFilePartition(AbstractFile* abstractIn, int partition) {
io_func* toReturn;
Partition* partitions;
int numPartitions;
int i;
toReturn = openDmgFile(abstractIn);
if(toReturn == NULL) {
return NULL;
}
partitions = (Partition*) malloc(sizeof(Partition));
toReturn->read(toReturn, SECTOR_SIZE, SECTOR_SIZE, partitions);
flipPartitionMultiple(partitions, FALSE, FALSE);
numPartitions = partitions->pmMapBlkCnt;
partitions = (Partition*) realloc(partitions, numPartitions * SECTOR_SIZE);
toReturn->read(toReturn, SECTOR_SIZE, numPartitions * SECTOR_SIZE, partitions);
flipPartition(partitions, FALSE);
if(partition >= 0) {
((DMG*)toReturn->data)->offset = partitions[partition].pmPyPartStart * SECTOR_SIZE;
} else {
for(i = 0; i < numPartitions; i++) {
if(strcmp((char*)partitions[i].pmParType, "Apple_HFSX") == 0 || strcmp((char*)partitions[i].pmParType, "Apple_HFS") == 0) {
((DMG*)toReturn->data)->offset = partitions[i].pmPyPartStart * SECTOR_SIZE;
break;
}
}
}
return toReturn;
}
/*
* dmgfile.c
* libdmg-hfsplus
*/
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#include "dmg.h"
#include "dmgfile.h"
static void cacheRun(DMG* dmg, BLKXTable* blkx, int run) {
size_t bufferSize;
z_stream strm;
void* inBuffer;
int ret;
size_t have;
if(dmg->runData) {
free(dmg->runData);
}
bufferSize = SECTOR_SIZE * blkx->decompressBufferRequested;
dmg->runData = (void*) malloc(bufferSize);
inBuffer = (void*) malloc(bufferSize);
memset(dmg->runData, 0, bufferSize);
ASSERT(dmg->dmg->seek(dmg->dmg, blkx->dataStart + blkx->runs[run].compOffset) == 0, "fseeko");
switch(blkx->runs[run].type) {
case BLOCK_ZLIB:
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ASSERT(inflateInit(&strm) == Z_OK, "inflateInit");
ASSERT((strm.avail_in = dmg->dmg->read(dmg->dmg, inBuffer, blkx->runs[run].compLength)) == blkx->runs[run].compLength, "fread");
strm.next_in = (unsigned char*) inBuffer;
do {
strm.avail_out = bufferSize;
strm.next_out = (unsigned char*) dmg->runData;
ASSERT((ret = inflate(&strm, Z_NO_FLUSH)) != Z_STREAM_ERROR, "inflate/Z_STREAM_ERROR");
if(ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_STREAM_END) {
ASSERT(FALSE, "inflate");
}
have = bufferSize - strm.avail_out;
} while (strm.avail_out == 0);
ASSERT(inflateEnd(&strm) == Z_OK, "inflateEnd");
break;
case BLOCK_RAW:
ASSERT((have = dmg->dmg->read(dmg->dmg, dmg->runData, blkx->runs[run].compLength)) == blkx->runs[run].compLength, "fread");
break;
case BLOCK_IGNORE:
break;
case BLOCK_COMMENT:
break;
case BLOCK_TERMINATOR:
break;
default:
break;
}
dmg->runStart = (blkx->runs[run].sectorStart + blkx->firstSectorNumber) * SECTOR_SIZE;
dmg->runEnd = dmg->runStart + (blkx->runs[run].sectorCount * SECTOR_SIZE);
}
static void cacheOffset(DMG* dmg, off_t location) {
int i;
int j;
uint64_t sector;
sector = (uint64_t)(location / SECTOR_SIZE);
for(i = 0; i < dmg->numBLKX; i++) {
if(sector >= dmg->blkx[i]->firstSectorNumber && sector < (dmg->blkx[i]->firstSectorNumber + dmg->blkx[i]->sectorCount)) {
for(j = 0; j < dmg->blkx[i]->blocksRunCount; j++) {
if(sector >= (dmg->blkx[i]->firstSectorNumber + dmg->blkx[i]->runs[j].sectorStart) &&
sector < (dmg->blkx[i]->firstSectorNumber + dmg->blkx[i]->runs[j].sectorStart + dmg->blkx[i]->runs[j].sectorCount)) {
cacheRun(dmg, dmg->blkx[i], j);
}
}
}
}
}
static int dmgFileRead(io_func* io, off_t location, size_t size, void *buffer) {
DMG* dmg;
size_t toRead;
dmg = (DMG*) io->data;
location += dmg->offset;
if(size == 0) {
return TRUE;
}
if(location < dmg->runStart || location >= dmg->runEnd) {
cacheOffset(dmg, location);
}
if((location + size) > dmg->runEnd) {
toRead = dmg->runEnd - location;
} else {
toRead = size;
}
memcpy(buffer, (void*)((uint8_t*)dmg->runData + (uint32_t)(location - dmg->runStart)), toRead);
size -= toRead;
location += toRead;
buffer = (void*)((uint8_t*)buffer + toRead);
if(size > 0) {
return dmgFileRead(io, location, size, buffer);
} else {
return TRUE;
}
}
static int dmgFileWrite(io_func* io, off_t location, size_t size, void *buffer) {
fprintf(stderr, "Error: writing to DMGs is not supported (impossible to achieve with compressed images and retain asr multicast ordering).\n");
return FALSE;
}
static void closeDmgFile(io_func* io) {
DMG* dmg;
dmg = (DMG*) io->data;
if(dmg->runData) {
free(dmg->runData);
}
free(dmg->blkx);
releaseResources(dmg->resources);
dmg->dmg->close(dmg->dmg);
free(dmg);
free(io);
}
io_func* openDmgFile(AbstractFile* abstractIn) {
off_t fileLength;
UDIFResourceFile resourceFile;
DMG* dmg;
ResourceData* blkx;
ResourceData* curData;
int i;
io_func* toReturn;
if(abstractIn == NULL) {
return NULL;
}
fileLength = abstractIn->getLength(abstractIn);
abstractIn->seek(abstractIn, fileLength - sizeof(UDIFResourceFile));
readUDIFResourceFile(abstractIn, &resourceFile);
dmg = (DMG*) malloc(sizeof(DMG));
dmg->dmg = abstractIn;
dmg->resources = readResources(abstractIn, &resourceFile);
dmg->numBLKX = 0;
blkx = (getResourceByKey(dmg->resources, "blkx"))->data;
curData = blkx;
while(curData != NULL) {
dmg->numBLKX++;
curData = curData->next;
}
dmg->blkx = (BLKXTable**) malloc(sizeof(BLKXTable*) * dmg->numBLKX);
i = 0;
while(blkx != NULL) {
dmg->blkx[i] = (BLKXTable*)(blkx->data);
i++;
blkx = blkx->next;
}
dmg->offset = 0;
dmg->runData = NULL;
cacheOffset(dmg, 0);
toReturn = (io_func*) malloc(sizeof(io_func));
toReturn->data = dmg;
toReturn->read = &dmgFileRead;
toReturn->write = &dmgFileWrite;
toReturn->close = &closeDmgFile;
return toReturn;
}
io_func* openDmgFilePartition(AbstractFile* abstractIn, int partition) {
io_func* toReturn;
Partition* partitions;
int numPartitions;
int i;
toReturn = openDmgFile(abstractIn);
if(toReturn == NULL) {
return NULL;
}
partitions = (Partition*) malloc(sizeof(Partition));
toReturn->read(toReturn, SECTOR_SIZE, SECTOR_SIZE, partitions);
flipPartitionMultiple(partitions, FALSE, FALSE);
numPartitions = partitions->pmMapBlkCnt;
partitions = (Partition*) realloc(partitions, numPartitions * SECTOR_SIZE);
toReturn->read(toReturn, SECTOR_SIZE, numPartitions * SECTOR_SIZE, partitions);
flipPartition(partitions, FALSE);
if(partition >= 0) {
((DMG*)toReturn->data)->offset = partitions[partition].pmPyPartStart * SECTOR_SIZE;
} else {
for(i = 0; i < numPartitions; i++) {
if(strcmp((char*)partitions[i].pmParType, "Apple_HFSX") == 0 || strcmp((char*)partitions[i].pmParType, "Apple_HFS") == 0) {
((DMG*)toReturn->data)->offset = partitions[i].pmPyPartStart * SECTOR_SIZE;
break;
}
}
}
return toReturn;
}

Просмотреть файл

@ -1,22 +1,22 @@
/*
* dmgfile.h
* libdmg-hfsplus
*
*/
#include "../hfs/common.h"
#include "dmg.h"
io_func* openDmgFile(AbstractFile* dmg);
io_func* openDmgFilePartition(AbstractFile* dmg, int partition);
typedef struct DMG {
AbstractFile* dmg;
ResourceKey* resources;
uint32_t numBLKX;
BLKXTable** blkx;
void* runData;
uint64_t runStart;
uint64_t runEnd;
uint64_t offset;
} DMG;
/*
* dmgfile.h
* libdmg-hfsplus
*
*/
#include "../hfs/common.h"
#include "dmg.h"
io_func* openDmgFile(AbstractFile* dmg);
io_func* openDmgFilePartition(AbstractFile* dmg, int partition);
typedef struct DMG {
AbstractFile* dmg;
ResourceKey* resources;
uint32_t numBLKX;
BLKXTable** blkx;
void* runData;
uint64_t runStart;
uint64_t runEnd;
uint64_t offset;
} DMG;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,4 @@
#ifndef DMGLIB_H
#ifndef DMGLIB_H
#define DMGLIB_H
#include "dmg.h"
@ -6,7 +6,7 @@
#ifdef __cplusplus
extern "C" {
#endif
#endif
int extractDmg(AbstractFile* abstractIn, AbstractFile* abstractOut, int partNum);
int buildDmg(AbstractFile* abstractIn, AbstractFile* abstractOut);
@ -15,5 +15,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif
#endif
#endif

Просмотреть файл

@ -1,263 +1,263 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "dmg.h"
#include "filevault.h"
#ifdef HAVE_CRYPT
#include <openssl/hmac.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#define CHUNKNO(oft, info) ((uint32_t)((oft)/info->blockSize))
#define CHUNKOFFSET(oft, info) ((size_t)((oft) - ((off_t)(CHUNKNO(oft, info)) * (off_t)info->blockSize)))
static void flipFileVaultV2Header(FileVaultV2Header* header) {
FLIPENDIAN(header->signature);
FLIPENDIAN(header->version);
FLIPENDIAN(header->encIVSize);
FLIPENDIAN(header->unk1);
FLIPENDIAN(header->unk2);
FLIPENDIAN(header->unk3);
FLIPENDIAN(header->unk4);
FLIPENDIAN(header->unk5);
FLIPENDIAN(header->unk5);
FLIPENDIAN(header->blockSize);
FLIPENDIAN(header->dataSize);
FLIPENDIAN(header->dataOffset);
FLIPENDIAN(header->kdfAlgorithm);
FLIPENDIAN(header->kdfPRNGAlgorithm);
FLIPENDIAN(header->kdfIterationCount);
FLIPENDIAN(header->kdfSaltLen);
FLIPENDIAN(header->blobEncIVSize);
FLIPENDIAN(header->blobEncKeyBits);
FLIPENDIAN(header->blobEncAlgorithm);
FLIPENDIAN(header->blobEncPadding);
FLIPENDIAN(header->blobEncMode);
FLIPENDIAN(header->encryptedKeyblobSize);
}
static void writeChunk(FileVaultInfo* info) {
unsigned char buffer[info->blockSize];
unsigned char buffer2[info->blockSize];
unsigned char msgDigest[FILEVAULT_MSGDGST_LENGTH];
uint32_t msgDigestLen;
uint32_t myChunk;
myChunk = info->curChunk;
FLIPENDIAN(myChunk);
HMAC_Init_ex(&(info->hmacCTX), NULL, 0, NULL, NULL);
HMAC_Update(&(info->hmacCTX), (unsigned char *) &myChunk, sizeof(uint32_t));
HMAC_Final(&(info->hmacCTX), msgDigest, &msgDigestLen);
AES_cbc_encrypt(info->chunk, buffer, info->blockSize, &(info->aesEncKey), msgDigest, AES_ENCRYPT);
info->file->seek(info->file, (info->curChunk * info->blockSize) + info->dataOffset);
info->file->read(info->file, buffer2, info->blockSize);
info->file->seek(info->file, (info->curChunk * info->blockSize) + info->dataOffset);
info->file->write(info->file, buffer, info->blockSize);
info->dirty = FALSE;
}
static void cacheChunk(FileVaultInfo* info, uint32_t chunk) {
unsigned char buffer[info->blockSize];
unsigned char msgDigest[FILEVAULT_MSGDGST_LENGTH];
uint32_t msgDigestLen;
if(chunk == info->curChunk) {
return;
}
if(info->dirty) {
writeChunk(info);
}
info->file->seek(info->file, chunk * info->blockSize + info->dataOffset);
info->file->read(info->file, buffer, info->blockSize);
info->curChunk = chunk;
FLIPENDIAN(chunk);
HMAC_Init_ex(&(info->hmacCTX), NULL, 0, NULL, NULL);
HMAC_Update(&(info->hmacCTX), (unsigned char *) &chunk, sizeof(uint32_t));
HMAC_Final(&(info->hmacCTX), msgDigest, &msgDigestLen);
AES_cbc_encrypt(buffer, info->chunk, info->blockSize, &(info->aesKey), msgDigest, AES_DECRYPT);
}
size_t fvRead(AbstractFile* file, void* data, size_t len) {
FileVaultInfo* info;
size_t toRead;
info = (FileVaultInfo*) (file->data);
if((CHUNKOFFSET(info->offset, info) + len) > info->blockSize) {
toRead = info->blockSize - CHUNKOFFSET(info->offset, info);
memcpy(data, (void *)((uint8_t*)(&(info->chunk)) + CHUNKOFFSET(info->offset, info)), toRead);
info->offset += toRead;
cacheChunk(info, CHUNKNO(info->offset, info));
return toRead + fvRead(file, (void *)((uint8_t*)data + toRead), len - toRead);
} else {
toRead = len;
memcpy(data, (void *)((uint8_t*)(&(info->chunk)) + CHUNKOFFSET(info->offset, info)), toRead);
info->offset += toRead;
cacheChunk(info, CHUNKNO(info->offset, info));
return toRead;
}
}
size_t fvWrite(AbstractFile* file, const void* data, size_t len) {
FileVaultInfo* info;
size_t toRead;
int i;
info = (FileVaultInfo*) (file->data);
if(info->dataSize < (info->offset + len)) {
if(info->version == 2) {
info->header.v2.dataSize = info->offset + len;
}
info->headerDirty = TRUE;
}
if((CHUNKOFFSET(info->offset, info) + len) > info->blockSize) {
toRead = info->blockSize - CHUNKOFFSET(info->offset, info);
for(i = 0; i < toRead; i++) {
ASSERT(*((char*)((uint8_t*)(&(info->chunk)) + (uint32_t)CHUNKOFFSET(info->offset, info) + i)) == ((char*)data)[i], "blah");
}
memcpy((void *)((uint8_t*)(&(info->chunk)) + (uint32_t)CHUNKOFFSET(info->offset, info)), data, toRead);
info->dirty = TRUE;
info->offset += toRead;
cacheChunk(info, CHUNKNO(info->offset, info));
return toRead + fvWrite(file, (void *)((uint8_t*)data + toRead), len - toRead);
} else {
toRead = len;
for(i = 0; i < toRead; i++) {
ASSERT(*((char*)((uint8_t*)(&(info->chunk)) + CHUNKOFFSET(info->offset, info) + i)) == ((char*)data)[i], "blah");
}
memcpy((void *)((uint8_t*)(&(info->chunk)) + CHUNKOFFSET(info->offset, info)), data, toRead);
info->dirty = TRUE;
info->offset += toRead;
cacheChunk(info, CHUNKNO(info->offset, info));
return toRead;
}
}
int fvSeek(AbstractFile* file, off_t offset) {
FileVaultInfo* info = (FileVaultInfo*) (file->data);
info->offset = offset;
cacheChunk(info, CHUNKNO(offset, info));
return 0;
}
off_t fvTell(AbstractFile* file) {
FileVaultInfo* info = (FileVaultInfo*) (file->data);
return info->offset;
}
off_t fvGetLength(AbstractFile* file) {
FileVaultInfo* info = (FileVaultInfo*) (file->data);
return info->dataSize;
}
void fvClose(AbstractFile* file) {
FileVaultInfo* info = (FileVaultInfo*) (file->data);
/* force a flush */
if(info->curChunk == 0) {
cacheChunk(info, 1);
} else {
cacheChunk(info, 0);
}
HMAC_CTX_cleanup(&(info->hmacCTX));
if(info->headerDirty) {
if(info->version == 2) {
file->seek(file, 0);
flipFileVaultV2Header(&(info->header.v2));
file->write(file, &(info->header.v2), sizeof(FileVaultV2Header));
}
}
info->file->close(info->file);
free(info);
free(file);
}
AbstractFile* createAbstractFileFromFileVault(AbstractFile* file, const char* key) {
FileVaultInfo* info;
AbstractFile* toReturn;
uint64_t signature;
uint8_t aesKey[16];
uint8_t hmacKey[20];
int i;
if(file == NULL)
return NULL;
file->seek(file, 0);
file->read(file, &signature, sizeof(uint64_t));
FLIPENDIAN(signature);
if(signature != FILEVAULT_V2_SIGNATURE) {
/* no FileVault v1 handling yet */
return NULL;
}
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
info = (FileVaultInfo*) malloc(sizeof(FileVaultInfo));
info->version = 2;
file->seek(file, 0);
file->read(file, &(info->header.v2), sizeof(FileVaultV2Header));
flipFileVaultV2Header(&(info->header.v2));
for(i = 0; i < 16; i++) {
sscanf(&(key[i * 2]), "%02hhx", &(aesKey[i]));
}
for(i = 0; i < 20; i++) {
sscanf(&(key[(16 * 2) + i * 2]), "%02hhx", &(hmacKey[i]));
}
HMAC_CTX_init(&(info->hmacCTX));
HMAC_Init_ex(&(info->hmacCTX), hmacKey, sizeof(hmacKey), EVP_sha1(), NULL);
AES_set_decrypt_key(aesKey, FILEVAULT_CIPHER_KEY_LENGTH * 8, &(info->aesKey));
AES_set_encrypt_key(aesKey, FILEVAULT_CIPHER_KEY_LENGTH * 8, &(info->aesEncKey));
info->dataOffset = info->header.v2.dataOffset;
info->dataSize = info->header.v2.dataSize;
info->blockSize = info->header.v2.blockSize;
info->offset = 0;
info->file = file;
info->headerDirty = FALSE;
info->dirty = FALSE;
info->curChunk = 1; /* just to set it to a value not 0 */
cacheChunk(info, 0);
toReturn->data = info;
toReturn->read = fvRead;
toReturn->write = fvWrite;
toReturn->seek = fvSeek;
toReturn->tell = fvTell;
toReturn->getLength = fvGetLength;
toReturn->close = fvClose;
return toReturn;
}
#else
AbstractFile* createAbstractFileFromFileVault(AbstractFile* file, const char* key) {
return NULL;
}
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "dmg.h"
#include "filevault.h"
#ifdef HAVE_CRYPT
#include <openssl/hmac.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#define CHUNKNO(oft, info) ((uint32_t)((oft)/info->blockSize))
#define CHUNKOFFSET(oft, info) ((size_t)((oft) - ((off_t)(CHUNKNO(oft, info)) * (off_t)info->blockSize)))
static void flipFileVaultV2Header(FileVaultV2Header* header) {
FLIPENDIAN(header->signature);
FLIPENDIAN(header->version);
FLIPENDIAN(header->encIVSize);
FLIPENDIAN(header->unk1);
FLIPENDIAN(header->unk2);
FLIPENDIAN(header->unk3);
FLIPENDIAN(header->unk4);
FLIPENDIAN(header->unk5);
FLIPENDIAN(header->unk5);
FLIPENDIAN(header->blockSize);
FLIPENDIAN(header->dataSize);
FLIPENDIAN(header->dataOffset);
FLIPENDIAN(header->kdfAlgorithm);
FLIPENDIAN(header->kdfPRNGAlgorithm);
FLIPENDIAN(header->kdfIterationCount);
FLIPENDIAN(header->kdfSaltLen);
FLIPENDIAN(header->blobEncIVSize);
FLIPENDIAN(header->blobEncKeyBits);
FLIPENDIAN(header->blobEncAlgorithm);
FLIPENDIAN(header->blobEncPadding);
FLIPENDIAN(header->blobEncMode);
FLIPENDIAN(header->encryptedKeyblobSize);
}
static void writeChunk(FileVaultInfo* info) {
unsigned char buffer[info->blockSize];
unsigned char buffer2[info->blockSize];
unsigned char msgDigest[FILEVAULT_MSGDGST_LENGTH];
uint32_t msgDigestLen;
uint32_t myChunk;
myChunk = info->curChunk;
FLIPENDIAN(myChunk);
HMAC_Init_ex(&(info->hmacCTX), NULL, 0, NULL, NULL);
HMAC_Update(&(info->hmacCTX), (unsigned char *) &myChunk, sizeof(uint32_t));
HMAC_Final(&(info->hmacCTX), msgDigest, &msgDigestLen);
AES_cbc_encrypt(info->chunk, buffer, info->blockSize, &(info->aesEncKey), msgDigest, AES_ENCRYPT);
info->file->seek(info->file, (info->curChunk * info->blockSize) + info->dataOffset);
info->file->read(info->file, buffer2, info->blockSize);
info->file->seek(info->file, (info->curChunk * info->blockSize) + info->dataOffset);
info->file->write(info->file, buffer, info->blockSize);
info->dirty = FALSE;
}
static void cacheChunk(FileVaultInfo* info, uint32_t chunk) {
unsigned char buffer[info->blockSize];
unsigned char msgDigest[FILEVAULT_MSGDGST_LENGTH];
uint32_t msgDigestLen;
if(chunk == info->curChunk) {
return;
}
if(info->dirty) {
writeChunk(info);
}
info->file->seek(info->file, chunk * info->blockSize + info->dataOffset);
info->file->read(info->file, buffer, info->blockSize);
info->curChunk = chunk;
FLIPENDIAN(chunk);
HMAC_Init_ex(&(info->hmacCTX), NULL, 0, NULL, NULL);
HMAC_Update(&(info->hmacCTX), (unsigned char *) &chunk, sizeof(uint32_t));
HMAC_Final(&(info->hmacCTX), msgDigest, &msgDigestLen);
AES_cbc_encrypt(buffer, info->chunk, info->blockSize, &(info->aesKey), msgDigest, AES_DECRYPT);
}
size_t fvRead(AbstractFile* file, void* data, size_t len) {
FileVaultInfo* info;
size_t toRead;
info = (FileVaultInfo*) (file->data);
if((CHUNKOFFSET(info->offset, info) + len) > info->blockSize) {
toRead = info->blockSize - CHUNKOFFSET(info->offset, info);
memcpy(data, (void *)((uint8_t*)(&(info->chunk)) + CHUNKOFFSET(info->offset, info)), toRead);
info->offset += toRead;
cacheChunk(info, CHUNKNO(info->offset, info));
return toRead + fvRead(file, (void *)((uint8_t*)data + toRead), len - toRead);
} else {
toRead = len;
memcpy(data, (void *)((uint8_t*)(&(info->chunk)) + CHUNKOFFSET(info->offset, info)), toRead);
info->offset += toRead;
cacheChunk(info, CHUNKNO(info->offset, info));
return toRead;
}
}
size_t fvWrite(AbstractFile* file, const void* data, size_t len) {
FileVaultInfo* info;
size_t toRead;
int i;
info = (FileVaultInfo*) (file->data);
if(info->dataSize < (info->offset + len)) {
if(info->version == 2) {
info->header.v2.dataSize = info->offset + len;
}
info->headerDirty = TRUE;
}
if((CHUNKOFFSET(info->offset, info) + len) > info->blockSize) {
toRead = info->blockSize - CHUNKOFFSET(info->offset, info);
for(i = 0; i < toRead; i++) {
ASSERT(*((char*)((uint8_t*)(&(info->chunk)) + (uint32_t)CHUNKOFFSET(info->offset, info) + i)) == ((char*)data)[i], "blah");
}
memcpy((void *)((uint8_t*)(&(info->chunk)) + (uint32_t)CHUNKOFFSET(info->offset, info)), data, toRead);
info->dirty = TRUE;
info->offset += toRead;
cacheChunk(info, CHUNKNO(info->offset, info));
return toRead + fvWrite(file, (void *)((uint8_t*)data + toRead), len - toRead);
} else {
toRead = len;
for(i = 0; i < toRead; i++) {
ASSERT(*((char*)((uint8_t*)(&(info->chunk)) + CHUNKOFFSET(info->offset, info) + i)) == ((char*)data)[i], "blah");
}
memcpy((void *)((uint8_t*)(&(info->chunk)) + CHUNKOFFSET(info->offset, info)), data, toRead);
info->dirty = TRUE;
info->offset += toRead;
cacheChunk(info, CHUNKNO(info->offset, info));
return toRead;
}
}
int fvSeek(AbstractFile* file, off_t offset) {
FileVaultInfo* info = (FileVaultInfo*) (file->data);
info->offset = offset;
cacheChunk(info, CHUNKNO(offset, info));
return 0;
}
off_t fvTell(AbstractFile* file) {
FileVaultInfo* info = (FileVaultInfo*) (file->data);
return info->offset;
}
off_t fvGetLength(AbstractFile* file) {
FileVaultInfo* info = (FileVaultInfo*) (file->data);
return info->dataSize;
}
void fvClose(AbstractFile* file) {
FileVaultInfo* info = (FileVaultInfo*) (file->data);
/* force a flush */
if(info->curChunk == 0) {
cacheChunk(info, 1);
} else {
cacheChunk(info, 0);
}
HMAC_CTX_cleanup(&(info->hmacCTX));
if(info->headerDirty) {
if(info->version == 2) {
file->seek(file, 0);
flipFileVaultV2Header(&(info->header.v2));
file->write(file, &(info->header.v2), sizeof(FileVaultV2Header));
}
}
info->file->close(info->file);
free(info);
free(file);
}
AbstractFile* createAbstractFileFromFileVault(AbstractFile* file, const char* key) {
FileVaultInfo* info;
AbstractFile* toReturn;
uint64_t signature;
uint8_t aesKey[16];
uint8_t hmacKey[20];
int i;
if(file == NULL)
return NULL;
file->seek(file, 0);
file->read(file, &signature, sizeof(uint64_t));
FLIPENDIAN(signature);
if(signature != FILEVAULT_V2_SIGNATURE) {
/* no FileVault v1 handling yet */
return NULL;
}
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
info = (FileVaultInfo*) malloc(sizeof(FileVaultInfo));
info->version = 2;
file->seek(file, 0);
file->read(file, &(info->header.v2), sizeof(FileVaultV2Header));
flipFileVaultV2Header(&(info->header.v2));
for(i = 0; i < 16; i++) {
sscanf(&(key[i * 2]), "%02hhx", &(aesKey[i]));
}
for(i = 0; i < 20; i++) {
sscanf(&(key[(16 * 2) + i * 2]), "%02hhx", &(hmacKey[i]));
}
HMAC_CTX_init(&(info->hmacCTX));
HMAC_Init_ex(&(info->hmacCTX), hmacKey, sizeof(hmacKey), EVP_sha1(), NULL);
AES_set_decrypt_key(aesKey, FILEVAULT_CIPHER_KEY_LENGTH * 8, &(info->aesKey));
AES_set_encrypt_key(aesKey, FILEVAULT_CIPHER_KEY_LENGTH * 8, &(info->aesEncKey));
info->dataOffset = info->header.v2.dataOffset;
info->dataSize = info->header.v2.dataSize;
info->blockSize = info->header.v2.blockSize;
info->offset = 0;
info->file = file;
info->headerDirty = FALSE;
info->dirty = FALSE;
info->curChunk = 1; /* just to set it to a value not 0 */
cacheChunk(info, 0);
toReturn->data = info;
toReturn->read = fvRead;
toReturn->write = fvWrite;
toReturn->seek = fvSeek;
toReturn->tell = fvTell;
toReturn->getLength = fvGetLength;
toReturn->close = fvClose;
return toReturn;
}
#else
AbstractFile* createAbstractFileFromFileVault(AbstractFile* file, const char* key) {
return NULL;
}
#endif

Просмотреть файл

@ -1,98 +1,98 @@
#ifndef FILEVAULT_H
#define FILEVAULT_H
#include <stdint.h>
#include "dmg.h"
#ifdef HAVE_CRYPT
#include <openssl/hmac.h>
#include <openssl/aes.h>
#define FILEVAULT_CIPHER_KEY_LENGTH 16
#define FILEVAULT_CIPHER_BLOCKSIZE 16
#define FILEVAULT_CHUNK_SIZE 4096
#define FILEVAULT_PBKDF2_ITER_COUNT 1000
#define FILEVAULT_MSGDGST_LENGTH 20
/*
* Information about the FileVault format was yoinked from vfdecrypt, which was written by Ralf-Philipp Weinmann <ralf@coderpunks.org>,
* Jacob Appelbaum <jacob@appelbaum.net>, and Christian Fromme <kaner@strace.org>
*/
#define FILEVAULT_V2_SIGNATURE 0x656e637263647361ULL
typedef struct FileVaultV1Header {
uint8_t padding1[48];
uint32_t kdfIterationCount;
uint32_t kdfSaltLen;
uint8_t kdfSalt[48];
uint8_t unwrapIV[0x20];
uint32_t wrappedAESKeyLen;
uint8_t wrappedAESKey[296];
uint32_t wrappedHMACSHA1KeyLen;
uint8_t wrappedHMACSHA1Key[300];
uint32_t integrityKeyLen;
uint8_t integrityKey[48];
uint8_t padding2[484];
} __attribute__((__packed__)) FileVaultV1Header;
typedef struct FileVaultV2Header {
uint64_t signature;
uint32_t version;
uint32_t encIVSize;
uint32_t unk1;
uint32_t unk2;
uint32_t unk3;
uint32_t unk4;
uint32_t unk5;
UDIFID uuid;
uint32_t blockSize;
uint64_t dataSize;
uint64_t dataOffset;
uint8_t padding[0x260];
uint32_t kdfAlgorithm;
uint32_t kdfPRNGAlgorithm;
uint32_t kdfIterationCount;
uint32_t kdfSaltLen;
uint8_t kdfSalt[0x20];
uint32_t blobEncIVSize;
uint8_t blobEncIV[0x20];
uint32_t blobEncKeyBits;
uint32_t blobEncAlgorithm;
uint32_t blobEncPadding;
uint32_t blobEncMode;
uint32_t encryptedKeyblobSize;
uint8_t encryptedKeyblob[0x30];
} __attribute__((__packed__)) FileVaultV2Header;
typedef struct FileVaultInfo {
union {
FileVaultV1Header v1;
FileVaultV2Header v2;
} header;
uint8_t version;
uint64_t dataOffset;
uint64_t dataSize;
uint32_t blockSize;
AbstractFile* file;
HMAC_CTX hmacCTX;
AES_KEY aesKey;
AES_KEY aesEncKey;
off_t offset;
uint32_t curChunk;
unsigned char chunk[FILEVAULT_CHUNK_SIZE];
char dirty;
char headerDirty;
} FileVaultInfo;
#endif
AbstractFile* createAbstractFileFromFileVault(AbstractFile* file, const char* key);
#endif
#ifndef FILEVAULT_H
#define FILEVAULT_H
#include <stdint.h>
#include "dmg.h"
#ifdef HAVE_CRYPT
#include <openssl/hmac.h>
#include <openssl/aes.h>
#define FILEVAULT_CIPHER_KEY_LENGTH 16
#define FILEVAULT_CIPHER_BLOCKSIZE 16
#define FILEVAULT_CHUNK_SIZE 4096
#define FILEVAULT_PBKDF2_ITER_COUNT 1000
#define FILEVAULT_MSGDGST_LENGTH 20
/*
* Information about the FileVault format was yoinked from vfdecrypt, which was written by Ralf-Philipp Weinmann <ralf@coderpunks.org>,
* Jacob Appelbaum <jacob@appelbaum.net>, and Christian Fromme <kaner@strace.org>
*/
#define FILEVAULT_V2_SIGNATURE 0x656e637263647361ULL
typedef struct FileVaultV1Header {
uint8_t padding1[48];
uint32_t kdfIterationCount;
uint32_t kdfSaltLen;
uint8_t kdfSalt[48];
uint8_t unwrapIV[0x20];
uint32_t wrappedAESKeyLen;
uint8_t wrappedAESKey[296];
uint32_t wrappedHMACSHA1KeyLen;
uint8_t wrappedHMACSHA1Key[300];
uint32_t integrityKeyLen;
uint8_t integrityKey[48];
uint8_t padding2[484];
} __attribute__((__packed__)) FileVaultV1Header;
typedef struct FileVaultV2Header {
uint64_t signature;
uint32_t version;
uint32_t encIVSize;
uint32_t unk1;
uint32_t unk2;
uint32_t unk3;
uint32_t unk4;
uint32_t unk5;
UDIFID uuid;
uint32_t blockSize;
uint64_t dataSize;
uint64_t dataOffset;
uint8_t padding[0x260];
uint32_t kdfAlgorithm;
uint32_t kdfPRNGAlgorithm;
uint32_t kdfIterationCount;
uint32_t kdfSaltLen;
uint8_t kdfSalt[0x20];
uint32_t blobEncIVSize;
uint8_t blobEncIV[0x20];
uint32_t blobEncKeyBits;
uint32_t blobEncAlgorithm;
uint32_t blobEncPadding;
uint32_t blobEncMode;
uint32_t encryptedKeyblobSize;
uint8_t encryptedKeyblob[0x30];
} __attribute__((__packed__)) FileVaultV2Header;
typedef struct FileVaultInfo {
union {
FileVaultV1Header v1;
FileVaultV2Header v2;
} header;
uint8_t version;
uint64_t dataOffset;
uint64_t dataSize;
uint32_t blockSize;
AbstractFile* file;
HMAC_CTX hmacCTX;
AES_KEY aesKey;
AES_KEY aesEncKey;
off_t offset;
uint32_t curChunk;
unsigned char chunk[FILEVAULT_CHUNK_SIZE];
char dirty;
char headerDirty;
} FileVaultInfo;
#endif
AbstractFile* createAbstractFileFromFileVault(AbstractFile* file, const char* key);
#endif

436
dmg/io.c
Просмотреть файл

@ -1,224 +1,224 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <zlib.h>
#include "dmg.h"
#define SECTORS_AT_A_TIME 0x200
BLKXTable* insertBLKX(AbstractFile* out, AbstractFile* in, uint32_t firstSectorNumber, uint32_t numSectors, uint32_t blocksDescriptor,
uint32_t checksumType, ChecksumFunc uncompressedChk, void* uncompressedChkToken, ChecksumFunc compressedChk,
void* compressedChkToken, Volume* volume) {
BLKXTable* blkx;
uint32_t roomForRuns;
uint32_t curRun;
uint64_t curSector;
unsigned char* inBuffer;
unsigned char* outBuffer;
size_t bufferSize;
size_t have;
int ret;
z_stream strm;
blkx = (BLKXTable*) malloc(sizeof(BLKXTable) + (2 * sizeof(BLKXRun)));
roomForRuns = 2;
memset(blkx, 0, sizeof(BLKXTable) + (roomForRuns * sizeof(BLKXRun)));
blkx->fUDIFBlocksSignature = UDIF_BLOCK_SIGNATURE;
blkx->infoVersion = 1;
blkx->firstSectorNumber = firstSectorNumber;
blkx->sectorCount = numSectors;
blkx->dataStart = 0;
blkx->decompressBufferRequested = 0x208;
blkx->blocksDescriptor = blocksDescriptor;
blkx->reserved1 = 0;
blkx->reserved2 = 0;
blkx->reserved3 = 0;
blkx->reserved4 = 0;
blkx->reserved5 = 0;
blkx->reserved6 = 0;
memset(&(blkx->checksum), 0, sizeof(blkx->checksum));
blkx->checksum.type = checksumType;
blkx->checksum.size = 0x20;
blkx->blocksRunCount = 0;
bufferSize = SECTOR_SIZE * blkx->decompressBufferRequested;
ASSERT(inBuffer = (unsigned char*) malloc(bufferSize), "malloc");
ASSERT(outBuffer = (unsigned char*) malloc(bufferSize), "malloc");
curRun = 0;
curSector = 0;
while(numSectors > 0) {
if(curRun >= roomForRuns) {
roomForRuns <<= 1;
blkx = (BLKXTable*) realloc(blkx, sizeof(BLKXTable) + (roomForRuns * sizeof(BLKXRun)));
}
blkx->runs[curRun].type = BLOCK_ZLIB;
blkx->runs[curRun].reserved = 0;
blkx->runs[curRun].sectorStart = curSector;
blkx->runs[curRun].sectorCount = (numSectors > SECTORS_AT_A_TIME) ? SECTORS_AT_A_TIME : numSectors;
memset(&strm, 0, sizeof(strm));
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
printf("run %d: sectors=%lld, left=%d\n", curRun, blkx->runs[curRun].sectorCount, numSectors);
ASSERT(deflateInit(&strm, Z_DEFAULT_COMPRESSION) == Z_OK, "deflateInit");
ASSERT((strm.avail_in = in->read(in, inBuffer, blkx->runs[curRun].sectorCount * SECTOR_SIZE)) == (blkx->runs[curRun].sectorCount * SECTOR_SIZE), "mRead");
strm.next_in = inBuffer;
if(uncompressedChk)
(*uncompressedChk)(uncompressedChkToken, inBuffer, blkx->runs[curRun].sectorCount * SECTOR_SIZE);
blkx->runs[curRun].compOffset = out->tell(out) - blkx->dataStart;
blkx->runs[curRun].compLength = 0;
strm.avail_out = bufferSize;
strm.next_out = outBuffer;
ASSERT((ret = deflate(&strm, Z_FINISH)) != Z_STREAM_ERROR, "deflate/Z_STREAM_ERROR");
if(ret != Z_STREAM_END) {
ASSERT(FALSE, "deflate");
}
have = bufferSize - strm.avail_out;
if((have / SECTOR_SIZE) > blkx->runs[curRun].sectorCount) {
blkx->runs[curRun].type = BLOCK_RAW;
ASSERT(out->write(out, inBuffer, blkx->runs[curRun].sectorCount * SECTOR_SIZE) == (blkx->runs[curRun].sectorCount * SECTOR_SIZE), "fwrite");
blkx->runs[curRun].compLength += blkx->runs[curRun].sectorCount * SECTOR_SIZE;
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <zlib.h>
if(compressedChk)
#include "dmg.h"
#define SECTORS_AT_A_TIME 0x200
BLKXTable* insertBLKX(AbstractFile* out, AbstractFile* in, uint32_t firstSectorNumber, uint32_t numSectors, uint32_t blocksDescriptor,
uint32_t checksumType, ChecksumFunc uncompressedChk, void* uncompressedChkToken, ChecksumFunc compressedChk,
void* compressedChkToken, Volume* volume) {
BLKXTable* blkx;
uint32_t roomForRuns;
uint32_t curRun;
uint64_t curSector;
unsigned char* inBuffer;
unsigned char* outBuffer;
size_t bufferSize;
size_t have;
int ret;
z_stream strm;
blkx = (BLKXTable*) malloc(sizeof(BLKXTable) + (2 * sizeof(BLKXRun)));
roomForRuns = 2;
memset(blkx, 0, sizeof(BLKXTable) + (roomForRuns * sizeof(BLKXRun)));
blkx->fUDIFBlocksSignature = UDIF_BLOCK_SIGNATURE;
blkx->infoVersion = 1;
blkx->firstSectorNumber = firstSectorNumber;
blkx->sectorCount = numSectors;
blkx->dataStart = 0;
blkx->decompressBufferRequested = 0x208;
blkx->blocksDescriptor = blocksDescriptor;
blkx->reserved1 = 0;
blkx->reserved2 = 0;
blkx->reserved3 = 0;
blkx->reserved4 = 0;
blkx->reserved5 = 0;
blkx->reserved6 = 0;
memset(&(blkx->checksum), 0, sizeof(blkx->checksum));
blkx->checksum.type = checksumType;
blkx->checksum.size = 0x20;
blkx->blocksRunCount = 0;
bufferSize = SECTOR_SIZE * blkx->decompressBufferRequested;
ASSERT(inBuffer = (unsigned char*) malloc(bufferSize), "malloc");
ASSERT(outBuffer = (unsigned char*) malloc(bufferSize), "malloc");
curRun = 0;
curSector = 0;
while(numSectors > 0) {
if(curRun >= roomForRuns) {
roomForRuns <<= 1;
blkx = (BLKXTable*) realloc(blkx, sizeof(BLKXTable) + (roomForRuns * sizeof(BLKXRun)));
}
blkx->runs[curRun].type = BLOCK_ZLIB;
blkx->runs[curRun].reserved = 0;
blkx->runs[curRun].sectorStart = curSector;
blkx->runs[curRun].sectorCount = (numSectors > SECTORS_AT_A_TIME) ? SECTORS_AT_A_TIME : numSectors;
memset(&strm, 0, sizeof(strm));
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
printf("run %d: sectors=%lld, left=%d\n", curRun, blkx->runs[curRun].sectorCount, numSectors);
ASSERT(deflateInit(&strm, Z_DEFAULT_COMPRESSION) == Z_OK, "deflateInit");
ASSERT((strm.avail_in = in->read(in, inBuffer, blkx->runs[curRun].sectorCount * SECTOR_SIZE)) == (blkx->runs[curRun].sectorCount * SECTOR_SIZE), "mRead");
strm.next_in = inBuffer;
if(uncompressedChk)
(*uncompressedChk)(uncompressedChkToken, inBuffer, blkx->runs[curRun].sectorCount * SECTOR_SIZE);
blkx->runs[curRun].compOffset = out->tell(out) - blkx->dataStart;
blkx->runs[curRun].compLength = 0;
strm.avail_out = bufferSize;
strm.next_out = outBuffer;
ASSERT((ret = deflate(&strm, Z_FINISH)) != Z_STREAM_ERROR, "deflate/Z_STREAM_ERROR");
if(ret != Z_STREAM_END) {
ASSERT(FALSE, "deflate");
}
have = bufferSize - strm.avail_out;
if((have / SECTOR_SIZE) > blkx->runs[curRun].sectorCount) {
blkx->runs[curRun].type = BLOCK_RAW;
ASSERT(out->write(out, inBuffer, blkx->runs[curRun].sectorCount * SECTOR_SIZE) == (blkx->runs[curRun].sectorCount * SECTOR_SIZE), "fwrite");
blkx->runs[curRun].compLength += blkx->runs[curRun].sectorCount * SECTOR_SIZE;
if(compressedChk)
(*compressedChk)(compressedChkToken, inBuffer, blkx->runs[curRun].sectorCount * SECTOR_SIZE);
} else {
} else {
ASSERT(out->write(out, outBuffer, have) == have, "fwrite");
if(compressedChk)
if(compressedChk)
(*compressedChk)(compressedChkToken, outBuffer, have);
blkx->runs[curRun].compLength += have;
}
deflateEnd(&strm);
curSector += blkx->runs[curRun].sectorCount;
numSectors -= blkx->runs[curRun].sectorCount;
curRun++;
}
if(curRun >= roomForRuns) {
roomForRuns <<= 1;
blkx = (BLKXTable*) realloc(blkx, sizeof(BLKXTable) + (roomForRuns * sizeof(BLKXRun)));
}
blkx->runs[curRun].type = BLOCK_TERMINATOR;
blkx->runs[curRun].reserved = 0;
blkx->runs[curRun].sectorStart = curSector;
blkx->runs[curRun].sectorCount = 0;
blkx->runs[curRun].compOffset = out->tell(out) - blkx->dataStart;
blkx->runs[curRun].compLength = 0;
blkx->blocksRunCount = curRun + 1;
free(inBuffer);
free(outBuffer);
return blkx;
}
void extractBLKX(AbstractFile* in, AbstractFile* out, BLKXTable* blkx) {
unsigned char* inBuffer;
unsigned char* outBuffer;
unsigned char zero;
size_t bufferSize;
size_t have;
off_t initialOffset;
int i;
int ret;
z_stream strm;
bufferSize = SECTOR_SIZE * blkx->decompressBufferRequested;
ASSERT(inBuffer = (unsigned char*) malloc(bufferSize), "malloc");
ASSERT(outBuffer = (unsigned char*) malloc(bufferSize), "malloc");
initialOffset = out->tell(out);
ASSERT(initialOffset != -1, "ftello");
zero = 0;
for(i = 0; i < blkx->blocksRunCount; i++) {
ASSERT(in->seek(in, blkx->dataStart + blkx->runs[i].compOffset) == 0, "fseeko");
ASSERT(out->seek(out, initialOffset + (blkx->runs[i].sectorStart * SECTOR_SIZE)) == 0, "mSeek");
if(blkx->runs[i].sectorCount > 0) {
ASSERT(out->seek(out, initialOffset + (blkx->runs[i].sectorStart + blkx->runs[i].sectorCount) * SECTOR_SIZE - 1) == 0, "mSeek");
ASSERT(out->write(out, &zero, 1) == 1, "mWrite");
ASSERT(out->seek(out, initialOffset + (blkx->runs[i].sectorStart * SECTOR_SIZE)) == 0, "mSeek");
}
if(blkx->runs[i].type == BLOCK_TERMINATOR) {
break;
}
if( blkx->runs[i].compLength == 0) {
continue;
}
printf("run %d: sectors=%lld, length=%lld, fileOffset=0x%llx\n", i, blkx->runs[i].sectorCount, blkx->runs[i].compLength, blkx->runs[i].compOffset);
switch(blkx->runs[i].type) {
case BLOCK_ZLIB:
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ASSERT(inflateInit(&strm) == Z_OK, "inflateInit");
ASSERT((strm.avail_in = in->read(in, inBuffer, blkx->runs[i].compLength)) == blkx->runs[i].compLength, "fread");
strm.next_in = inBuffer;
do {
strm.avail_out = bufferSize;
strm.next_out = outBuffer;
ASSERT((ret = inflate(&strm, Z_NO_FLUSH)) != Z_STREAM_ERROR, "inflate/Z_STREAM_ERROR");
if(ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_STREAM_END) {
ASSERT(FALSE, "inflate");
}
have = bufferSize - strm.avail_out;
ASSERT(out->write(out, outBuffer, have) == have, "mWrite");
} while (strm.avail_out == 0);
ASSERT(inflateEnd(&strm) == Z_OK, "inflateEnd");
break;
case BLOCK_RAW:
ASSERT((have = in->read(in, inBuffer, blkx->runs[i].compLength)) == blkx->runs[i].compLength, "fread");
ASSERT(out->write(out, inBuffer, have) == have, "mWrite");
break;
case BLOCK_IGNORE:
break;
case BLOCK_COMMENT:
break;
case BLOCK_TERMINATOR:
break;
default:
break;
}
}
free(inBuffer);
free(outBuffer);
}
blkx->runs[curRun].compLength += have;
}
deflateEnd(&strm);
curSector += blkx->runs[curRun].sectorCount;
numSectors -= blkx->runs[curRun].sectorCount;
curRun++;
}
if(curRun >= roomForRuns) {
roomForRuns <<= 1;
blkx = (BLKXTable*) realloc(blkx, sizeof(BLKXTable) + (roomForRuns * sizeof(BLKXRun)));
}
blkx->runs[curRun].type = BLOCK_TERMINATOR;
blkx->runs[curRun].reserved = 0;
blkx->runs[curRun].sectorStart = curSector;
blkx->runs[curRun].sectorCount = 0;
blkx->runs[curRun].compOffset = out->tell(out) - blkx->dataStart;
blkx->runs[curRun].compLength = 0;
blkx->blocksRunCount = curRun + 1;
free(inBuffer);
free(outBuffer);
return blkx;
}
void extractBLKX(AbstractFile* in, AbstractFile* out, BLKXTable* blkx) {
unsigned char* inBuffer;
unsigned char* outBuffer;
unsigned char zero;
size_t bufferSize;
size_t have;
off_t initialOffset;
int i;
int ret;
z_stream strm;
bufferSize = SECTOR_SIZE * blkx->decompressBufferRequested;
ASSERT(inBuffer = (unsigned char*) malloc(bufferSize), "malloc");
ASSERT(outBuffer = (unsigned char*) malloc(bufferSize), "malloc");
initialOffset = out->tell(out);
ASSERT(initialOffset != -1, "ftello");
zero = 0;
for(i = 0; i < blkx->blocksRunCount; i++) {
ASSERT(in->seek(in, blkx->dataStart + blkx->runs[i].compOffset) == 0, "fseeko");
ASSERT(out->seek(out, initialOffset + (blkx->runs[i].sectorStart * SECTOR_SIZE)) == 0, "mSeek");
if(blkx->runs[i].sectorCount > 0) {
ASSERT(out->seek(out, initialOffset + (blkx->runs[i].sectorStart + blkx->runs[i].sectorCount) * SECTOR_SIZE - 1) == 0, "mSeek");
ASSERT(out->write(out, &zero, 1) == 1, "mWrite");
ASSERT(out->seek(out, initialOffset + (blkx->runs[i].sectorStart * SECTOR_SIZE)) == 0, "mSeek");
}
if(blkx->runs[i].type == BLOCK_TERMINATOR) {
break;
}
if( blkx->runs[i].compLength == 0) {
continue;
}
printf("run %d: sectors=%lld, length=%lld, fileOffset=0x%llx\n", i, blkx->runs[i].sectorCount, blkx->runs[i].compLength, blkx->runs[i].compOffset);
switch(blkx->runs[i].type) {
case BLOCK_ZLIB:
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ASSERT(inflateInit(&strm) == Z_OK, "inflateInit");
ASSERT((strm.avail_in = in->read(in, inBuffer, blkx->runs[i].compLength)) == blkx->runs[i].compLength, "fread");
strm.next_in = inBuffer;
do {
strm.avail_out = bufferSize;
strm.next_out = outBuffer;
ASSERT((ret = inflate(&strm, Z_NO_FLUSH)) != Z_STREAM_ERROR, "inflate/Z_STREAM_ERROR");
if(ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_STREAM_END) {
ASSERT(FALSE, "inflate");
}
have = bufferSize - strm.avail_out;
ASSERT(out->write(out, outBuffer, have) == have, "mWrite");
} while (strm.avail_out == 0);
ASSERT(inflateEnd(&strm) == Z_OK, "inflateEnd");
break;
case BLOCK_RAW:
ASSERT((have = in->read(in, inBuffer, blkx->runs[i].compLength)) == blkx->runs[i].compLength, "fread");
ASSERT(out->write(out, inBuffer, have) == have, "mWrite");
break;
case BLOCK_IGNORE:
break;
case BLOCK_COMMENT:
break;
case BLOCK_TERMINATOR:
break;
default:
break;
}
}
free(inBuffer);
free(outBuffer);
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,129 +1,129 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include "dmg.h"
void flipUDIFChecksum(UDIFChecksum* o, char out) {
int i;
FLIPENDIAN(o->type);
if(out) {
for(i = 0; i < o->size; i++) {
FLIPENDIAN(o->data[i]);
}
FLIPENDIAN(o->size);
} else {
FLIPENDIAN(o->size);
for(i = 0; i < o->size; i++) {
FLIPENDIAN(o->data[i]);
}
}
}
void readUDIFChecksum(AbstractFile* file, UDIFChecksum* o) {
int i;
o->type = readUInt32(file);
o->size = readUInt32(file);
for(i = 0; i < 0x20; i++) {
o->data[i] = readUInt32(file);
}
}
void writeUDIFChecksum(AbstractFile* file, UDIFChecksum* o) {
int i;
writeUInt32(file, o->type);
writeUInt32(file, o->size);
for(i = 0; i < o->size; i++) {
writeUInt32(file, o->data[i]);
}
}
void readUDIFID(AbstractFile* file, UDIFID* o) {
o->data4 = readUInt32(file); FLIPENDIAN(o->data4);
o->data3 = readUInt32(file); FLIPENDIAN(o->data3);
o->data2 = readUInt32(file); FLIPENDIAN(o->data2);
o->data1 = readUInt32(file); FLIPENDIAN(o->data1);
}
void writeUDIFID(AbstractFile* file, UDIFID* o) {
FLIPENDIAN(o->data4); writeUInt32(file, o->data4); FLIPENDIAN(o->data4);
FLIPENDIAN(o->data3); writeUInt32(file, o->data3); FLIPENDIAN(o->data3);
FLIPENDIAN(o->data2); writeUInt32(file, o->data2); FLIPENDIAN(o->data2);
FLIPENDIAN(o->data1); writeUInt32(file, o->data1); FLIPENDIAN(o->data1);
}
void readUDIFResourceFile(AbstractFile* file, UDIFResourceFile* o) {
o->fUDIFSignature = readUInt32(file);
ASSERT(o->fUDIFSignature == 0x6B6F6C79, "readUDIFResourceFile - signature incorrect");
o->fUDIFVersion = readUInt32(file);
o->fUDIFHeaderSize = readUInt32(file);
o->fUDIFFlags = readUInt32(file);
o->fUDIFRunningDataForkOffset = readUInt64(file);
o->fUDIFDataForkOffset = readUInt64(file);
o->fUDIFDataForkLength = readUInt64(file);
o->fUDIFRsrcForkOffset = readUInt64(file);
o->fUDIFRsrcForkLength = readUInt64(file);
o->fUDIFSegmentNumber = readUInt32(file);
o->fUDIFSegmentCount = readUInt32(file);
readUDIFID(file, &(o->fUDIFSegmentID));
readUDIFChecksum(file, &(o->fUDIFDataForkChecksum));
o->fUDIFXMLOffset = readUInt64(file);
o->fUDIFXMLLength = readUInt64(file);
ASSERT(file->read(file, &(o->reserved1), 0x78) == 0x78, "fread");
readUDIFChecksum(file, &(o->fUDIFMasterChecksum));
o->fUDIFImageVariant = readUInt32(file);
o->fUDIFSectorCount = readUInt64(file);
o->reserved2 = readUInt32(file);
o->reserved3 = readUInt32(file);
o->reserved4 = readUInt32(file);
}
void writeUDIFResourceFile(AbstractFile* file, UDIFResourceFile* o) {
writeUInt32(file, o->fUDIFSignature);
writeUInt32(file, o->fUDIFVersion);
writeUInt32(file, o->fUDIFHeaderSize);
writeUInt32(file, o->fUDIFFlags);
writeUInt64(file, o->fUDIFRunningDataForkOffset);
writeUInt64(file, o->fUDIFDataForkOffset);
writeUInt64(file, o->fUDIFDataForkLength);
writeUInt64(file, o->fUDIFRsrcForkOffset);
writeUInt64(file, o->fUDIFRsrcForkLength);
writeUInt32(file, o->fUDIFSegmentNumber);
writeUInt32(file, o->fUDIFSegmentCount);
writeUDIFID(file, &(o->fUDIFSegmentID));
writeUDIFChecksum(file, &(o->fUDIFDataForkChecksum));
writeUInt64(file, o->fUDIFXMLOffset);
writeUInt64(file, o->fUDIFXMLLength);
ASSERT(file->write(file, &(o->reserved1), 0x78) == 0x78, "fwrite");
writeUDIFChecksum(file, &(o->fUDIFMasterChecksum));
writeUInt32(file, o->fUDIFImageVariant);
writeUInt64(file, o->fUDIFSectorCount);
writeUInt32(file, o->reserved2);
writeUInt32(file, o->reserved3);
writeUInt32(file, o->reserved4);
}
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include "dmg.h"
void flipUDIFChecksum(UDIFChecksum* o, char out) {
int i;
FLIPENDIAN(o->type);
if(out) {
for(i = 0; i < o->size; i++) {
FLIPENDIAN(o->data[i]);
}
FLIPENDIAN(o->size);
} else {
FLIPENDIAN(o->size);
for(i = 0; i < o->size; i++) {
FLIPENDIAN(o->data[i]);
}
}
}
void readUDIFChecksum(AbstractFile* file, UDIFChecksum* o) {
int i;
o->type = readUInt32(file);
o->size = readUInt32(file);
for(i = 0; i < 0x20; i++) {
o->data[i] = readUInt32(file);
}
}
void writeUDIFChecksum(AbstractFile* file, UDIFChecksum* o) {
int i;
writeUInt32(file, o->type);
writeUInt32(file, o->size);
for(i = 0; i < o->size; i++) {
writeUInt32(file, o->data[i]);
}
}
void readUDIFID(AbstractFile* file, UDIFID* o) {
o->data4 = readUInt32(file); FLIPENDIAN(o->data4);
o->data3 = readUInt32(file); FLIPENDIAN(o->data3);
o->data2 = readUInt32(file); FLIPENDIAN(o->data2);
o->data1 = readUInt32(file); FLIPENDIAN(o->data1);
}
void writeUDIFID(AbstractFile* file, UDIFID* o) {
FLIPENDIAN(o->data4); writeUInt32(file, o->data4); FLIPENDIAN(o->data4);
FLIPENDIAN(o->data3); writeUInt32(file, o->data3); FLIPENDIAN(o->data3);
FLIPENDIAN(o->data2); writeUInt32(file, o->data2); FLIPENDIAN(o->data2);
FLIPENDIAN(o->data1); writeUInt32(file, o->data1); FLIPENDIAN(o->data1);
}
void readUDIFResourceFile(AbstractFile* file, UDIFResourceFile* o) {
o->fUDIFSignature = readUInt32(file);
ASSERT(o->fUDIFSignature == 0x6B6F6C79, "readUDIFResourceFile - signature incorrect");
o->fUDIFVersion = readUInt32(file);
o->fUDIFHeaderSize = readUInt32(file);
o->fUDIFFlags = readUInt32(file);
o->fUDIFRunningDataForkOffset = readUInt64(file);
o->fUDIFDataForkOffset = readUInt64(file);
o->fUDIFDataForkLength = readUInt64(file);
o->fUDIFRsrcForkOffset = readUInt64(file);
o->fUDIFRsrcForkLength = readUInt64(file);
o->fUDIFSegmentNumber = readUInt32(file);
o->fUDIFSegmentCount = readUInt32(file);
readUDIFID(file, &(o->fUDIFSegmentID));
readUDIFChecksum(file, &(o->fUDIFDataForkChecksum));
o->fUDIFXMLOffset = readUInt64(file);
o->fUDIFXMLLength = readUInt64(file);
ASSERT(file->read(file, &(o->reserved1), 0x78) == 0x78, "fread");
readUDIFChecksum(file, &(o->fUDIFMasterChecksum));
o->fUDIFImageVariant = readUInt32(file);
o->fUDIFSectorCount = readUInt64(file);
o->reserved2 = readUInt32(file);
o->reserved3 = readUInt32(file);
o->reserved4 = readUInt32(file);
}
void writeUDIFResourceFile(AbstractFile* file, UDIFResourceFile* o) {
writeUInt32(file, o->fUDIFSignature);
writeUInt32(file, o->fUDIFVersion);
writeUInt32(file, o->fUDIFHeaderSize);
writeUInt32(file, o->fUDIFFlags);
writeUInt64(file, o->fUDIFRunningDataForkOffset);
writeUInt64(file, o->fUDIFDataForkOffset);
writeUInt64(file, o->fUDIFDataForkLength);
writeUInt64(file, o->fUDIFRsrcForkOffset);
writeUInt64(file, o->fUDIFRsrcForkLength);
writeUInt32(file, o->fUDIFSegmentNumber);
writeUInt32(file, o->fUDIFSegmentCount);
writeUDIFID(file, &(o->fUDIFSegmentID));
writeUDIFChecksum(file, &(o->fUDIFDataForkChecksum));
writeUInt64(file, o->fUDIFXMLOffset);
writeUInt64(file, o->fUDIFXMLLength);
ASSERT(file->write(file, &(o->reserved1), 0x78) == 0x78, "fwrite");
writeUDIFChecksum(file, &(o->fUDIFMasterChecksum));
writeUInt32(file, o->fUDIFImageVariant);
writeUInt64(file, o->fUDIFSectorCount);
writeUInt32(file, o->reserved2);
writeUInt32(file, o->reserved3);
writeUInt32(file, o->reserved4);
}

Просмотреть файл

@ -1,9 +1,9 @@
#include <stdlib.h>
#ifdef WIN32
blahfs-o_f-0-(){ {}A
#else
int main(int argc, char* argv[]) {
return 0;
}
#endif
#include <stdlib.h>
#ifdef WIN32
blahfs-o_f-0-(){ {}A
#else
int main(int argc, char* argv[]) {
return 0;
}
#endif

Просмотреть файл

@ -1,186 +1,186 @@
/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding
* version for AMD64 on Windows using Microsoft C compiler
*
* Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Copyright (C) 2003 Chris Anderson <christop@charm.net>
* Please use the copyright conditions above.
*
* 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant
*
* inffas8664.c call function inffas8664fnc in inffasx64.asm
* inffasx64.asm is automatically convert from AMD64 portion of inffas86.c
*
* Dec-29-2003 -- I added AMD64 inflate asm support. This version is also
* slightly quicker on x86 systems because, instead of using rep movsb to copy
* data, it uses rep movsw, which moves data in 2-byte chunks instead of single
* bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates
* from http://fedora.linux.duke.edu/fc1_x86_64
* which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with
* 1GB ram. The 64-bit version is about 4% faster than the 32-bit version,
* when decompressing mozilla-source-1.3.tar.gz.
*
* Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
* the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at
* the moment. I have successfully compiled and tested this code with gcc2.96,
* gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S
* compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
* enabled. I will attempt to merge the MMX code into this version. Newer
* versions of this and inffast.S can be found at
* http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
*
*/
#include <stdio.h>
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
/* Mark Adler's comments from inffast.c: */
/*
Decode literal, length, and distance codes and write out the resulting
literal and match bytes until either not enough input or output is
available, an end-of-block is encountered, or a data error is encountered.
When large enough input and output buffers are supplied to inflate(), for
example, a 16K input buffer and a 64K output buffer, more than 95% of the
inflate execution time is spent in this routine.
Entry assumptions:
state->mode == LEN
strm->avail_in >= 6
strm->avail_out >= 258
start >= strm->avail_out
state->bits < 8
On return, state->mode is one of:
LEN -- ran out of enough output space or enough available input
TYPE -- reached end of block code, inflate() to interpret next block
BAD -- error in block data
Notes:
- The maximum input bits used by a length/distance pair is 15 bits for the
length code, 5 bits for the length extra, 15 bits for the distance code,
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
Therefore if strm->avail_in >= 6, then there is enough input to avoid
checking for available input while decoding.
- The maximum bytes that a single length/distance pair can output is 258
bytes, which is the maximum length that can be coded. inflate_fast()
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
typedef struct inffast_ar {
/* 64 32 x86 x86_64 */
/* ar offset register */
/* 0 0 */ void *esp; /* esp save */
/* 8 4 */ void *ebp; /* ebp save */
/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */
/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */
/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */
/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */
/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */
/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */
/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */
/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */
/* 80 40 */ size_t /*unsigned long */hold; /* edx rdx local strm->hold */
/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */
/* 92 48 */ unsigned wsize; /* window size */
/* 96 52 */ unsigned write; /* window write index */
/*100 56 */ unsigned lmask; /* r12 mask for lcode */
/*104 60 */ unsigned dmask; /* r13 mask for dcode */
/*108 64 */ unsigned len; /* r14 match length */
/*112 68 */ unsigned dist; /* r15 match distance */
/*116 72 */ unsigned status; /* set when state chng*/
} type_ar;
#ifdef ASMINF
void inflate_fast(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
struct inflate_state FAR *state;
type_ar ar;
void inffas8664fnc(struct inffast_ar * par);
#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64))
#define PAD_AVAIL_IN 6
#define PAD_AVAIL_OUT 258
#else
#define PAD_AVAIL_IN 5
#define PAD_AVAIL_OUT 257
#endif
/* copy state to local variables */
state = (struct inflate_state FAR *)strm->state;
ar.in = strm->next_in;
ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
ar.out = strm->next_out;
ar.beg = ar.out - (start - strm->avail_out);
ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
ar.wsize = state->wsize;
ar.write = state->write;
ar.window = state->window;
ar.hold = state->hold;
ar.bits = state->bits;
ar.lcode = state->lencode;
ar.dcode = state->distcode;
ar.lmask = (1U << state->lenbits) - 1;
ar.dmask = (1U << state->distbits) - 1;
/* decode literals and length/distances until end-of-block or not enough
input data or output space */
/* align in on 1/2 hold size boundary */
while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
ar.hold += (unsigned long)*ar.in++ << ar.bits;
ar.bits += 8;
}
inffas8664fnc(&ar);
if (ar.status > 1) {
if (ar.status == 2)
strm->msg = "invalid literal/length code";
else if (ar.status == 3)
strm->msg = "invalid distance code";
else
strm->msg = "invalid distance too far back";
state->mode = BAD;
}
else if ( ar.status == 1 ) {
state->mode = TYPE;
}
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
ar.len = ar.bits >> 3;
ar.in -= ar.len;
ar.bits -= ar.len << 3;
ar.hold &= (1U << ar.bits) - 1;
/* update state and return */
strm->next_in = ar.in;
strm->next_out = ar.out;
strm->avail_in = (unsigned)(ar.in < ar.last ?
PAD_AVAIL_IN + (ar.last - ar.in) :
PAD_AVAIL_IN - (ar.in - ar.last));
strm->avail_out = (unsigned)(ar.out < ar.end ?
PAD_AVAIL_OUT + (ar.end - ar.out) :
PAD_AVAIL_OUT - (ar.out - ar.end));
state->hold = (unsigned long)ar.hold;
state->bits = ar.bits;
return;
}
#endif
/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding
* version for AMD64 on Windows using Microsoft C compiler
*
* Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Copyright (C) 2003 Chris Anderson <christop@charm.net>
* Please use the copyright conditions above.
*
* 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant
*
* inffas8664.c call function inffas8664fnc in inffasx64.asm
* inffasx64.asm is automatically convert from AMD64 portion of inffas86.c
*
* Dec-29-2003 -- I added AMD64 inflate asm support. This version is also
* slightly quicker on x86 systems because, instead of using rep movsb to copy
* data, it uses rep movsw, which moves data in 2-byte chunks instead of single
* bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates
* from http://fedora.linux.duke.edu/fc1_x86_64
* which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with
* 1GB ram. The 64-bit version is about 4% faster than the 32-bit version,
* when decompressing mozilla-source-1.3.tar.gz.
*
* Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
* the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at
* the moment. I have successfully compiled and tested this code with gcc2.96,
* gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S
* compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
* enabled. I will attempt to merge the MMX code into this version. Newer
* versions of this and inffast.S can be found at
* http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
*
*/
#include <stdio.h>
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
/* Mark Adler's comments from inffast.c: */
/*
Decode literal, length, and distance codes and write out the resulting
literal and match bytes until either not enough input or output is
available, an end-of-block is encountered, or a data error is encountered.
When large enough input and output buffers are supplied to inflate(), for
example, a 16K input buffer and a 64K output buffer, more than 95% of the
inflate execution time is spent in this routine.
Entry assumptions:
state->mode == LEN
strm->avail_in >= 6
strm->avail_out >= 258
start >= strm->avail_out
state->bits < 8
On return, state->mode is one of:
LEN -- ran out of enough output space or enough available input
TYPE -- reached end of block code, inflate() to interpret next block
BAD -- error in block data
Notes:
- The maximum input bits used by a length/distance pair is 15 bits for the
length code, 5 bits for the length extra, 15 bits for the distance code,
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
Therefore if strm->avail_in >= 6, then there is enough input to avoid
checking for available input while decoding.
- The maximum bytes that a single length/distance pair can output is 258
bytes, which is the maximum length that can be coded. inflate_fast()
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
typedef struct inffast_ar {
/* 64 32 x86 x86_64 */
/* ar offset register */
/* 0 0 */ void *esp; /* esp save */
/* 8 4 */ void *ebp; /* ebp save */
/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */
/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */
/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */
/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */
/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */
/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */
/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */
/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */
/* 80 40 */ size_t /*unsigned long */hold; /* edx rdx local strm->hold */
/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */
/* 92 48 */ unsigned wsize; /* window size */
/* 96 52 */ unsigned write; /* window write index */
/*100 56 */ unsigned lmask; /* r12 mask for lcode */
/*104 60 */ unsigned dmask; /* r13 mask for dcode */
/*108 64 */ unsigned len; /* r14 match length */
/*112 68 */ unsigned dist; /* r15 match distance */
/*116 72 */ unsigned status; /* set when state chng*/
} type_ar;
#ifdef ASMINF
void inflate_fast(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
struct inflate_state FAR *state;
type_ar ar;
void inffas8664fnc(struct inffast_ar * par);
#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64))
#define PAD_AVAIL_IN 6
#define PAD_AVAIL_OUT 258
#else
#define PAD_AVAIL_IN 5
#define PAD_AVAIL_OUT 257
#endif
/* copy state to local variables */
state = (struct inflate_state FAR *)strm->state;
ar.in = strm->next_in;
ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
ar.out = strm->next_out;
ar.beg = ar.out - (start - strm->avail_out);
ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
ar.wsize = state->wsize;
ar.write = state->write;
ar.window = state->window;
ar.hold = state->hold;
ar.bits = state->bits;
ar.lcode = state->lencode;
ar.dcode = state->distcode;
ar.lmask = (1U << state->lenbits) - 1;
ar.dmask = (1U << state->distbits) - 1;
/* decode literals and length/distances until end-of-block or not enough
input data or output space */
/* align in on 1/2 hold size boundary */
while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
ar.hold += (unsigned long)*ar.in++ << ar.bits;
ar.bits += 8;
}
inffas8664fnc(&ar);
if (ar.status > 1) {
if (ar.status == 2)
strm->msg = "invalid literal/length code";
else if (ar.status == 3)
strm->msg = "invalid distance code";
else
strm->msg = "invalid distance too far back";
state->mode = BAD;
}
else if ( ar.status == 1 ) {
state->mode = TYPE;
}
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
ar.len = ar.bits >> 3;
ar.in -= ar.len;
ar.bits -= ar.len << 3;
ar.hold &= (1U << ar.bits) - 1;
/* update state and return */
strm->next_in = ar.in;
strm->next_out = ar.out;
strm->avail_in = (unsigned)(ar.in < ar.last ?
PAD_AVAIL_IN + (ar.last - ar.in) :
PAD_AVAIL_IN - (ar.in - ar.last));
strm->avail_out = (unsigned)(ar.out < ar.end ?
PAD_AVAIL_OUT + (ar.end - ar.out) :
PAD_AVAIL_OUT - (ar.out - ar.end));
state->hold = (unsigned long)ar.hold;
state->bits = ar.bits;
return;
}
#endif

Просмотреть файл

@ -1,62 +1,62 @@
/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86
* Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
* File written by Gilles Vollant, by modifiying the longest_match
* from Jean-loup Gailly in deflate.c
* it prepare all parameters and call the assembly longest_match_gvasm
* longest_match execute standard C code is wmask != 0x7fff
* (assembly code is faster with a fixed wmask)
*
* Read comment at beginning of gvmat32.asm for more information
*/
#if defined(ASMV) && (!defined(NOOLDPENTIUMCODE))
#include "deflate.h"
/* if your C compiler don't add underline before function name,
define ADD_UNDERLINE_ASMFUNC */
#ifdef ADD_UNDERLINE_ASMFUNC
#define longest_match_7fff _longest_match_7fff
#define longest_match_686 _longest_match_686
#define cpudetect32 _cpudetect32
#endif
unsigned long cpudetect32();
uInt longest_match_c(
deflate_state *s,
IPos cur_match); /* current match */
uInt longest_match_7fff(
deflate_state *s,
IPos cur_match); /* current match */
uInt longest_match_686(
deflate_state *s,
IPos cur_match); /* current match */
static uInt iIsPPro=2;
void match_init ()
{
iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
}
uInt longest_match(
deflate_state *s,
IPos cur_match) /* current match */
{
if (iIsPPro!=0)
return longest_match_686(s,cur_match);
if (s->w_mask != 0x7fff)
return longest_match_686(s,cur_match);
/* now ((s->w_mask == 0x7fff) && (iIsPPro==0)) */
return longest_match_7fff(s,cur_match);
}
#endif /* defined(ASMV) && (!defined(NOOLDPENTIUMCODE)) */
/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86
* Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
* File written by Gilles Vollant, by modifiying the longest_match
* from Jean-loup Gailly in deflate.c
* it prepare all parameters and call the assembly longest_match_gvasm
* longest_match execute standard C code is wmask != 0x7fff
* (assembly code is faster with a fixed wmask)
*
* Read comment at beginning of gvmat32.asm for more information
*/
#if defined(ASMV) && (!defined(NOOLDPENTIUMCODE))
#include "deflate.h"
/* if your C compiler don't add underline before function name,
define ADD_UNDERLINE_ASMFUNC */
#ifdef ADD_UNDERLINE_ASMFUNC
#define longest_match_7fff _longest_match_7fff
#define longest_match_686 _longest_match_686
#define cpudetect32 _cpudetect32
#endif
unsigned long cpudetect32();
uInt longest_match_c(
deflate_state *s,
IPos cur_match); /* current match */
uInt longest_match_7fff(
deflate_state *s,
IPos cur_match); /* current match */
uInt longest_match_686(
deflate_state *s,
IPos cur_match); /* current match */
static uInt iIsPPro=2;
void match_init ()
{
iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
}
uInt longest_match(
deflate_state *s,
IPos cur_match) /* current match */
{
if (iIsPPro!=0)
return longest_match_686(s,cur_match);
if (s->w_mask != 0x7fff)
return longest_match_686(s,cur_match);
/* now ((s->w_mask == 0x7fff) && (iIsPPro==0)) */
return longest_match_7fff(s,cur_match);
}
#endif /* defined(ASMV) && (!defined(NOOLDPENTIUMCODE)) */

Просмотреть файл

@ -1,275 +1,275 @@
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "zlib.h"
void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B)
{
R->HighPart = A.HighPart - B.HighPart;
if (A.LowPart >= B.LowPart)
R->LowPart = A.LowPart - B.LowPart;
else
{
R->LowPart = A.LowPart - B.LowPart;
R->HighPart --;
}
}
#ifdef _M_X64
// see http://msdn2.microsoft.com/library/twchhe95(en-us,vs.80).aspx for __rdtsc
unsigned __int64 __rdtsc(void);
void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
{
// printf("rdtsc = %I64x\n",__rdtsc());
pbeginTime64->QuadPart=__rdtsc();
}
LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
{
LARGE_INTEGER LIres;
unsigned _int64 res=__rdtsc()-((unsigned _int64)(beginTime64.QuadPart));
LIres.QuadPart=res;
// printf("rdtsc = %I64x\n",__rdtsc());
return LIres;
}
#else
#ifdef _M_IX86
void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
{
DWORD dwEdx,dwEax;
_asm
{
rdtsc
mov dwEax,eax
mov dwEdx,edx
}
pbeginTime64->LowPart=dwEax;
pbeginTime64->HighPart=dwEdx;
}
void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
{
myGetRDTSC32(pbeginTime64);
}
LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
{
LARGE_INTEGER LIres,endTime64;
myGetRDTSC32(&endTime64);
LIres.LowPart=LIres.HighPart=0;
MyDoMinus64(&LIres,endTime64,beginTime64);
return LIres;
}
#else
void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
{
}
void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
{
}
LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
{
LARGE_INTEGER lr;
lr.QuadPart=0;
return lr;
}
#endif
#endif
void BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf)
{
if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64)))
{
pbeginTime64->LowPart = GetTickCount();
pbeginTime64->HighPart = 0;
}
}
DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
{
LARGE_INTEGER endTime64,ticksPerSecond,ticks;
DWORDLONG ticksShifted,tickSecShifted;
DWORD dwLog=16+0;
DWORD dwRet;
if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64)))
dwRet = (GetTickCount() - beginTime64.LowPart)*1;
else
{
MyDoMinus64(&ticks,endTime64,beginTime64);
QueryPerformanceFrequency(&ticksPerSecond);
{
ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog);
tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog);
}
dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted));
dwRet *=1;
}
return dwRet;
}
int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr)
{
FILE* stream;
void* ptr;
int retVal=1;
stream=fopen(filename, "rb");
if (stream==NULL)
return 0;
fseek(stream,0,SEEK_END);
*plFileSize=ftell(stream);
fseek(stream,0,SEEK_SET);
ptr=malloc((*plFileSize)+1);
if (ptr==NULL)
retVal=0;
else
{
if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))
retVal=0;
}
fclose(stream);
*pFilePtr=ptr;
return retVal;
}
int main(int argc, char *argv[])
{
int BlockSizeCompress=0x8000;
int BlockSizeUncompress=0x8000;
int cprLevel=Z_DEFAULT_COMPRESSION ;
long lFileSize;
unsigned char* FilePtr;
long lBufferSizeCpr;
long lBufferSizeUncpr;
long lCompressedSize=0;
unsigned char* CprPtr;
unsigned char* UncprPtr;
long lSizeCpr,lSizeUncpr;
DWORD dwGetTick,dwMsecQP;
LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc;
if (argc<=1)
{
printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n");
return 0;
}
if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0)
{
printf("error reading %s\n",argv[1]);
return 1;
}
else printf("file %s read, %u bytes\n",argv[1],lFileSize);
if (argc>=3)
BlockSizeCompress=atol(argv[2]);
if (argc>=4)
BlockSizeUncompress=atol(argv[3]);
if (argc>=5)
cprLevel=(int)atol(argv[4]);
lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;
lBufferSizeUncpr = lBufferSizeCpr;
CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);
BeginCountPerfCounter(&li_qp,TRUE);
dwGetTick=GetTickCount();
BeginCountRdtsc(&li_rdtsc);
{
z_stream zcpr;
int ret=Z_OK;
long lOrigToDo = lFileSize;
long lOrigDone = 0;
int step=0;
memset(&zcpr,0,sizeof(z_stream));
deflateInit(&zcpr,cprLevel);
zcpr.next_in = FilePtr;
zcpr.next_out = CprPtr;
do
{
long all_read_before = zcpr.total_in;
zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);
zcpr.avail_out = BlockSizeCompress;
ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);
lOrigDone += (zcpr.total_in-all_read_before);
lOrigToDo -= (zcpr.total_in-all_read_before);
step++;
} while (ret==Z_OK);
lSizeCpr=zcpr.total_out;
deflateEnd(&zcpr);
dwGetTick=GetTickCount()-dwGetTick;
dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);
dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);
printf("total compress size = %u, in %u step\n",lSizeCpr,step);
printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);
printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);
printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);
}
CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr);
UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);
BeginCountPerfCounter(&li_qp,TRUE);
dwGetTick=GetTickCount();
BeginCountRdtsc(&li_rdtsc);
{
z_stream zcpr;
int ret=Z_OK;
long lOrigToDo = lSizeCpr;
long lOrigDone = 0;
int step=0;
memset(&zcpr,0,sizeof(z_stream));
inflateInit(&zcpr);
zcpr.next_in = CprPtr;
zcpr.next_out = UncprPtr;
do
{
long all_read_before = zcpr.total_in;
zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);
zcpr.avail_out = BlockSizeUncompress;
ret=inflate(&zcpr,Z_SYNC_FLUSH);
lOrigDone += (zcpr.total_in-all_read_before);
lOrigToDo -= (zcpr.total_in-all_read_before);
step++;
} while (ret==Z_OK);
lSizeUncpr=zcpr.total_out;
inflateEnd(&zcpr);
dwGetTick=GetTickCount()-dwGetTick;
dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);
dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);
printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step);
printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);
printf("uncpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);
printf("uncpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);
}
if (lSizeUncpr==lFileSize)
{
if (memcmp(FilePtr,UncprPtr,lFileSize)==0)
printf("compare ok\n");
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "zlib.h"
void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B)
{
R->HighPart = A.HighPart - B.HighPart;
if (A.LowPart >= B.LowPart)
R->LowPart = A.LowPart - B.LowPart;
else
{
R->LowPart = A.LowPart - B.LowPart;
R->HighPart --;
}
}
#ifdef _M_X64
// see http://msdn2.microsoft.com/library/twchhe95(en-us,vs.80).aspx for __rdtsc
unsigned __int64 __rdtsc(void);
void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
{
// printf("rdtsc = %I64x\n",__rdtsc());
pbeginTime64->QuadPart=__rdtsc();
}
LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
{
LARGE_INTEGER LIres;
unsigned _int64 res=__rdtsc()-((unsigned _int64)(beginTime64.QuadPart));
LIres.QuadPart=res;
// printf("rdtsc = %I64x\n",__rdtsc());
return LIres;
}
#else
#ifdef _M_IX86
void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
{
DWORD dwEdx,dwEax;
_asm
{
rdtsc
mov dwEax,eax
mov dwEdx,edx
}
pbeginTime64->LowPart=dwEax;
pbeginTime64->HighPart=dwEdx;
}
void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
{
myGetRDTSC32(pbeginTime64);
}
LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
{
LARGE_INTEGER LIres,endTime64;
myGetRDTSC32(&endTime64);
LIres.LowPart=LIres.HighPart=0;
MyDoMinus64(&LIres,endTime64,beginTime64);
return LIres;
}
#else
void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
{
}
void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
{
}
LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
{
LARGE_INTEGER lr;
lr.QuadPart=0;
return lr;
}
#endif
#endif
void BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf)
{
if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64)))
{
pbeginTime64->LowPart = GetTickCount();
pbeginTime64->HighPart = 0;
}
}
DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
{
LARGE_INTEGER endTime64,ticksPerSecond,ticks;
DWORDLONG ticksShifted,tickSecShifted;
DWORD dwLog=16+0;
DWORD dwRet;
if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64)))
dwRet = (GetTickCount() - beginTime64.LowPart)*1;
else
{
MyDoMinus64(&ticks,endTime64,beginTime64);
QueryPerformanceFrequency(&ticksPerSecond);
{
ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog);
tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog);
}
dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted));
dwRet *=1;
}
return dwRet;
}
int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr)
{
FILE* stream;
void* ptr;
int retVal=1;
stream=fopen(filename, "rb");
if (stream==NULL)
return 0;
fseek(stream,0,SEEK_END);
*plFileSize=ftell(stream);
fseek(stream,0,SEEK_SET);
ptr=malloc((*plFileSize)+1);
if (ptr==NULL)
retVal=0;
else
{
if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))
retVal=0;
}
fclose(stream);
*pFilePtr=ptr;
return retVal;
}
int main(int argc, char *argv[])
{
int BlockSizeCompress=0x8000;
int BlockSizeUncompress=0x8000;
int cprLevel=Z_DEFAULT_COMPRESSION ;
long lFileSize;
unsigned char* FilePtr;
long lBufferSizeCpr;
long lBufferSizeUncpr;
long lCompressedSize=0;
unsigned char* CprPtr;
unsigned char* UncprPtr;
long lSizeCpr,lSizeUncpr;
DWORD dwGetTick,dwMsecQP;
LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc;
if (argc<=1)
{
printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n");
return 0;
}
if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0)
{
printf("error reading %s\n",argv[1]);
return 1;
}
else printf("file %s read, %u bytes\n",argv[1],lFileSize);
if (argc>=3)
BlockSizeCompress=atol(argv[2]);
if (argc>=4)
BlockSizeUncompress=atol(argv[3]);
if (argc>=5)
cprLevel=(int)atol(argv[4]);
lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;
lBufferSizeUncpr = lBufferSizeCpr;
CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);
BeginCountPerfCounter(&li_qp,TRUE);
dwGetTick=GetTickCount();
BeginCountRdtsc(&li_rdtsc);
{
z_stream zcpr;
int ret=Z_OK;
long lOrigToDo = lFileSize;
long lOrigDone = 0;
int step=0;
memset(&zcpr,0,sizeof(z_stream));
deflateInit(&zcpr,cprLevel);
zcpr.next_in = FilePtr;
zcpr.next_out = CprPtr;
do
{
long all_read_before = zcpr.total_in;
zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);
zcpr.avail_out = BlockSizeCompress;
ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);
lOrigDone += (zcpr.total_in-all_read_before);
lOrigToDo -= (zcpr.total_in-all_read_before);
step++;
} while (ret==Z_OK);
lSizeCpr=zcpr.total_out;
deflateEnd(&zcpr);
dwGetTick=GetTickCount()-dwGetTick;
dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);
dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);
printf("total compress size = %u, in %u step\n",lSizeCpr,step);
printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);
printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);
printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);
}
CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr);
UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);
BeginCountPerfCounter(&li_qp,TRUE);
dwGetTick=GetTickCount();
BeginCountRdtsc(&li_rdtsc);
{
z_stream zcpr;
int ret=Z_OK;
long lOrigToDo = lSizeCpr;
long lOrigDone = 0;
int step=0;
memset(&zcpr,0,sizeof(z_stream));
inflateInit(&zcpr);
zcpr.next_in = CprPtr;
zcpr.next_out = UncprPtr;
do
{
long all_read_before = zcpr.total_in;
zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);
zcpr.avail_out = BlockSizeUncompress;
ret=inflate(&zcpr,Z_SYNC_FLUSH);
lOrigDone += (zcpr.total_in-all_read_before);
lOrigToDo -= (zcpr.total_in-all_read_before);
step++;
} while (ret==Z_OK);
lSizeUncpr=zcpr.total_out;
inflateEnd(&zcpr);
dwGetTick=GetTickCount()-dwGetTick;
dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);
dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);
printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step);
printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);
printf("uncpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);
printf("uncpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);
}
if (lSizeUncpr==lFileSize)
{
if (memcmp(FilePtr,UncprPtr,lFileSize)==0)
printf("compare ok\n");
}
return 0;
}

Просмотреть файл

@ -1,73 +1,73 @@
Microsoft Developer Studio Project Files, Format Version 6.00 for zlib.
Copyright (C) 2000-2004 Simon-Pierre Cadieux.
Copyright (C) 2004 Cosmin Truta.
For conditions of distribution and use, see copyright notice in zlib.h.
This project builds the zlib binaries as follows:
* Win32_DLL_Release\zlib1.dll DLL build
* Win32_DLL_Debug\zlib1d.dll DLL build (debug version)
* Win32_DLL_ASM_Release\zlib1.dll DLL build using ASM code
* Win32_DLL_ASM_Debug\zlib1d.dll DLL build using ASM code (debug version)
* Win32_LIB_Release\zlib.lib static build
* Win32_LIB_Debug\zlibd.lib static build (debug version)
* Win32_LIB_ASM_Release\zlib.lib static build using ASM code
* Win32_LIB_ASM_Debug\zlibd.lib static build using ASM code (debug version)
For more information regarding the DLL builds, please see the DLL FAQ
in ..\..\win32\DLL_FAQ.txt.
To build and test:
1) On the main menu, select "File | Open Workspace".
Open "zlib.dsw".
2) Select "Build | Set Active Configuration".
Choose the configuration you wish to build.
3) Select "Build | Clean".
4) Select "Build | Build ... (F7)". Ignore warning messages about
not being able to find certain include files (e.g. alloc.h).
5) If you built one of the sample programs (example or minigzip),
select "Build | Execute ... (Ctrl+F5)".
To use:
1) Select "Project | Settings (Alt+F7)".
Make note of the configuration names used in your project.
Usually, these names are "Win32 Release" and "Win32 Debug".
2) In the Workspace window, select the "FileView" tab.
Right-click on the root item "Workspace '...'".
Select "Insert Project into Workspace".
Switch on the checkbox "Dependency of:", and select the name
of your project. Open "zlib.dsp".
3) Select "Build | Configurations".
For each configuration of your project:
3.1) Choose the zlib configuration you wish to use.
3.2) Click on "Add".
3.3) Set the new zlib configuration name to the name used by
the configuration from the current iteration.
4) Select "Build | Set Active Configuration".
Choose the configuration you wish to build.
5) Select "Build | Build ... (F7)".
6) If you built an executable program, select
"Build | Execute ... (Ctrl+F5)".
Note:
To build the ASM-enabled code, you need Microsoft Assembler
(ML.EXE). You can get it by downloading and installing the
latest Processor Pack for Visual C++ 6.0.
Microsoft Developer Studio Project Files, Format Version 6.00 for zlib.
Copyright (C) 2000-2004 Simon-Pierre Cadieux.
Copyright (C) 2004 Cosmin Truta.
For conditions of distribution and use, see copyright notice in zlib.h.
This project builds the zlib binaries as follows:
* Win32_DLL_Release\zlib1.dll DLL build
* Win32_DLL_Debug\zlib1d.dll DLL build (debug version)
* Win32_DLL_ASM_Release\zlib1.dll DLL build using ASM code
* Win32_DLL_ASM_Debug\zlib1d.dll DLL build using ASM code (debug version)
* Win32_LIB_Release\zlib.lib static build
* Win32_LIB_Debug\zlibd.lib static build (debug version)
* Win32_LIB_ASM_Release\zlib.lib static build using ASM code
* Win32_LIB_ASM_Debug\zlibd.lib static build using ASM code (debug version)
For more information regarding the DLL builds, please see the DLL FAQ
in ..\..\win32\DLL_FAQ.txt.
To build and test:
1) On the main menu, select "File | Open Workspace".
Open "zlib.dsw".
2) Select "Build | Set Active Configuration".
Choose the configuration you wish to build.
3) Select "Build | Clean".
4) Select "Build | Build ... (F7)". Ignore warning messages about
not being able to find certain include files (e.g. alloc.h).
5) If you built one of the sample programs (example or minigzip),
select "Build | Execute ... (Ctrl+F5)".
To use:
1) Select "Project | Settings (Alt+F7)".
Make note of the configuration names used in your project.
Usually, these names are "Win32 Release" and "Win32 Debug".
2) In the Workspace window, select the "FileView" tab.
Right-click on the root item "Workspace '...'".
Select "Insert Project into Workspace".
Switch on the checkbox "Dependency of:", and select the name
of your project. Open "zlib.dsp".
3) Select "Build | Configurations".
For each configuration of your project:
3.1) Choose the zlib configuration you wish to use.
3.2) Click on "Add".
3.3) Set the new zlib configuration name to the name used by
the configuration from the current iteration.
4) Select "Build | Set Active Configuration".
Choose the configuration you wish to build.
5) Select "Build | Build ... (F7)".
6) If you built an executable program, select
"Build | Execute ... (Ctrl+F5)".
Note:
To build the ASM-enabled code, you need Microsoft Assembler
(ML.EXE). You can get it by downloading and installing the
latest Processor Pack for Visual C++ 6.0.

Просмотреть файл

@ -1,16 +1,16 @@
HFSPLUSOBJS=btree.o catalog.o extents.o flatfile.o rawfile.o volume.o utility.o hfs.o fastunicodecompare.o abstractfile.o hfslib.o
CFLAGS=-D_FILE_OFFSET_BITS=64 -O3
all: hfsplus
hfsplus: $(HFSPLUSOBJS)
$(CC) $(CFLAGS) $(HFSPLUSOBJS) -o hfsplus
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
-rm *.o
-rm hfsplus
-rm hfsplus.exe
HFSPLUSOBJS=btree.o catalog.o extents.o flatfile.o rawfile.o volume.o utility.o hfs.o fastunicodecompare.o abstractfile.o hfslib.o
CFLAGS=-D_FILE_OFFSET_BITS=64 -O3
all: hfsplus
hfsplus: $(HFSPLUSOBJS)
$(CC) $(CFLAGS) $(HFSPLUSOBJS) -o hfsplus
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
-rm *.o
-rm hfsplus
-rm hfsplus.exe

Просмотреть файл

@ -1,302 +1,302 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdint.h>
#include "abstractfile.h"
#include "common.h"
size_t freadWrapper(AbstractFile* file, void* data, size_t len) {
return fread(data, 1, len, (FILE*) (file->data));
}
size_t fwriteWrapper(AbstractFile* file, const void* data, size_t len) {
return fwrite(data, 1, len, (FILE*) (file->data));
}
int fseekWrapper(AbstractFile* file, off_t offset) {
return fseeko((FILE*) (file->data), offset, SEEK_SET);
}
off_t ftellWrapper(AbstractFile* file) {
return ftello((FILE*) (file->data));
}
void fcloseWrapper(AbstractFile* file) {
fclose((FILE*) (file->data));
free(file);
}
off_t fileGetLength(AbstractFile* file) {
off_t length;
off_t pos;
pos = ftello((FILE*) (file->data));
fseeko((FILE*) (file->data), 0, SEEK_END);
length = ftello((FILE*) (file->data));
fseeko((FILE*) (file->data), pos, SEEK_SET);
return length;
}
AbstractFile* createAbstractFileFromFile(FILE* file) {
AbstractFile* toReturn;
if(file == NULL) {
return NULL;
}
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
toReturn->data = file;
toReturn->read = freadWrapper;
toReturn->write = fwriteWrapper;
toReturn->seek = fseekWrapper;
toReturn->tell = ftellWrapper;
toReturn->getLength = fileGetLength;
toReturn->close = fcloseWrapper;
return toReturn;
}
size_t dummyRead(AbstractFile* file, void* data, size_t len) {
return 0;
}
size_t dummyWrite(AbstractFile* file, const void* data, size_t len) {
*((off_t*) (file->data)) += len;
return len;
}
int dummySeek(AbstractFile* file, off_t offset) {
*((off_t*) (file->data)) = offset;
return 0;
}
off_t dummyTell(AbstractFile* file) {
return *((off_t*) (file->data));
}
void dummyClose(AbstractFile* file) {
free(file);
}
AbstractFile* createAbstractFileFromDummy() {
AbstractFile* toReturn;
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
toReturn->data = NULL;
toReturn->read = dummyRead;
toReturn->write = dummyWrite;
toReturn->seek = dummySeek;
toReturn->tell = dummyTell;
toReturn->getLength = NULL;
toReturn->close = dummyClose;
return toReturn;
}
size_t memRead(AbstractFile* file, void* data, size_t len) {
MemWrapperInfo* info = (MemWrapperInfo*) (file->data);
memcpy(data, (void*)((uint8_t*)(*(info->buffer)) + (uint32_t)info->offset), len);
info->offset += (size_t)len;
return len;
}
size_t memWrite(AbstractFile* file, const void* data, size_t len) {
MemWrapperInfo* info = (MemWrapperInfo*) (file->data);
while((info->offset + (size_t)len) > info->bufferSize) {
info->bufferSize <<= 1;
*(info->buffer) = realloc(*(info->buffer), info->bufferSize);
}
memcpy((void*)((uint8_t*)(*(info->buffer)) + (uint32_t)info->offset), data, len);
info->offset += (size_t)len;
return len;
}
int memSeek(AbstractFile* file, off_t offset) {
MemWrapperInfo* info = (MemWrapperInfo*) (file->data);
info->offset = (size_t)offset;
return 0;
}
off_t memTell(AbstractFile* file) {
MemWrapperInfo* info = (MemWrapperInfo*) (file->data);
return (off_t)info->offset;
}
off_t memGetLength(AbstractFile* file) {
MemWrapperInfo* info = (MemWrapperInfo*) (file->data);
return info->bufferSize;
}
void memClose(AbstractFile* file) {
free(file->data);
free(file);
}
AbstractFile* createAbstractFileFromMemory(void** buffer, size_t size) {
MemWrapperInfo* info;
AbstractFile* toReturn;
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
info = (MemWrapperInfo*) malloc(sizeof(MemWrapperInfo));
info->offset = 0;
info->buffer = buffer;
info->bufferSize = size;
toReturn->data = info;
toReturn->read = memRead;
toReturn->write = memWrite;
toReturn->seek = memSeek;
toReturn->tell = memTell;
toReturn->getLength = memGetLength;
toReturn->close = memClose;
return toReturn;
}
void abstractFilePrint(AbstractFile* file, const char* format, ...) {
va_list args;
char buffer[1024];
size_t length;
buffer[0] = '\0';
va_start(args, format);
length = vsprintf(buffer, format, args);
va_end(args);
ASSERT(file->write(file, buffer, length) == length, "fwrite");
}
int absFileRead(io_func* io, off_t location, size_t size, void *buffer) {
AbstractFile* file;
file = (AbstractFile*) io->data;
file->seek(file, location);
if(file->read(file, buffer, size) == size) {
return TRUE;
} else {
return FALSE;
}
}
int absFileWrite(io_func* io, off_t location, size_t size, void *buffer) {
AbstractFile* file;
file = (AbstractFile*) io->data;
file->seek(file, location);
if(file->write(file, buffer, size) == size) {
return TRUE;
} else {
return FALSE;
}
}
void closeAbsFile(io_func* io) {
AbstractFile* file;
file = (AbstractFile*) io->data;
file->close(file);
free(io);
}
io_func* IOFuncFromAbstractFile(AbstractFile* file) {
io_func* io;
io = (io_func*) malloc(sizeof(io_func));
io->data = file;
io->read = &absFileRead;
io->write = &absFileWrite;
io->close = &closeAbsFile;
return io;
}
size_t memFileRead(AbstractFile* file, void* data, size_t len) {
MemFileWrapperInfo* info = (MemFileWrapperInfo*) (file->data);
memcpy(data, (void*)((uint8_t*)(*(info->buffer)) + (uint32_t)info->offset), len);
info->offset += (size_t)len;
return len;
}
size_t memFileWrite(AbstractFile* file, const void* data, size_t len) {
MemFileWrapperInfo* info = (MemFileWrapperInfo*) (file->data);
while((info->offset + (size_t)len) > info->actualBufferSize) {
info->actualBufferSize <<= 1;
*(info->buffer) = realloc(*(info->buffer), info->actualBufferSize);
}
if((info->offset + (size_t)len) > (*(info->bufferSize))) {
*(info->bufferSize) = info->offset + (size_t)len;
}
memcpy((void*)((uint8_t*)(*(info->buffer)) + (uint32_t)info->offset), data, len);
info->offset += (size_t)len;
return len;
}
int memFileSeek(AbstractFile* file, off_t offset) {
MemFileWrapperInfo* info = (MemFileWrapperInfo*) (file->data);
info->offset = (size_t)offset;
return 0;
}
off_t memFileTell(AbstractFile* file) {
MemFileWrapperInfo* info = (MemFileWrapperInfo*) (file->data);
return (off_t)info->offset;
}
off_t memFileGetLength(AbstractFile* file) {
MemFileWrapperInfo* info = (MemFileWrapperInfo*) (file->data);
return *(info->bufferSize);
}
void memFileClose(AbstractFile* file) {
free(file->data);
free(file);
}
AbstractFile* createAbstractFileFromMemoryFile(void** buffer, size_t* size) {
MemFileWrapperInfo* info;
AbstractFile* toReturn;
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
info = (MemFileWrapperInfo*) malloc(sizeof(MemFileWrapperInfo));
info->offset = 0;
info->buffer = buffer;
info->bufferSize = size;
#include "common.h"
size_t freadWrapper(AbstractFile* file, void* data, size_t len) {
return fread(data, 1, len, (FILE*) (file->data));
}
size_t fwriteWrapper(AbstractFile* file, const void* data, size_t len) {
return fwrite(data, 1, len, (FILE*) (file->data));
}
int fseekWrapper(AbstractFile* file, off_t offset) {
return fseeko((FILE*) (file->data), offset, SEEK_SET);
}
off_t ftellWrapper(AbstractFile* file) {
return ftello((FILE*) (file->data));
}
void fcloseWrapper(AbstractFile* file) {
fclose((FILE*) (file->data));
free(file);
}
off_t fileGetLength(AbstractFile* file) {
off_t length;
off_t pos;
pos = ftello((FILE*) (file->data));
fseeko((FILE*) (file->data), 0, SEEK_END);
length = ftello((FILE*) (file->data));
fseeko((FILE*) (file->data), pos, SEEK_SET);
return length;
}
AbstractFile* createAbstractFileFromFile(FILE* file) {
AbstractFile* toReturn;
if(file == NULL) {
return NULL;
}
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
toReturn->data = file;
toReturn->read = freadWrapper;
toReturn->write = fwriteWrapper;
toReturn->seek = fseekWrapper;
toReturn->tell = ftellWrapper;
toReturn->getLength = fileGetLength;
toReturn->close = fcloseWrapper;
return toReturn;
}
size_t dummyRead(AbstractFile* file, void* data, size_t len) {
return 0;
}
size_t dummyWrite(AbstractFile* file, const void* data, size_t len) {
*((off_t*) (file->data)) += len;
return len;
}
int dummySeek(AbstractFile* file, off_t offset) {
*((off_t*) (file->data)) = offset;
return 0;
}
off_t dummyTell(AbstractFile* file) {
return *((off_t*) (file->data));
}
void dummyClose(AbstractFile* file) {
free(file);
}
AbstractFile* createAbstractFileFromDummy() {
AbstractFile* toReturn;
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
toReturn->data = NULL;
toReturn->read = dummyRead;
toReturn->write = dummyWrite;
toReturn->seek = dummySeek;
toReturn->tell = dummyTell;
toReturn->getLength = NULL;
toReturn->close = dummyClose;
return toReturn;
}
size_t memRead(AbstractFile* file, void* data, size_t len) {
MemWrapperInfo* info = (MemWrapperInfo*) (file->data);
memcpy(data, (void*)((uint8_t*)(*(info->buffer)) + (uint32_t)info->offset), len);
info->offset += (size_t)len;
return len;
}
size_t memWrite(AbstractFile* file, const void* data, size_t len) {
MemWrapperInfo* info = (MemWrapperInfo*) (file->data);
while((info->offset + (size_t)len) > info->bufferSize) {
info->bufferSize <<= 1;
*(info->buffer) = realloc(*(info->buffer), info->bufferSize);
}
memcpy((void*)((uint8_t*)(*(info->buffer)) + (uint32_t)info->offset), data, len);
info->offset += (size_t)len;
return len;
}
int memSeek(AbstractFile* file, off_t offset) {
MemWrapperInfo* info = (MemWrapperInfo*) (file->data);
info->offset = (size_t)offset;
return 0;
}
off_t memTell(AbstractFile* file) {
MemWrapperInfo* info = (MemWrapperInfo*) (file->data);
return (off_t)info->offset;
}
off_t memGetLength(AbstractFile* file) {
MemWrapperInfo* info = (MemWrapperInfo*) (file->data);
return info->bufferSize;
}
void memClose(AbstractFile* file) {
free(file->data);
free(file);
}
AbstractFile* createAbstractFileFromMemory(void** buffer, size_t size) {
MemWrapperInfo* info;
AbstractFile* toReturn;
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
info = (MemWrapperInfo*) malloc(sizeof(MemWrapperInfo));
info->offset = 0;
info->buffer = buffer;
info->bufferSize = size;
toReturn->data = info;
toReturn->read = memRead;
toReturn->write = memWrite;
toReturn->seek = memSeek;
toReturn->tell = memTell;
toReturn->getLength = memGetLength;
toReturn->close = memClose;
return toReturn;
}
void abstractFilePrint(AbstractFile* file, const char* format, ...) {
va_list args;
char buffer[1024];
size_t length;
buffer[0] = '\0';
va_start(args, format);
length = vsprintf(buffer, format, args);
va_end(args);
ASSERT(file->write(file, buffer, length) == length, "fwrite");
}
int absFileRead(io_func* io, off_t location, size_t size, void *buffer) {
AbstractFile* file;
file = (AbstractFile*) io->data;
file->seek(file, location);
if(file->read(file, buffer, size) == size) {
return TRUE;
} else {
return FALSE;
}
}
int absFileWrite(io_func* io, off_t location, size_t size, void *buffer) {
AbstractFile* file;
file = (AbstractFile*) io->data;
file->seek(file, location);
if(file->write(file, buffer, size) == size) {
return TRUE;
} else {
return FALSE;
}
}
void closeAbsFile(io_func* io) {
AbstractFile* file;
file = (AbstractFile*) io->data;
file->close(file);
free(io);
}
io_func* IOFuncFromAbstractFile(AbstractFile* file) {
io_func* io;
io = (io_func*) malloc(sizeof(io_func));
io->data = file;
io->read = &absFileRead;
io->write = &absFileWrite;
io->close = &closeAbsFile;
return io;
}
size_t memFileRead(AbstractFile* file, void* data, size_t len) {
MemFileWrapperInfo* info = (MemFileWrapperInfo*) (file->data);
memcpy(data, (void*)((uint8_t*)(*(info->buffer)) + (uint32_t)info->offset), len);
info->offset += (size_t)len;
return len;
}
size_t memFileWrite(AbstractFile* file, const void* data, size_t len) {
MemFileWrapperInfo* info = (MemFileWrapperInfo*) (file->data);
while((info->offset + (size_t)len) > info->actualBufferSize) {
info->actualBufferSize <<= 1;
*(info->buffer) = realloc(*(info->buffer), info->actualBufferSize);
}
if((info->offset + (size_t)len) > (*(info->bufferSize))) {
*(info->bufferSize) = info->offset + (size_t)len;
}
memcpy((void*)((uint8_t*)(*(info->buffer)) + (uint32_t)info->offset), data, len);
info->offset += (size_t)len;
return len;
}
int memFileSeek(AbstractFile* file, off_t offset) {
MemFileWrapperInfo* info = (MemFileWrapperInfo*) (file->data);
info->offset = (size_t)offset;
return 0;
}
off_t memFileTell(AbstractFile* file) {
MemFileWrapperInfo* info = (MemFileWrapperInfo*) (file->data);
return (off_t)info->offset;
}
off_t memFileGetLength(AbstractFile* file) {
MemFileWrapperInfo* info = (MemFileWrapperInfo*) (file->data);
return *(info->bufferSize);
}
void memFileClose(AbstractFile* file) {
free(file->data);
free(file);
}
AbstractFile* createAbstractFileFromMemoryFile(void** buffer, size_t* size) {
MemFileWrapperInfo* info;
AbstractFile* toReturn;
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
info = (MemFileWrapperInfo*) malloc(sizeof(MemFileWrapperInfo));
info->offset = 0;
info->buffer = buffer;
info->bufferSize = size;
info->actualBufferSize = (1024 < (*size)) ? (*size) : 1024;
if(info->actualBufferSize != *(info->bufferSize)) {
if(info->actualBufferSize != *(info->bufferSize)) {
*(info->buffer) = realloc(*(info->buffer), info->actualBufferSize);
}
toReturn->data = info;
toReturn->read = memFileRead;
toReturn->write = memFileWrite;
toReturn->seek = memFileSeek;
toReturn->tell = memFileTell;
toReturn->getLength = memFileGetLength;
toReturn->close = memFileClose;
return toReturn;
}
AbstractFile* createAbstractFileFromMemoryFileBuffer(void** buffer, size_t* size, size_t actualBufferSize) {
MemFileWrapperInfo* info;
AbstractFile* toReturn;
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
info = (MemFileWrapperInfo*) malloc(sizeof(MemFileWrapperInfo));
info->offset = 0;
info->buffer = buffer;
info->bufferSize = size;
info->actualBufferSize = actualBufferSize;
toReturn->data = info;
toReturn->read = memFileRead;
toReturn->write = memFileWrite;
toReturn->seek = memFileSeek;
toReturn->tell = memFileTell;
toReturn->getLength = memFileGetLength;
toReturn->close = memFileClose;
return toReturn;
}
}
toReturn->data = info;
toReturn->read = memFileRead;
toReturn->write = memFileWrite;
toReturn->seek = memFileSeek;
toReturn->tell = memFileTell;
toReturn->getLength = memFileGetLength;
toReturn->close = memFileClose;
return toReturn;
}
AbstractFile* createAbstractFileFromMemoryFileBuffer(void** buffer, size_t* size, size_t actualBufferSize) {
MemFileWrapperInfo* info;
AbstractFile* toReturn;
toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
info = (MemFileWrapperInfo*) malloc(sizeof(MemFileWrapperInfo));
info->offset = 0;
info->buffer = buffer;
info->bufferSize = size;
info->actualBufferSize = actualBufferSize;
toReturn->data = info;
toReturn->read = memFileRead;
toReturn->write = memFileWrite;
toReturn->seek = memFileSeek;
toReturn->tell = memFileTell;
toReturn->getLength = memFileGetLength;
toReturn->close = memFileClose;
return toReturn;
}

Просмотреть файл

@ -3,47 +3,47 @@
#include "common.h"
typedef struct AbstractFile AbstractFile;
typedef size_t (*WriteFunc)(AbstractFile* file, const void* data, size_t len);
typedef size_t (*ReadFunc)(AbstractFile* file, void* data, size_t len);
typedef int (*SeekFunc)(AbstractFile* file, off_t offset);
typedef off_t (*TellFunc)(AbstractFile* file);
typedef void (*CloseFunc)(AbstractFile* file);
typedef off_t (*GetLengthFunc)(AbstractFile* file);
struct AbstractFile {
void* data;
WriteFunc write;
ReadFunc read;
SeekFunc seek;
TellFunc tell;
GetLengthFunc getLength;
CloseFunc close;
typedef struct AbstractFile AbstractFile;
typedef size_t (*WriteFunc)(AbstractFile* file, const void* data, size_t len);
typedef size_t (*ReadFunc)(AbstractFile* file, void* data, size_t len);
typedef int (*SeekFunc)(AbstractFile* file, off_t offset);
typedef off_t (*TellFunc)(AbstractFile* file);
typedef void (*CloseFunc)(AbstractFile* file);
typedef off_t (*GetLengthFunc)(AbstractFile* file);
struct AbstractFile {
void* data;
WriteFunc write;
ReadFunc read;
SeekFunc seek;
TellFunc tell;
GetLengthFunc getLength;
CloseFunc close;
};
typedef struct {
size_t offset;
void** buffer;
size_t bufferSize;
} MemWrapperInfo;
typedef struct {
size_t offset;
void** buffer;
size_t* bufferSize;
size_t actualBufferSize;
} MemFileWrapperInfo;
typedef struct {
size_t offset;
void** buffer;
size_t bufferSize;
} MemWrapperInfo;
typedef struct {
size_t offset;
void** buffer;
size_t* bufferSize;
size_t actualBufferSize;
} MemFileWrapperInfo;
#ifdef __cplusplus
extern "C" {
#endif
AbstractFile* createAbstractFileFromFile(FILE* file);
AbstractFile* createAbstractFileFromDummy();
AbstractFile* createAbstractFileFromMemory(void** buffer, size_t size);
AbstractFile* createAbstractFileFromMemoryFile(void** buffer, size_t* size);
AbstractFile* createAbstractFileFromMemoryFileBuffer(void** buffer, size_t* size, size_t actualBufferSize);
void abstractFilePrint(AbstractFile* file, const char* format, ...);
AbstractFile* createAbstractFileFromFile(FILE* file);
AbstractFile* createAbstractFileFromDummy();
AbstractFile* createAbstractFileFromMemory(void** buffer, size_t size);
AbstractFile* createAbstractFileFromMemoryFile(void** buffer, size_t* size);
AbstractFile* createAbstractFileFromMemoryFileBuffer(void** buffer, size_t* size, size_t actualBufferSize);
void abstractFilePrint(AbstractFile* file, const char* format, ...);
io_func* IOFuncFromAbstractFile(AbstractFile* file);
#ifdef __cplusplus
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,75 +1,75 @@
#ifndef COMMON_H
#define COMMON_H
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#ifdef WIN32
#define fseeko fseeko64
#define ftello ftello64
#define off_t off64_t
#define mkdir(x, y) mkdir(x)
#endif
#define TRUE 1
#define FALSE 0
#define FLIPENDIAN(x) flipEndian((unsigned char *)(&(x)), sizeof(x))
#define FLIPENDIANLE(x) flipEndianLE((unsigned char *)(&(x)), sizeof(x))
#define IS_BIG_ENDIAN 0
#define IS_LITTLE_ENDIAN 1
#define TIME_OFFSET_FROM_UNIX 2082844800L
#define APPLE_TO_UNIX_TIME(x) ((x) - TIME_OFFSET_FROM_UNIX)
#define UNIX_TO_APPLE_TIME(x) ((x) + TIME_OFFSET_FROM_UNIX)
#define ASSERT(x, m) if(!(x)) { fflush(stdout); fprintf(stderr, "error: %s\n", m); perror("error"); fflush(stderr); exit(1); }
extern char endianness;
static inline void flipEndian(unsigned char* x, int length) {
int i;
unsigned char tmp;
if(endianness == IS_BIG_ENDIAN) {
return;
} else {
for(i = 0; i < (length / 2); i++) {
tmp = x[i];
x[i] = x[length - i - 1];
x[length - i - 1] = tmp;
}
}
}
static inline void flipEndianLE(unsigned char* x, int length) {
int i;
unsigned char tmp;
if(endianness == IS_LITTLE_ENDIAN) {
return;
} else {
for(i = 0; i < (length / 2); i++) {
tmp = x[i];
x[i] = x[length - i - 1];
x[length - i - 1] = tmp;
}
}
}
struct io_func_struct;
typedef int (*readFunc)(struct io_func_struct* io, off_t location, size_t size, void *buffer);
typedef int (*writeFunc)(struct io_func_struct* io, off_t location, size_t size, void *buffer);
typedef void (*closeFunc)(struct io_func_struct* io);
typedef struct io_func_struct {
void* data;
readFunc read;
writeFunc write;
closeFunc close;
} io_func;
#endif
#ifndef COMMON_H
#define COMMON_H
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#ifdef WIN32
#define fseeko fseeko64
#define ftello ftello64
#define off_t off64_t
#define mkdir(x, y) mkdir(x)
#endif
#define TRUE 1
#define FALSE 0
#define FLIPENDIAN(x) flipEndian((unsigned char *)(&(x)), sizeof(x))
#define FLIPENDIANLE(x) flipEndianLE((unsigned char *)(&(x)), sizeof(x))
#define IS_BIG_ENDIAN 0
#define IS_LITTLE_ENDIAN 1
#define TIME_OFFSET_FROM_UNIX 2082844800L
#define APPLE_TO_UNIX_TIME(x) ((x) - TIME_OFFSET_FROM_UNIX)
#define UNIX_TO_APPLE_TIME(x) ((x) + TIME_OFFSET_FROM_UNIX)
#define ASSERT(x, m) if(!(x)) { fflush(stdout); fprintf(stderr, "error: %s\n", m); perror("error"); fflush(stderr); exit(1); }
extern char endianness;
static inline void flipEndian(unsigned char* x, int length) {
int i;
unsigned char tmp;
if(endianness == IS_BIG_ENDIAN) {
return;
} else {
for(i = 0; i < (length / 2); i++) {
tmp = x[i];
x[i] = x[length - i - 1];
x[length - i - 1] = tmp;
}
}
}
static inline void flipEndianLE(unsigned char* x, int length) {
int i;
unsigned char tmp;
if(endianness == IS_LITTLE_ENDIAN) {
return;
} else {
for(i = 0; i < (length / 2); i++) {
tmp = x[i];
x[i] = x[length - i - 1];
x[length - i - 1] = tmp;
}
}
}
struct io_func_struct;
typedef int (*readFunc)(struct io_func_struct* io, off_t location, size_t size, void *buffer);
typedef int (*writeFunc)(struct io_func_struct* io, off_t location, size_t size, void *buffer);
typedef void (*closeFunc)(struct io_func_struct* io);
typedef struct io_func_struct {
void* data;
readFunc read;
writeFunc write;
closeFunc close;
} io_func;
#endif

Просмотреть файл

@ -1,119 +1,119 @@
#include <stdlib.h>
#include <string.h>
#include "hfsplus.h"
static inline void flipExtentDescriptor(HFSPlusExtentDescriptor* extentDescriptor) {
FLIPENDIAN(extentDescriptor->startBlock);
FLIPENDIAN(extentDescriptor->blockCount);
}
void flipExtentRecord(HFSPlusExtentRecord* extentRecord) {
HFSPlusExtentDescriptor *extentDescriptor;
extentDescriptor = (HFSPlusExtentDescriptor*)extentRecord;
flipExtentDescriptor(&extentDescriptor[0]);
flipExtentDescriptor(&extentDescriptor[1]);
flipExtentDescriptor(&extentDescriptor[2]);
flipExtentDescriptor(&extentDescriptor[3]);
flipExtentDescriptor(&extentDescriptor[4]);
flipExtentDescriptor(&extentDescriptor[5]);
flipExtentDescriptor(&extentDescriptor[6]);
flipExtentDescriptor(&extentDescriptor[7]);
}
static int extentCompare(BTKey* vLeft, BTKey* vRight) {
HFSPlusExtentKey* left;
HFSPlusExtentKey* right;
left = (HFSPlusExtentKey*) vLeft;
right =(HFSPlusExtentKey*) vRight;
if(left->forkType < right->forkType) {
return -1;
} else if(left->forkType > right->forkType) {
return 1;
} else {
if(left->fileID < right->fileID) {
return -1;
} else if(left->fileID > right->fileID) {
return 1;
} else {
if(left->startBlock < right->startBlock) {
return -1;
} else if(left->startBlock > right->startBlock) {
return 1;
} else {
/* do a safety check on key length. Otherwise, bad things may happen later on when we try to add or remove with this key */
if(left->keyLength == right->keyLength) {
return 0;
} else if(left->keyLength < right->keyLength) {
return -1;
} else {
return 1;
}
return 0;
}
}
}
}
static BTKey* extentKeyRead(off_t offset, io_func* io) {
HFSPlusExtentKey* key;
key = (HFSPlusExtentKey*) malloc(sizeof(HFSPlusExtentKey));
if(!READ(io, offset, sizeof(HFSPlusExtentKey), key))
return NULL;
FLIPENDIAN(key->keyLength);
FLIPENDIAN(key->forkType);
FLIPENDIAN(key->fileID);
FLIPENDIAN(key->startBlock);
return (BTKey*)key;
}
static int extentKeyWrite(off_t offset, BTKey* toWrite, io_func* io) {
HFSPlusExtentKey* key;
key = (HFSPlusExtentKey*) malloc(sizeof(HFSPlusExtentKey));
memcpy(key, toWrite, sizeof(HFSPlusExtentKey));
FLIPENDIAN(key->keyLength);
FLIPENDIAN(key->forkType);
FLIPENDIAN(key->fileID);
FLIPENDIAN(key->startBlock);
if(!WRITE(io, offset, sizeof(HFSPlusExtentKey), key))
return FALSE;
free(key);
return TRUE;
}
static void extentKeyPrint(BTKey* toPrint) {
HFSPlusExtentKey* key;
key = (HFSPlusExtentKey*)toPrint;
printf("extent%d:%d:%d", key->forkType, key->fileID, key->startBlock);
}
static BTKey* extentDataRead(off_t offset, io_func* io) {
HFSPlusExtentRecord* record;
record = (HFSPlusExtentRecord*) malloc(sizeof(HFSPlusExtentRecord));
if(!READ(io, offset, sizeof(HFSPlusExtentRecord), record))
return NULL;
flipExtentRecord(record);
return (BTKey*)record;
}
BTree* openExtentsTree(io_func* file) {
return openBTree(file, &extentCompare, &extentKeyRead, &extentKeyWrite, &extentKeyPrint, &extentDataRead);
}
#include <string.h>
#include "hfsplus.h"
static inline void flipExtentDescriptor(HFSPlusExtentDescriptor* extentDescriptor) {
FLIPENDIAN(extentDescriptor->startBlock);
FLIPENDIAN(extentDescriptor->blockCount);
}
void flipExtentRecord(HFSPlusExtentRecord* extentRecord) {
HFSPlusExtentDescriptor *extentDescriptor;
extentDescriptor = (HFSPlusExtentDescriptor*)extentRecord;
flipExtentDescriptor(&extentDescriptor[0]);
flipExtentDescriptor(&extentDescriptor[1]);
flipExtentDescriptor(&extentDescriptor[2]);
flipExtentDescriptor(&extentDescriptor[3]);
flipExtentDescriptor(&extentDescriptor[4]);
flipExtentDescriptor(&extentDescriptor[5]);
flipExtentDescriptor(&extentDescriptor[6]);
flipExtentDescriptor(&extentDescriptor[7]);
}
static int extentCompare(BTKey* vLeft, BTKey* vRight) {
HFSPlusExtentKey* left;
HFSPlusExtentKey* right;
left = (HFSPlusExtentKey*) vLeft;
right =(HFSPlusExtentKey*) vRight;
if(left->forkType < right->forkType) {
return -1;
} else if(left->forkType > right->forkType) {
return 1;
} else {
if(left->fileID < right->fileID) {
return -1;
} else if(left->fileID > right->fileID) {
return 1;
} else {
if(left->startBlock < right->startBlock) {
return -1;
} else if(left->startBlock > right->startBlock) {
return 1;
} else {
/* do a safety check on key length. Otherwise, bad things may happen later on when we try to add or remove with this key */
if(left->keyLength == right->keyLength) {
return 0;
} else if(left->keyLength < right->keyLength) {
return -1;
} else {
return 1;
}
return 0;
}
}
}
}
static BTKey* extentKeyRead(off_t offset, io_func* io) {
HFSPlusExtentKey* key;
key = (HFSPlusExtentKey*) malloc(sizeof(HFSPlusExtentKey));
if(!READ(io, offset, sizeof(HFSPlusExtentKey), key))
return NULL;
FLIPENDIAN(key->keyLength);
FLIPENDIAN(key->forkType);
FLIPENDIAN(key->fileID);
FLIPENDIAN(key->startBlock);
return (BTKey*)key;
}
static int extentKeyWrite(off_t offset, BTKey* toWrite, io_func* io) {
HFSPlusExtentKey* key;
key = (HFSPlusExtentKey*) malloc(sizeof(HFSPlusExtentKey));
memcpy(key, toWrite, sizeof(HFSPlusExtentKey));
FLIPENDIAN(key->keyLength);
FLIPENDIAN(key->forkType);
FLIPENDIAN(key->fileID);
FLIPENDIAN(key->startBlock);
if(!WRITE(io, offset, sizeof(HFSPlusExtentKey), key))
return FALSE;
free(key);
return TRUE;
}
static void extentKeyPrint(BTKey* toPrint) {
HFSPlusExtentKey* key;
key = (HFSPlusExtentKey*)toPrint;
printf("extent%d:%d:%d", key->forkType, key->fileID, key->startBlock);
}
static BTKey* extentDataRead(off_t offset, io_func* io) {
HFSPlusExtentRecord* record;
record = (HFSPlusExtentRecord*) malloc(sizeof(HFSPlusExtentRecord));
if(!READ(io, offset, sizeof(HFSPlusExtentRecord), record))
return NULL;
flipExtentRecord(record);
return (BTKey*)record;
}
BTree* openExtentsTree(io_func* file) {
return openBTree(file, &extentCompare, &extentKeyRead, &extentKeyWrite, &extentKeyPrint, &extentDataRead);
}

Просмотреть файл

@ -1,418 +1,418 @@
#include <stdint.h>
#include "hfsplus.h"
/* This routine is taken from Apple's TN 1150, with adaptations for C */
/* The lower case table consists of a 256-entry high-byte table followed by
some number of 256-entry subtables. The high-byte table contains either an
offset to the subtable for characters with that high byte or zero, which
means that there are no case mappings or ignored characters in that block.
Ignored characters are mapped to zero.
*/
uint16_t gLowerCaseTable[] = {
/* 0 */ 0x0100, 0x0200, 0x0000, 0x0300, 0x0400, 0x0500, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 1 */ 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 2 */ 0x0700, 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 3 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 4 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 5 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 6 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 7 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 9 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* A */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* B */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* C */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* D */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* E */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* F */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0900, 0x0A00,
/* 0 */ 0xFFFF, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
/* 1 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
/* 2 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
/* 3 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
/* 4 */ 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
/* 5 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
/* 6 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
/* 7 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
/* 8 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
/* 9 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
/* A */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
/* B */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
/* C */ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00E6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
/* D */ 0x00F0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00F8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00FE, 0x00DF,
/* E */ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
/* F */ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
/* 0 */ 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107,
0x0108, 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x010E, 0x010F,
/* 1 */ 0x0111, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117,
0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, 0x011F,
/* 2 */ 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0127, 0x0127,
0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F,
/* 3 */ 0x0130, 0x0131, 0x0133, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x0140,
/* 4 */ 0x0140, 0x0142, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147,
0x0148, 0x0149, 0x014B, 0x014B, 0x014C, 0x014D, 0x014E, 0x014F,
/* 5 */ 0x0150, 0x0151, 0x0153, 0x0153, 0x0154, 0x0155, 0x0156, 0x0157,
0x0158, 0x0159, 0x015A, 0x015B, 0x015C, 0x015D, 0x015E, 0x015F,
/* 6 */ 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, 0x0167, 0x0167,
0x0168, 0x0169, 0x016A, 0x016B, 0x016C, 0x016D, 0x016E, 0x016F,
/* 7 */ 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, 0x0176, 0x0177,
0x0178, 0x0179, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E, 0x017F,
/* 8 */ 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188,
0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259,
/* 9 */ 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268,
0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275,
/* A */ 0x01A0, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x01A6, 0x01A8,
0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01AF,
/* B */ 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292,
0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF,
/* C */ 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9,
0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC, 0x01CD, 0x01CE, 0x01CF,
/* D */ 0x01D0, 0x01D1, 0x01D2, 0x01D3, 0x01D4, 0x01D5, 0x01D6, 0x01D7,
0x01D8, 0x01D9, 0x01DA, 0x01DB, 0x01DC, 0x01DD, 0x01DE, 0x01DF,
/* E */ 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E5, 0x01E5, 0x01E6, 0x01E7,
0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x01EC, 0x01ED, 0x01EE, 0x01EF,
/* F */ 0x01F0, 0x01F3, 0x01F3, 0x01F3, 0x01F4, 0x01F5, 0x01F6, 0x01F7,
0x01F8, 0x01F9, 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF,
/* 0 */ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307,
0x0308, 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, 0x030E, 0x030F,
/* 1 */ 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,
0x0318, 0x0319, 0x031A, 0x031B, 0x031C, 0x031D, 0x031E, 0x031F,
/* 2 */ 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327,
0x0328, 0x0329, 0x032A, 0x032B, 0x032C, 0x032D, 0x032E, 0x032F,
/* 3 */ 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337,
0x0338, 0x0339, 0x033A, 0x033B, 0x033C, 0x033D, 0x033E, 0x033F,
/* 4 */ 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347,
0x0348, 0x0349, 0x034A, 0x034B, 0x034C, 0x034D, 0x034E, 0x034F,
/* 5 */ 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357,
0x0358, 0x0359, 0x035A, 0x035B, 0x035C, 0x035D, 0x035E, 0x035F,
/* 6 */ 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367,
0x0368, 0x0369, 0x036A, 0x036B, 0x036C, 0x036D, 0x036E, 0x036F,
/* 7 */ 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377,
0x0378, 0x0379, 0x037A, 0x037B, 0x037C, 0x037D, 0x037E, 0x037F,
/* 8 */ 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, 0x0387,
0x0388, 0x0389, 0x038A, 0x038B, 0x038C, 0x038D, 0x038E, 0x038F,
/* 9 */ 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
/* A */ 0x03C0, 0x03C1, 0x03A2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
0x03C8, 0x03C9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
/* B */ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
/* C */ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x03CF,
/* D */ 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
0x03D8, 0x03D9, 0x03DA, 0x03DB, 0x03DC, 0x03DD, 0x03DE, 0x03DF,
/* E */ 0x03E0, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7,
0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF,
/* F */ 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03F4, 0x03F5, 0x03F6, 0x03F7,
0x03F8, 0x03F9, 0x03FA, 0x03FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF,
/* 0 */ 0x0400, 0x0401, 0x0452, 0x0403, 0x0454, 0x0455, 0x0456, 0x0407,
0x0458, 0x0459, 0x045A, 0x045B, 0x040C, 0x040D, 0x040E, 0x045F,
/* 1 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0419, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
/* 2 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
/* 3 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
/* 4 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
/* 5 */ 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F,
/* 6 */ 0x0461, 0x0461, 0x0463, 0x0463, 0x0465, 0x0465, 0x0467, 0x0467,
0x0469, 0x0469, 0x046B, 0x046B, 0x046D, 0x046D, 0x046F, 0x046F,
/* 7 */ 0x0471, 0x0471, 0x0473, 0x0473, 0x0475, 0x0475, 0x0476, 0x0477,
0x0479, 0x0479, 0x047B, 0x047B, 0x047D, 0x047D, 0x047F, 0x047F,
/* 8 */ 0x0481, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487,
0x0488, 0x0489, 0x048A, 0x048B, 0x048C, 0x048D, 0x048E, 0x048F,
/* 9 */ 0x0491, 0x0491, 0x0493, 0x0493, 0x0495, 0x0495, 0x0497, 0x0497,
0x0499, 0x0499, 0x049B, 0x049B, 0x049D, 0x049D, 0x049F, 0x049F,
/* A */ 0x04A1, 0x04A1, 0x04A3, 0x04A3, 0x04A5, 0x04A5, 0x04A7, 0x04A7,
0x04A9, 0x04A9, 0x04AB, 0x04AB, 0x04AD, 0x04AD, 0x04AF, 0x04AF,
/* B */ 0x04B1, 0x04B1, 0x04B3, 0x04B3, 0x04B5, 0x04B5, 0x04B7, 0x04B7,
0x04B9, 0x04B9, 0x04BB, 0x04BB, 0x04BD, 0x04BD, 0x04BF, 0x04BF,
/* C */ 0x04C0, 0x04C1, 0x04C2, 0x04C4, 0x04C4, 0x04C5, 0x04C6, 0x04C8,
0x04C8, 0x04C9, 0x04CA, 0x04CC, 0x04CC, 0x04CD, 0x04CE, 0x04CF,
/* D */ 0x04D0, 0x04D1, 0x04D2, 0x04D3, 0x04D4, 0x04D5, 0x04D6, 0x04D7,
0x04D8, 0x04D9, 0x04DA, 0x04DB, 0x04DC, 0x04DD, 0x04DE, 0x04DF,
/* E */ 0x04E0, 0x04E1, 0x04E2, 0x04E3, 0x04E4, 0x04E5, 0x04E6, 0x04E7,
0x04E8, 0x04E9, 0x04EA, 0x04EB, 0x04EC, 0x04ED, 0x04EE, 0x04EF,
/* F */ 0x04F0, 0x04F1, 0x04F2, 0x04F3, 0x04F4, 0x04F5, 0x04F6, 0x04F7,
0x04F8, 0x04F9, 0x04FA, 0x04FB, 0x04FC, 0x04FD, 0x04FE, 0x04FF,
/* 0 */ 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, 0x0507,
0x0508, 0x0509, 0x050A, 0x050B, 0x050C, 0x050D, 0x050E, 0x050F,
/* 1 */ 0x0510, 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517,
0x0518, 0x0519, 0x051A, 0x051B, 0x051C, 0x051D, 0x051E, 0x051F,
/* 2 */ 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527,
0x0528, 0x0529, 0x052A, 0x052B, 0x052C, 0x052D, 0x052E, 0x052F,
/* 3 */ 0x0530, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
/* 4 */ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577,
0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
/* 5 */ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0557,
0x0558, 0x0559, 0x055A, 0x055B, 0x055C, 0x055D, 0x055E, 0x055F,
/* 6 */ 0x0560, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
/* 7 */ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577,
0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
/* 8 */ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0587,
0x0588, 0x0589, 0x058A, 0x058B, 0x058C, 0x058D, 0x058E, 0x058F,
/* 9 */ 0x0590, 0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597,
0x0598, 0x0599, 0x059A, 0x059B, 0x059C, 0x059D, 0x059E, 0x059F,
/* A */ 0x05A0, 0x05A1, 0x05A2, 0x05A3, 0x05A4, 0x05A5, 0x05A6, 0x05A7,
0x05A8, 0x05A9, 0x05AA, 0x05AB, 0x05AC, 0x05AD, 0x05AE, 0x05AF,
/* B */ 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
0x05B8, 0x05B9, 0x05BA, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
/* C */ 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05C4, 0x05C5, 0x05C6, 0x05C7,
0x05C8, 0x05C9, 0x05CA, 0x05CB, 0x05CC, 0x05CD, 0x05CE, 0x05CF,
/* D */ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
/* E */ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x05EB, 0x05EC, 0x05ED, 0x05EE, 0x05EF,
/* F */ 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x05F5, 0x05F6, 0x05F7,
0x05F8, 0x05F9, 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF,
/* 0 */ 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
0x1008, 0x1009, 0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
/* 1 */ 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
/* 2 */ 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
0x1028, 0x1029, 0x102A, 0x102B, 0x102C, 0x102D, 0x102E, 0x102F,
/* 3 */ 0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035, 0x1036, 0x1037,
0x1038, 0x1039, 0x103A, 0x103B, 0x103C, 0x103D, 0x103E, 0x103F,
/* 4 */ 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047,
0x1048, 0x1049, 0x104A, 0x104B, 0x104C, 0x104D, 0x104E, 0x104F,
/* 5 */ 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057,
0x1058, 0x1059, 0x105A, 0x105B, 0x105C, 0x105D, 0x105E, 0x105F,
/* 6 */ 0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067,
0x1068, 0x1069, 0x106A, 0x106B, 0x106C, 0x106D, 0x106E, 0x106F,
/* 7 */ 0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077,
0x1078, 0x1079, 0x107A, 0x107B, 0x107C, 0x107D, 0x107E, 0x107F,
/* 8 */ 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087,
0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D, 0x108E, 0x108F,
/* 9 */ 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097,
0x1098, 0x1099, 0x109A, 0x109B, 0x109C, 0x109D, 0x109E, 0x109F,
/* A */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7,
0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF,
/* B */ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7,
0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF,
/* C */ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10C6, 0x10C7,
0x10C8, 0x10C9, 0x10CA, 0x10CB, 0x10CC, 0x10CD, 0x10CE, 0x10CF,
/* D */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7,
0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF,
/* E */ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7,
0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF,
/* F */ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10F6, 0x10F7,
0x10F8, 0x10F9, 0x10FA, 0x10FB, 0x10FC, 0x10FD, 0x10FE, 0x10FF,
/* 0 */ 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
0x2008, 0x2009, 0x200A, 0x200B, 0x0000, 0x0000, 0x0000, 0x0000,
/* 1 */ 0x2010, 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 0x2017,
0x2018, 0x2019, 0x201A, 0x201B, 0x201C, 0x201D, 0x201E, 0x201F,
/* 2 */ 0x2020, 0x2021, 0x2022, 0x2023, 0x2024, 0x2025, 0x2026, 0x2027,
0x2028, 0x2029, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x202F,
/* 3 */ 0x2030, 0x2031, 0x2032, 0x2033, 0x2034, 0x2035, 0x2036, 0x2037,
0x2038, 0x2039, 0x203A, 0x203B, 0x203C, 0x203D, 0x203E, 0x203F,
/* 4 */ 0x2040, 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, 0x2047,
0x2048, 0x2049, 0x204A, 0x204B, 0x204C, 0x204D, 0x204E, 0x204F,
/* 5 */ 0x2050, 0x2051, 0x2052, 0x2053, 0x2054, 0x2055, 0x2056, 0x2057,
0x2058, 0x2059, 0x205A, 0x205B, 0x205C, 0x205D, 0x205E, 0x205F,
/* 6 */ 0x2060, 0x2061, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067,
0x2068, 0x2069, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 7 */ 0x2070, 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077,
0x2078, 0x2079, 0x207A, 0x207B, 0x207C, 0x207D, 0x207E, 0x207F,
/* 8 */ 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087,
0x2088, 0x2089, 0x208A, 0x208B, 0x208C, 0x208D, 0x208E, 0x208F,
/* 9 */ 0x2090, 0x2091, 0x2092, 0x2093, 0x2094, 0x2095, 0x2096, 0x2097,
0x2098, 0x2099, 0x209A, 0x209B, 0x209C, 0x209D, 0x209E, 0x209F,
/* A */ 0x20A0, 0x20A1, 0x20A2, 0x20A3, 0x20A4, 0x20A5, 0x20A6, 0x20A7,
0x20A8, 0x20A9, 0x20AA, 0x20AB, 0x20AC, 0x20AD, 0x20AE, 0x20AF,
/* B */ 0x20B0, 0x20B1, 0x20B2, 0x20B3, 0x20B4, 0x20B5, 0x20B6, 0x20B7,
0x20B8, 0x20B9, 0x20BA, 0x20BB, 0x20BC, 0x20BD, 0x20BE, 0x20BF,
/* C */ 0x20C0, 0x20C1, 0x20C2, 0x20C3, 0x20C4, 0x20C5, 0x20C6, 0x20C7,
0x20C8, 0x20C9, 0x20CA, 0x20CB, 0x20CC, 0x20CD, 0x20CE, 0x20CF,
/* D */ 0x20D0, 0x20D1, 0x20D2, 0x20D3, 0x20D4, 0x20D5, 0x20D6, 0x20D7,
0x20D8, 0x20D9, 0x20DA, 0x20DB, 0x20DC, 0x20DD, 0x20DE, 0x20DF,
/* E */ 0x20E0, 0x20E1, 0x20E2, 0x20E3, 0x20E4, 0x20E5, 0x20E6, 0x20E7,
0x20E8, 0x20E9, 0x20EA, 0x20EB, 0x20EC, 0x20ED, 0x20EE, 0x20EF,
/* F */ 0x20F0, 0x20F1, 0x20F2, 0x20F3, 0x20F4, 0x20F5, 0x20F6, 0x20F7,
0x20F8, 0x20F9, 0x20FA, 0x20FB, 0x20FC, 0x20FD, 0x20FE, 0x20FF,
/* 0 */ 0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105, 0x2106, 0x2107,
0x2108, 0x2109, 0x210A, 0x210B, 0x210C, 0x210D, 0x210E, 0x210F,
/* 1 */ 0x2110, 0x2111, 0x2112, 0x2113, 0x2114, 0x2115, 0x2116, 0x2117,
0x2118, 0x2119, 0x211A, 0x211B, 0x211C, 0x211D, 0x211E, 0x211F,
/* 2 */ 0x2120, 0x2121, 0x2122, 0x2123, 0x2124, 0x2125, 0x2126, 0x2127,
0x2128, 0x2129, 0x212A, 0x212B, 0x212C, 0x212D, 0x212E, 0x212F,
/* 3 */ 0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137,
0x2138, 0x2139, 0x213A, 0x213B, 0x213C, 0x213D, 0x213E, 0x213F,
/* 4 */ 0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, 0x2146, 0x2147,
0x2148, 0x2149, 0x214A, 0x214B, 0x214C, 0x214D, 0x214E, 0x214F,
/* 5 */ 0x2150, 0x2151, 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157,
0x2158, 0x2159, 0x215A, 0x215B, 0x215C, 0x215D, 0x215E, 0x215F,
/* 6 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F,
/* 7 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F,
/* 8 */ 0x2180, 0x2181, 0x2182, 0x2183, 0x2184, 0x2185, 0x2186, 0x2187,
0x2188, 0x2189, 0x218A, 0x218B, 0x218C, 0x218D, 0x218E, 0x218F,
/* 9 */ 0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x2196, 0x2197,
0x2198, 0x2199, 0x219A, 0x219B, 0x219C, 0x219D, 0x219E, 0x219F,
/* A */ 0x21A0, 0x21A1, 0x21A2, 0x21A3, 0x21A4, 0x21A5, 0x21A6, 0x21A7,
0x21A8, 0x21A9, 0x21AA, 0x21AB, 0x21AC, 0x21AD, 0x21AE, 0x21AF,
/* B */ 0x21B0, 0x21B1, 0x21B2, 0x21B3, 0x21B4, 0x21B5, 0x21B6, 0x21B7,
0x21B8, 0x21B9, 0x21BA, 0x21BB, 0x21BC, 0x21BD, 0x21BE, 0x21BF,
/* C */ 0x21C0, 0x21C1, 0x21C2, 0x21C3, 0x21C4, 0x21C5, 0x21C6, 0x21C7,
0x21C8, 0x21C9, 0x21CA, 0x21CB, 0x21CC, 0x21CD, 0x21CE, 0x21CF,
/* D */ 0x21D0, 0x21D1, 0x21D2, 0x21D3, 0x21D4, 0x21D5, 0x21D6, 0x21D7,
0x21D8, 0x21D9, 0x21DA, 0x21DB, 0x21DC, 0x21DD, 0x21DE, 0x21DF,
/* E */ 0x21E0, 0x21E1, 0x21E2, 0x21E3, 0x21E4, 0x21E5, 0x21E6, 0x21E7,
0x21E8, 0x21E9, 0x21EA, 0x21EB, 0x21EC, 0x21ED, 0x21EE, 0x21EF,
/* F */ 0x21F0, 0x21F1, 0x21F2, 0x21F3, 0x21F4, 0x21F5, 0x21F6, 0x21F7,
0x21F8, 0x21F9, 0x21FA, 0x21FB, 0x21FC, 0x21FD, 0x21FE, 0x21FF,
/* 0 */ 0xFE00, 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07,
0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, 0xFE0F,
/* 1 */ 0xFE10, 0xFE11, 0xFE12, 0xFE13, 0xFE14, 0xFE15, 0xFE16, 0xFE17,
0xFE18, 0xFE19, 0xFE1A, 0xFE1B, 0xFE1C, 0xFE1D, 0xFE1E, 0xFE1F,
/* 2 */ 0xFE20, 0xFE21, 0xFE22, 0xFE23, 0xFE24, 0xFE25, 0xFE26, 0xFE27,
0xFE28, 0xFE29, 0xFE2A, 0xFE2B, 0xFE2C, 0xFE2D, 0xFE2E, 0xFE2F,
/* 3 */ 0xFE30, 0xFE31, 0xFE32, 0xFE33, 0xFE34, 0xFE35, 0xFE36, 0xFE37,
0xFE38, 0xFE39, 0xFE3A, 0xFE3B, 0xFE3C, 0xFE3D, 0xFE3E, 0xFE3F,
/* 4 */ 0xFE40, 0xFE41, 0xFE42, 0xFE43, 0xFE44, 0xFE45, 0xFE46, 0xFE47,
0xFE48, 0xFE49, 0xFE4A, 0xFE4B, 0xFE4C, 0xFE4D, 0xFE4E, 0xFE4F,
/* 5 */ 0xFE50, 0xFE51, 0xFE52, 0xFE53, 0xFE54, 0xFE55, 0xFE56, 0xFE57,
0xFE58, 0xFE59, 0xFE5A, 0xFE5B, 0xFE5C, 0xFE5D, 0xFE5E, 0xFE5F,
/* 6 */ 0xFE60, 0xFE61, 0xFE62, 0xFE63, 0xFE64, 0xFE65, 0xFE66, 0xFE67,
0xFE68, 0xFE69, 0xFE6A, 0xFE6B, 0xFE6C, 0xFE6D, 0xFE6E, 0xFE6F,
/* 7 */ 0xFE70, 0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE75, 0xFE76, 0xFE77,
0xFE78, 0xFE79, 0xFE7A, 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F,
/* 8 */ 0xFE80, 0xFE81, 0xFE82, 0xFE83, 0xFE84, 0xFE85, 0xFE86, 0xFE87,
0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, 0xFE8D, 0xFE8E, 0xFE8F,
/* 9 */ 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95, 0xFE96, 0xFE97,
0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E, 0xFE9F,
/* A */ 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7,
0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF,
/* B */ 0xFEB0, 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7,
0xFEB8, 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF,
/* C */ 0xFEC0, 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7,
0xFEC8, 0xFEC9, 0xFECA, 0xFECB, 0xFECC, 0xFECD, 0xFECE, 0xFECF,
/* D */ 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4, 0xFED5, 0xFED6, 0xFED7,
0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD, 0xFEDE, 0xFEDF,
/* E */ 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6, 0xFEE7,
0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF,
/* F */ 0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7,
0xFEF8, 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0xFEFD, 0xFEFE, 0x0000,
/* 0 */ 0xFF00, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, 0xFF06, 0xFF07,
0xFF08, 0xFF09, 0xFF0A, 0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F,
/* 1 */ 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17,
0xFF18, 0xFF19, 0xFF1A, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0xFF1F,
/* 2 */ 0xFF20, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47,
0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
/* 3 */ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57,
0xFF58, 0xFF59, 0xFF5A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F,
/* 4 */ 0xFF40, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47,
0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
/* 5 */ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57,
0xFF58, 0xFF59, 0xFF5A, 0xFF5B, 0xFF5C, 0xFF5D, 0xFF5E, 0xFF5F,
/* 6 */ 0xFF60, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67,
0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F,
/* 7 */ 0xFF70, 0xFF71, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77,
0xFF78, 0xFF79, 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F,
/* 8 */ 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87,
0xFF88, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F,
/* 9 */ 0xFF90, 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97,
0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F,
/* A */ 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3, 0xFFA4, 0xFFA5, 0xFFA6, 0xFFA7,
0xFFA8, 0xFFA9, 0xFFAA, 0xFFAB, 0xFFAC, 0xFFAD, 0xFFAE, 0xFFAF,
/* B */ 0xFFB0, 0xFFB1, 0xFFB2, 0xFFB3, 0xFFB4, 0xFFB5, 0xFFB6, 0xFFB7,
0xFFB8, 0xFFB9, 0xFFBA, 0xFFBB, 0xFFBC, 0xFFBD, 0xFFBE, 0xFFBF,
/* C */ 0xFFC0, 0xFFC1, 0xFFC2, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6, 0xFFC7,
0xFFC8, 0xFFC9, 0xFFCA, 0xFFCB, 0xFFCC, 0xFFCD, 0xFFCE, 0xFFCF,
/* D */ 0xFFD0, 0xFFD1, 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6, 0xFFD7,
0xFFD8, 0xFFD9, 0xFFDA, 0xFFDB, 0xFFDC, 0xFFDD, 0xFFDE, 0xFFDF,
/* E */ 0xFFE0, 0xFFE1, 0xFFE2, 0xFFE3, 0xFFE4, 0xFFE5, 0xFFE6, 0xFFE7,
0xFFE8, 0xFFE9, 0xFFEA, 0xFFEB, 0xFFEC, 0xFFED, 0xFFEE, 0xFFEF,
/* F */ 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7,
0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF,
};
int32_t FastUnicodeCompare ( register uint16_t str1[], register uint16_t length1,
register uint16_t str2[], register uint16_t length2)
{
register uint16_t c1,c2;
register uint16_t temp;
register uint16_t* lowerCaseTable;
lowerCaseTable = gLowerCaseTable;
while (1) {
c1 = 0;
c2 = 0;
while (length1 && c1 == 0) {
c1 = *(str1++);
--length1;
if ((temp = lowerCaseTable[c1>>8]) != 0)
c1 = lowerCaseTable[temp + (c1 & 0x00FF)];
}
while (length2 && c2 == 0) {
c2 = *(str2++);
--length2;
if ((temp = lowerCaseTable[c2>>8]) != 0)
c2 = lowerCaseTable[temp + (c2 & 0x00FF)];
}
if (c1 == ':') {
c1 = '/';
}
if (c2 == ':') {
c2 = '/';
}
if (c1 != c2)
break;
if (c1 == 0)
return 0;
}
if (c1 < c2)
return -1;
else
return 1;
}
#include <stdint.h>
#include "hfsplus.h"
/* This routine is taken from Apple's TN 1150, with adaptations for C */
/* The lower case table consists of a 256-entry high-byte table followed by
some number of 256-entry subtables. The high-byte table contains either an
offset to the subtable for characters with that high byte or zero, which
means that there are no case mappings or ignored characters in that block.
Ignored characters are mapped to zero.
*/
uint16_t gLowerCaseTable[] = {
/* 0 */ 0x0100, 0x0200, 0x0000, 0x0300, 0x0400, 0x0500, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 1 */ 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 2 */ 0x0700, 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 3 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 4 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 5 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 6 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 7 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 9 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* A */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* B */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* C */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* D */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* E */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* F */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0900, 0x0A00,
/* 0 */ 0xFFFF, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
/* 1 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
/* 2 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
/* 3 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
/* 4 */ 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
/* 5 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
/* 6 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
/* 7 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
/* 8 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
/* 9 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
/* A */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
/* B */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
/* C */ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00E6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
/* D */ 0x00F0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00F8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00FE, 0x00DF,
/* E */ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
/* F */ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
/* 0 */ 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107,
0x0108, 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x010E, 0x010F,
/* 1 */ 0x0111, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117,
0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, 0x011F,
/* 2 */ 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0127, 0x0127,
0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F,
/* 3 */ 0x0130, 0x0131, 0x0133, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x0140,
/* 4 */ 0x0140, 0x0142, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147,
0x0148, 0x0149, 0x014B, 0x014B, 0x014C, 0x014D, 0x014E, 0x014F,
/* 5 */ 0x0150, 0x0151, 0x0153, 0x0153, 0x0154, 0x0155, 0x0156, 0x0157,
0x0158, 0x0159, 0x015A, 0x015B, 0x015C, 0x015D, 0x015E, 0x015F,
/* 6 */ 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, 0x0167, 0x0167,
0x0168, 0x0169, 0x016A, 0x016B, 0x016C, 0x016D, 0x016E, 0x016F,
/* 7 */ 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, 0x0176, 0x0177,
0x0178, 0x0179, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E, 0x017F,
/* 8 */ 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188,
0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259,
/* 9 */ 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268,
0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275,
/* A */ 0x01A0, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x01A6, 0x01A8,
0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01AF,
/* B */ 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292,
0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF,
/* C */ 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9,
0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC, 0x01CD, 0x01CE, 0x01CF,
/* D */ 0x01D0, 0x01D1, 0x01D2, 0x01D3, 0x01D4, 0x01D5, 0x01D6, 0x01D7,
0x01D8, 0x01D9, 0x01DA, 0x01DB, 0x01DC, 0x01DD, 0x01DE, 0x01DF,
/* E */ 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E5, 0x01E5, 0x01E6, 0x01E7,
0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x01EC, 0x01ED, 0x01EE, 0x01EF,
/* F */ 0x01F0, 0x01F3, 0x01F3, 0x01F3, 0x01F4, 0x01F5, 0x01F6, 0x01F7,
0x01F8, 0x01F9, 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF,
/* 0 */ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307,
0x0308, 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, 0x030E, 0x030F,
/* 1 */ 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,
0x0318, 0x0319, 0x031A, 0x031B, 0x031C, 0x031D, 0x031E, 0x031F,
/* 2 */ 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327,
0x0328, 0x0329, 0x032A, 0x032B, 0x032C, 0x032D, 0x032E, 0x032F,
/* 3 */ 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337,
0x0338, 0x0339, 0x033A, 0x033B, 0x033C, 0x033D, 0x033E, 0x033F,
/* 4 */ 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347,
0x0348, 0x0349, 0x034A, 0x034B, 0x034C, 0x034D, 0x034E, 0x034F,
/* 5 */ 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357,
0x0358, 0x0359, 0x035A, 0x035B, 0x035C, 0x035D, 0x035E, 0x035F,
/* 6 */ 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367,
0x0368, 0x0369, 0x036A, 0x036B, 0x036C, 0x036D, 0x036E, 0x036F,
/* 7 */ 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377,
0x0378, 0x0379, 0x037A, 0x037B, 0x037C, 0x037D, 0x037E, 0x037F,
/* 8 */ 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, 0x0387,
0x0388, 0x0389, 0x038A, 0x038B, 0x038C, 0x038D, 0x038E, 0x038F,
/* 9 */ 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
/* A */ 0x03C0, 0x03C1, 0x03A2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
0x03C8, 0x03C9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
/* B */ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
/* C */ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x03CF,
/* D */ 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
0x03D8, 0x03D9, 0x03DA, 0x03DB, 0x03DC, 0x03DD, 0x03DE, 0x03DF,
/* E */ 0x03E0, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7,
0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF,
/* F */ 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03F4, 0x03F5, 0x03F6, 0x03F7,
0x03F8, 0x03F9, 0x03FA, 0x03FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF,
/* 0 */ 0x0400, 0x0401, 0x0452, 0x0403, 0x0454, 0x0455, 0x0456, 0x0407,
0x0458, 0x0459, 0x045A, 0x045B, 0x040C, 0x040D, 0x040E, 0x045F,
/* 1 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0419, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
/* 2 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
/* 3 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
/* 4 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
/* 5 */ 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F,
/* 6 */ 0x0461, 0x0461, 0x0463, 0x0463, 0x0465, 0x0465, 0x0467, 0x0467,
0x0469, 0x0469, 0x046B, 0x046B, 0x046D, 0x046D, 0x046F, 0x046F,
/* 7 */ 0x0471, 0x0471, 0x0473, 0x0473, 0x0475, 0x0475, 0x0476, 0x0477,
0x0479, 0x0479, 0x047B, 0x047B, 0x047D, 0x047D, 0x047F, 0x047F,
/* 8 */ 0x0481, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487,
0x0488, 0x0489, 0x048A, 0x048B, 0x048C, 0x048D, 0x048E, 0x048F,
/* 9 */ 0x0491, 0x0491, 0x0493, 0x0493, 0x0495, 0x0495, 0x0497, 0x0497,
0x0499, 0x0499, 0x049B, 0x049B, 0x049D, 0x049D, 0x049F, 0x049F,
/* A */ 0x04A1, 0x04A1, 0x04A3, 0x04A3, 0x04A5, 0x04A5, 0x04A7, 0x04A7,
0x04A9, 0x04A9, 0x04AB, 0x04AB, 0x04AD, 0x04AD, 0x04AF, 0x04AF,
/* B */ 0x04B1, 0x04B1, 0x04B3, 0x04B3, 0x04B5, 0x04B5, 0x04B7, 0x04B7,
0x04B9, 0x04B9, 0x04BB, 0x04BB, 0x04BD, 0x04BD, 0x04BF, 0x04BF,
/* C */ 0x04C0, 0x04C1, 0x04C2, 0x04C4, 0x04C4, 0x04C5, 0x04C6, 0x04C8,
0x04C8, 0x04C9, 0x04CA, 0x04CC, 0x04CC, 0x04CD, 0x04CE, 0x04CF,
/* D */ 0x04D0, 0x04D1, 0x04D2, 0x04D3, 0x04D4, 0x04D5, 0x04D6, 0x04D7,
0x04D8, 0x04D9, 0x04DA, 0x04DB, 0x04DC, 0x04DD, 0x04DE, 0x04DF,
/* E */ 0x04E0, 0x04E1, 0x04E2, 0x04E3, 0x04E4, 0x04E5, 0x04E6, 0x04E7,
0x04E8, 0x04E9, 0x04EA, 0x04EB, 0x04EC, 0x04ED, 0x04EE, 0x04EF,
/* F */ 0x04F0, 0x04F1, 0x04F2, 0x04F3, 0x04F4, 0x04F5, 0x04F6, 0x04F7,
0x04F8, 0x04F9, 0x04FA, 0x04FB, 0x04FC, 0x04FD, 0x04FE, 0x04FF,
/* 0 */ 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, 0x0507,
0x0508, 0x0509, 0x050A, 0x050B, 0x050C, 0x050D, 0x050E, 0x050F,
/* 1 */ 0x0510, 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517,
0x0518, 0x0519, 0x051A, 0x051B, 0x051C, 0x051D, 0x051E, 0x051F,
/* 2 */ 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527,
0x0528, 0x0529, 0x052A, 0x052B, 0x052C, 0x052D, 0x052E, 0x052F,
/* 3 */ 0x0530, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
/* 4 */ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577,
0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
/* 5 */ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0557,
0x0558, 0x0559, 0x055A, 0x055B, 0x055C, 0x055D, 0x055E, 0x055F,
/* 6 */ 0x0560, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
/* 7 */ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577,
0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
/* 8 */ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0587,
0x0588, 0x0589, 0x058A, 0x058B, 0x058C, 0x058D, 0x058E, 0x058F,
/* 9 */ 0x0590, 0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597,
0x0598, 0x0599, 0x059A, 0x059B, 0x059C, 0x059D, 0x059E, 0x059F,
/* A */ 0x05A0, 0x05A1, 0x05A2, 0x05A3, 0x05A4, 0x05A5, 0x05A6, 0x05A7,
0x05A8, 0x05A9, 0x05AA, 0x05AB, 0x05AC, 0x05AD, 0x05AE, 0x05AF,
/* B */ 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
0x05B8, 0x05B9, 0x05BA, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
/* C */ 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05C4, 0x05C5, 0x05C6, 0x05C7,
0x05C8, 0x05C9, 0x05CA, 0x05CB, 0x05CC, 0x05CD, 0x05CE, 0x05CF,
/* D */ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
/* E */ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x05EB, 0x05EC, 0x05ED, 0x05EE, 0x05EF,
/* F */ 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x05F5, 0x05F6, 0x05F7,
0x05F8, 0x05F9, 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF,
/* 0 */ 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
0x1008, 0x1009, 0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
/* 1 */ 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
/* 2 */ 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
0x1028, 0x1029, 0x102A, 0x102B, 0x102C, 0x102D, 0x102E, 0x102F,
/* 3 */ 0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035, 0x1036, 0x1037,
0x1038, 0x1039, 0x103A, 0x103B, 0x103C, 0x103D, 0x103E, 0x103F,
/* 4 */ 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047,
0x1048, 0x1049, 0x104A, 0x104B, 0x104C, 0x104D, 0x104E, 0x104F,
/* 5 */ 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057,
0x1058, 0x1059, 0x105A, 0x105B, 0x105C, 0x105D, 0x105E, 0x105F,
/* 6 */ 0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067,
0x1068, 0x1069, 0x106A, 0x106B, 0x106C, 0x106D, 0x106E, 0x106F,
/* 7 */ 0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077,
0x1078, 0x1079, 0x107A, 0x107B, 0x107C, 0x107D, 0x107E, 0x107F,
/* 8 */ 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087,
0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D, 0x108E, 0x108F,
/* 9 */ 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097,
0x1098, 0x1099, 0x109A, 0x109B, 0x109C, 0x109D, 0x109E, 0x109F,
/* A */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7,
0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF,
/* B */ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7,
0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF,
/* C */ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10C6, 0x10C7,
0x10C8, 0x10C9, 0x10CA, 0x10CB, 0x10CC, 0x10CD, 0x10CE, 0x10CF,
/* D */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7,
0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF,
/* E */ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7,
0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF,
/* F */ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10F6, 0x10F7,
0x10F8, 0x10F9, 0x10FA, 0x10FB, 0x10FC, 0x10FD, 0x10FE, 0x10FF,
/* 0 */ 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
0x2008, 0x2009, 0x200A, 0x200B, 0x0000, 0x0000, 0x0000, 0x0000,
/* 1 */ 0x2010, 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 0x2017,
0x2018, 0x2019, 0x201A, 0x201B, 0x201C, 0x201D, 0x201E, 0x201F,
/* 2 */ 0x2020, 0x2021, 0x2022, 0x2023, 0x2024, 0x2025, 0x2026, 0x2027,
0x2028, 0x2029, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x202F,
/* 3 */ 0x2030, 0x2031, 0x2032, 0x2033, 0x2034, 0x2035, 0x2036, 0x2037,
0x2038, 0x2039, 0x203A, 0x203B, 0x203C, 0x203D, 0x203E, 0x203F,
/* 4 */ 0x2040, 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, 0x2047,
0x2048, 0x2049, 0x204A, 0x204B, 0x204C, 0x204D, 0x204E, 0x204F,
/* 5 */ 0x2050, 0x2051, 0x2052, 0x2053, 0x2054, 0x2055, 0x2056, 0x2057,
0x2058, 0x2059, 0x205A, 0x205B, 0x205C, 0x205D, 0x205E, 0x205F,
/* 6 */ 0x2060, 0x2061, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067,
0x2068, 0x2069, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 7 */ 0x2070, 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077,
0x2078, 0x2079, 0x207A, 0x207B, 0x207C, 0x207D, 0x207E, 0x207F,
/* 8 */ 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087,
0x2088, 0x2089, 0x208A, 0x208B, 0x208C, 0x208D, 0x208E, 0x208F,
/* 9 */ 0x2090, 0x2091, 0x2092, 0x2093, 0x2094, 0x2095, 0x2096, 0x2097,
0x2098, 0x2099, 0x209A, 0x209B, 0x209C, 0x209D, 0x209E, 0x209F,
/* A */ 0x20A0, 0x20A1, 0x20A2, 0x20A3, 0x20A4, 0x20A5, 0x20A6, 0x20A7,
0x20A8, 0x20A9, 0x20AA, 0x20AB, 0x20AC, 0x20AD, 0x20AE, 0x20AF,
/* B */ 0x20B0, 0x20B1, 0x20B2, 0x20B3, 0x20B4, 0x20B5, 0x20B6, 0x20B7,
0x20B8, 0x20B9, 0x20BA, 0x20BB, 0x20BC, 0x20BD, 0x20BE, 0x20BF,
/* C */ 0x20C0, 0x20C1, 0x20C2, 0x20C3, 0x20C4, 0x20C5, 0x20C6, 0x20C7,
0x20C8, 0x20C9, 0x20CA, 0x20CB, 0x20CC, 0x20CD, 0x20CE, 0x20CF,
/* D */ 0x20D0, 0x20D1, 0x20D2, 0x20D3, 0x20D4, 0x20D5, 0x20D6, 0x20D7,
0x20D8, 0x20D9, 0x20DA, 0x20DB, 0x20DC, 0x20DD, 0x20DE, 0x20DF,
/* E */ 0x20E0, 0x20E1, 0x20E2, 0x20E3, 0x20E4, 0x20E5, 0x20E6, 0x20E7,
0x20E8, 0x20E9, 0x20EA, 0x20EB, 0x20EC, 0x20ED, 0x20EE, 0x20EF,
/* F */ 0x20F0, 0x20F1, 0x20F2, 0x20F3, 0x20F4, 0x20F5, 0x20F6, 0x20F7,
0x20F8, 0x20F9, 0x20FA, 0x20FB, 0x20FC, 0x20FD, 0x20FE, 0x20FF,
/* 0 */ 0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105, 0x2106, 0x2107,
0x2108, 0x2109, 0x210A, 0x210B, 0x210C, 0x210D, 0x210E, 0x210F,
/* 1 */ 0x2110, 0x2111, 0x2112, 0x2113, 0x2114, 0x2115, 0x2116, 0x2117,
0x2118, 0x2119, 0x211A, 0x211B, 0x211C, 0x211D, 0x211E, 0x211F,
/* 2 */ 0x2120, 0x2121, 0x2122, 0x2123, 0x2124, 0x2125, 0x2126, 0x2127,
0x2128, 0x2129, 0x212A, 0x212B, 0x212C, 0x212D, 0x212E, 0x212F,
/* 3 */ 0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137,
0x2138, 0x2139, 0x213A, 0x213B, 0x213C, 0x213D, 0x213E, 0x213F,
/* 4 */ 0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, 0x2146, 0x2147,
0x2148, 0x2149, 0x214A, 0x214B, 0x214C, 0x214D, 0x214E, 0x214F,
/* 5 */ 0x2150, 0x2151, 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157,
0x2158, 0x2159, 0x215A, 0x215B, 0x215C, 0x215D, 0x215E, 0x215F,
/* 6 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F,
/* 7 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F,
/* 8 */ 0x2180, 0x2181, 0x2182, 0x2183, 0x2184, 0x2185, 0x2186, 0x2187,
0x2188, 0x2189, 0x218A, 0x218B, 0x218C, 0x218D, 0x218E, 0x218F,
/* 9 */ 0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x2196, 0x2197,
0x2198, 0x2199, 0x219A, 0x219B, 0x219C, 0x219D, 0x219E, 0x219F,
/* A */ 0x21A0, 0x21A1, 0x21A2, 0x21A3, 0x21A4, 0x21A5, 0x21A6, 0x21A7,
0x21A8, 0x21A9, 0x21AA, 0x21AB, 0x21AC, 0x21AD, 0x21AE, 0x21AF,
/* B */ 0x21B0, 0x21B1, 0x21B2, 0x21B3, 0x21B4, 0x21B5, 0x21B6, 0x21B7,
0x21B8, 0x21B9, 0x21BA, 0x21BB, 0x21BC, 0x21BD, 0x21BE, 0x21BF,
/* C */ 0x21C0, 0x21C1, 0x21C2, 0x21C3, 0x21C4, 0x21C5, 0x21C6, 0x21C7,
0x21C8, 0x21C9, 0x21CA, 0x21CB, 0x21CC, 0x21CD, 0x21CE, 0x21CF,
/* D */ 0x21D0, 0x21D1, 0x21D2, 0x21D3, 0x21D4, 0x21D5, 0x21D6, 0x21D7,
0x21D8, 0x21D9, 0x21DA, 0x21DB, 0x21DC, 0x21DD, 0x21DE, 0x21DF,
/* E */ 0x21E0, 0x21E1, 0x21E2, 0x21E3, 0x21E4, 0x21E5, 0x21E6, 0x21E7,
0x21E8, 0x21E9, 0x21EA, 0x21EB, 0x21EC, 0x21ED, 0x21EE, 0x21EF,
/* F */ 0x21F0, 0x21F1, 0x21F2, 0x21F3, 0x21F4, 0x21F5, 0x21F6, 0x21F7,
0x21F8, 0x21F9, 0x21FA, 0x21FB, 0x21FC, 0x21FD, 0x21FE, 0x21FF,
/* 0 */ 0xFE00, 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07,
0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, 0xFE0F,
/* 1 */ 0xFE10, 0xFE11, 0xFE12, 0xFE13, 0xFE14, 0xFE15, 0xFE16, 0xFE17,
0xFE18, 0xFE19, 0xFE1A, 0xFE1B, 0xFE1C, 0xFE1D, 0xFE1E, 0xFE1F,
/* 2 */ 0xFE20, 0xFE21, 0xFE22, 0xFE23, 0xFE24, 0xFE25, 0xFE26, 0xFE27,
0xFE28, 0xFE29, 0xFE2A, 0xFE2B, 0xFE2C, 0xFE2D, 0xFE2E, 0xFE2F,
/* 3 */ 0xFE30, 0xFE31, 0xFE32, 0xFE33, 0xFE34, 0xFE35, 0xFE36, 0xFE37,
0xFE38, 0xFE39, 0xFE3A, 0xFE3B, 0xFE3C, 0xFE3D, 0xFE3E, 0xFE3F,
/* 4 */ 0xFE40, 0xFE41, 0xFE42, 0xFE43, 0xFE44, 0xFE45, 0xFE46, 0xFE47,
0xFE48, 0xFE49, 0xFE4A, 0xFE4B, 0xFE4C, 0xFE4D, 0xFE4E, 0xFE4F,
/* 5 */ 0xFE50, 0xFE51, 0xFE52, 0xFE53, 0xFE54, 0xFE55, 0xFE56, 0xFE57,
0xFE58, 0xFE59, 0xFE5A, 0xFE5B, 0xFE5C, 0xFE5D, 0xFE5E, 0xFE5F,
/* 6 */ 0xFE60, 0xFE61, 0xFE62, 0xFE63, 0xFE64, 0xFE65, 0xFE66, 0xFE67,
0xFE68, 0xFE69, 0xFE6A, 0xFE6B, 0xFE6C, 0xFE6D, 0xFE6E, 0xFE6F,
/* 7 */ 0xFE70, 0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE75, 0xFE76, 0xFE77,
0xFE78, 0xFE79, 0xFE7A, 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F,
/* 8 */ 0xFE80, 0xFE81, 0xFE82, 0xFE83, 0xFE84, 0xFE85, 0xFE86, 0xFE87,
0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, 0xFE8D, 0xFE8E, 0xFE8F,
/* 9 */ 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95, 0xFE96, 0xFE97,
0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E, 0xFE9F,
/* A */ 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7,
0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF,
/* B */ 0xFEB0, 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7,
0xFEB8, 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF,
/* C */ 0xFEC0, 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7,
0xFEC8, 0xFEC9, 0xFECA, 0xFECB, 0xFECC, 0xFECD, 0xFECE, 0xFECF,
/* D */ 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4, 0xFED5, 0xFED6, 0xFED7,
0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD, 0xFEDE, 0xFEDF,
/* E */ 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6, 0xFEE7,
0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF,
/* F */ 0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7,
0xFEF8, 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0xFEFD, 0xFEFE, 0x0000,
/* 0 */ 0xFF00, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, 0xFF06, 0xFF07,
0xFF08, 0xFF09, 0xFF0A, 0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F,
/* 1 */ 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17,
0xFF18, 0xFF19, 0xFF1A, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0xFF1F,
/* 2 */ 0xFF20, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47,
0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
/* 3 */ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57,
0xFF58, 0xFF59, 0xFF5A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F,
/* 4 */ 0xFF40, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47,
0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
/* 5 */ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57,
0xFF58, 0xFF59, 0xFF5A, 0xFF5B, 0xFF5C, 0xFF5D, 0xFF5E, 0xFF5F,
/* 6 */ 0xFF60, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67,
0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F,
/* 7 */ 0xFF70, 0xFF71, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77,
0xFF78, 0xFF79, 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F,
/* 8 */ 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87,
0xFF88, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F,
/* 9 */ 0xFF90, 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97,
0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F,
/* A */ 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3, 0xFFA4, 0xFFA5, 0xFFA6, 0xFFA7,
0xFFA8, 0xFFA9, 0xFFAA, 0xFFAB, 0xFFAC, 0xFFAD, 0xFFAE, 0xFFAF,
/* B */ 0xFFB0, 0xFFB1, 0xFFB2, 0xFFB3, 0xFFB4, 0xFFB5, 0xFFB6, 0xFFB7,
0xFFB8, 0xFFB9, 0xFFBA, 0xFFBB, 0xFFBC, 0xFFBD, 0xFFBE, 0xFFBF,
/* C */ 0xFFC0, 0xFFC1, 0xFFC2, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6, 0xFFC7,
0xFFC8, 0xFFC9, 0xFFCA, 0xFFCB, 0xFFCC, 0xFFCD, 0xFFCE, 0xFFCF,
/* D */ 0xFFD0, 0xFFD1, 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6, 0xFFD7,
0xFFD8, 0xFFD9, 0xFFDA, 0xFFDB, 0xFFDC, 0xFFDD, 0xFFDE, 0xFFDF,
/* E */ 0xFFE0, 0xFFE1, 0xFFE2, 0xFFE3, 0xFFE4, 0xFFE5, 0xFFE6, 0xFFE7,
0xFFE8, 0xFFE9, 0xFFEA, 0xFFEB, 0xFFEC, 0xFFED, 0xFFEE, 0xFFEF,
/* F */ 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7,
0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF,
};
int32_t FastUnicodeCompare ( register uint16_t str1[], register uint16_t length1,
register uint16_t str2[], register uint16_t length2)
{
register uint16_t c1,c2;
register uint16_t temp;
register uint16_t* lowerCaseTable;
lowerCaseTable = gLowerCaseTable;
while (1) {
c1 = 0;
c2 = 0;
while (length1 && c1 == 0) {
c1 = *(str1++);
--length1;
if ((temp = lowerCaseTable[c1>>8]) != 0)
c1 = lowerCaseTable[temp + (c1 & 0x00FF)];
}
while (length2 && c2 == 0) {
c2 = *(str2++);
--length2;
if ((temp = lowerCaseTable[c2>>8]) != 0)
c2 = lowerCaseTable[temp + (c2 & 0x00FF)];
}
if (c1 == ':') {
c1 = '/';
}
if (c2 == ':') {
c2 = '/';
}
if (c1 != c2)
break;
if (c1 == 0)
return 0;
}
if (c1 < c2)
return -1;
else
return 1;
}

Просмотреть файл

@ -1,104 +1,104 @@
#include <stdlib.h>
#include "hfsplus.h"
static int flatFileRead(io_func* io, off_t location, size_t size, void *buffer) {
FILE* file;
file = (FILE*) io->data;
if(size == 0) {
return TRUE;
}
//printf("%d %d\n", location, size); fflush(stdout);
if(fseeko(file, location, SEEK_SET) != 0) {
perror("fseek");
return FALSE;
}
if(fread(buffer, size, 1, file) != 1) {
perror("fread");
return FALSE;
} else {
return TRUE;
}
}
static int flatFileWrite(io_func* io, off_t location, size_t size, void *buffer) {
FILE* file;
/*int i;
printf("write: %lld %d - ", location, size); fflush(stdout);
for(i = 0; i < size; i++) {
printf("%x ", ((unsigned char*)buffer)[i]);
fflush(stdout);
}
printf("\n"); fflush(stdout);*/
if(size == 0) {
return TRUE;
}
file = (FILE*) io->data;
if(fseeko(file, location, SEEK_SET) != 0) {
perror("fseek");
return FALSE;
}
if(fwrite(buffer, size, 1, file) != 1) {
perror("fwrite");
return FALSE;
} else {
return TRUE;
#include <stdlib.h>
#include "hfsplus.h"
static int flatFileRead(io_func* io, off_t location, size_t size, void *buffer) {
FILE* file;
file = (FILE*) io->data;
if(size == 0) {
return TRUE;
}
return TRUE;
}
static void closeFlatFile(io_func* io) {
FILE* file;
file = (FILE*) io->data;
fclose(file);
free(io);
}
io_func* openFlatFile(const char* fileName) {
io_func* io;
io = (io_func*) malloc(sizeof(io_func));
io->data = fopen(fileName, "rb+");
if(io->data == NULL) {
perror("fopen");
return NULL;
}
io->read = &flatFileRead;
io->write = &flatFileWrite;
io->close = &closeFlatFile;
return io;
}
io_func* openFlatFileRO(const char* fileName) {
io_func* io;
io = (io_func*) malloc(sizeof(io_func));
io->data = fopen(fileName, "rb");
if(io->data == NULL) {
perror("fopen");
return NULL;
}
io->read = &flatFileRead;
io->write = &flatFileWrite;
io->close = &closeFlatFile;
return io;
}
//printf("%d %d\n", location, size); fflush(stdout);
if(fseeko(file, location, SEEK_SET) != 0) {
perror("fseek");
return FALSE;
}
if(fread(buffer, size, 1, file) != 1) {
perror("fread");
return FALSE;
} else {
return TRUE;
}
}
static int flatFileWrite(io_func* io, off_t location, size_t size, void *buffer) {
FILE* file;
/*int i;
printf("write: %lld %d - ", location, size); fflush(stdout);
for(i = 0; i < size; i++) {
printf("%x ", ((unsigned char*)buffer)[i]);
fflush(stdout);
}
printf("\n"); fflush(stdout);*/
if(size == 0) {
return TRUE;
}
file = (FILE*) io->data;
if(fseeko(file, location, SEEK_SET) != 0) {
perror("fseek");
return FALSE;
}
if(fwrite(buffer, size, 1, file) != 1) {
perror("fwrite");
return FALSE;
} else {
return TRUE;
}
return TRUE;
}
static void closeFlatFile(io_func* io) {
FILE* file;
file = (FILE*) io->data;
fclose(file);
free(io);
}
io_func* openFlatFile(const char* fileName) {
io_func* io;
io = (io_func*) malloc(sizeof(io_func));
io->data = fopen(fileName, "rb+");
if(io->data == NULL) {
perror("fopen");
return NULL;
}
io->read = &flatFileRead;
io->write = &flatFileWrite;
io->close = &closeFlatFile;
return io;
}
io_func* openFlatFileRO(const char* fileName) {
io_func* io;
io = (io_func*) malloc(sizeof(io_func));
io->data = fopen(fileName, "rb");
if(io->data == NULL) {
perror("fopen");
return NULL;
}
io->read = &flatFileRead;
io->write = &flatFileWrite;
io->close = &closeFlatFile;
return io;
}

544
hfs/hfs.c
Просмотреть файл

@ -1,298 +1,298 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include "hfsplus.h"
#include <unistd.h>
#include "hfsplus.h"
#include <dirent.h>
#include "hfslib.h"
#include "abstractfile.h"
char endianness;
void cmd_ls(Volume* volume, int argc, const char *argv[]) {
HFSPlusCatalogRecord* record;
char* name;
if(argc > 1)
hfs_ls(volume, argv[1]);
else
hfs_ls(volume, "/"); }
void cmd_cat(Volume* volume, int argc, const char *argv[]) {
HFSPlusCatalogRecord* record;
#include "abstractfile.h"
char endianness;
void cmd_ls(Volume* volume, int argc, const char *argv[]) {
HFSPlusCatalogRecord* record;
char* name;
if(argc > 1)
hfs_ls(volume, argv[1]);
else
hfs_ls(volume, "/"); }
void cmd_cat(Volume* volume, int argc, const char *argv[]) {
HFSPlusCatalogRecord* record;
AbstractFile* stdoutFile;
record = getRecordFromPath(argv[1], volume, NULL, NULL);
record = getRecordFromPath(argv[1], volume, NULL, NULL);
stdoutFile = createAbstractFileFromFile(stdout);
if(record != NULL) {
if(record->recordType == kHFSPlusFileRecord)
writeToFile((HFSPlusCatalogFile*)record, stdoutFile, volume);
else
printf("Not a file\n");
} else {
printf("No such file or directory\n");
}
if(record != NULL) {
if(record->recordType == kHFSPlusFileRecord)
writeToFile((HFSPlusCatalogFile*)record, stdoutFile, volume);
else
printf("Not a file\n");
} else {
printf("No such file or directory\n");
}
free(record);
free(stdoutFile);
}
void cmd_extract(Volume* volume, int argc, const char *argv[]) {
HFSPlusCatalogRecord* record;
AbstractFile *outFile;
if(argc < 3) {
printf("Not enough arguments");
return;
}
outFile = createAbstractFileFromFile(fopen(argv[2], "wb"));
if(outFile == NULL) {
printf("cannot create file");
}
record = getRecordFromPath(argv[1], volume, NULL, NULL);
if(record != NULL) {
if(record->recordType == kHFSPlusFileRecord)
writeToFile((HFSPlusCatalogFile*)record, outFile, volume);
else
printf("Not a file\n");
} else {
printf("No such file or directory\n");
}
outFile->close(outFile);
free(record);
}
void cmd_mv(Volume* volume, int argc, const char *argv[]) {
if(argc > 2) {
move(argv[1], argv[2], volume);
} else {
printf("Not enough arguments");
}
free(stdoutFile);
}
void cmd_symlink(Volume* volume, int argc, const char *argv[]) {
if(argc > 2) {
makeSymlink(argv[1], argv[2], volume);
} else {
printf("Not enough arguments");
}
}
void cmd_mkdir(Volume* volume, int argc, const char *argv[]) {
if(argc > 1) {
newFolder(argv[1], volume);
} else {
printf("Not enough arguments");
}
}
void cmd_add(Volume* volume, int argc, const char *argv[]) {
AbstractFile *inFile;
if(argc < 3) {
printf("Not enough arguments");
return;
}
inFile = createAbstractFileFromFile(fopen(argv[1], "rb"));
if(inFile == NULL) {
printf("file to add not found");
void cmd_extract(Volume* volume, int argc, const char *argv[]) {
HFSPlusCatalogRecord* record;
AbstractFile *outFile;
if(argc < 3) {
printf("Not enough arguments");
return;
}
outFile = createAbstractFileFromFile(fopen(argv[2], "wb"));
if(outFile == NULL) {
printf("cannot create file");
}
record = getRecordFromPath(argv[1], volume, NULL, NULL);
if(record != NULL) {
if(record->recordType == kHFSPlusFileRecord)
writeToFile((HFSPlusCatalogFile*)record, outFile, volume);
else
printf("Not a file\n");
} else {
printf("No such file or directory\n");
}
outFile->close(outFile);
free(record);
}
void cmd_mv(Volume* volume, int argc, const char *argv[]) {
if(argc > 2) {
move(argv[1], argv[2], volume);
} else {
printf("Not enough arguments");
}
}
void cmd_symlink(Volume* volume, int argc, const char *argv[]) {
if(argc > 2) {
makeSymlink(argv[1], argv[2], volume);
} else {
printf("Not enough arguments");
}
}
void cmd_mkdir(Volume* volume, int argc, const char *argv[]) {
if(argc > 1) {
newFolder(argv[1], volume);
} else {
printf("Not enough arguments");
}
}
void cmd_add(Volume* volume, int argc, const char *argv[]) {
AbstractFile *inFile;
if(argc < 3) {
printf("Not enough arguments");
return;
}
inFile = createAbstractFileFromFile(fopen(argv[1], "rb"));
if(inFile == NULL) {
printf("file to add not found");
}
add_hfs(volume, inFile, argv[2]);
}
void cmd_rm(Volume* volume, int argc, const char *argv[]) {
if(argc > 1) {
removeFile(argv[1], volume);
} else {
printf("Not enough arguments");
}
}
void cmd_chmod(Volume* volume, int argc, const char *argv[]) {
int mode;
if(argc > 2) {
sscanf(argv[1], "%o", &mode);
chmodFile(argv[2], mode, volume);
} else {
printf("Not enough arguments");
}
}
void cmd_extractall(Volume* volume, int argc, const char *argv[]) {
HFSPlusCatalogRecord* record;
char cwd[1024];
char* name;
ASSERT(getcwd(cwd, 1024) != NULL, "cannot get current working directory");
if(argc > 1)
record = getRecordFromPath(argv[1], volume, &name, NULL);
else
record = getRecordFromPath("/", volume, &name, NULL);
if(argc > 2) {
ASSERT(chdir(argv[2]) == 0, "chdir");
}
if(record != NULL) {
if(record->recordType == kHFSPlusFolderRecord)
extractAllInFolder(((HFSPlusCatalogFolder*)record)->folderID, volume);
else
printf("Not a folder\n");
} else {
printf("No such file or directory\n");
}
free(record);
ASSERT(chdir(cwd) == 0, "chdir");
}
void cmd_rmall(Volume* volume, int argc, const char *argv[]) {
HFSPlusCatalogRecord* record;
char* name;
char initPath[1024];
int lastCharOfPath;
if(argc > 1) {
record = getRecordFromPath(argv[1], volume, &name, NULL);
strcpy(initPath, argv[1]);
lastCharOfPath = strlen(argv[1]) - 1;
if(argv[1][lastCharOfPath] != '/') {
initPath[lastCharOfPath + 1] = '/';
initPath[lastCharOfPath + 2] = '\0';
}
} else {
record = getRecordFromPath("/", volume, &name, NULL);
initPath[0] = '/';
initPath[1] = '\0';
}
if(record != NULL) {
if(record->recordType == kHFSPlusFolderRecord) {
removeAllInFolder(((HFSPlusCatalogFolder*)record)->folderID, volume, initPath);
} else {
printf("Not a folder\n");
}
} else {
printf("No such file or directory\n");
}
free(record);
}
void cmd_addall(Volume* volume, int argc, const char *argv[]) {
if(argc < 2) {
printf("Not enough arguments");
return;
add_hfs(volume, inFile, argv[2]);
}
void cmd_rm(Volume* volume, int argc, const char *argv[]) {
if(argc > 1) {
removeFile(argv[1], volume);
} else {
printf("Not enough arguments");
}
}
void cmd_chmod(Volume* volume, int argc, const char *argv[]) {
int mode;
if(argc > 2) {
sscanf(argv[1], "%o", &mode);
chmodFile(argv[2], mode, volume);
} else {
printf("Not enough arguments");
}
}
void cmd_extractall(Volume* volume, int argc, const char *argv[]) {
HFSPlusCatalogRecord* record;
char cwd[1024];
char* name;
ASSERT(getcwd(cwd, 1024) != NULL, "cannot get current working directory");
if(argc > 1)
record = getRecordFromPath(argv[1], volume, &name, NULL);
else
record = getRecordFromPath("/", volume, &name, NULL);
if(argc > 2) {
ASSERT(chdir(argv[2]) == 0, "chdir");
}
if(argc > 2) {
addall_hfs(volume, argv[1], argv[2]);
} else {
addall_hfs(volume, argv[1], "/");
}
}
void cmd_grow(Volume* volume, int argc, const char *argv[]) {
uint64_t newSize;
if(argc < 2) {
printf("Not enough arguments\n");
return;
}
newSize = 0;
if(record != NULL) {
if(record->recordType == kHFSPlusFolderRecord)
extractAllInFolder(((HFSPlusCatalogFolder*)record)->folderID, volume);
else
printf("Not a folder\n");
} else {
printf("No such file or directory\n");
}
free(record);
ASSERT(chdir(cwd) == 0, "chdir");
}
void cmd_rmall(Volume* volume, int argc, const char *argv[]) {
HFSPlusCatalogRecord* record;
char* name;
char initPath[1024];
int lastCharOfPath;
if(argc > 1) {
record = getRecordFromPath(argv[1], volume, &name, NULL);
strcpy(initPath, argv[1]);
lastCharOfPath = strlen(argv[1]) - 1;
if(argv[1][lastCharOfPath] != '/') {
initPath[lastCharOfPath + 1] = '/';
initPath[lastCharOfPath + 2] = '\0';
}
} else {
record = getRecordFromPath("/", volume, &name, NULL);
initPath[0] = '/';
initPath[1] = '\0';
}
if(record != NULL) {
if(record->recordType == kHFSPlusFolderRecord) {
removeAllInFolder(((HFSPlusCatalogFolder*)record)->folderID, volume, initPath);
} else {
printf("Not a folder\n");
}
} else {
printf("No such file or directory\n");
}
free(record);
}
void cmd_addall(Volume* volume, int argc, const char *argv[]) {
if(argc < 2) {
printf("Not enough arguments");
return;
}
if(argc > 2) {
addall_hfs(volume, argv[1], argv[2]);
} else {
addall_hfs(volume, argv[1], "/");
}
}
void cmd_grow(Volume* volume, int argc, const char *argv[]) {
uint64_t newSize;
if(argc < 2) {
printf("Not enough arguments\n");
return;
}
newSize = 0;
sscanf(argv[1], "%lld", &newSize);
grow_hfs(volume, newSize);
printf("grew volume: %lld\n", newSize);
printf("grew volume: %lld\n", newSize);
}
void TestByteOrder()
{
short int word = 0x0001;
char *byte = (char *) &word;
endianness = byte[0] ? IS_LITTLE_ENDIAN : IS_BIG_ENDIAN;
}
int main(int argc, const char *argv[]) {
io_func* io;
Volume* volume;
TestByteOrder();
if(argc < 3) {
printf("usage: %s <image-file> <ls|cat|mv|mkdir|add|rm|chmod|extract|extractall|rmall|addall|debug> <arguments>\n", argv[0]);
return 0;
}
io = openFlatFile(argv[1]);
if(io == NULL) {
fprintf(stderr, "error: Cannot open image-file.\n");
return 1;
}
volume = openVolume(io);
if(volume == NULL) {
fprintf(stderr, "error: Cannot open volume.\n");
CLOSE(io);
return 1;
}
if(argc > 1) {
if(strcmp(argv[2], "ls") == 0) {
cmd_ls(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "cat") == 0) {
cmd_cat(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "mv") == 0) {
cmd_mv(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "symlink") == 0) {
cmd_symlink(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "mkdir") == 0) {
cmd_mkdir(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "add") == 0) {
cmd_add(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "rm") == 0) {
cmd_rm(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "chmod") == 0) {
cmd_chmod(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "extract") == 0) {
cmd_extract(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "extractall") == 0) {
cmd_extractall(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "rmall") == 0) {
cmd_rmall(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "addall") == 0) {
cmd_addall(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "grow") == 0) {
cmd_grow(volume, argc - 2, argv + 2);
void TestByteOrder()
{
short int word = 0x0001;
char *byte = (char *) &word;
endianness = byte[0] ? IS_LITTLE_ENDIAN : IS_BIG_ENDIAN;
}
int main(int argc, const char *argv[]) {
io_func* io;
Volume* volume;
TestByteOrder();
if(argc < 3) {
printf("usage: %s <image-file> <ls|cat|mv|mkdir|add|rm|chmod|extract|extractall|rmall|addall|debug> <arguments>\n", argv[0]);
return 0;
}
io = openFlatFile(argv[1]);
if(io == NULL) {
fprintf(stderr, "error: Cannot open image-file.\n");
return 1;
}
volume = openVolume(io);
if(volume == NULL) {
fprintf(stderr, "error: Cannot open volume.\n");
CLOSE(io);
return 1;
}
if(argc > 1) {
if(strcmp(argv[2], "ls") == 0) {
cmd_ls(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "cat") == 0) {
cmd_cat(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "mv") == 0) {
cmd_mv(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "symlink") == 0) {
cmd_symlink(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "mkdir") == 0) {
cmd_mkdir(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "add") == 0) {
cmd_add(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "rm") == 0) {
cmd_rm(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "chmod") == 0) {
cmd_chmod(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "extract") == 0) {
cmd_extract(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "extractall") == 0) {
cmd_extractall(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "rmall") == 0) {
cmd_rmall(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "addall") == 0) {
cmd_addall(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "grow") == 0) {
cmd_grow(volume, argc - 2, argv + 2);
} else if(strcmp(argv[2], "debug") == 0) {
if(argc > 3 && argv[3] == "verbose") {
debugBTree(volume->catalogTree, TRUE);
} else {
debugBTree(volume->catalogTree, FALSE);
}
}
}
closeVolume(volume);
CLOSE(io);
return 0;
}
}
}
closeVolume(volume);
CLOSE(io);
return 0;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу