Я рад слышать, что вы делаете это на C++. Похоже, что никто больше не видит C++ как «необходимого». Это все C# это, и ASP.NET, что ... Даже я работаю во всем доме C#, когда я поклялся, что бы никогда не выключал, поскольку C++ делает все, что мне когда-либо понадобится, а затем и некоторые. Я достаточно взрослый, чтобы очистить свою память! хех .. В любом случае, вернемся к проблеме ...
DefineDOSDevice()
- это метод, который используется для назначения букв дисков, имен портов (LPT1, COM1 и т. Д.). Вы передаете ему имя, некоторые флаги и «путь», который обрабатывает это устройство. Но не позволяйте этому обмануть вас. Это не путь к файловой системе, это путь объекта NT. Я уверен, что вы видели их как «\ Device \ HardDisk0» и т. Д. Вы можете использовать WinObj.exe из sysinternals, чтобы понять, что я имею в виду. В любом случае вы можете создать драйвер устройства, а затем указать на него ссылку на MSDOS, и вы выключены и запущены. Но предоставлено это, похоже, большая работа для оригинальной проблемы.
Сколько из этих мега-гигабайтных файлов находится в типичном каталоге? Вам может быть лучше всего вклеить все файлы внутри одного гигантского файла и сохранить рядом с ним индексный файл (или заголовок для каждого файла), который указывает на следующий «файл» в вашем файле «virtual FileSystem».
Хорошим примером может быть просмотр формата Microsoft MSN Archive. Я отменил этот формат архива, когда я работал в AV-компании, и на самом деле он довольно креативен, но ОЧЕНЬ прост. Это может быть сделано в одном файле, и если вы хотите получить фантазию, вы должны сохранить данные по 3 файлам в конфигурации типа RAID 5, поэтому, если какой-либо из 3-х файлов будет запущен, вы можете перестроить остальные , Кроме того, пользователи просто видят 3 ОЧЕНЬ больших файлов в каталоге и не смогут получить доступ к отдельным (внутренним) файлам.
Я предоставил вам код, который распаковывает один из этих форматов MSN Archive. У меня нет кода, который CREATES один, но из источника извлечения, вы могли бы построить/написать один без проблем. Если файлы удаляются и/или часто переименовываются, это может создать проблему с использованным пространством в файле, которое время от времени нужно будет обрезать.
Этот формат даже поддерживает поля CRC, поэтому вы можете проверить, есть ли у вас файл в порядке. Я никогда не мог полностью отменить алгоритм, используемый Microsoft для CRC-данных, но у меня есть довольно хорошая идея.
Вы не сможете поддерживать текущие процедуры ввода-вывода, то есть CreateFile() не сможет просто открыть любой файл в архиве, однако с uber-coolness на C++ вы можете переопределить CreateFile для реализации формата архива.
Если вам нужна помощь, и это довольно серьезная проблема, возможно, мы могли бы поговорить в автономном режиме и найти решение для вас.
Я не против писать вам FileSystemDriver, но для этого нам придется начать говорить о компенсации. Я был бы более чем счастлив дать вам направление и идеи бесплатно, как и сейчас.
Я не уверен, что для меня здесь кошерный адрес, чтобы сообщить вам свой адрес электронной почты, я не уверен в политике SO, поскольку мы можем говорить о потенциальной работе/приглашении, но это не моя единственная намерение. Я бы скорее помог вам найти ваши собственные решения.
Перед тем, как заглянуть в драйвер устройства, загрузите WinDDK. На нем есть образцы драйверов.
Если вы задаетесь вопросом, почему я так сильно об этом беспокоюсь, это связано с тем, что в течение многих лет мне приходилось писать драйвер, похожий на этот, который должен был быть Windows И OSX совместим, что позволит пользователям для защиты томов накопителей (USB-ключей, съемных томов) БЕЗ установки каких-либо драйверов или сложного (и громоздкого, иногда раздражающего) программного обеспечения. В последние годы многие производители оборудования сделали аналогичные вещи, но я не думаю, что безопасность - все это безопасно. Я смотрю на использование RSA и AES, точно так же, как GPG и PGP.Первоначально меня связали об этом, для чего (я считаю, но не имею никаких доказательств) собирались использовать для защиты файлов MP3. Поскольку они будут храниться в зашифрованном формате, они просто не будут работать без правильной кодовой фразы. Но я видел и другие варианты использования. (Это было обратно, когда 16 Мб (да MEG) USB-ключ стоил более 100 долларов или около того).
Этот проект также сочетался с моей системой безопасности ПК в нефтяной и газовой промышленности, которая использовала нечто похожее на смарт-карты, гораздо проще в использовании, повторное использование/повторное выдачу, невозможное (читай: ОЧЕНЬ сложно и маловероятно) взломать, и я мог бы использовать его у своих детей дома! (Поскольку всегда есть борьба за то, кто получает время на компьютере, и кто получил больше всего, и дальше, и дальше, и дальше, и ...)
Phew .. Думаю, я ушел от темы здесь. В любом случае, вот пример формата архива Microsoft MSN. Посмотрите, можете ли вы использовать что-то вроде этого, зная, что вы всегда можете «пропустить» право на файл, выполнив смещения в файле при анализе/поиске запрошенного файла в главном файле; или в предварительно проанализированных данных, хранящихся в памяти. И так как вы не загружаете необработанные двоичные данные файла в памяти, ваш единственный предел, вероятно, будет ограничением файла 4gb на 32-битных машинах.
Формат MARC (Microsoft MSN Archive) выложена (свободно), как это:
- 12 байт заголовка (только один)
- Файл Волшебства
- МАРК версия
- Номер файлов (в следующей таблице)
- 68 Байт файла Таблица заголовков (от 1 до Hea der.NumFiles из них)
- Имя файла
- Размер файла
- Контрольная сумма
- смещение к Необработанные данные файла
Теперь, в 12 байт записей таблицы файлов, 32 биты используются для длины файла и смещения. Для ваших ОЧЕНЬ больших файлов вам может потребоваться до 48 или 64 бит целых чисел.
Вот код, который я написал, чтобы справиться с этим.
#define MARC_FILE_MAGIC 0x4352414D // In Little Endian
#define MARC_FILENAME_LEN 56 //(You'll notice this is rather small)
#define MARC_HEADER_SIZE 12
#define MARC_FILE_ENT_SIZE 68
#define MARC_DATA_SIZE 1024 * 128 // 128k Read Buffer should be enough.
#define MARC_ERR_OK 0 // No error
#define MARC_ERR_OOD 314 // Out of data error
#define MARC_ERR_OS 315 // Error returned by the OS
#define MARC_ERR_CRC 316 // CRC error
struct marc_file_hdr
{
ULONG h_magic;
ULONG h_version;
ULONG h_files;
int h_fd;
struct marc_dir *h_dir;
};
struct marc_file
{
char f_filename[MARC_FILENAME_LEN];
long f_filesize;
unsigned long f_checksum;
long f_offset;
};
struct marc_dir
{
struct marc_file *dir_file;
ULONG dir_filenum;
struct marc_dir *dir_next;
};
Это дает вам представление о заголовках, которые я написал для них, и вот открытая функция. Да, у него отсутствуют все вызовы поддержки, процедуры err и т. Д., Но вы получаете эту идею. Извините, пожалуйста, код стиля кода C и C++. Наш сканер представлял собой множество различных проблем, таких как ... Я использовал античные звонки, такие как open(), fopen(), чтобы поддерживать стандарты с остальной базой кода.
struct marc_file_hdr *marc_open(char *filename)
{
struct marc_file_hdr *fhdr = (struct marc_file_hdr*)malloc(sizeof(marc_file_hdr));
fhdr->h_dir = NULL;
#if defined(_sopen_s)
int errno = _sopen_s(fhdr->h_fd, filename, _O_BINARY | _O_RDONLY, _SH_DENYWR, _S_IREAD | _S_IWRITE);
#else
fhdr->h_fd = open(filename, _O_BINARY | _O_RDONLY);
#endif
if(fhdr->h_fd < 0)
{
marc_close(fhdr);
return NULL;
}
//Once we have the file open, read all the file headers, and populate our main headers linked list.
if(read(fhdr->h_fd, fhdr, MARC_HEADER_SIZE) != MARC_HEADER_SIZE)
{
errmsg("MARC: Could not read MARC header from file %s.\n", filename);
marc_close(fhdr);
return NULL;
}
// Verify the file magic
if(fhdr->h_magic != MARC_FILE_MAGIC)
{
errmsg("MARC: Incorrect file magic %x found in MARC file.", fhdr->h_magic);
marc_close(fhdr);
return NULL;
}
if(fhdr->h_files <= 0)
{
errmsg("MARC: No files found in archive.\n");
marc_close(fhdr);
return NULL;
}
// Get all the file headers from this archive, and link them to the main header.
struct marc_dir *lastdir = NULL, *curdir = NULL;
curdir = (struct marc_dir*)malloc(sizeof(marc_dir));
fhdr->h_dir = curdir;
for(int x = 0;x < fhdr->h_files;x++)
{
if(lastdir)
{
lastdir->dir_next = (struct marc_dir*)malloc(sizeof(marc_dir));
lastdir->dir_next->dir_next = NULL;
curdir = lastdir->dir_next;
}
curdir->dir_file = (struct marc_file*)malloc(sizeof(marc_file));
curdir->dir_filenum = x + 1;
if(read(fhdr->h_fd, curdir->dir_file, MARC_FILE_ENT_SIZE) != MARC_FILE_ENT_SIZE)
{
errmsg("MARC: Could not read file header for file %d\n", x);
marc_close(fhdr);
return NULL;
}
// LEF: Just a little extra insurance...
curdir->dir_file->f_filename[MARC_FILENAME_LEN] = NULL;
lastdir = curdir;
}
lastdir->dir_next = NULL;
return fhdr;
}
Затем у вас есть простой способ экстракции. Имейте в виду, что это было строго для сканирования вирусов, поэтому нет поисковых подпрограмм и т. Д. Это было предназначено, чтобы просто выгрузить файл, отсканировать его и продолжить. Ниже приведена программа CRC-кода, которую я ВЕРЮ, чтобы использовать Microsoft, но я не уверен WHAT именно они CRC'ed. Он может включать данные заголовка + данные файла и т. Д. Я просто не заботился о том, чтобы вернуться и попытаться отменить его. В любом случае, как вы можете видеть, в этом архиве нет сжатия, но это ОЧЕНЬ легко добавить.Если вы хотите, можно предоставить полный источник. (Я думаю, что все, что осталось, это близко() рутина, и код, который вызывает и извлекает каждый файл, и т.д. !!)
bool marc_extract(struct marc_file_hdr *marc, struct marc_file *marcfile, char *file, int &err)
{
// Create the file from marcfile, in *file's location, return any errors.
int ofd = 0;
#if defined(_sopen_s)
err = _sopen_s(ofd, filename, _O_CREAT | _O_SHORT_LIVED | _O_BINARY | _O_RDWR, _SH_DENYNO, _S_IREAD | _S_IWRITE);
#else
ofd = open(file, _O_CREAT | _O_SHORT_LIVED | _O_BINARY | _O_RDWR);
#endif
// Seek to the offset of the file to extract
if(lseek(marc->h_fd, marcfile->f_offset, SEEK_SET) != marcfile->f_offset)
{
errmsg("MARC: Could not seek to offset 0x%04x for file %s.\n", marcfile->f_offset, marcfile->f_filename);
close(ofd);
err = MARC_ERR_OS; // Get the last error from the OS.
return false;
}
unsigned char *buffer = (unsigned char*)malloc(MARC_DATA_SIZE);
long bytesleft = marcfile->f_filesize;
long readsize = MARC_DATA_SIZE >= marcfile->f_filesize ? marcfile->f_filesize : MARC_DATA_SIZE;
unsigned long crc = 0;
while(bytesleft)
{
if(read(marc->h_fd, buffer, readsize) != readsize)
{
errmsg("MARC: Failed to extract data from MARC archive.\n");
free(buffer);
close(ofd);
err = MARC_ERR_OOD;
return false;
}
crc = marc_checksum(buffer, readsize, crc);
if(write(ofd, buffer, readsize) != readsize)
{
errmsg("MARC: Failed to write data to file.\n");
free(buffer);
close(ofd);
err = MARC_ERR_OS; // Get the last error from the OS.
return false;
}
bytesleft -= readsize;
readsize = MARC_DATA_SIZE >= bytesleft ? bytesleft : MARC_DATA_SIZE;
}
// LEF: I can't quite figure out how the checksum is computed, but I think it has to do with the file header, PLUS the data in the file, or it's checked on the data in the file
// minus any BOM's at the start... So, we'll just rem out this code for now, but I wrote it anyways.
//if(crc != marcfile->f_checksum)
//{
// warningmsg("MARC: File CRC does not match. File could be corrupt, or altered. CRC=0x%08X, expected 0x%08X\n", crc, marcfile->f_checksum);
// err = MARC_ERR_CRC;
//}
free(buffer);
close(ofd);
return true;
}
Здесь MY предполагается процедура CRC (я, возможно, украл из Стюарта Caie и libmspack, я не могу вспомнить):
static unsigned long marc_checksum(void *pv, UINT cb, unsigned long seed)
{
int count = cb/4;
unsigned long csum = seed;
BYTE *p = (BYTE*)pv;
unsigned long ul;
while(count-- > 0)
{
ul = *p++;
ul |= (((unsigned long)(*p++)) << 8);
ul |= (((unsigned long)(*p++)) << 16);
ul |= (((unsigned long)(*p++)) << 24);
csum ^= ul;
}
ul = 0;
switch(cb % 4)
{
case 3: ul |= (((unsigned long)(*p++)) << 16);
case 2: ul |= (((unsigned long)(*p++)) << 8);
case 1: ul |= *p++;
default: break;
}
csum ^= ul;
return csum;
}
Ну, я думаю, что сейчас этот пост достаточно долго ... Свяжитесь со мной, если вам нужна помощь или есть вопросы.
Можете ли вы пролить свет на какой язык/среду вы находитесь? – Tomalak 2008-12-12 19:31:15
Конечно, обновленный ответ – 2008-12-13 14:55:56