1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-07-04 23:36:00 +02:00

Bug fixes, installer, [Export]

Fixed a bunch of bugs in aggregate const initializers
Fixed ZIP bugs
Fixed a compilation case where we change protection while reifying a type
Added another project kind - Dynamic Library
Added [Export] for DLL method exporting
Fixed some issues of things being  generated as __NOINLINE incorrectly
Fixed an issue with module extensions with not-yet-demanded on-demand methods
Started adding Installer
This commit is contained in:
Brian Fiete 2019-08-27 08:04:41 -07:00
parent efa22e51fb
commit 09016c8dc0
135 changed files with 3615 additions and 2337 deletions

View file

@ -0,0 +1,25 @@
FileVersion = 1
[Project]
Name = "Stub"
StartupObject = "BIStub.Program"
[Configs.Debug.Win64]
TargetDirectory = "$(WorkspaceDir)/../dist"
TargetName = "$(ProjectName)_d"
BeefLibType = "Static"
[Configs.Release.Win64]
TargetDirectory = "$(WorkspaceDir)/../dist"
[Configs.Paranoid.Win64]
TargetDirectory = "$(WorkspaceDir)/../dist"
[Configs.Test.Win64]
TargetDirectory = "$(WorkspaceDir)/../dist"
[ProjectFolder]
[[ProjectFolder.Items]]
Type = "Source"
Path = "../../../IDE/src/util/Zip.bf"

View file

@ -0,0 +1,11 @@
FileVersion = 1
Projects = {Stub = {Path = "."}}
Unlocked = ["corlib"]
[Workspace]
StartupProject = "Stub"
[Configs.Debug.Win64]
AllocType = "CRT"
EnableObjectDebugFlags = false
IntermediateType = "ObjectAndIRCode"

View file

