Skip to content

Commit

Permalink
Locale-independent chm compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
alabuzhev committed May 13, 2021
1 parent 06624b1 commit 7ac3014
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 25 deletions.
11 changes: 1 addition & 10 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ install:
- cd far && for /f "tokens=1,2,4 delims=, " %%i in ('tools\m4 -P farversion.inc.m4') do appveyor UpdateBuild -Version %%i.%%j.%%k.%APPVEYOR_BUILD_NUMBER% && cd ..
#clone NetBox
- git clone https://github.com/FarGroup/Far-NetBox.git
#set locale to russian, needed for chm generation
- ps: Set-WinSystemLocale -SystemLocale ru-RU
- ps: Start-Sleep -s 5
- ps: Restart-Computer
- ps: Start-Sleep -s 5

environment:
matrix:
Expand Down Expand Up @@ -69,12 +64,8 @@ environment:
bit: 64

build_script:
#prevent lost commands after reboot in install
- ps: Start-Sleep -s 5
#update AppVeyor build number to match Far build number (again after reboot)
- cd far && for /f "tokens=1,2,4 delims=, " %%i in ('tools\m4 -P farversion.inc.m4') do appveyor UpdateBuild -Version %%i.%%j.%%k.%APPVEYOR_BUILD_NUMBER% && cd ..
#build Plugin SDK Encyclopedia
- set PATH=C:\Python39-x64;%PATH%
- set PATH=C:\Python39-x64;%PATH%;C:\Program Files (x86)\HTML Help Workshop
- enc/tools/tool.make_enc_chm.bat
#build Lua MacroAPI docs
- enc/tools/tool.make_lua_chm.bat
Expand Down
2 changes: 2 additions & 0 deletions enc/tools/hh_compiler/build.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cl /nologo /O1 /MT hh_compiler.cpp ole32.lib
editbin /nologo /subsystem:console,5.0 /osversion:5.0 hh_compiler.exe
144 changes: 144 additions & 0 deletions enc/tools/hh_compiler/hh_compiler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#include <cstdio>
#include <windows.h>

int CodePage;

namespace replacement
{
static int WINAPI GetACP_hook()
{
return CodePage;
}

static int WINAPI MultiByteToWideChar_hook(UINT cp, DWORD flags, LPCCH lpMultiByte, int cbMultiByte, LPWSTR lpWide, int cchWide)
{
return MultiByteToWideChar(cp == CP_ACP? CodePage : cp, flags, lpMultiByte, cbMultiByte, lpWide, cchWide);
}

static int WINAPI WideCharToMultiByte_hook(UINT cp, DWORD flags, LPCWCH lpWide, int cchWide, LPSTR lpMultiByte, int cbMultiByte, LPCCH lpDef, LPBOOL lpUsedDef)
{
return WideCharToMultiByte(cp == CP_ACP? CodePage : cp, flags, lpWide, cchWide, lpMultiByte, cbMultiByte, lpDef, lpUsedDef);
}
}

static void* FindByName(const char* Name)
{
if (!lstrcmpA(Name, "GetACP"))
return reinterpret_cast<void*>(replacement::GetACP_hook);

if (!lstrcmpA(Name, "MultiByteToWideChar"))
return reinterpret_cast<void*>(replacement::MultiByteToWideChar_hook);

if (!lstrcmpA(Name, "WideCharToMultiByte"))
return reinterpret_cast<void*>(replacement::WideCharToMultiByte_hook);

return {};
}

template <class type>
auto FromRva(HMODULE const Module, DWORD const Rva)
{
return reinterpret_cast<type>(PBYTE(Module) + Rva);
}

static bool write_memory(void const** const To, const void* const From)
{
MEMORY_BASIC_INFORMATION Info;
if (!VirtualQuery(To, &Info, sizeof(Info)))
return false;

DWORD Protection;

switch (Info.Protect)
{
case PAGE_READWRITE:
case PAGE_EXECUTE_READWRITE:
*To = From;
return true;

case PAGE_READONLY:
Protection = PAGE_READWRITE;
break;

default:
Protection = PAGE_EXECUTE_READWRITE;
break;
}

if (!VirtualProtect(Info.BaseAddress, Info.RegionSize, Protection, &Protection))
return false;

*To = From;

return VirtualProtect(Info.BaseAddress, Info.RegionSize, Info.Protect, &Protection);
}

static bool patch(HMODULE Module)
{
const auto Headers = reinterpret_cast<PIMAGE_NT_HEADERS>(PBYTE(Module) + PIMAGE_DOS_HEADER(Module)->e_lfanew);
if (Headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size <= 0)
return false;

bool AnyPatched{};

for (auto ImportIterator = FromRva<PIMAGE_IMPORT_DESCRIPTOR>(Module, Headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); ImportIterator->OriginalFirstThunk; ++ImportIterator)
{
const auto DllName = FromRva<LPCSTR>(Module, ImportIterator->Name);
if (lstrcmpiA(DllName, "kernel32.dll"))
continue;

const auto FirstUnbound = FromRva<IMAGE_THUNK_DATA const*>(Module, ImportIterator->OriginalFirstThunk);
const auto FirstBound = FromRva<IMAGE_THUNK_DATA*>(Module, ImportIterator->FirstThunk);

for (size_t i = 0; FirstBound[i].u1.Function; ++i)
{
if (IMAGE_SNAP_BY_ORDINAL(FirstUnbound[i].u1.Ordinal))
continue;

const auto ImageImportByName = FromRva<IMAGE_IMPORT_BY_NAME const*>(Module, DWORD(UINT_PTR(FirstUnbound[i].u1.AddressOfData)));
const auto FunctionName = reinterpret_cast<const char*>(ImageImportByName->Name);
const auto Function = FindByName(FunctionName);

if (Function && write_memory(reinterpret_cast<void const**>(FirstBound + i), Function))
AnyPatched = true;
}
}

return AnyPatched;
}

