MSDN.WhiteKnight - Stack Overflow answers
Ответ на "QT C++ Создание ISO-образа"
Answer 1054632
Я думаю, примеров нету, потому что задача создания образа ISO фактически сводится к задаче побайтового копирования данных с устройства в файл. Подробнее это обсуждалось здесь: Склонировать диск (в т.ч системный) в ISO
IMAPI тут не нужен, достаточно обычных файловых API. Основная сложность состоит в том, чтобы реализовать чтение с устройства в конкретной ОС.
Реализация под Windows:
#include <stdio.h> #include <stdlib.h> #include <stdint.h> const unsigned int SECTOR_SIZE = 2048; //размер сектора для CD #ifdef _WIN32 #include <Windows.h> void GetDiskMetrics(const char* disk, unsigned int* pBlockSize, uint64_t* pTotalSize){ char path[MAX_PATH]=""; strcpy(path,disk); strcat(path,":\\"); unsigned long dwSectorsPerCluster, dwBytesPerSector, dwNumberOfFreeClusters, dwTotalNumberOfClusters; unsigned int blocksize; uint64_t totalsize; //найдем размер сектора и объем данных на диске int res = GetDiskFreeSpaceA(path, &dwSectorsPerCluster, &dwBytesPerSector, &dwNumberOfFreeClusters, &dwTotalNumberOfClusters); //вычислим размер блока, кратный размеру сектора, и общий объем данных в байтах if (res){ blocksize = dwBytesPerSector * 20; totalsize = dwSectorsPerCluster * dwBytesPerSector * (uint64_t)dwTotalNumberOfClusters; } else{ printf("GetDiskFreeSpace error %d", GetLastError()); blocksize = SECTOR_SIZE * 20; totalsize = 4700307456; //DVD } *pBlockSize = blocksize; *pTotalSize = totalsize; } bool OpenDevice(const char* disk, void** phFile){ char path[MAX_PATH]=""; sprintf(path,"\\\\.\\%s:",disk); //формат имени файла для открытия тома //открываем том для прямого доступа на чтение HANDLE handle = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (handle == INVALID_HANDLE_VALUE) { fprintf(stderr,"CreateFileA error %d", GetLastError()); return false; } else { *phFile = handle; return true; } } bool ReadDevice(void* hFile, void* lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead){ BOOL res = ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, NULL); if (res == FALSE){ fprintf(stderr,"ReadFile error %d", GetLastError()); return false; } else return true; } void CloseDevice(void* hFile){ CloseHandle(hFile); } #endif void CreateISO(const char* disk, const char* outfile){ char* buf; unsigned long dwRead = 0; uint64_t count = 0; unsigned int blocksize; uint64_t totalsize; GetDiskMetrics(disk,&blocksize,&totalsize); buf = (char*)malloc(blocksize); //открываем том для прямого доступа на чтение void* handle=NULL; bool res = OpenDevice(disk,&handle); if (res == false) goto End; //открываем файл для записи FILE* target = fopen(outfile,"wb"); while (true){ dwRead = 0; memset(buf,0,blocksize); //считаем блок данных res = ReadDevice(handle,buf, blocksize, &dwRead); if (res == false) goto End; if (dwRead == 0) break; //конец считывания count += dwRead; printf(" Creating image: %5.1f%% [%10.2f KB / %10.2f KB]\r", (count * 100.0f / totalsize), (count / 1024.0f), (totalsize / 1024.0f)); //запишем блок в файл fwrite(buf,dwRead,1,target); } End: CloseDevice(handle); fclose(target); free(buf); printf("\n"); } int main(int argc, char **argv) { CreateISO("K", "c:\\distr\\image.iso"); getchar(); return 0; }
Чтобы заставить это работать под другими ОС, вам нужно будет реализовать функции, расположенные в блоке
#ifdef _WIN32
.
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.