478 lines
18 KiB
C
478 lines
18 KiB
C
#include <Windows.h>
|
|
#include <stdio.h>
|
|
|
|
#include "../dll/hooks/drive/drive.h"
|
|
|
|
#define SECTOR_SIZE BLOCK_SIZE_HDD
|
|
|
|
#define HEADS_PER_CYLINDER 255
|
|
#define SECTORS_PER_TRACK 63
|
|
|
|
#define TRUECRYPT "\"C:\\Program Files (x86)\\TrueCrypt\\TrueCrypt.exe\""
|
|
#define OSR_PASSWORD "nogamenolife"
|
|
#define OSR_MOUNTPOINT "R:"
|
|
#define OSR_FLAGS "/w /q /m ro"
|
|
|
|
BYTE WINDOWS_MBR_BOOTSTRAP[MBR_BOOTSTRAP_SIZE] = {
|
|
0x33, 0xc0, 0x8e, 0xd0, 0xbc, 0x00, 0x7c, 0xfb, 0x50, 0x07, 0x50, 0x1f, 0xfc, 0xbe, 0x1b, 0x7c,
|
|
0xbf, 0x1b, 0x06, 0x50, 0x57, 0xb9, 0xe5, 0x01, 0xf3, 0xa4, 0xcb, 0xbd, 0xbe, 0x07, 0xb1, 0x04,
|
|
0x38, 0x6e, 0x00, 0x7c, 0x09, 0x75, 0x13, 0x83, 0xc5, 0x10, 0xe2, 0xf4, 0xcd, 0x18, 0x8b, 0xf5,
|
|
0x83, 0xc6, 0x10, 0x49, 0x74, 0x19, 0x38, 0x2c, 0x74, 0xf6, 0xa0, 0xb5, 0x07, 0xb4, 0x07, 0x8b,
|
|
0xf0, 0xac, 0x3c, 0x00, 0x74, 0xfc, 0xbb, 0x07, 0x00, 0xb4, 0x0e, 0xcd, 0x10, 0xeb, 0xf2, 0x88,
|
|
0x4e, 0x10, 0xe8, 0x46, 0x00, 0x73, 0x2a, 0xfe, 0x46, 0x10, 0x80, 0x7e, 0x04, 0x0b, 0x74, 0x0b,
|
|
0x80, 0x7e, 0x04, 0x0c, 0x74, 0x05, 0xa0, 0xb6, 0x07, 0x75, 0xd2, 0x80, 0x46, 0x02, 0x06, 0x83,
|
|
0x46, 0x08, 0x06, 0x83, 0x56, 0x0a, 0x00, 0xe8, 0x21, 0x00, 0x73, 0x05, 0xa0, 0xb6, 0x07, 0xeb,
|
|
0xbc, 0x81, 0x3e, 0xfe, 0x7d, 0x55, 0xaa, 0x74, 0x0b, 0x80, 0x7e, 0x10, 0x00, 0x74, 0xc8, 0xa0,
|
|
0xb7, 0x07, 0xeb, 0xa9, 0x8b, 0xfc, 0x1e, 0x57, 0x8b, 0xf5, 0xcb, 0xbf, 0x05, 0x00, 0x8a, 0x56,
|
|
0x00, 0xb4, 0x08, 0xcd, 0x13, 0x72, 0x23, 0x8a, 0xc1, 0x24, 0x3f, 0x98, 0x8a, 0xde, 0x8a, 0xfc,
|
|
0x43, 0xf7, 0xe3, 0x8b, 0xd1, 0x86, 0xd6, 0xb1, 0x06, 0xd2, 0xee, 0x42, 0xf7, 0xe2, 0x39, 0x56,
|
|
0x0a, 0x77, 0x23, 0x72, 0x05, 0x39, 0x46, 0x08, 0x73, 0x1c, 0xb8, 0x01, 0x02, 0xbb, 0x00, 0x7c,
|
|
0x8b, 0x4e, 0x02, 0x8b, 0x56, 0x00, 0xcd, 0x13, 0x73, 0x51, 0x4f, 0x74, 0x4e, 0x32, 0xe4, 0x8a,
|
|
0x56, 0x00, 0xcd, 0x13, 0xeb, 0xe4, 0x8a, 0x56, 0x00, 0x60, 0xbb, 0xaa, 0x55, 0xb4, 0x41, 0xcd,
|
|
0x13, 0x72, 0x36, 0x81, 0xfb, 0x55, 0xaa, 0x75, 0x30, 0xf6, 0xc1, 0x01, 0x74, 0x2b, 0x61, 0x60,
|
|
0x6a, 0x00, 0x6a, 0x00, 0xff, 0x76, 0x0a, 0xff, 0x76, 0x08, 0x6a, 0x00, 0x68, 0x00, 0x7c, 0x6a,
|
|
0x01, 0x6a, 0x10, 0xb4, 0x42, 0x8b, 0xf4, 0xcd, 0x13, 0x61, 0x61, 0x73, 0x0e, 0x4f, 0x74, 0x0b,
|
|
0x32, 0xe4, 0x8a, 0x56, 0x00, 0xcd, 0x13, 0xeb, 0xd6, 0x61, 0xf9, 0xc3, 0x49, 0x6e, 0x76, 0x61,
|
|
0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x61,
|
|
0x62, 0x6c, 0x65, 0x00, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e,
|
|
0x67, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74,
|
|
0x65, 0x6d, 0x00, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61,
|
|
0x74, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x44, 0x63, 0x46, 0xa4, 0x2b, 0xd1, 0x00, 0x00,
|
|
};
|
|
|
|
// Assumes a SECTOR_SIZE of 512
|
|
#define _KiB(x) (DWORD)(x * 2)
|
|
#define _MiB(x) (DWORD)(x * 1024 * 2)
|
|
#define _GiB(x) (DWORD)(x * 1024 * 1024 * 2)
|
|
#define _GMKiB(g, m, k) (_GiB(g) + _MiB(m) + _KiB(k))
|
|
|
|
physical_disk_t newSSD = {
|
|
.m_SerialNumber = 0x00144DB0,
|
|
|
|
.m_BusType = BusTypeAta,
|
|
.m_BootPartition = 1,
|
|
.m_HasSegaboot = TRUE,
|
|
.m_BlockSize = BLOCK_SIZE_HDD,
|
|
.m_TotalSize = 0, // Force re-calculation
|
|
.m_DiskType = DiskType_HardDisk,
|
|
.m_IsFormatted = true,
|
|
// .m_Partitions = {
|
|
// // 1.5GB boot partition
|
|
// { .m_Size = _GMKiB(1, 513, 450.5), .m_Filesystem = MBR_FS_NTFS },
|
|
// // 1.5GB OS recovery
|
|
// { .m_Size = _GMKiB(1, 513, 482), .m_Filesystem = MBR_FS_NTFS },
|
|
// },
|
|
// .m_Extended = {
|
|
// { _GMKiB(0, 517, 705.5), MBR_FS_FAT16, SPD_OS }, // 512MB OS update
|
|
// { _GMKiB(0, 2055, 163.5), MBR_FS_FAT16, SPD_Patch0 }, // 2GB patch0
|
|
// { _GMKiB(0, 2055, 163.5), MBR_FS_FAT16, SPD_Patch1 }, // 2GB patch1
|
|
// { _GMKiB(36, 474, 556.5), MBR_FS_NTFS, SPD_AppData }, // 40GB appdata
|
|
// { _GMKiB(16, 2, 597), MBR_FS_FAT16, SPD_Original0 }, // 16GB original0
|
|
// { 0 }, // End of table
|
|
// },
|
|
.m_Partitions = {
|
|
{ .m_Size = 40960, .m_Filesystem = MBR_FS_NTFS },
|
|
},
|
|
.m_Extended = { 0 },
|
|
};
|
|
|
|
sbr_t SegaBootRecord0 = { 0 };
|
|
sbr_t SegaBootRecord1 = { 0 };
|
|
sbr_slot_t* get_sbr_slot(spd_slot_t slot) {
|
|
switch (slot) {
|
|
case SPD_Original0:
|
|
return &SegaBootRecord0.slot_original0;
|
|
case SPD_Original1:
|
|
return NULL;
|
|
case SPD_Patch0:
|
|
return &SegaBootRecord0.slot_patch0;
|
|
case SPD_Patch1:
|
|
return &SegaBootRecord0.slot_patch1;
|
|
case SPD_OS:
|
|
return &SegaBootRecord0.slot_os;
|
|
case SPD_AppData:
|
|
return &SegaBootRecord0.slot_appdata;
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
void init_pd(physical_disk_t* pConfig) {
|
|
// Apply default block sizes
|
|
if (!pConfig->m_BlockSize) {
|
|
switch (pConfig->m_DiskType) {
|
|
case DiskType_HardDisk:
|
|
pConfig->m_BlockSize = BLOCK_SIZE_HDD;
|
|
break;
|
|
case DiskType_Flash:
|
|
pConfig->m_BlockSize = BLOCK_SIZE_FLASH;
|
|
break;
|
|
case DiskType_CdRom:
|
|
pConfig->m_BlockSize = BLOCK_SIZE_CDROM;
|
|
break;
|
|
default:
|
|
printf("Unable to guess block size for drive %d", pConfig->m_DriveNumber);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Non-SCSI devices don't have a SCSI type to report
|
|
if (pConfig->m_BusType != BusTypeScsi) pConfig->m_DeviceType = DeviceTypeUnknown;
|
|
|
|
// If we need to initialise the partition tables, do so
|
|
if (pConfig->m_IsFormatted) {
|
|
DWORD partitionNumber = 1;
|
|
DWORD currentLBA = MBR_LBA_GAP;
|
|
|
|
// Init MBR
|
|
for (int i = 0; i < 4; i++) {
|
|
if (pConfig->m_Partitions[i].m_Size == 0) break;
|
|
|
|
pConfig->m_Partitions[i].m_PartitionNumber = partitionNumber++;
|
|
pConfig->m_Partitions[i].m_PhysicalLBA = currentLBA;
|
|
|
|
pConfig->m_Partitions[i].m_Volume.m_pDrive = pConfig;
|
|
pConfig->m_Partitions[i].m_Volume.m_pPartition = &(pConfig->m_Partitions[i]);
|
|
|
|
currentLBA += pConfig->m_Partitions[i].m_Size;
|
|
}
|
|
|
|
// If we have any extended partitions
|
|
DWORD extendedPartNo = 0;
|
|
if (pConfig->m_Extended[0].m_Size) {
|
|
if (partitionNumber == 5) {
|
|
printf("Fatal: Too many paritions in drive %d!", pConfig->m_DriveNumber);
|
|
exit(1);
|
|
}
|
|
pConfig->m_Partitions[partitionNumber - 1].m_Filesystem = MBR_FS_EXT_LBA;
|
|
pConfig->m_Partitions[partitionNumber - 1].m_PhysicalLBA = currentLBA;
|
|
extendedPartNo = partitionNumber;
|
|
|
|
// Note: We don't increment partitionNumber, to keep the presence of this partition
|
|
// transparent elsewhere.
|
|
}
|
|
DWORD extendedStart = currentLBA;
|
|
|
|
// Init extended partitions
|
|
for (int i = 0;; i++) {
|
|
if (!pConfig->m_Extended[i].m_Size) break;
|
|
|
|
pConfig->m_Extended[i].m_PartitionNumber = partitionNumber++;
|
|
|
|
currentLBA += EXT_HEADER_GAP;
|
|
pConfig->m_Extended[i].m_PhysicalLBA = currentLBA;
|
|
pConfig->m_Extended[i].m_SlotLBA = currentLBA;
|
|
currentLBA += pConfig->m_Extended[i].m_Size;
|
|
|
|
pConfig->m_Extended[i].m_Volume.m_pDrive = pConfig;
|
|
pConfig->m_Extended[i].m_Volume.m_pPartition = &(pConfig->m_Extended[i]);
|
|
|
|
sbr_slot_t* pslot = get_sbr_slot(pConfig->m_Extended[i].m_SPDContent);
|
|
if (pslot != NULL) {
|
|
DWORD slot_size = ((LONGLONG)pslot->segcount * (LONGLONG)pslot->segsize) /
|
|
(long long)pConfig->m_BlockSize;
|
|
DWORD slot_offset = pConfig->m_Extended[i].m_Size - slot_size;
|
|
pConfig->m_Extended[i].m_SlotLBA += slot_offset;
|
|
}
|
|
}
|
|
|
|
// Back-fill, if needed
|
|
if (extendedPartNo) {
|
|
pConfig->m_Partitions[extendedPartNo - 1].m_Size = currentLBA - extendedStart;
|
|
}
|
|
|
|
pConfig->m_TotalSize = currentLBA;
|
|
} else {
|
|
// Raw disks have just a single spanning volume
|
|
pConfig->m_Partitions[0].m_PartitionNumber = 1;
|
|
pConfig->m_Partitions[0].m_PhysicalLBA = 0;
|
|
pConfig->m_Partitions[0].m_Size = pConfig->m_TotalSize;
|
|
pConfig->m_Partitions[0].m_Volume.m_pDrive = pConfig;
|
|
pConfig->m_Partitions[0].m_Volume.m_pPartition = &(pConfig->m_Partitions[0]);
|
|
}
|
|
}
|
|
|
|
inline void set_chs(BYTE* chs, WORD cylinder, BYTE head, BYTE sector) {
|
|
chs[0] = head;
|
|
chs[1] = ((sector & 0x3f) | ((cylinder & 0x300) >> 2)) & 0xff;
|
|
chs[2] = cylinder & 0xff;
|
|
}
|
|
inline void set_chs_from_lba(BYTE* chs, DWORD lba) {
|
|
WORD cylinder = (lba / (HEADS_PER_CYLINDER * SECTORS_PER_TRACK)) & 0xffff;
|
|
BYTE head = ((lba / SECTORS_PER_TRACK) % HEADS_PER_CYLINDER) & 0xff;
|
|
BYTE sector = ((lba % SECTORS_PER_TRACK) + 1) & 0xff;
|
|
set_chs(chs, cylinder, head, sector);
|
|
}
|
|
inline void fix_partition_chs(PMBR_PARTITION partition) {
|
|
set_chs_from_lba(partition->start_chs, partition->lba);
|
|
set_chs_from_lba(partition->end_chs, partition->lba + partition->sectors - 1);
|
|
}
|
|
|
|
BYTE writeBuffer[1024];
|
|
void write_buffer(HANDLE hDisk, DWORD nBlock, DWORD nBytes, physical_disk_t* pConfig) {
|
|
LARGE_INTEGER offset;
|
|
offset.HighPart = 0;
|
|
offset.LowPart = nBlock;
|
|
offset.QuadPart *= pConfig->m_BlockSize;
|
|
SetFilePointerEx(hDisk, offset, NULL, FILE_BEGIN);
|
|
printf("Performing write: %d@%08x%08x\n", nBytes, offset.HighPart, offset.LowPart);
|
|
DWORD nOut;
|
|
WriteFile(hDisk, writeBuffer, nBytes, &nOut, NULL);
|
|
if (nOut != nBytes) {
|
|
printf("WRITE FAILED!! %d\n", GetLastError());
|
|
CloseHandle(hDisk);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
void write_mbr(HANDLE hDisk, LONG nOffset, physical_disk_t* pConfig) {
|
|
printf("Writing MBR at block %d\n", nOffset);
|
|
PMBR_HEADER mbr = (PMBR_HEADER)writeBuffer;
|
|
|
|
memset(mbr, 0, sizeof *mbr);
|
|
memcpy_s(mbr->bootstrap_code, sizeof mbr->bootstrap_code, WINDOWS_MBR_BOOTSTRAP,
|
|
sizeof WINDOWS_MBR_BOOTSTRAP);
|
|
|
|
mbr->sig[0] = 0x55;
|
|
mbr->sig[1] = 0xAA;
|
|
|
|
for (size_t i = 0; i < 4; i++) {
|
|
if (pConfig->m_Partitions[i].m_Size == 0) break;
|
|
|
|
mbr->partitions[i].status =
|
|
(pConfig->m_BootPartition == i + 1) ? MBR_FLAG_BOOTABLE : MBR_FLAG_NONE;
|
|
mbr->partitions[i].type = pConfig->m_Partitions[i].m_Filesystem;
|
|
mbr->partitions[i].lba = pConfig->m_Partitions[i].m_PhysicalLBA;
|
|
mbr->partitions[i].sectors = pConfig->m_Partitions[i].m_Size;
|
|
|
|
fix_partition_chs(&(mbr->partitions[i]));
|
|
}
|
|
|
|
write_buffer(hDisk, nOffset, sizeof *mbr, pConfig);
|
|
}
|
|
void write_ext_header(HANDLE hDisk, LONG nOffset, physical_disk_t* pConfig, DWORD nPartition) {
|
|
printf("Writing extended header at block %d\n", nOffset);
|
|
printf(" -> Part %d = %d\n", nPartition + 5, nOffset);
|
|
|
|
PMBR_HEADER mbr = (PMBR_HEADER)writeBuffer;
|
|
|
|
memset(mbr, 0, sizeof *mbr);
|
|
mbr->sig[0] = 0x55;
|
|
mbr->sig[1] = 0xAA;
|
|
|
|
mbr->partitions[0].status = MBR_FLAG_NONE;
|
|
mbr->partitions[0].type = pConfig->m_Extended[nPartition].m_Filesystem;
|
|
mbr->partitions[0].lba = pConfig->m_Extended[nPartition].m_PhysicalLBA;
|
|
mbr->partitions[0].sectors = pConfig->m_Extended[nPartition].m_Size;
|
|
fix_partition_chs(&(mbr->partitions[0]));
|
|
// Write the EBR value
|
|
mbr->partitions[0].lba = EXT_HEADER_GAP;
|
|
|
|
if (pConfig->m_Extended[nPartition + 1].m_Size) {
|
|
mbr->partitions[1].status = MBR_FLAG_NONE;
|
|
mbr->partitions[1].type = MBR_FS_EXT_CHS;
|
|
mbr->partitions[1].lba = pConfig->m_Extended[nPartition + 1].m_PhysicalLBA - EXT_HEADER_GAP;
|
|
mbr->partitions[1].sectors = pConfig->m_Extended[nPartition + 1].m_Size + EXT_HEADER_GAP;
|
|
|
|
fix_partition_chs(&(mbr->partitions[1]));
|
|
// Write the EBR values
|
|
mbr->partitions[1].lba = pConfig->m_Extended[nPartition + 1].m_PhysicalLBA -
|
|
pConfig->m_Extended[0].m_PhysicalLBA;
|
|
|
|
mbr->partitions[1].end_chs[0] = 0xFE;
|
|
mbr->partitions[1].end_chs[1] = 0xFF;
|
|
mbr->partitions[1].end_chs[2] = 0xFF;
|
|
}
|
|
|
|
write_buffer(hDisk, nOffset, sizeof *mbr, pConfig);
|
|
}
|
|
|
|
void write_pd(HANDLE hDisk, physical_disk_t* pConfig) {
|
|
printf("Pre-allocating disk space (0x%x blocks)\n", pConfig->m_TotalSize);
|
|
write_buffer(hDisk, pConfig->m_TotalSize - 1, pConfig->m_BlockSize, pConfig);
|
|
|
|
// Write MBR headers
|
|
write_mbr(hDisk, 0, pConfig);
|
|
for (size_t i = 0; pConfig->m_Extended[i].m_Size; i++) {
|
|
DWORD headerLBA = pConfig->m_Extended[i].m_PhysicalLBA - EXT_HEADER_GAP;
|
|
write_ext_header(hDisk, headerLBA, pConfig, i);
|
|
|
|
if (i == 0 && pConfig->m_HasSegaboot) {
|
|
// SEGA Partition Description
|
|
spd_t* spd = (spd_t*)writeBuffer;
|
|
ZeroMemory(spd, sizeof *spd);
|
|
|
|
spd->version = SPD_VERSION;
|
|
for (size_t j = 0; pConfig->m_Extended[j].m_Size; j++) {
|
|
spd->slots[j].block_size = pConfig->m_BlockSize & 0xFFFF;
|
|
spd->slots[j].block_count = pConfig->m_Extended[j].m_Size;
|
|
spd->slots[j].slot_content = pConfig->m_Extended[j].m_SPDContent;
|
|
spd->slots[j].uk1 = pConfig->m_Extended[j].m_Filesystem == MBR_FS_FAT16 ? 0 : 1;
|
|
}
|
|
|
|
spd->crc = amiCrc32RCalc(sizeof *spd - 4, &(spd->version), 0);
|
|
write_buffer(hDisk, headerLBA + SPD_OFFSET, sizeof *spd, pConfig);
|
|
|
|
// TODO: Actually populate the SBRs
|
|
|
|
// SEGA Boot Record 0 and 1. The two are a redundant copy of each other
|
|
memcpy(writeBuffer, &SegaBootRecord0, sizeof SegaBootRecord0);
|
|
write_buffer(hDisk, headerLBA + SBR0_OFFSET, sizeof SegaBootRecord0, pConfig);
|
|
|
|
memcpy(writeBuffer, &SegaBootRecord1, sizeof SegaBootRecord1);
|
|
write_buffer(hDisk, headerLBA + SBR1_OFFSET, sizeof SegaBootRecord1, pConfig);
|
|
|
|
printf(" -> SEGA structures = %d+[1/2/3]\n", headerLBA);
|
|
}
|
|
}
|
|
}
|
|
|
|
void print_bar(LONGLONG nCurrent, LONGLONG nMax) {
|
|
printf("[");
|
|
DWORD filled = (DWORD)(((float)nCurrent / (float)nMax) * 40);
|
|
DWORD i = 0;
|
|
for (; i < filled; i++) printf("=");
|
|
for (; i < 40; i++) printf(" ");
|
|
printf("] %3.2f%%\r", (float)nCurrent / (float)nMax * 100);
|
|
}
|
|
void end_bar() { printf("[========================================] 100.00%%\n"); }
|
|
|
|
BOOL mount_OSR(LPSTR lpOSRPath) {
|
|
char szTcCommand[1024];
|
|
sprintf_s(szTcCommand, sizeof szTcCommand, "%s /p %s /v %s /l %s %s", TRUECRYPT, OSR_PASSWORD,
|
|
lpOSRPath, OSR_MOUNTPOINT, OSR_FLAGS);
|
|
|
|
int dTcRet = system(szTcCommand);
|
|
if (dTcRet != 0) {
|
|
printf("Failed to mount OSR: %d\n", dTcRet);
|
|
printf("Command used was: %s\n", szTcCommand);
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
BOOL dismount_OSR() {
|
|
char szTcCommand[1024];
|
|
sprintf_s(szTcCommand, sizeof szTcCommand, "%s /q /d %s", TRUECRYPT, OSR_MOUNTPOINT);
|
|
|
|
int dTcRet = system(szTcCommand);
|
|
if (dTcRet != 0) {
|
|
printf("Failed to dismount OSR: %d\n", dTcRet);
|
|
printf("Command used was: %s\n", szTcCommand);
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void install_OSR(HANDLE hDisk, LPSTR lpOSRPath) {
|
|
if (!mount_OSR(lpOSRPath)) return;
|
|
|
|
HANDLE hOSR = CreateFileA("\\\\.\\" OSR_MOUNTPOINT, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (hOSR == INVALID_HANDLE_VALUE) {
|
|
printf("Failed to open OSR! %d\n", GetLastError());
|
|
return;
|
|
}
|
|
|
|
DISK_GEOMETRY dg;
|
|
DWORD nBytesReturned;
|
|
DeviceIoControl(hOSR, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dg, sizeof dg, &nBytesReturned,
|
|
NULL);
|
|
LONGLONG nBytes =
|
|
dg.BytesPerSector * dg.SectorsPerTrack * dg.TracksPerCylinder * dg.Cylinders.QuadPart;
|
|
|
|
SetFilePointer(hDisk, 63 * 512, NULL, FILE_BEGIN);
|
|
|
|
puts("Installing Operating System");
|
|
|
|
BYTE block[4096];
|
|
int print_tick = 0;
|
|
for (LONGLONG i = 0; nBytes;) {
|
|
DWORD nRead = sizeof block;
|
|
if (nRead > nBytes) nRead = (DWORD)nBytes;
|
|
|
|
ReadFile(hOSR, block, nRead, &nRead, NULL);
|
|
if (nRead == 0) {
|
|
if (GetLastError() == ERROR_SUCCESS) break;
|
|
|
|
printf("Failed to read OSR. Code: %d\n", GetLastError());
|
|
goto end;
|
|
return;
|
|
}
|
|
|
|
DWORD nWrote = 0;
|
|
WriteFile(hDisk, block, nRead, &nWrote, NULL);
|
|
if (nWrote != nRead) {
|
|
printf("Failed to write OSR to disk. Code: %d\n", GetLastError());
|
|
goto end;
|
|
return;
|
|
}
|
|
|
|
if (print_tick++ == 512) {
|
|
print_tick = 0;
|
|
print_bar(i, nBytes);
|
|
}
|
|
|
|
i += nRead;
|
|
}
|
|
end_bar();
|
|
end:
|
|
CloseHandle(hOSR);
|
|
dismount_OSR();
|
|
}
|
|
BOOL install_OSR_xcopy(LPSTR lpDiskPath, LPSTR lpOSRPath) {
|
|
if (!mount_OSR(lpOSRPath)) return FALSE;
|
|
|
|
printf("Installing OS using xcopy %s -> %s\n", OSR_MOUNTPOINT, lpDiskPath);
|
|
|
|
char szXcCommand[1024];
|
|
sprintf_s(szXcCommand, sizeof szXcCommand, "xcopy %s %s /e /c /h /y /q", OSR_MOUNTPOINT,
|
|
lpDiskPath);
|
|
|
|
int dTcRet = system(szXcCommand);
|
|
if (dTcRet != 0) {
|
|
printf("Failed to xcopy OSR: %d\n", dTcRet);
|
|
printf("Command used was: %s\n", szXcCommand);
|
|
return FALSE;
|
|
}
|
|
|
|
if (!dismount_OSR()) return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
amiCrc32RInit();
|
|
|
|
init_pd(&newSSD);
|
|
|
|
HANDLE hDisk = INVALID_HANDLE_VALUE;
|
|
SetLastError(0);
|
|
|
|
hDisk = CreateFileA("H:\\NewDiskImage1.img", GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
// hDisk = CreateFileA("\\\\.\\PHYSICALDRIVE4", GENERIC_READ | GENERIC_WRITE,
|
|
// FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
|
|
|
if (hDisk == INVALID_HANDLE_VALUE) {
|
|
printf("Failed to open disk! %d\n", GetLastError());
|
|
return 1;
|
|
}
|
|
|
|
write_pd(hDisk, &newSSD);
|
|
|
|
// install_OSR(hDisk, "H:\\Arcades\\RingOS\\RecoverOS\\0009\\Minint\\system32\\OSR");
|
|
// install_OSR_xcopy(hDisk, "H:\\Arcades\\RingOS\\RecoverOS\\0009\\Minint\\system32\\OSR");
|
|
|
|
// puts("Please mount OS at W:");
|
|
// system("pause");
|
|
// install_OSR_xcopy("W:", "H:\\Arcades\\RingOS\\RecoverOS\\0009\\Minint\\system32\\OSR");
|
|
|
|
FlushFileBuffers(hDisk);
|
|
CloseHandle(hDisk);
|
|
return 0;
|
|
}
|