static int WINAPI unknown(int)
{
return 1;
}

int main(int const argc, const char* const argv[])
{
if (argc != 3)
return 1;

CodePage = atoi(argv[1]);

const auto HhaModule = LoadLibraryA("hha.dll");
if (!HhaModule)
return 1;

using CompileHHP_t = int WINAPI(const char*, int(*)(const char*, ...), int(WINAPI*)(int), DWORD);
const auto CompileHHP = reinterpret_cast<CompileHHP_t*>(GetProcAddress(HhaModule, reinterpret_cast<LPCSTR>(319)));
if (!CompileHHP)
return 1;

if (!patch(HhaModule))
return 1;

if (!SUCCEEDED(CoInitialize({})))
return 1;

const auto Result = CompileHHP(argv[2], printf, unknown, 0);

CoUninitialize();

FreeLibrary(HhaModule);

return Result? EXIT_SUCCESS : EXIT_FAILURE;
}
Binary file added enc/tools/hh_compiler/hh_compiler.exe
Binary file not shown.
3 changes: 1 addition & 2 deletions enc/tools/tool.make_enc_chm.bat
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ cd "%~dp0" || exit 1
python clean.py || exit 1
python tool.make_chm.py || exit 1
cd ../build/chm/ru || exit 1
rem system locate must be set to russian for this command to generate the chm file correctly
"C:\Program Files (x86)\HTML Help Workshop\hhc.exe" pluginsr.hhp
"%~dp0hh_compiler\hh_compiler.exe" 1251 pluginsr.hhp
if not exist FarEncyclopedia.ru.chm (
echo "Error: FarEncyclopedia.ru.chm wasn't created!"
exit 1
Expand Down
10 changes: 5 additions & 5 deletions enc/tools/tool.make_lua_chm.bat
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ cd ..\build\lua || exit 1

if not '%1'=='' goto :make

call :make luafar_manual utf-8-sig windows-1252
call :make macroapi_manual.ru utf-8-sig windows-1251
call :make macroapi_manual.en utf-8-sig windows-1252
call :make luafar_manual utf-8-sig 1252
call :make macroapi_manual.ru utf-8-sig 1251
call :make macroapi_manual.en utf-8-sig 1252

goto :end

:make
mkdir %1
cd %1 || exit 1
python %~dp0convert.py "..\..\..\enc_lua\%1.tsi" %2 "%1.tsi" %3
python %~dp0convert.py "..\..\..\enc_lua\%1.tsi" %2 "%1.tsi" windows-%3
"%~dp0lua\lua.exe" "%~dp0lua\scripts\tp2hh.lua" "%1.tsi" tsi "%~dp0lua\templates\api.tem"
"C:\Program Files (x86)\HTML Help Workshop\hhc.exe" %1.hhp
"%~dp0hh_compiler\hh_compiler.exe" %3 %1.hhp
if not exist %1.chm (
echo "Error: %1.chm wasn't created!"
exit 1
Expand Down
17 changes: 9 additions & 8 deletions misc/nightly/enc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
function benc2 {
LNG=$1
L=$2
CP=$3

cd ${LNG} || return 1
wine "C:/Program Files (x86)/HTML Help Workshop/hhc.exe" plugins${L}.hhp
wine "../../../tools/hh_compiler/hh_compiler.exe" ${CP} plugins${L}.hhp

( \
cp -f FarEncyclopedia.${LNG}.chm ../../../../outfinalnew32/Encyclopedia/ && \
Expand All @@ -21,9 +22,9 @@ function blua {
mkdir $1
cd $1 || return 1

python ../../../tools/convert.py "../../../enc_lua/${1}.tsi" ${2} "${1}.tsi" ${3}
python ../../../tools/convert.py "../../../enc_lua/${1}.tsi" ${2} "${1}.tsi" windows-${3}
wine "C:/src/enc/tools/lua/lua.exe" "C:/src/enc/tools/lua/scripts/tp2hh.lua" "${1}.tsi" tsi "C:/src/enc/tools/lua/templates/api.tem"
wine "C:/Program Files (x86)/HTML Help Workshop/hhc.exe" ${1}.hhp
wine "../../../tools/hh_compiler/hh_compiler.exe" ${3} ${1}.hhp

( \
cp -f ${1}.chm ../../../../outfinalnew32/Encyclopedia/ && \
Expand All @@ -46,8 +47,8 @@ python tool.make_chm.py
cd ../build/chm

( \
#benc2 en e && \
benc2 ru r \
#benc2 en e 1252 && \
benc2 ru r 1251 \
) || exit 1

popd
Expand All @@ -56,9 +57,9 @@ mkdir -p enc/build/lua
pushd enc/build/lua || exit 1

( \
blua macroapi_manual.ru utf-8-sig windows-1251 && \
blua macroapi_manual.en utf-8-sig windows-1252 && \
blua luafar_manual utf-8-sig windows-1252 \
blua macroapi_manual.ru utf-8-sig 1251 && \
blua macroapi_manual.en utf-8-sig 1252 && \
blua luafar_manual utf-8-sig 1252 \
) || exit 1

popd
Expand Down

0 comments on commit 7ac3014

Please sign in to comment.