17 Commits
3.0.1 ... 3.0.3

Author SHA1 Message Date
f69b0a4214 Update LLVM
All checks were successful
Builds / XTchain (minimal, windows) (push) Successful in 2m7s
Builds / XTchain (minimal, linux) (push) Successful in 2m23s
Builds / XTchain (full, windows) (push) Successful in 55m35s
Builds / XTchain (full, linux) (push) Successful in 1h22m53s
2025-10-07 16:19:52 +02:00
0ba79fd489 Set DriveNumber to emulate hard disk
All checks were successful
Builds / XTchain (minimal, windows) (push) Successful in 2m14s
Builds / XTchain (minimal, linux) (push) Successful in 10m44s
Builds / XTchain (full, windows) (push) Successful in 56m0s
Builds / XTchain (full, linux) (push) Successful in 1h31m7s
2025-10-05 20:39:51 +02:00
e16284f3aa Rename GetFileSize to GetSectorFileSize to avoid conflict with WinAPI
All checks were successful
Builds / XTchain (minimal, linux) (push) Successful in 2m6s
Builds / XTchain (minimal, windows) (push) Successful in 1m53s
Builds / XTchain (full, linux) (push) Successful in 55m48s
Builds / XTchain (full, windows) (push) Successful in 1h23m56s
2025-10-02 22:19:54 +02:00
09e54a670a Remove duplicate RESERVED_SECTOR_INFO definition
Some checks failed
Builds / XTchain (full, windows) (push) Failing after 17s
Builds / XTchain (minimal, windows) (push) Failing after 16s
Builds / XTchain (minimal, linux) (push) Successful in 1m59s
Builds / XTchain (full, linux) (push) Has started running
2025-10-02 22:16:16 +02:00
9827395c8c Enhance disk image tool with multi-sector VBR support
Some checks failed
Builds / XTchain (full, windows) (push) Failing after 15s
Builds / XTchain (minimal, windows) (push) Failing after 15s
Builds / XTchain (full, linux) (push) Failing after 21s
Builds / XTchain (minimal, linux) (push) Failing after 20s
2025-10-02 22:14:12 +02:00
ef272847e1 Correct key fields in VBR generated by mformat
All checks were successful
Builds / XTchain (minimal, linux) (push) Successful in 2m10s
Builds / XTchain (minimal, windows) (push) Successful in 2m17s
Builds / XTchain (full, windows) (push) Successful in 56m47s
Builds / XTchain (full, linux) (push) Successful in 1h22m3s
2025-10-02 09:36:30 +02:00
2271d6bde1 Preserve BPB when writing custom VBR
All checks were successful
Builds / XTchain (minimal, linux) (push) Successful in 2m2s
Builds / XTchain (minimal, windows) (push) Successful in 2m2s
Builds / XTchain (full, linux) (push) Successful in 54m36s
Builds / XTchain (full, windows) (push) Successful in 1h23m28s
2025-10-01 23:06:15 +02:00
32a254468b Fix build
All checks were successful
Builds / XTchain (minimal, linux) (push) Successful in 1m36s
Builds / XTchain (minimal, windows) (push) Successful in 1m34s
Builds / XTchain (full, linux) (push) Successful in 1h36m10s
Builds / XTchain (full, windows) (push) Successful in 1h37m6s
2025-09-29 19:09:09 +02:00
50dbda6ccc Add support for recursive data copy into FAT image
Some checks failed
Builds / XTchain (full, windows) (push) Failing after 14s
Builds / XTchain (minimal, linux) (push) Successful in 1m56s
Builds / XTchain (full, linux) (push) Has been cancelled
Builds / XTchain (minimal, windows) (push) Has been cancelled
2025-09-29 19:06:26 +02:00
3fff3b487b Resolve XTchain directory based on script path
All checks were successful
Builds / XTchain (full, linux) (push) Successful in 2h17m22s
Builds / XTchain (full, windows) (push) Successful in 2h18m41s
Builds / XTchain (minimal, linux) (push) Successful in 1m46s
Builds / XTchain (minimal, windows) (push) Successful in 1m36s
2025-09-28 22:57:35 +02:00
297937aeb3 Allow formatting as FAT-16 or FAT-32
All checks were successful
Builds / XTchain (full, linux) (push) Successful in 2h18m27s
Builds / XTchain (full, windows) (push) Successful in 2h19m38s
Builds / XTchain (minimal, linux) (push) Successful in 1m48s
Builds / XTchain (minimal, windows) (push) Successful in 1m36s
2025-09-27 19:59:20 +02:00
ca9a116e9b Add option to automatically format partition in disk image
Some checks failed
Builds / XTchain (full, linux) (push) Has started running
Builds / XTchain (full, windows) (push) Has started running
Builds / XTchain (minimal, linux) (push) Has been cancelled
Builds / XTchain (minimal, windows) (push) Has been cancelled
2025-09-27 18:14:07 +02:00
ca637f057b Fix overflow
Some checks failed
Builds / XTchain (minimal, linux) (push) Has been cancelled
Builds / XTchain (minimal, windows) (push) Has been cancelled
Builds / XTchain (full, linux) (push) Has been cancelled
Builds / XTchain (full, windows) (push) Has been cancelled
2025-09-27 17:36:13 +02:00
d366c94ac8 Import disk image manipulation tool
Some checks failed
Builds / XTchain (minimal, linux) (push) Has been cancelled
Builds / XTchain (minimal, windows) (push) Has been cancelled
Builds / XTchain (full, windows) (push) Has been cancelled
Builds / XTchain (full, linux) (push) Has been cancelled
2025-09-27 17:25:51 +02:00
ce379beeb2 Update LLVM to 21.1.2 and add Mtools
All checks were successful
Builds / XTchain (full, linux) (push) Successful in 2h17m38s
Builds / XTchain (full, windows) (push) Successful in 2h18m57s
Builds / XTchain (minimal, linux) (push) Successful in 1m54s
Builds / XTchain (minimal, windows) (push) Successful in 1m37s
2025-09-27 14:27:27 +02:00
2d4dffe38f Fix WaitForSingleObject() argument type on MinGW
All checks were successful
Builds / XTchain (full, linux) (push) Successful in 2h18m45s
Builds / XTchain (full, windows) (push) Successful in 2h19m58s
Builds / XTchain (minimal, linux) (push) Successful in 1m41s
Builds / XTchain (minimal, windows) (push) Successful in 1m22s
2025-09-14 19:24:05 +02:00
124ef802b3 Update tools
Some checks failed
Builds / XTchain (full, windows) (push) Failing after 1h18m35s
Builds / XTchain (minimal, linux) (push) Successful in 1m51s
Builds / XTchain (minimal, windows) (push) Successful in 1m47s
Builds / XTchain (full, linux) (push) Successful in 1h54m25s
2025-09-14 10:49:11 +02:00
8 changed files with 812 additions and 42 deletions

