corda/src/embed.cpp

134 lines
3.4 KiB
C++
Raw Normal View History

2012-11-13 08:11:49 +00:00
/* 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. */
2012-12-05 00:37:02 +00:00
#include <windows.h>
2012-11-13 08:11:49 +00:00
#include <tchar.h>
#include <stdio.h>
#include <stdint.h>
#include <vector>
#include <string>
#include "embed.h"
2013-01-25 14:57:57 +00:00
#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)[];
2012-11-13 08:11:49 +00:00
__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"))
{
2013-01-25 14:57:57 +00:00
size_t count = BINARY_LOADER(end) - BINARY_LOADER(start);
if(count == fwrite(BINARY_LOADER(start), sizeof(BINARY_LOADER(start)[0]), count, file))
2012-11-13 08:11:49 +00:00
{
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)
{
2012-12-05 22:30:49 +00:00
for(unsigned i = 0; i < strings.size(); i += 16)
2012-11-13 08:11:49 +00:00
{
std::vector<wchar_t> stringSection;
if(mkStringSection(&stringSection, strings, i, std::min<int>(i + 15, strings.size() - 1)))
2012-12-05 22:30:49 +00:00
UpdateResourceW(hDest, reinterpret_cast<LPCWSTR>(RT_STRING), reinterpret_cast<LPCWSTR>(MAKEINTRESOURCE((i >> 4) + 1)), LANG_NEUTRAL, &stringSection.at(0), sizeof(wchar_t) * stringSection.size());
2012-11-13 08:11:49 +00:00
}
}
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);
2012-12-05 22:30:49 +00:00
UpdateResourceW(hDest, reinterpret_cast<LPCWSTR>(RT_RCDATA), RESID_BOOT_JAR, LANG_NEUTRAL, &jarFile.at(0), jarFile.size());
2012-11-13 08:11:49 +00:00
EndUpdateResource(hDest, FALSE);
}
return 0;
}
2012-12-05 22:30:49 +00:00
#ifndef _MSC_VER
2012-11-13 08:11:49 +00:00
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);
}
2012-12-05 22:30:49 +00:00
#endif