mirror of
https://github.com/corda/corda.git
synced 2025-01-09 22:42:40 +00:00
134 lines
3.4 KiB
C++
134 lines
3.4 KiB
C++
/* Copyright (c) 2008-2012, Avian Contributors
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
for any purpose with or without fee is hereby granted, provided
|
|
that the above copyright notice and this permission notice appear
|
|
in all copies.
|
|
|
|
There is NO WARRANTY for this software. See license.txt for
|
|
details. */
|
|
|
|
#include <windows.h>
|
|
#include <tchar.h>
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
#include "embed.h"
|
|
|
|
#ifdef __x86_64__
|
|
# define BINARY_LOADER(x) _binary_loader_##x
|
|
#else
|
|
# define BINARY_LOADER(x) binary_loader_##x
|
|
#endif
|
|
|
|
extern "C" const uint8_t BINARY_LOADER(start)[];
|
|
extern "C" const uint8_t BINARY_LOADER(end)[];
|
|
|
|
__declspec(noreturn)
|
|
void printUsage(const wchar_t* executableName)
|
|
{
|
|
wprintf(L"Usage: %s destination.exe classes.jar package.Main\n", executableName);
|
|
exit(0);
|
|
}
|
|
|
|
void writeDestinationFile(const wchar_t* filename)
|
|
{
|
|
if(FILE* file = _wfopen(filename, L"wb"))
|
|
{
|
|
size_t count = BINARY_LOADER(end) - BINARY_LOADER(start);
|
|
if(count == fwrite(BINARY_LOADER(start), sizeof(BINARY_LOADER(start)[0]), count, file))
|
|
{
|
|
fclose(file);
|
|
return;
|
|
}
|
|
}
|
|
|
|
fprintf(stderr, "Unable to write to destination file\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
void readFile(std::vector<char>* jarFile, const wchar_t* fileName)
|
|
{
|
|
if(FILE* file = _wfopen(fileName, L"rb"))
|
|
{
|
|
fseek(file, 0, SEEK_END);
|
|
jarFile->resize(ftell(file));
|
|
fseek(file, 0, SEEK_SET);
|
|
fread(&jarFile->at(0), 1, jarFile->size(), file);
|
|
fclose(file);
|
|
}
|
|
}
|
|
|
|
bool mkStringSection(std::vector<wchar_t>* stringSection, const std::vector<std::wstring>& strings, int first, int last)
|
|
{
|
|
stringSection->clear();
|
|
for(int i = first; i <= last; ++i)
|
|
{
|
|
const std::wstring& s = strings.at(i);
|
|
stringSection->push_back(s.size());
|
|
stringSection->insert(stringSection->end(), s.begin(), s.end());
|
|
}
|
|
|
|
// pad to 16 entries
|
|
for(int i = last - first; i < 15; ++i)
|
|
stringSection->push_back(0);
|
|
|
|
return stringSection->size() > 16;
|
|
}
|
|
|
|
void writeStringResources(HANDLE hDest, const std::vector<std::wstring>& strings)
|
|
{
|
|
for(unsigned i = 0; i < strings.size(); i += 16)
|
|
{
|
|
std::vector<wchar_t> stringSection;
|
|
|
|
if(mkStringSection(&stringSection, strings, i, std::min<int>(i + 15, strings.size() - 1)))
|
|
UpdateResourceW(hDest, reinterpret_cast<LPCWSTR>(RT_STRING), reinterpret_cast<LPCWSTR>(MAKEINTRESOURCE((i >> 4) + 1)), LANG_NEUTRAL, &stringSection.at(0), sizeof(wchar_t) * stringSection.size());
|
|
}
|
|
}
|
|
|
|
int wmain(int argc, wchar_t* argv[])
|
|
{
|
|
if(argc != 4)
|
|
printUsage(argv[0]);
|
|
|
|
const wchar_t* destinationName = argv[1];
|
|
const wchar_t* classesName = argv[2];
|
|
const wchar_t* mainClassName = argv[3];
|
|
|
|
writeDestinationFile(destinationName);
|
|
|
|
if(HANDLE hDest = BeginUpdateResourceW(destinationName, TRUE))
|
|
{
|
|
std::vector<std::wstring> strings;
|
|
strings.resize(RESID_MAIN_CLASS + 1);
|
|
strings.at(RESID_MAIN_CLASS) = mainClassName;
|
|
|
|
writeStringResources(hDest, strings);
|
|
|
|
std::vector<char> jarFile;
|
|
readFile(&jarFile, classesName);
|
|
UpdateResourceW(hDest, reinterpret_cast<LPCWSTR>(RT_RCDATA), RESID_BOOT_JAR, LANG_NEUTRAL, &jarFile.at(0), jarFile.size());
|
|
|
|
EndUpdateResource(hDest, FALSE);
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifndef _MSC_VER
|
|
extern "C" int _CRT_glob;
|
|
extern "C" void __wgetmainargs(int*, wchar_t***, wchar_t***, int, int*);
|
|
|
|
int main()
|
|
{
|
|
wchar_t **enpv, **argv;
|
|
int argc, si = 0;
|
|
__wgetmainargs(&argc, &argv, &enpv, _CRT_glob, &si);
|
|
return wmain(argc, argv);
|
|
}
|
|
#endif
|