View File

@@ -26,14 +26,19 @@ TARGET_SYSTEM=linux
# CMake Settings
CMAKEDIR="${SRCDIR}/cmake"
CMAKETAG="v4.0.3"
CMAKETAG="v4.1.1"
CMAKEVCS="https://gitlab.kitware.com/cmake/cmake.git"
# LLVM Settings
LLVMDIR="${SRCDIR}/llvm"
LLVMTAG="llvmorg-20.1.8"
LLVMTAG="llvmorg-21.1.3"
LLVMVCS="https://github.com/llvm/llvm-project.git"
# Mtools Settings
MTOOLSDIR="${SRCDIR}/mtools"
MTOOLSTAG="v4.0.49"
MTOOLSVCS="https://github.com/xt-sys/mtools.git"
# Ninja Settings
NINJADIR="${SRCDIR}/ninja"
NINJATAG="v1.13.1"
@@ -41,7 +46,7 @@ NINJAVCS="https://github.com/ninja-build/ninja.git"
# Wine Settings
WINEDIR="${SRCDIR}/wine"
WINETAG="wine-10.12"
WINETAG="wine-10.15"
WINEVCS="https://github.com/wine-mirror/wine.git"
@@ -207,6 +212,48 @@ llvm_fetch()
fi
}
# This function compiles and installs MTOOLS
mtools_build()
{
local CONFIGURE_PARAMETERS=""
local EXTENSION=""
# Clean old build if necessary
[ "${CLEAN_BUILD}" -eq 1 ] && rm -rf ${MTOOLSDIR}/build-${SYSTEM_NAME}
# Additional, target-specific configuration options
case "${SYSTEM_NAME}" in
Windows)
CONFIGURE_PARAMETERS="${CONFIGURE_PARAMETERS} --host=${SYSTEM_HOST}"
EXTENSION=".exe"
;;
esac
# Build Mtools
echo ">>> Building MTOOLS ..."
mkdir -p ${MTOOLSDIR}/build-${SYSTEM_NAME}
cd ${MTOOLSDIR}/build-${SYSTEM_NAME}
../configure ${CONFIGURE_PARAMETERS}
make -j ${BUILD_JOBS}
cp mtools${EXTENSION} ${BINDIR}/bin/
for TOOL in mcat mcd mcopy mdel mdir mformat minfo mlabel mmd mmove mpartition mrd mren mshowfat mtype mzip; do
cp mtools${EXTENSION} ${BINDIR}/bin/${TOOL}${EXTENSION}
done
cd ${WRKDIR}
}
# This function downloads MTOOLS from VCS
mtools_fetch()
{
if [ ! -d ${MTOOLSDIR} ]; then
echo ">>> Downloading MTOOLS ..."
git clone --depth 1 --branch ${MTOOLSTAG} ${MTOOLSVCS} ${MTOOLSDIR}
cd ${MTOOLSDIR}
apply_patches ${MTOOLSDIR##*/} ${MTOOLSTAG}
cd ${WRKDIR}
fi
}
# This function compiles and installs NINJA
ninja_build()
{
@@ -361,7 +408,7 @@ xtchain_build()
echo ">>> Building XTchain tools ..."
mkdir -p ${BINDIR}/bin
mkdir -p ${BINDIR}/lib/xtchain
for EXEC in bin2c exetool xtcspecc; do
for EXEC in bin2c diskimg exetool xtcspecc; do
if [ ! -e ${BINDIR}/bin/${EXEC} ]; then
${CCOMPILER} ${WRKDIR}/tools/${EXEC}.c -o ${BINDIR}/bin/${EXEC}
fi
@@ -479,6 +526,10 @@ xtchain_build
wine_fetch
wine_build
# Download and build GNU Mtools
mtools_fetch
mtools_build
if [ ${BUILD_MINIMAL} -eq 0 ]; then
# Download and build LLVM
llvm_fetch

View File

@@ -0,0 +1,13 @@
diff --git a/lldb/source/Host/windows/MainLoopWindows.cpp b/lldb/source/Host/windows/MainLoopWindows.cpp
index c0b10797e..e971b8cfd 100644
--- a/lldb/source/Host/windows/MainLoopWindows.cpp
+++ b/lldb/source/Host/windows/MainLoopWindows.cpp
@@ -58,7 +58,7 @@ public:
// Keep trying to cancel ReadFile() until the thread exits.
do {
CancelIoEx(m_handle, /*lpOverlapped=*/NULL);
- } while (WaitForSingleObject(m_monitor_thread.native_handle(), 1) ==
+ } while (WaitForSingleObject((HANDLE)m_monitor_thread.native_handle(), 1) ==
WAIT_TIMEOUT);
m_monitor_thread.join();
}

View File

@@ -0,0 +1,13 @@
diff --git a/lldb/source/Host/windows/MainLoopWindows.cpp b/lldb/source/Host/windows/MainLoopWindows.cpp
index c0b10797e..e971b8cfd 100644
--- a/lldb/source/Host/windows/MainLoopWindows.cpp
+++ b/lldb/source/Host/windows/MainLoopWindows.cpp
@@ -58,7 +58,7 @@ public:
// Keep trying to cancel ReadFile() until the thread exits.
do {
CancelIoEx(m_handle, /*lpOverlapped=*/NULL);
- } while (WaitForSingleObject(m_monitor_thread.native_handle(), 1) ==
+ } while (WaitForSingleObject((HANDLE)m_monitor_thread.native_handle(), 1) ==
WAIT_TIMEOUT);
m_monitor_thread.join();
}

