Implement CrackProof drivers
This commit is contained in:
parent
701887940c
commit
d3ff2e7c24
@ -165,6 +165,8 @@ void init_injection(HMODULE hModule) {
|
|||||||
if (MiceConfig.drivers.mxsmbus) setup_mxsmbus();
|
if (MiceConfig.drivers.mxsmbus) setup_mxsmbus();
|
||||||
// MX Parallel: The parallel port (i.e. keychip)
|
// MX Parallel: The parallel port (i.e. keychip)
|
||||||
if (MiceConfig.drivers.mxparallel) setup_mxparallel();
|
if (MiceConfig.drivers.mxparallel) setup_mxparallel();
|
||||||
|
// CrackProof
|
||||||
|
if (MiceConfig.drivers.htsysmnt) setup_htsysmnt();
|
||||||
|
|
||||||
if (MiceConfig.drivers.platform) {
|
if (MiceConfig.drivers.platform) {
|
||||||
if (!add_fake_device(&PLATFORM_GUID, L"\\\\.\\platform")) {
|
if (!add_fake_device(&PLATFORM_GUID, L"\\\\.\\platform")) {
|
||||||
|
113
src/micetools/dll/drivers/htsysmnt.c
Normal file
113
src/micetools/dll/drivers/htsysmnt.c
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#include "mx.h"
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct {
|
||||||
|
LPBYTE dest;
|
||||||
|
LPBYTE src;
|
||||||
|
DWORD nBytes;
|
||||||
|
} HTSYSMNT_1x, *LPHTSYSMNT_1x;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
DWORD offset;
|
||||||
|
LPBYTE data;
|
||||||
|
DWORD nBytes;
|
||||||
|
} HTSYSMNT_2x, *LPHTSYSMNT_2x;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void (*callback)(void);
|
||||||
|
} HTSYSMNT_3x, *LPHTSYSMNT_3x;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
static BYTE HTSYS_BUFFER[256];
|
||||||
|
|
||||||
|
static BOOL htsysmntBufferTransact(DWORD offset, LPBYTE data, DWORD nbytes, BOOL doWrite) {
|
||||||
|
LPBYTE source;
|
||||||
|
LPBYTE destination;
|
||||||
|
|
||||||
|
if (!(offset < 16 && nbytes < 16)) return FALSE;
|
||||||
|
|
||||||
|
destination = HTSYS_BUFFER + offset * 16;
|
||||||
|
source = data;
|
||||||
|
if (!doWrite) {
|
||||||
|
source = destination;
|
||||||
|
destination = data;
|
||||||
|
}
|
||||||
|
memcpy(destination, source, nbytes);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL htsysmntExchangeBuffers(LPBYTE dest, LPBYTE src, DWORD nBytes, BOOL direction) {
|
||||||
|
if (dest == NULL || src == NULL || nBytes == 0) return FALSE;
|
||||||
|
|
||||||
|
LPBYTE destination;
|
||||||
|
destination = dest;
|
||||||
|
if (!direction) {
|
||||||
|
destination = src;
|
||||||
|
src = dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(src, destination, nBytes);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI htsysmnt_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer,
|
||||||
|
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
|
||||||
|
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
|
||||||
|
DWORD expectedIn = 0;
|
||||||
|
DWORD expectedOut = /* 4 */ sizeof(BOOL);
|
||||||
|
|
||||||
|
switch (dwIoControlCode) {
|
||||||
|
case IOCTL_CRACKPROOF_10:
|
||||||
|
case IOCTL_CRACKPROOF_11:
|
||||||
|
case IOCTL_CRACKPROOF_20:
|
||||||
|
case IOCTL_CRACKPROOF_21:
|
||||||
|
expectedIn = 12;
|
||||||
|
break;
|
||||||
|
case IOCTL_CRACKPROOF_30:
|
||||||
|
expectedIn = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log_warning(plfHtsysmnt, "unhandled 0x%08x", dwIoControlCode);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nInBufferSize != expectedIn || nOutBufferSize != expectedOut) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL result = TRUE;
|
||||||
|
|
||||||
|
switch (dwIoControlCode) {
|
||||||
|
case IOCTL_CRACKPROOF_10:
|
||||||
|
case IOCTL_CRACKPROOF_11: {
|
||||||
|
result = htsysmntExchangeBuffers(
|
||||||
|
((LPHTSYSMNT_1x)lpInBuffer)->dest, ((LPHTSYSMNT_1x)lpInBuffer)->src,
|
||||||
|
((LPHTSYSMNT_1x)lpInBuffer)->nBytes, dwIoControlCode == IOCTL_CRACKPROOF_11);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case IOCTL_CRACKPROOF_20:
|
||||||
|
case IOCTL_CRACKPROOF_21: {
|
||||||
|
result = htsysmntBufferTransact(
|
||||||
|
((LPHTSYSMNT_2x)lpInBuffer)->offset, ((LPHTSYSMNT_2x)lpInBuffer)->data,
|
||||||
|
((LPHTSYSMNT_2x)lpInBuffer)->nBytes, dwIoControlCode == IOCTL_CRACKPROOF_21);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case IOCTL_CRACKPROOF_30:
|
||||||
|
result = TRUE;
|
||||||
|
((LPHTSYSMNT_3x)lpInBuffer)->callback();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(LPBOOL)lpOutBuffer = result;
|
||||||
|
*lpBytesReturned = expectedOut;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_htsysmnt() {
|
||||||
|
file_hook_t* htsysmnt = new_file_hook(L"\\\\.\\Htsysm");
|
||||||
|
htsysmnt->DeviceIoControl = &htsysmnt_DeviceIoControl;
|
||||||
|
|
||||||
|
hook_file(htsysmnt);
|
||||||
|
}
|
@ -6,4 +6,5 @@ drivers_files = files(
|
|||||||
'mxsmbus.c',
|
'mxsmbus.c',
|
||||||
'mxsram.c',
|
'mxsram.c',
|
||||||
'mxsuperio.c',
|
'mxsuperio.c',
|
||||||
|
'htsysmnt.c',
|
||||||
)
|
)
|
@ -26,3 +26,6 @@ void setup_columba();
|
|||||||
|
|
||||||
FnDeviceIoControl mxparallel_DeviceIoControl;
|
FnDeviceIoControl mxparallel_DeviceIoControl;
|
||||||
void setup_mxparallel();
|
void setup_mxparallel();
|
||||||
|
|
||||||
|
FnDeviceIoControl htsysmnt_DeviceIoControl;
|
||||||
|
void setup_htsysmnt();
|
||||||
|
@ -28,7 +28,6 @@ physical_disk_t SSD = {
|
|||||||
{ 0x403947, MBR_FS_FAT16, SPD_Patch1, .m_ReadFunc = NULL }, // 2GB patch1
|
{ 0x403947, MBR_FS_FAT16, SPD_Patch1, .m_ReadFunc = NULL }, // 2GB patch1
|
||||||
{ 0x48ed459, MBR_FS_NTFS, SPD_AppData, .m_ReadFunc = NULL }, // 40GB something
|
{ 0x48ed459, MBR_FS_NTFS, SPD_AppData, .m_ReadFunc = NULL }, // 40GB something
|
||||||
{
|
{
|
||||||
// mxinstaller.exe -cmdport 40102 -bindport 40103
|
|
||||||
// 16GB partition for the game
|
// 16GB partition for the game
|
||||||
// The real value here should be "0x20014aa,"
|
// The real value here should be "0x20014aa,"
|
||||||
0x20014aa, // 16GB, FiNALE
|
0x20014aa, // 16GB, FiNALE
|
||||||
|
@ -78,6 +78,7 @@ CFG_bool(drivers, mxjvs, true, "")
|
|||||||
CFG_bool(drivers, mxhwreset, true, "")
|
CFG_bool(drivers, mxhwreset, true, "")
|
||||||
CFG_bool(drivers, mxsmbus, true, "")
|
CFG_bool(drivers, mxsmbus, true, "")
|
||||||
CFG_bool(drivers, mxparallel, true, "")
|
CFG_bool(drivers, mxparallel, true, "")
|
||||||
|
CFG_bool(drivers, htsysmnt, true, "")
|
||||||
CFG_bool(drivers, platform, true, "")
|
CFG_bool(drivers, platform, true, "")
|
||||||
ENDSECTION(drivers)
|
ENDSECTION(drivers)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
|
|
||||||
#define FILE_DEVICE_SEGA 0x9c40
|
#define FILE_DEVICE_SEGA 0x9c40
|
||||||
|
#define FILE_DEVICE_HTSYS 0xaa00
|
||||||
|
|
||||||
// amSramInit
|
// amSramInit
|
||||||
#define IOCTL_MXSRAM_PING \
|
#define IOCTL_MXSRAM_PING \
|
||||||
@ -83,3 +84,10 @@
|
|||||||
(DWORD) CTL_CODE(FILE_DEVICE_SEGA, 0x806, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
(DWORD) CTL_CODE(FILE_DEVICE_SEGA, 0x806, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||||
#define IOCTL_MXPARALLEL_READ_FLAGS \
|
#define IOCTL_MXPARALLEL_READ_FLAGS \
|
||||||
(DWORD) CTL_CODE(FILE_DEVICE_SEGA, 0x807, METHOD_BUFFERED, FILE_READ_ACCESS)
|
(DWORD) CTL_CODE(FILE_DEVICE_SEGA, 0x807, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||||
|
|
||||||
|
// CrackProof
|
||||||
|
#define IOCTL_CRACKPROOF_10 CTL_CODE(FILE_DEVICE_HTSYS, 0x810, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_CRACKPROOF_11 CTL_CODE(FILE_DEVICE_HTSYS, 0x811, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_CRACKPROOF_20 CTL_CODE(FILE_DEVICE_HTSYS, 0x820, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_CRACKPROOF_21 CTL_CODE(FILE_DEVICE_HTSYS, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define IOCTL_CRACKPROOF_30 CTL_CODE(FILE_DEVICE_HTSYS, 0x830, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
@ -39,3 +39,4 @@ _LF(Drivers, MxSuperio, "mxsuperio")
|
|||||||
_LF(Drivers, MxSmbus, "mxsmbus")
|
_LF(Drivers, MxSmbus, "mxsmbus")
|
||||||
_LF(Drivers, MxHwreset, "mxhwreset")
|
_LF(Drivers, MxHwreset, "mxhwreset")
|
||||||
_LF(Drivers, Platform, "platform")
|
_LF(Drivers, Platform, "platform")
|
||||||
|
_LF(Drivers, Htsysmnt, "htsysmnt")
|
||||||
|
@ -66,3 +66,14 @@ executable(
|
|||||||
amiDebug,
|
amiDebug,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
executable(
|
||||||
|
'storagecraft',
|
||||||
|
win_subsystem: subsystem,
|
||||||
|
sources: [
|
||||||
|
'storagecraft.c',
|
||||||
|
],
|
||||||
|
link_with: [
|
||||||
|
amiCrc,
|
||||||
|
amiDebug,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
249
src/micetools/util/storagecraft.c
Normal file
249
src/micetools/util/storagecraft.c
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../dll/hooks/drive/drive.h"
|
||||||
|
|
||||||
|
physical_disk_t newSSD = {
|
||||||
|
.m_SerialNumber = 0x00144DB0,
|
||||||
|
|
||||||
|
.m_BusType = BusTypeAta,
|
||||||
|
.m_BootPartition = 1,
|
||||||
|
.m_HasSegaboot = TRUE,
|
||||||
|
.m_BlockSize = BLOCK_SIZE_HDD,
|
||||||
|
.m_TotalSize = 64 * 1024 * 1024 * (1024 / BLOCK_SIZE_HDD),
|
||||||
|
.m_DiskType = DiskType_HardDisk,
|
||||||
|
.m_IsFormatted = true,
|
||||||
|
.m_Partitions = {
|
||||||
|
// 1.5GB boot partition
|
||||||
|
{ .m_Size = 0x300B85, .m_Filesystem = MBR_FS_NTFS },
|
||||||
|
// 1.5GB OS recovery
|
||||||
|
{ .m_Size = 0x300BC4, .m_Filesystem = MBR_FS_NTFS },
|
||||||
|
},
|
||||||
|
.m_Extended = {
|
||||||
|
{ 0x102d83, MBR_FS_FAT16, SPD_OS }, // 512MB OS update
|
||||||
|
{ 0x403947, MBR_FS_FAT16, SPD_Patch0 }, // 2GB patch0
|
||||||
|
{ 0x403947, MBR_FS_FAT16, SPD_Patch1 }, // 2GB patch1
|
||||||
|
{ 0x48ed459, MBR_FS_NTFS, SPD_AppData }, // 40GB appdata
|
||||||
|
{ 0x20014aa, MBR_FS_FAT16, SPD_Original0 }, // 16GB original0
|
||||||
|
{ 0 }, // End of table
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
sbr_t SegaBootRecord0;
|
||||||
|
sbr_t SegaBootRecord1;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
} 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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE writeBuffer[1024];
|
||||||
|
void write_buffer(HANDLE hDisk, LONG nOffset, DWORD nBytes, physical_disk_t* pConfig) {
|
||||||
|
LARGE_INTEGER offset;
|
||||||
|
offset.QuadPart = nOffset * pConfig->m_BlockSize;
|
||||||
|
SetFilePointerEx(hDisk, offset, NULL, FILE_BEGIN);
|
||||||
|
DWORD nOut;
|
||||||
|
WriteFile(hDisk, writeBuffer, nBytes, &nOut, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Write start_chs lol
|
||||||
|
void write_mbr(HANDLE hDisk, LONG nOffset, physical_disk_t* pConfig) {
|
||||||
|
printf("Writing MBR at block %d\n", nOffset);
|
||||||
|
mbr_t* mbr = (mbr_t*)writeBuffer;
|
||||||
|
|
||||||
|
memset(mbr, 0, sizeof *mbr);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
mbr_t* mbr = (mbr_t*)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 = EXT_HEADER_GAP;
|
||||||
|
mbr->partitions[0].sectors = pConfig->m_Extended[nPartition].m_Size;
|
||||||
|
|
||||||
|
if (pConfig->m_Extended[nPartition + 1].m_Size) {
|
||||||
|
mbr->partitions[1].status = MBR_FLAG_NONE;
|
||||||
|
// ! mxinstaller expects to see CHS here, then uses the LBA values
|
||||||
|
mbr->partitions[1].type = MBR_FS_EXT_CHS;
|
||||||
|
mbr->partitions[1].lba = pConfig->m_Extended[nPartition + 1].m_PhysicalLBA -
|
||||||
|
pConfig->m_Extended[0].m_PhysicalLBA;
|
||||||
|
mbr->partitions[1].sectors = pConfig->m_Extended[nPartition + 1].m_Size + EXT_HEADER_GAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_buffer(hDisk, nOffset, sizeof *mbr, pConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_pd(HANDLE hDisk, physical_disk_t* pConfig) {
|
||||||
|
puts("Force-allocating disk space");
|
||||||
|
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) {
|
||||||
|
puts("Writing segaboot");
|
||||||
|
|
||||||
|
// SEGA Partition Description
|
||||||
|
spd_t* spd = (spd_t*)writeBuffer;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
init_pd(&newSSD);
|
||||||
|
|
||||||
|
HANDLE hDisk = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
hDisk = CreateFileA("H:\\NewDiskImage.img", GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
|
||||||
|
|
||||||
|
write_pd(hDisk, &newSSD);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user