@ -0,0 +1,278 @@
using System;
using System.IO;
namespace System.Windows
{
class CabFile
{
struct HFDI : int
{
}
struct HFile : int
{
}
enum FDIERROR : int32
{
FDIERROR_NONE,
FDIERROR_CABINET_NOT_FOUND,
FDIERROR_NOT_A_CABINET,
FDIERROR_UNKNOWN_CABINET_VERSION,
FDIERROR_CORRUPT_CABINET,
FDIERROR_ALLOC_FAIL,
FDIERROR_BAD_COMPR_TYPE,
FDIERROR_MDI_FAIL,
FDIERROR_TARGET_FILE,
FDIERROR_RESERVE_MISMATCH,
FDIERROR_WRONG_CABINET,
FDIERROR_USER_ABORT,
FDIERROR_EOF,
}
[CRepr]
struct FDICABINETINFO
{
public int32 cbCabinet; // Total length of cabinet file
public uint16 cFolders; // Count of folders in cabinet
public uint16 cFiles; // Count of files in cabinet
public uint16 setID; // Cabinet set ID
public uint16 iCabinet; // Cabinet number in set (0 based)
public Windows.IntBool fReserve; // TRUE => RESERVE present in cabinet
public Windows.IntBool hasprev; // TRUE => Cabinet is chained prev
public Windows.IntBool hasnext; // TRUE => Cabinet is chained next
}
[CRepr]
struct FDINOTIFICATION
{
public int32 cb;
public char8* psz1;
public char8* psz2;
public char8* psz3; // Points to a 256 character buffer
public void* pv; // Value for client
public HFile hf;
public uint16 date;
public uint16 time;
public uint16 attribs;
public uint16 setID; // Cabinet set ID
public uint16 iCabinet; // Cabinet number (0-based)
public uint16 iFolder; // Folder number (0-based)
public FDIERROR fdie;
}
enum NotificationType : int32
{
CABINET_INFO, // General information about cabinet
PARTIAL_FILE, // First file in cabinet is continuation
COPY_FILE, // File to be copied
CLOSE_FILE_INFO, // close the file, set relevant info
NEXT_CABINET, // File continued to next cabinet
ENUMERATE, // Enumeration status
}
struct ERF
{
public int32 erfOper; // FCI/FDI error code -- see FDIERROR_XXX
// and FCIERR_XXX equates for details.
public int32 erfType; // Optional error value filled in by FCI/FDI.
// For FCI, this is usually the C run-time
// *errno* value.
public Windows.IntBool fError; // TRUE => error present
}
enum FDIDECRYPTTYPE : int32
{
NEW_CABINET, // New cabinet
NEW_FOLDER, // New folder
DECRYPT, // Decrypt a data block
}
[CRepr]
struct FDIDECRYPT
{
public FDIDECRYPTTYPE fdidt; // Command type (selects union below)
public void* pvUser; // Decryption context
}
[CRepr]
struct FDIDECRYPT_CABINET : FDIDECRYPT
{
public void* pHeaderReserve; // RESERVE section from CFHEADER
public uint16 cbHeaderReserve; // Size of pHeaderReserve
public uint16 setID; // Cabinet set ID
public int32 iCabinet; // Cabinet number in set (0 based)
}
[CRepr]
struct FDIDECRYPT_FOLDER : FDIDECRYPT
{
public void* pFolderReserve; // RESERVE section from CFFOLDER
public uint16 cbFolderReserve; // Size of pFolderReserve
public uint16 iFolder; // Folder number in cabinet (0 based)
}
[CRepr]
struct FDIDECRYPT_DECRYPT : FDIDECRYPT
{
public void* pDataReserve; // RESERVE section from CFDATA
public uint16 cbDataReserve; // Size of pDataReserve
public void* pbData; // Data buffer
public uint16 cbData; // Size of data buffer
public Windows.IntBool fSplit; // TRUE if this is a split data block
public uint16 cbPartial; // 0 if this is not a split block, or
// the first piece of a split block;
// Greater than 0 if this is the
// second piece of a split block.
}
function void* FNALLOC(uint32 cb);
function void FNFREE(void* p);
function HFile FNOPEN(char8* fileName, int32 oflag, int32 pmode);
function uint32 FNREAD(HFile file, void* pv, uint32 cb);
function uint32 FNWRITE(HFile file, void* pv, uint32 cb);
function int32 FNCLOSE(HFile file);
function int32 FNSEEK(HFile file, int32 dist, int32 seekType);
function int FNFDINOTIFY(NotificationType notifyType, FDINOTIFICATION* notifyData);
function int32 FNFDIDECRYPT(FDIDECRYPT* fdid);
static void* CabMemAlloc(uint32 cb)
{
return new uint8[cb]*;
}
static void CabMemFree(void* p)
{
delete p;
}
static HFile CabFileOpen(char8* fileName, int32 oflag, int32 pmode)
{
String fileNameStr = scope .(fileName);
Windows.Handle fh;
if (oflag & 0x0100 != 0)
{
// Creating
fh = Windows.CreateFileW(fileNameStr.ToScopedNativeWChar!(), Windows.GENERIC_READ | Windows.GENERIC_WRITE, .Read | .Write, null, .Create, 0, .NullHandle);
}
else
{
// Reading
fh = Windows.CreateFileW(fileNameStr.ToScopedNativeWChar!(), Windows.GENERIC_READ, .Read | .Write, null, .Open, 0, .NullHandle);
}
return (.)fh;
}
static uint32 CabFileRead(HFile file, void* pv, uint32 cb)
{
Windows.ReadFile((.)file, (.)pv, (.)cb, var bytesRead, null);
return (.)bytesRead;
}
static uint32 CabFileWrite(HFile file, void* pv, uint32 cb)
{
Windows.WriteFile((.)file, (.)pv, (.)cb, var bytesWritten, null);
return (.)bytesWritten;
}
static int32 CabFileClose(HFile file)
{
((Windows.Handle)file).Close();
return 0;
}
static int32 CabFileSeek(HFile file, int32 dist, int32 seekType)
{
return Windows.SetFilePointer((.)file, dist, null, seekType);
}
static int CabFDINotify(NotificationType notifyType, FDINOTIFICATION* notifyData)
{
if (notifyType == .COPY_FILE)
{
String destFileName = scope .();
destFileName.Append(@"c:\temp\out\");
destFileName.Append(notifyData.psz1);
//_O_BINARY | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL
//_S_IREAD | _S_IWRITE
String dirPath = scope String();
Path.GetDirectoryPath(destFileName, dirPath);
Directory.CreateDirectory(dirPath).IgnoreError();
let hOutFile = CabFileOpen(destFileName, 0x8121, 0x0180);
return (.)hOutFile;
}
else if (notifyType == .CLOSE_FILE_INFO)
{
CabFileClose(notifyData.hf);
return 1;
}
return 0;
}
[Import("Cabinet.lib"), CLink]
static extern HFDI FDICreate(FNALLOC pfnalloc,
FNFREE pfnfree,
FNOPEN pfnopen,
FNREAD pfnread,
FNWRITE pfnwrite,
FNCLOSE pfnclose,
FNSEEK pfnseek,
int32 cpuType,
ERF* erf);
[CLink]
static extern Windows.IntBool FDIDestroy(HFDI hfdi);
[CLink]
static extern Windows.IntBool FDICopy(HFDI hfdi,
char8* pszCabinet,
char8* pszCabPath,
int32 flags,
FNFDINOTIFY fnfdin,
FNFDIDECRYPT pfnfdid,
void* pvUser);
HFDI mHDFI;
public ~this()
{
if (mHDFI != 0)
{
FDIDestroy(mHDFI);
}
}
public void Init()
{
ERF erf;
mHDFI = FDICreate(=> CabMemAlloc,
=> CabMemFree,
=> CabFileOpen,
=> CabFileRead,
=> CabFileWrite,
=> CabFileClose,
=> CabFileSeek,
1 /*cpu80386*/,
&erf);
}
public void Copy()
{
FDICopy(mHDFI, "test.cab", "c:\\temp\\", 0, => CabFDINotify, null, Internal.UnsafeCastToPtr(this));
}
}
}

View file

@ -0,0 +1,236 @@
using System;
namespace System.Windows
{
class PEFile
{
public const uint16 PE_MACHINE_X86 = 0x14c;
public const uint16 PE_MACHINE_X64 = 0x8664;
[CRepr]
public struct PEHeader
{
public uint16 e_magic; // Magic number
public uint16 e_cblp; // uint8s on last page of file
public uint16 e_cp; // Pages in file
public uint16 e_crlc; // Relocations
public uint16 e_cparhdr; // Size of header in paragraphs
public uint16 e_minalloc; // Minimum extra paragraphs needed
public uint16 e_maxalloc; // Maximum extra paragraphs needed
public uint16 e_ss; // Initial (relative) SS value
public uint16 e_sp; // Initial SP value
public uint16 e_csum; // Checksum
public uint16 e_ip; // Initial IP value
public uint16 e_cs; // Initial (relative) CS value
public uint16 e_lfarlc; // File address of relocation table
public uint16 e_ovno; // Overlay number
public uint16[4] e_res; // Reserved uint16s
public uint16 e_oemid; // OEM identifier (for e_oeminfo)
public uint16 e_oeminfo; // OEM information; e_oemid specific
public uint16[10] e_res2; // Reserved uint16s
public int32 e_lfanew; // File address of new exe header
};
[CRepr]
public struct PEFileHeader
{
public uint16 mMachine;
public uint16 mNumberOfSections;
public uint32 mTimeDateStamp;
public uint32 mPointerToSymbolTable;
public uint32 mNumberOfSymbols;
public uint16 mSizeOfOptionalHeader;
public uint16 mCharacteristics;
};
[CRepr]
public struct PEImportObjectHeader
{
public uint16 mSig1;
public uint16 mSig2;
public uint16 mVersion;
public uint16 mMachine;
public uint32 mTimeDateStamp;
public uint32 mDataSize;
public uint16 mHint;
public uint16 mType;
};
[CRepr]
public struct PEDataDirectory
{
public uint32 mVirtualAddress;
public uint32 mSize;
};
[CRepr]
public struct PEOptionalHeader32
{
//
// Standard fields.
//
public uint16 mMagic;
public uint8 mMajorLinkerVersion;
public uint8 mMinorLinkerVersion;
public uint32 mSizeOfCode;
public uint32 mSizeOfInitializedData;
public uint32 mSizeOfUninitializedData;
public uint32 mAddressOfEntryPoint;
public uint32 mBaseOfCode;
public uint32 mBaseOfData;
//
// NT additional fields.
//
public uint32 mImageBase;
public uint32 mSectionAlignment;
public uint32 mFileAlignment;
public uint16 mMajorOperatingSystemVersion;
public uint16 mMinorOperatingSystemVersion;
public uint16 mMajorImageVersion;
public uint16 mMinorImageVersion;
public uint16 mMajorSubsystemVersion;
public uint16 mMinorSubsystemVersion;
public uint32 mReserved1;
public uint32 mSizeOfImage;
public uint32 mSizeOfHeaders;
public uint32 mCheckSum;
public uint16 mSubsystem;
public uint16 mDllCharacteristics;
public uint32 mSizeOfStackReserve;
public uint32 mSizeOfStackCommit;
public uint32 mSizeOfHeapReserve;
public uint32 mSizeOfHeapCommit;
public uint32 mLoaderFlags;
public uint32 mNumberOfRvaAndSizes;
public PEDataDirectory[16] mDataDirectory;
};
[CRepr]
public struct PEOptionalHeader64
{
//
// Standard fields.
//
public uint16 mMagic;
public uint8 mMajorLinkerVersion;
public uint8 mMinorLinkerVersion;
public uint32 mSizeOfCode;
public uint32 mSizeOfInitializedData;
public uint32 mSizeOfUninitializedData;
public uint32 mAddressOfEntryPoint;
public uint32 mBaseOfCode;
//
// NT additional fields.
//
public uint64 mImageBase;
public uint32 mSectionAlignment;
public uint32 mFileAlignment;
public uint16 mMajorOperatingSystemVersion;
public uint16 mMinorOperatingSystemVersion;
public uint16 mMajorImageVersion;
public uint16 mMinorImageVersion;
public uint16 mMajorSubsystemVersion;
public uint16 mMinorSubsystemVersion;
public uint32 mReserved1;
public uint32 mSizeOfImage;
public uint32 mSizeOfHeaders;
public uint32 mCheckSum;
public uint16 mSubsystem;
public uint16 mDllCharacteristics;
public uint64 mSizeOfStackReserve;
public uint64 mSizeOfStackCommit;
public uint64 mSizeOfHeapReserve;
public uint64 mSizeOfHeapCommit;
public uint32 mLoaderFlags;
public uint32 mNumberOfRvaAndSizes;
public PEDataDirectory[16] mDataDirectory;
};
[CRepr]
struct PE_NTHeaders32
{
uint32 mSignature;
PEFileHeader mFileHeader;
PEOptionalHeader32 mOptionalHeader;
};
[CRepr]
public struct PE_NTHeaders64
{
public uint32 mSignature;
public PEFileHeader mFileHeader;
public PEOptionalHeader64 mOptionalHeader;
};
const int IMAGE_SIZEOF_SHORT_NAME = 8;
[CRepr]
public struct PESectionHeader
{
public char8[IMAGE_SIZEOF_SHORT_NAME] mName;
public uint32 mVirtualSize;
public uint32 mVirtualAddress;
public uint32 mSizeOfRawData;
public uint32 mPointerToRawData;
public uint32 mPointerToRelocations;
public uint32 mPointerToLineNumbers;
public uint16 mNumberOfRelocations;
public uint16 mNumberOfLineNumbers;
public uint32 mCharacteristics;
};
[CRepr]
struct COFFRelocation
{
uint32 mVirtualAddress;
uint32 mSymbolTableIndex;
uint16 mType;
};
[CRepr]
struct PE_SymInfo
{
[Union]
public struct Name
{
public char8[8] mName;
public int32[2] mNameOfs;
}
public Name mName;
/*union
{
char mName[8];
int32 mNameOfs[2];
};*/
public int32 mValue;
public uint16 mSectionNum;
public uint16 mType;
public int8 mStorageClass;
public int8 mNumOfAuxSymbols;
};
[CRepr]
struct PE_SymInfoAux
{
public uint32 mLength;
public uint16 mNumberOfRelocations;
public uint16 mNumberOfLinenumbers;
public uint32 mCheckSum;
public uint16 mNumber;
public uint8 mSelection;
public char8 mUnused;
public char8 mUnused2;
public char8 mUnused3;
};
}
}

View file

@ -0,0 +1,179 @@
using System;
using IDE.Util;
using System.IO;
using System.Windows;
namespace BIStub
{
class Program
{
bool mFailed;
void Fail(StringView str)
{
if (mFailed)
return;
mFailed = true;
Windows.MessageBoxA(default, scope String..AppendF("ERROR: {}", str), "FATAL ERROR", Windows.MB_ICONHAND);
}
bool HandleCommandLineParam(String key, String value)
{
return false;
}
void UnhandledCommandLine(String key, String value)
{
}
void ParseCommandLine(String[] args)
{
for (var str in args)
{
int eqPos = str.IndexOf('=');
if (eqPos == -1)
{
if (!HandleCommandLineParam(str, null))
UnhandledCommandLine(str, null);
}
else
{
var cmd = scope String(str, 0, eqPos);
var param = scope String(str, eqPos + 1);
if (!HandleCommandLineParam(cmd, param))
UnhandledCommandLine(cmd, param);
}
}
}
Result<void> ExtractTo(ZipFile zipFile, StringView destDir, StringView subStr)
{
String fileName = scope .();
String destPath = scope .();
for (int i < zipFile.GetNumFiles())
{
ZipFile.Entry entry = scope .();
if (zipFile.SelectEntry(i, entry) case .Err)
continue;
fileName.Clear();
entry.GetFileName(fileName);
if (!fileName.StartsWith(subStr))
continue;
destPath.Clear();
destPath.Append(destDir);
destPath.Append('/');
destPath.Append(fileName);
if (entry.IsDirectory)
{
if (Directory.CreateDirectory(destPath) case .Err)
return .Err;
}
else
{
if (entry.ExtractToFile(destPath) case .Err)
return .Err;
}
}
return .Ok;
}
void CheckPE()
{
let module = Windows.GetModuleHandleW(null);
uint8* moduleData = (uint8*)(int)module;
PEFile.PEHeader* header = (.)moduleData;
PEFile.PE_NTHeaders64* hdr64 = (.)(moduleData + header.e_lfanew);
if (hdr64.mFileHeader.mMachine == PEFile.PE_MACHINE_X64)
{
int fileEnd = 0;
for (int sectIdx < hdr64.mFileHeader.mNumberOfSections)
{
PEFile.PESectionHeader* sectHdrHead = (.)((uint8*)(hdr64 + 1)) + sectIdx;
fileEnd = Math.Max(fileEnd, sectHdrHead.mPointerToRawData + sectHdrHead.mSizeOfRawData);
}
}
}
public function void InstallFunc(StringView dest, StringView filter);
public function int ProgressFunc();
public function void CancelFunc();
public function void StartFunc(InstallFunc installFunc, ProgressFunc progressFunc, CancelFunc cancelFunc);
static void UI_Install(StringView dest, StringView filter)
{
}
static int UI_GetProgress()
{
return 0;
}
static void UI_Cancel()
{
}
void StartUI(StringView dir)
{
String destLib = scope .();
destLib.Append(dir);
destLib.Append("/../dist/StubUI_d.dll");
var lib = Windows.LoadLibraryW(destLib.ToScopedNativeWChar!());
if (lib.IsInvalid)
{
Fail(scope String()..AppendF("Failed to load installer UI '{}'", destLib));
return;
}
StartFunc startFunc = (.)Windows.GetProcAddress(lib, "Start");
if (startFunc == null)
{
Fail(scope String()..AppendF("Failed to initialize installer UI '{}'", destLib));
return;
}
startFunc(=> UI_Install, => UI_GetProgress, => UI_Cancel);
}
void Run()
{
String cwd = scope .();
Directory.GetCurrentDirectory(cwd);
StartUI(cwd);
CheckPE();
ZipFile zipFile = scope .();
zipFile.Open(@"c:\\temp\\build_1827.zip");
ExtractTo(zipFile, @"c:\temp\unzip", .());
CabFile cabFile = scope .();
cabFile.Init();
cabFile.Copy();
}
static int Main(String[] args)
{
Program pg = new Program();
pg.ParseCommandLine(args);
pg.Run();
delete pg;
return 0;
}
}
}