View File

@@ -5,7 +5,7 @@
# DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
# Get the absolute path to the XTchain
$XTCDIR = (Get-Item -Path ".\").FullName
$XTCDIR = Split-Path -Parent $MyInvocation.MyCommand.Definition
# Read the XTchain version
$env:XTCVER = Get-Content "${XTCDIR}\Version"

666
tools/diskimg.c Normal file
View File

@@ -0,0 +1,666 @@
/**
* PROJECT: XTchain
* LICENSE: See COPYING.md in the top level directory
* FILE: tools/diskimg.c
* DESCRIPTION: Disk Image manipulation tool
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#include "xtchain.h"
static RESERVED_SECTOR_INFO Fat32ReservedMap[] =
{
{0, "Main VBR"},
{1, "FSInfo Sector"},
{6, "Backup VBR"},
{7, "Backup FSInfo Sector"},
{-1, NULL}
};
/* Forward references */
static void CopyData(const char *Image, long Offset, const char *SourceDir, const char *Relative);
static void CopyImageFile(const char *Image, long Offset, const char *SourceFile, const char *Relative);
static long DetermineExtraSector(long sectors_to_write);
long GetSectorFileSize(const char *FileName);
int LoadSectors(const char *FileName, uint8_t *Buffer, int SectorCount);
static void MakeDirectory(const char *Image, long Offset, const char *Relative);
/* Copies a directory recursively to the image */
static void CopyData(const char *Image, long Offset, const char *SourceDir, const char *Relative)
{
char Path[2048];
struct dirent *Entry;
DIR *Directory;
struct stat Stat;
char new_rel[2048];
/* Create the directory in the image */
if(Relative[0] != '\0')
{
MakeDirectory(Image, Offset, Relative);
}
/* Open the source directory */
Directory = opendir(SourceDir);
if(!Directory)
{
/* Failed to open directory */
perror("Failed to open source directory");
return;
}
/* Read all entries in the directory */
while((Entry = readdir(Directory)))
{
/* Skip . and .. entries */
if(strcmp(Entry->d_name, ".") == 0 || strcmp(Entry->d_name, "..") == 0)
{
continue;
}
/* Build the full path to the entry */
snprintf(Path, sizeof(Path), "%s%c%s", SourceDir, PATH_SEP, Entry->d_name);
/* Stat the entry */
if(stat(Path, &Stat) == -1)
{
/* Failed to stat entry */
perror("Failed to stat file or directory");
continue;
}
/* Build the relative path to the entry */
if(Relative[0] != '\0')
{
snprintf(new_rel, sizeof(new_rel), "%s/%s", Relative, Entry->d_name);
}
else
{
snprintf(new_rel, sizeof(new_rel), "%s", Entry->d_name);
}
/* Copy the entry to the image */
if(S_ISDIR(Stat.st_mode))
{
/* Entry is a directory, copy it recursively */
CopyData(Image, Offset, Path, new_rel);
}
else if(S_ISREG(Stat.st_mode))
{
/* Entry is a file, copy it */
CopyImageFile(Image, Offset, Path, new_rel);
}
}
/* Close the directory */
closedir(Directory);
}
/* Copies a file to the image */
static void CopyImageFile(const char *Image, long Offset, const char *SourceFile, const char *Relative)
{
char Command[4096];
/* Copy the file to the image */
snprintf(Command, sizeof(Command), "mcopy -i \"%s@@%ld\" \"%s\" \"::/%s\"", Image, Offset, SourceFile, Relative);
if(system(Command) != 0)
{
/* Failed to copy file */
fprintf(stderr, "Faile to copy file '%s' to image\n", SourceFile);
}
}
/* Determines a safe sector to write extra VBR data to */
static long DetermineExtraSector(long sectors_to_write)
{
long Candidate;
long Conflict;
long Index;
long LastSector;
/* Start search from sector 1 (sector 0 is the main VBR) */
for(Candidate = 1; Candidate < 32; Candidate++)
{
/* Calculate the last sector to write */
LastSector = Candidate + sectors_to_write - 1;
Conflict = 0;
/* Check if it fits within the reserved region (32 sectors) */
if(LastSector >= 32)
{
/* The remaining space is not large enough */
break;
}
/* Check for conflicts with critical sectors */
for(Index = 0; Fat32ReservedMap[Index].SectorNumber != -1; Index++)
{
if(Candidate <= Fat32ReservedMap[Index].SectorNumber && LastSector >= Fat32ReservedMap[Index].SectorNumber)
{
/* Found a conflict */
Conflict = 1;
break;
}
}
/* Make sure there are no conflicts */
if(!Conflict)
{
/* Found a suitable slot */
return Candidate;
}
}
/* No suitable slot found */
return -1;
}
/* Gets the size of a file */
long GetSectorFileSize(const char *FileName)
{
FILE *File;
long Size;
/* Open the file in binary mode */
File = fopen(FileName, "rb");
if(!File)
{
/* Failed to open file */
perror("Failed to open file for size check");
return -1;
}
/* Get the file size */
fseek(File, 0, SEEK_END);
Size = ftell(File);
/* Close the file and return the size */
fclose(File);
return Size;
}
/* Loads one or more sectors from a file */
int LoadSectors(const char *FileName, uint8_t *Buffer, int SectorCount)
{
FILE *File;
long FileSize;
long BytesToRead = SectorCount * SECTOR_SIZE;
/* Get and validate file size */
FileSize = GetSectorFileSize(FileName);
if(FileSize < 0)
{
/* Failed to get file size */
perror("Failed to get file size");
return -1;
}
if(FileSize != BytesToRead)
{
fprintf(stderr, "Error: file '%s' must be exactly %ld bytes, but is %ld bytes.\n", FileName, BytesToRead, FileSize);
return -1;
}
/* Open the file in binary mode for reading */
File = fopen(FileName, "rb");
if(!File) {
/* Failed to open file */
perror("Failed to open sector file for reading");
return -1;
}
/* Read sectors to buffer */
if(fread(Buffer, 1, BytesToRead, File) != BytesToRead)
{
/* Failed to read sectors */
perror("Failed to read sectors from file");
fclose(File);
return -1;
}
/* Close the file */
fclose(File);
return 0;
}
/* Creates a directory in the image */
static void MakeDirectory(const char *Image, long Offset, const char *Relative)
{
char Command[4096];
/* Create the directory in the image */
snprintf(Command, sizeof(Command), "mmd -i \"%s@@%ld\" \"::/%s\"", Image, Offset, Relative);
system(Command);
}
/* Main function */
int main(int argc, char **argv)
{
FILE *File;
long Index;
long FatFormat = 32;
char FormatCommand[512];
long FormatPartition = 0;
long DiskSizeBytes = 0;
long DiskSizeMB = 0;
long SectorsToWrite = 0;
long VbrExtraSector = -1;
long VbrFileSize = -1;
long VbrTotalSectors = 0;
long VbrLastSector = 99;
char VbrInfo[128] = "";
MBR_PARTITION Partition = {0};
char Zero[SECTOR_SIZE] = {0};
uint8_t Mbr[SECTOR_SIZE] = {0};
uint8_t ImageVbr[SECTOR_SIZE * 2] = {0};
uint8_t *FullVbr = NULL;
const char *FileName = NULL;
const char *MbrFile = NULL;
const char *VbrFile = NULL;
const char *CopyDir = NULL;
/* Parse command line arguments */
for(Index = 1; Index < argc; Index++)
{
if(strcmp(argv[Index], "-c") == 0 && Index + 1 < argc)
{
/* Copy directory */
CopyDir = argv[++Index];
}
else if(strcmp(argv[Index], "-e") == 0 && Index + 1 < argc)
{
/* VBR extra data sector */
VbrExtraSector = atol(argv[++Index]);
}
else if(strcmp(argv[Index], "-f") == 0 && Index + 1 < argc)
{
/* Format partition */
FormatPartition = 1;
FatFormat = atoi(argv[++Index]);
if(FatFormat != 16 && FatFormat != 32)
{
fprintf(stderr, "Error: FAT format (-f) must be 16 or 32\n");
return 1;
}
}
else if(strcmp(argv[Index], "-m") == 0 && Index + 1 < argc)
{
/* MBR file */
MbrFile = argv[++Index];
}
else if(strcmp(argv[Index], "-o") == 0 && Index + 1 < argc)
{
/* Output file */
FileName = argv[++Index];
}
else if(strcmp(argv[Index], "-s") == 0 && Index + 1 < argc)
{
/* Disk size */
DiskSizeMB = atol(argv[++Index]);
}
else if(strcmp(argv[Index], "-v") == 0 && Index + 1 < argc)
{
/* VBR file */
VbrFile = argv[++Index];
}
else
{
/* Unknown argument */
fprintf(stderr, "Unknown argument: %s\n", argv[Index]);
return 1;
}
}
/* Check for required arguments */
if(DiskSizeMB <= 0 || FileName == NULL)
{
/* Missing required arguments, print usage */
fprintf(stderr, "Usage: %s -o <output.img> -s <size_MB> [-b <sector>] [-c <dir>] [-f 16|32] [-m <mbr.img>] [-v <vbr.img>]\n", argv[0]);
return 1;
}
/* Calculate disk size in bytes */
DiskSizeBytes = DiskSizeMB * 1024 * 1024;
/* Open the output file in binary mode */
File = fopen(FileName, "wb");
if(!File) {
/* Failed to open file */
perror("Failed to open disk image file");
return 1;
}
/* Write zeros to the disk image file */
for(Index = 0; Index < DiskSizeBytes / SECTOR_SIZE; Index++)
{
if(fwrite(Zero, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
{
/* Failed to write to disk image file */
perror("Failed to write to disk image file");
fclose(File);
return 1;
}
}
/* Load MBR if provided */
if(MbrFile)
{
if(LoadSectors(MbrFile, Mbr, 1) != 0)
{
/* Failed to load MBR from file */
perror("Failed to load MBR from file");
fclose(File);
return 1;
}
}
/* Setup MBR partition as W95 FAT16 or FAT32 */
Partition.BootFlag = 0x80;
Partition.Type = (FatFormat == 16) ? 0x06 : 0x0B;
Partition.StartLBA = 2048;
Partition.Size = (DiskSizeBytes / SECTOR_SIZE) - Partition.StartLBA;
/* Write MBR */
memcpy(&Mbr[446], &Partition, sizeof(MBR_PARTITION));
Mbr[510] = 0x55;
Mbr[511] = 0xAA;
/* Write the MBR to the beginning of the disk image */
fseek(File, 0, SEEK_SET);
if(fwrite(Mbr, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
{
/* Failed to write MBR to disk image */
perror("Failed to write MBR to disk image");
fclose(File);
return 1;
}
/* Check if we need to format the partition */
if(FormatPartition)
{
/* Close file before calling external formatter */
fclose(File);
/* Build mformat command */
if(FatFormat == 16)
{
/* Format partition as FAT16 */
snprintf(FormatCommand, sizeof(FormatCommand),
"mformat -i %s@@%ld",
FileName, (long)(Partition.StartLBA * SECTOR_SIZE));
}
else
{
/* Format partition as FAT32 */
snprintf(FormatCommand, sizeof(FormatCommand),
"mformat -i %s@@%ld -F",
FileName, (long)(Partition.StartLBA * SECTOR_SIZE));
}
/* Format the partition */
if(system(FormatCommand) != 0)
{
/* Failed to format partition */
perror("Failed to format partition");
return 1;
}
/* Reopen disk image */
File = fopen(FileName, "r+b");
if(!File) {
/* Failed to open file */
perror("Failed to reopen disk image");
return 1;
}
/* Read the VBR created by mformat */
fseek(File, Partition.StartLBA * SECTOR_SIZE, SEEK_SET);
if(fread(ImageVbr, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
{
/* Failed to read VBR */
perror("Failed to read VBR from disk image");
fclose(File);
return 1;
}
/* Set the number of hidden sectors, as mformat sets it to 0 */
if(*(uint32_t*)&ImageVbr[0x1C] == 0)
{
memcpy(&ImageVbr[0x1C], &Partition.StartLBA, sizeof(uint32_t));
}
/* Check FAT format */
if(FatFormat == 32)
{
/* For FAT32, TotalSectors32 must be set */
*(uint16_t*)&ImageVbr[0x13] = 0;
if(*(uint32_t*)&ImageVbr[0x20] == 0)
{
/* Mformat did not set the field, update it */
memcpy(&ImageVbr[0x20], &Partition.Size, sizeof(uint32_t));
}
}
else
{
/* For FAT16, check if parition size exceeds 65535 sectors */
if(Partition.Size < 65536)
{
/* Partition smaller than 32MB (65536 sectors), use 16-bit field TotalSectors16 */
if(*(uint16_t*)&ImageVbr[0x13] == 0)
{
/* Mformat did not set the field, update it */
memcpy(&ImageVbr[0x13], &((uint16_t){Partition.Size}), sizeof(uint16_t));
}
}
else
{
/* Partition larger than 32MB (65536 sectors), use 32-bit field TotalSectors32 */
*(uint16_t*)&ImageVbr[0x13] = 0;
if(*(uint32_t*)&ImageVbr[0x20] == 0)
{
/* Mformat did not set the field, update it */
memcpy(&ImageVbr[0x20], &Partition.Size, sizeof(uint32_t));
}
}
}
/* Set DriveNumber to emulate hard disk */
ImageVbr[0x40] = 0x80;
/* Write the corrected VBR back to the disk image */
fseek(File, Partition.StartLBA * SECTOR_SIZE, SEEK_SET);
if(fwrite(ImageVbr, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
{
/* Failed to write VBR */
perror("Failed to write VBR to disk image");
fclose(File);
return 1;
}
}
/* Write VBR to the start of the partition, if provided */
if(VbrFile)
{
VbrFileSize = GetSectorFileSize(VbrFile);
if(VbrFileSize < 0)
{
/* The GetFileSize function already prints a perror message */
perror("Could not get size of VBR file\n");
return 1;
}
/* Check if VBR file size is a multiple of sector size */
if(VbrFileSize % SECTOR_SIZE != 0)
{
/* Unable to determine VBR file size */
perror("Failed to determine VBR file size");
return 1;
}
VbrTotalSectors = VbrFileSize / SECTOR_SIZE;
/* Allocate memory for the entire VBR file */
FullVbr = malloc(VbrFileSize);
if(!FullVbr)
{
/* Memory allocation failed */
perror("Failed to allocate memory for VBR file");
return 1;
}
/* Read the entire VBR file into the buffer */
if(LoadSectors(VbrFile, FullVbr, VbrTotalSectors) != 0)
{
/* Failed to load VBR from file */
perror("Failed to load VBR from file");
free(FullVbr);
return 1;
}
/* Read the existing VBR from the formatted partition to get the correct BPB */
fseek(File, Partition.StartLBA * SECTOR_SIZE, SEEK_SET);
if(fread(ImageVbr, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
{
/* Failed to read VBR from disk image */
perror("Failed to read BPB from disk image");
free(FullVbr);
fclose(File);
return 1;
}
/* Copy the BPB from the image's VBR to VBR buffer */
if(FatFormat == 32)
{
/* For FAT32, BPB is larger (up to offset 89) */
memcpy(&FullVbr[3], &ImageVbr[3], 87);
}
else
{
/* For FAT16, BPB is smaller (up to offset 61) */
memcpy(&FullVbr[3], &ImageVbr[3], 59);
}
/* Write the first 512 bytes of the final, merged VBR to the start of the partition */
fseek(File, Partition.StartLBA * SECTOR_SIZE, SEEK_SET);
if(fwrite(FullVbr, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
{
/* Failed to write VBR to disk image */
perror("Failed to write VBR to disk image");
free(FullVbr);
fclose(File);
return 1;
}
/* Handle extra VBR data if it exists */
if(FatFormat == 32)
{
/* Check if there is extra VBR data to write */
if(VbrTotalSectors > 1)
{
/* Check if extra sector has been provided by the user */
if(VbrExtraSector == -1)
{
/* Determine a safe sector to write extra VBR data to */
long sectors_to_write = VbrTotalSectors - 1;
VbrExtraSector = DetermineExtraSector(sectors_to_write);
if(VbrExtraSector == -1)
{
/* Failed to find a safe sector */
fprintf(stderr, "Error: Could not automatically find a safe space in the FAT32 reserved region for %ld extra VBR sectors.\n",
sectors_to_write);
free(FullVbr);
return 1;
}
}
/* Calculate number of sectors and last sector to write */
SectorsToWrite = VbrTotalSectors - 1;
VbrLastSector = VbrExtraSector + SectorsToWrite - 1;
/* Ensure VBR will not be writen outside the reserved region (32 sectors for FAT32) */
if(VbrLastSector >= 32)
{
/* The remaining space is not large enough to fit the extra VBR data */
fprintf(stderr, "Error: VBR file is too large. Writing to sector %ld would exceed the FAT32 reserved region (32 sectors).\n", VbrLastSector);
free(FullVbr);
return 1;
}
/* Safety check: ensure we do not overwrite critical sectors */
for(Index = 0; Fat32ReservedMap[Index].SectorNumber != -1; Index++)
{
/* Check if we are about to overwrite a critical sector */
if(VbrExtraSector <= Fat32ReservedMap[Index].SectorNumber && VbrLastSector >= Fat32ReservedMap[Index].SectorNumber)
{
/* We are about to overwrite a critical sector */
fprintf(stderr, "Error: Writing VBR extra data would overwrite critical sector %d (%s).\n",
Fat32ReservedMap[Index].SectorNumber, Fat32ReservedMap[Index].Description);
free(FullVbr);
return 1;
}
}
/* Write the rest of the VBR data */
fseek(File, (Partition.StartLBA + VbrExtraSector) * SECTOR_SIZE, SEEK_SET);
if(fwrite(FullVbr + SECTOR_SIZE, 1, SectorsToWrite * SECTOR_SIZE, File) != (size_t)(SectorsToWrite * SECTOR_SIZE))
{
/* Failed to write extra VBR data to disk image */
perror("Failed to write extra VBR data to disk image");
free(FullVbr);
fclose(File);
return 1;
}
}
}
else /* FatFormat == 16 */
{
/* Check if there is extra VBR data to write */
if(VbrTotalSectors > 1)
{
/* FAT16 only supports a 1-sector VBR */
fprintf(stderr, "Error: VBR file is %ld sectors, but FAT16 only supports a 1-sector VBR.\n", VbrTotalSectors);
free(FullVbr);
return 1;
}
}
/* Free allocated memory */
free(FullVbr);
}
/* Close file */
fclose(File);
/* Copy files if requested */
if(CopyDir)
{
CopyData(FileName, (long)(Partition.StartLBA * SECTOR_SIZE), CopyDir, "");
}
/* Check if VBR was written */
if(VbrFile)
{
/* Compose VBR info string */
if(VbrExtraSector != -1)
{
/* VBR with extra data */
snprintf(VbrInfo, sizeof(VbrInfo), ", VBR written (extra data at sector %ld)", VbrExtraSector);
}
else
{
/* Standard VBR */
snprintf(VbrInfo, sizeof(VbrInfo), ", VBR written");
}
}
/* Print success message */
printf("Successfully created disk image '%s' (%ld MB) with bootable W95 FAT-%ld partition%s%s%s.\n",
FileName,
DiskSizeMB,
FatFormat,
MbrFile ? ", MBR written" : "",
VbrInfo,
CopyDir ? ", files copied" : "");
return 0;
}

View File

@@ -167,7 +167,7 @@ int main(int argc, char *argv[])
fread(&SubSystem, sizeof(unsigned short), 1, ExeFile);
/* Seek back to the SubSystem field in the optional header */
fseek(ExeFile, -sizeof(unsigned short), SEEK_CUR);
fseek(ExeFile, -(long)sizeof(unsigned short), SEEK_CUR);
/* Write the new SubSystem value */
fwrite(&NewSubSystem->Identifier, sizeof(unsigned short), 1, ExeFile);

View File

@@ -7,12 +7,40 @@
* Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <dirent.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#define _T(x) x
#ifdef _WIN32
#include <windows.h>
#define PATH_SEP '\\'
#else
#define PATH_SEP '/'
#endif
#define SECTOR_SIZE 512
#define _T(x) x
typedef struct MBR_PARTITION {
uint8_t BootFlag; // 0x80 = bootable, 0x00 = non-boot
uint8_t StartCHS [3]; // CHS address
uint8_t Type; // Partition type
uint8_t EndCHS[3]; // CHS address
uint32_t StartLBA; // Start sector
uint32_t Size; // Sectors count
} MBR_PARTITION, *PMBR_PARTITION;
typedef struct _RESERVED_SECTOR_INFO
{
int SectorNumber;
const char* Description;
} RESERVED_SECTOR_INFO, *PRESERVED_SECTOR_INFO;
static
inline
@@ -52,17 +80,17 @@ split_argv(const char *argv0,
char **exe_ptr)
{
const char *sep = _tcsrchrs(argv0, '/', '\\');
const char *basename_ptr_const = argv0;
char *dir = strdup(_T(""));
const char *basename = argv0;
if(sep)
{
dir = strdup(argv0);
dir[sep + 1 - argv0] = '\0';
basename = sep + 1;
basename_ptr_const = sep + 1;
}
basename = strdup(basename);
char *basename = strdup(basename_ptr_const);
char *period = strchr(basename, '.');
if(period)
@@ -72,7 +100,7 @@ split_argv(const char *argv0,
char *target = strdup(basename);
char *dash = strrchr(target, '-');
const char *exe = basename;
char *exe = basename;
if(dash)
{

View File

@@ -14,9 +14,8 @@
#include "xtchain.h"
#define XTCSPECC_VERSION "1.2"
#define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0]))
#define XTCSPECC_VERSION "1.2"
typedef struct _STRING
{
@@ -77,12 +76,12 @@ enum
enum
{
CC_STDCALL,
CC_CDECL,
CC_FASTCALL,
CC_THISCALL,
CC_EXTERN,
CC_STUB,
CCONV_STDCALL,
CCONV_CDECL,
CCONV_FASTCALL,
CCONV_THISCALL,
CCONV_EXTERN,
CCONV_STUB,
};
enum
@@ -257,11 +256,11 @@ OutputLine_stub(FILE *file,
int bRelay = 0;
int bInPrototype = 0;
if(pexp->nCallingConvention != CC_STUB &&
if(pexp->nCallingConvention != CCONV_STUB &&
(pexp->uFlags & FL_STUB) == 0)
{
/* Only relay trace stdcall C functions */
if(!gbTracing || (pexp->nCallingConvention != CC_STDCALL) ||
if(!gbTracing || (pexp->nCallingConvention != CCONV_STDCALL) ||
(pexp->uFlags & FL_NORELAY) ||
(pexp->strName.buf[0] == '?'))
{
@@ -294,7 +293,7 @@ OutputLine_stub(FILE *file,
}
if((giArch == ARCH_X86) &&
pexp->nCallingConvention == CC_STDCALL)
pexp->nCallingConvention == CCONV_STDCALL)
{
fprintf(file, "__stdcall ");
}
@@ -398,7 +397,7 @@ OutputLine_stub(FILE *file,
}
fprintf(file, ");\n");
if(pexp->nCallingConvention == CC_STUB)
if(pexp->nCallingConvention == CCONV_STUB)
{
fprintf(file, "\t__wine_spec_unimplemented_stub(\"%s\", __FUNCTION__);\n", pszDllName);
}
@@ -510,8 +509,8 @@ PrintName(FILE *fileDest,
fprintf(fileDest, "%.*s", nNameLength, pcName);
}
else if(fDeco &&
((pexp->nCallingConvention == CC_STDCALL) ||
(pexp->nCallingConvention == CC_FASTCALL)))
((pexp->nCallingConvention == CCONV_STDCALL) ||
(pexp->nCallingConvention == CCONV_FASTCALL)))
{
/* Scan for a dll forwarding dot */
pcDot = ScanToken(pcName, '.');
@@ -536,9 +535,9 @@ PrintName(FILE *fileDest,
else
{
/* Print the prefix, but skip it for stdcall */
if(pexp->nCallingConvention != CC_STDCALL)
if(pexp->nCallingConvention != CCONV_STDCALL)
{
fprintf(fileDest, "%c", pexp->nCallingConvention == CC_FASTCALL ? '@' : '_');
fprintf(fileDest, "%c", pexp->nCallingConvention == CCONV_FASTCALL ? '@' : '_');
}
/* Print the name with trailing decoration */
@@ -581,8 +580,8 @@ OutputLine_def(FILE *fileDest,
/* If the original name was decorated, use decoration in the forwarder as well */
if((giArch == ARCH_X86) && ScanToken(pexp->strName.buf, '@') &&
!ScanToken(pexp->strTarget.buf, '@') &&
((pexp->nCallingConvention == CC_STDCALL) ||
(pexp->nCallingConvention == CC_FASTCALL)) )
((pexp->nCallingConvention == CCONV_STDCALL) ||
(pexp->nCallingConvention == CCONV_FASTCALL)) )
{
PrintName(fileDest, pexp, &pexp->strTarget, 1);
}
@@ -593,13 +592,13 @@ OutputLine_def(FILE *fileDest,
}
}
}
else if(((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
else if(((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CCONV_STUB)) &&
(pexp->strName.buf[0] == '?'))
{
/* C++ stubs are forwarded to C stubs */
fprintf(fileDest, "=stub_function%d", pexp->nNumber);
}
else if(gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) && (pexp->nCallingConvention == CC_STDCALL) &&
else if(gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) && (pexp->nCallingConvention == CCONV_STDCALL) &&
(pexp->strName.buf[0] != '?'))
{
/* Redirect it to the relay-tracing trampoline */
@@ -616,7 +615,7 @@ OutputLine_def(FILE *fileDest,
{
fprintf(fileDest, " PRIVATE");
}
else if(pexp->nCallingConvention == CC_EXTERN)
else if(pexp->nCallingConvention == CCONV_EXTERN)
{
fprintf(fileDest, " DATA");
}
@@ -798,28 +797,28 @@ ParseFile(char* pcStart,
/* Now we should get the type */
if(CompareToken(pc, "stdcall"))
{
exp.nCallingConvention = CC_STDCALL;
exp.nCallingConvention = CCONV_STDCALL;
}
else if(CompareToken(pc, "cdecl") ||
CompareToken(pc, "varargs"))
{
exp.nCallingConvention = CC_CDECL;
exp.nCallingConvention = CCONV_CDECL;
}
else if(CompareToken(pc, "fastcall"))
{
exp.nCallingConvention = CC_FASTCALL;
exp.nCallingConvention = CCONV_FASTCALL;
}
else if(CompareToken(pc, "thiscall"))
{
exp.nCallingConvention = CC_THISCALL;
exp.nCallingConvention = CCONV_THISCALL;
}
else if(CompareToken(pc, "extern"))
{
exp.nCallingConvention = CC_EXTERN;
exp.nCallingConvention = CCONV_EXTERN;
}
else if(CompareToken(pc, "stub"))
{
exp.nCallingConvention = CC_STUB;
exp.nCallingConvention = CCONV_STUB;
}
else
{
@@ -986,8 +985,8 @@ ParseFile(char* pcStart,
/* Handle parameters */
exp.nStackBytes = 0;
if(exp.nCallingConvention != CC_EXTERN &&
exp.nCallingConvention != CC_STUB)
if(exp.nCallingConvention != CCONV_EXTERN &&
exp.nCallingConvention != CCONV_STUB)
{
/* Go to next token */
if(!(pc = NextToken(pc)))
@@ -1069,7 +1068,7 @@ ParseFile(char* pcStart,
}
/* Handle special stub cases */
if(exp.nCallingConvention == CC_STUB)
if(exp.nCallingConvention == CCONV_STUB)
{
/* Check for c++ mangled name */
if(pc[0] == '?')
@@ -1093,7 +1092,7 @@ ParseFile(char* pcStart,
}
exp.nStackBytes = atoi(p + 1);
exp.nArgCount = exp.nStackBytes / 4;
exp.nCallingConvention = CC_STDCALL;
exp.nCallingConvention = CCONV_STDCALL;
exp.uFlags |= FL_STUB;
for(i = 0; i < exp.nArgCount; i++)
{