• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revision8d6e8f0f1dcaa7bd55ec2d9aa8498b996fe227a1 (tree)
Time2021-04-27 10:15:19
Authormajiponi <majiponi@yaho...>
Commitermajiponi

Log Message

Ver0.02 - The engin ignores needless [aviutl path] in .aus files correctly.

Change Summary

Incremental Difference

--- a/apihook.cpp
+++ b/apihook.cpp
@@ -10,68 +10,65 @@ namespace
1010 }
1111
1212
13-IATModifier::IATModifier(const char* dll, const char* name, const void* hook, HMODULE mod)
14- : dll(dll), name(name), hook(hook), oldproc(GetProcAddress(GetModuleHandleA(dll), name)), mod(mod)
13+IATModifier::IATModifier(const char* exporter, const char* apiname, const void* newproc, HMODULE importer)
14+ : exporter{exporter}, apiname{apiname}, newproc{newproc}, oldproc{ GetProcAddress(GetModuleHandleA(exporter), apiname) }, importer{importer}
1515 {
16- if(mod){
17- modifyIAT(dll, oldproc, hook, mod);
16+ if(importer){
17+ modifyIAT(exporter, oldproc, newproc, importer);
1818 }
1919 else{
20- modifyIAT(dll, oldproc, hook);
20+ modifyIAT(exporter, oldproc, newproc);
2121 }
2222 }
2323
2424 IATModifier::~IATModifier()
2525 {
26- if(mod){
27- modifyIAT(dll, hook, oldproc, mod);
26+ if(importer){
27+ modifyIAT(exporter, newproc, oldproc, importer);
2828 }
2929 else{
30- modifyIAT(dll, hook, oldproc);
30+ modifyIAT(exporter, newproc, oldproc);
3131 }
3232 }
3333
3434 namespace
3535 {
36- void modifyIAT(const char* apidll, const void* origaddr, const void* newaddr, HMODULE target)
36+ void modifyIAT(const char* exporter, const void* oldproc, const void* newproc)
37+ {
38+ MODULEENTRY32 entry{ sizeof(entry) };
39+
40+ const HANDLE hSnap{ CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()) };
41+
42+ if(Module32First(hSnap, &entry)){
43+ do{
44+ modifyIAT(exporter, oldproc, newproc, entry.hModule);
45+ }while(Module32Next(hSnap, &entry));
46+ }
47+
48+ CloseHandle(hSnap);
49+ }
50+
51+ void modifyIAT(const char* exporter, const void* oldproc, const void* newproc, HMODULE importer)
3752 {
3853 ULONG size;
39- const IMAGE_IMPORT_DESCRIPTOR* pDesc = static_cast<const IMAGE_IMPORT_DESCRIPTOR*>(ImageDirectoryEntryToData(target, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size));
54+ auto pDesc{ static_cast<const IMAGE_IMPORT_DESCRIPTOR*>(ImageDirectoryEntryToData(importer, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size)) };
4055 if(!pDesc) return;
4156
4257 for(; pDesc->Name; pDesc++){
43- const char* name = reinterpret_cast<const char*>(target) + pDesc->Name;
44- if(!_strcmpi(name, apidll)) break;
58+ const char* name{ reinterpret_cast<const char*>(importer) + pDesc->Name };
59+ if(!_strcmpi(name, exporter)) break;
4560 }
4661 if(!pDesc->Name) return;
4762
48- IMAGE_THUNK_DATA* pThunk = reinterpret_cast<IMAGE_THUNK_DATA*>(reinterpret_cast<char*>(target) + pDesc->FirstThunk);
63+ auto pThunk{ reinterpret_cast<IMAGE_THUNK_DATA*>(reinterpret_cast<char*>(importer) + pDesc->FirstThunk) };
4964 for(; pThunk->u1.Function; pThunk++){
50- const void* addr = reinterpret_cast<const void*>(pThunk->u1.Function);
51- if(addr == origaddr) break;
65+ if(pThunk->u1.Function == reinterpret_cast<DWORD>(oldproc)) break;
5266 }
5367 if(!pThunk->u1.Function) return;
5468
55- const void*& proc = reinterpret_cast<const void*&>(pThunk->u1.Function);
56-
5769 DWORD protect;
58- VirtualProtect(&proc, sizeof(proc), PAGE_EXECUTE_READWRITE, &protect);
59- proc = newaddr;
60- VirtualProtect(&proc, sizeof(proc), protect, &protect);
61- }
62-
63- void modifyIAT(const char* apidll, const void* origaddr, const void* newaddr)
64- {
65- MODULEENTRY32 entry { sizeof(entry) };
66-
67- HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
68-
69- if(Module32First(hSnap, &entry)){
70- do{
71- modifyIAT(apidll, origaddr, newaddr, entry.hModule);
72- }while(Module32Next(hSnap, &entry));
73- }
74-
75- CloseHandle(hSnap);
70+ VirtualProtect(&pThunk->u1.Function, sizeof(pThunk->u1.Function), PAGE_EXECUTE_READWRITE, &protect);
71+ pThunk->u1.Function = reinterpret_cast<DWORD>(newproc);
72+ VirtualProtect(&pThunk->u1.Function, sizeof(pThunk->u1.Function), protect, &protect);
7673 }
7774 }
--- a/apihook.h
+++ b/apihook.h
@@ -5,13 +5,14 @@
55 class IATModifier
66 {
77 private:
8- const char* dll;
9- const char* name;
10- const void* hook;
8+ const char* exporter;
9+ const char* apiname;
10+ const void* newproc;
1111 const void* oldproc;
12- HMODULE mod;
12+ HMODULE importer;
13+
1314 public:
14- IATModifier(const char* dll, const char* name, const void* hook, HMODULE mod = nullptr);
15+ IATModifier(const char* exporter, const char* apiname, const void* newproc, HMODULE importer = nullptr);
1516 IATModifier(const IATModifier&) = delete;
1617 ~IATModifier();
1718 };
--- a/aus.vcxproj
+++ b/aus.vcxproj
@@ -95,6 +95,7 @@
9595 <ConformanceMode>true</ConformanceMode>
9696 <AssemblerOutput>NoListing</AssemblerOutput>
9797 <AdditionalOptions>/source-charset:utf-8 %(AdditionalOptions)</AdditionalOptions>
98+ <LanguageStandard>stdcpp17</LanguageStandard>
9899 </ClCompile>
99100 <Link>
100101 <SubSystem>Windows</SubSystem>
@@ -130,6 +131,7 @@
130131 <ConformanceMode>true</ConformanceMode>
131132 <AssemblerOutput>NoListing</AssemblerOutput>
132133 <AdditionalOptions>/source-charset:utf-8 %(AdditionalOptions)</AdditionalOptions>
134+ <LanguageStandard>stdcpp17</LanguageStandard>
133135 </ClCompile>
134136 <Link>
135137 <SubSystem>Windows</SubSystem>
@@ -163,6 +165,7 @@
163165 <ClInclude Include="apihook.h" />
164166 <ClInclude Include="command.h" />
165167 <ClInclude Include="core.h" />
168+ <ClInclude Include="coreimp.h" />
166169 <ClInclude Include="parser.h" />
167170 <ClInclude Include="filter.h" />
168171 <ClInclude Include="stdafx.h" />
@@ -181,6 +184,8 @@
181184 <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
182185 </ClCompile>
183186 <ClCompile Include="ui.cpp" />
187+ <ClCompile Include="v1patch.cpp" />
188+ <ClCompile Include="v2patch.cpp" />
184189 </ItemGroup>
185190 <ItemGroup>
186191 <None Include="aus.def" />
--- a/aus.vcxproj.filters
+++ b/aus.vcxproj.filters
@@ -39,6 +39,9 @@
3939 <ClInclude Include="command.h">
4040 <Filter>ヘッダー ファイル</Filter>
4141 </ClInclude>
42+ <ClInclude Include="coreimp.h">
43+ <Filter>ヘッダー ファイル</Filter>
44+ </ClInclude>
4245 </ItemGroup>
4346 <ItemGroup>
4447 <ClCompile Include="stdafx.cpp">
@@ -59,6 +62,12 @@
5962 <ClCompile Include="command.cpp">
6063 <Filter>ソース ファイル</Filter>
6164 </ClCompile>
65+ <ClCompile Include="v1patch.cpp">
66+ <Filter>ソース ファイル</Filter>
67+ </ClCompile>
68+ <ClCompile Include="v2patch.cpp">
69+ <Filter>ソース ファイル</Filter>
70+ </ClCompile>
6271 </ItemGroup>
6372 <ItemGroup>
6473 <None Include="aus.def">
--- a/command.cpp
+++ b/command.cpp
@@ -1,6 +1,7 @@
11 #include "stdafx.h"
22 #include <commdlg.h>
3-#include <algorithm>
3+#include <cstdio>
4+#include <memory>
45 #include <typeinfo>
56
67 #include "apihook.h"
@@ -8,115 +9,126 @@
89
910 namespace
1011 {
11- HWND getExeditWindow();
12-
1312 union{
1413 int scene_no;
1514 struct{ unsigned int cx, cy, fps, freq; }* videoinfo;
1615 const char* path;
17- bool transparent;
16+ bool transparency;
1817 } dlgdata;
18+
19+ HWND getExeditWindow();
1920 }
2021
2122 namespace AviUtlCommand
2223 {
23- void CreateProject(size_t cx, size_t cy, size_t fps, size_t freq)
24- {
25- HMODULE ex = GetModuleHandleA("exedit.auf");
26- if(!ex) return;
27-
28- std::remove_pointer<decltype(dlgdata.videoinfo)>::type data{ cx, cy, fps, freq };
29- dlgdata.videoinfo = &data;
30-
31- IATModifier hook1{ "user32.dll", "DialogBoxParamA", static_cast<decltype(DialogBoxParamA)*>([](HINSTANCE, LPCSTR, HWND, DLGPROC proc, LPARAM) -> INT_PTR {
32- proc(nullptr, WM_COMMAND, IDOK, 0);
33- return IDOK;
34- }), ex };
35- IATModifier hook2{ "user32.dll", "GetDlgItemInt", static_cast<decltype(GetDlgItemInt)*>([](HWND, int id, BOOL*, BOOL) -> UINT {
36- if(id == 171) return dlgdata.videoinfo->cx;
37- if(id == 172) return dlgdata.videoinfo->cy;
38- return dlgdata.videoinfo->freq;
39- }), ex };
40- IATModifier hook3{ "user32.dll", "GetDlgItemTextA", static_cast<decltype(GetDlgItemTextA)*>([](HWND, int, char* buf, int nmax) -> UINT {
41- return sprintf_s(buf, nmax, "%d", dlgdata.videoinfo->fps);
42- }), ex };
43-
44- SendMessageA(getExeditWindow(), WM_COMMAND, 1030, 0xFFFFFFFF);
45- }
46-
47- void OpenExoFile(const char* path)
24+ void SaveProject(const char* path)
4825 {
49- dlgdata.path = path;
50- IATModifier hook3{ "comdlg32.dll", "GetOpenFileNameA", static_cast<decltype(GetOpenFileNameA)*>([](LPOPENFILENAMEA pofn) -> BOOL {
26+ const IATModifier hook{ "comdlg32.dll", "GetSaveFileNameA", static_cast<decltype(GetSaveFileNameA)*>(
27+ [](LPOPENFILENAMEA pofn) -> BOOL {
5128 strcpy_s(pofn->lpstrFile, pofn->nMaxFile, dlgdata.path);
5229 return TRUE;
5330 }), GetModuleHandleA(nullptr) };
5431
55- SendMessageA(getExeditWindow(), WM_COMMAND, 1037, 0xFFFFFFFF);
32+ dlgdata.path = path;
33+ SendMessageA(AviUtlUI::GetMainWindow(), WM_COMMAND, 1023, -1);
5634 }
35+}
5736
58- void Quit()
37+namespace ExeditCommand
38+{
39+ void CreateProject(size_t cx, size_t cy, size_t fps, size_t freq)
5940 {
60- PostMessageA(AviUtlUI::GetMainWindow(), WM_CLOSE, 0, 0);
41+ const HMODULE ex{ GetModuleHandleA("exedit.auf") };
42+ const IATModifier hook[]{
43+ { "user32.dll", "DialogBoxParamA", static_cast<decltype(DialogBoxParamA)*>(
44+ [](HINSTANCE, LPCSTR, HWND, DLGPROC proc, LPARAM) -> INT_PTR {
45+ proc(nullptr, WM_COMMAND, IDOK, 0);
46+ return IDOK;
47+ }), ex },
48+ { "user32.dll", "GetDlgItemInt", static_cast<decltype(GetDlgItemInt)*>(
49+ [](HWND, int id, BOOL*, BOOL) -> UINT {
50+ if(id == 171) return dlgdata.videoinfo->cx;
51+ if(id == 172) return dlgdata.videoinfo->cy;
52+ return dlgdata.videoinfo->freq;
53+ }), ex },
54+ { "user32.dll", "GetDlgItemTextA", static_cast<decltype(GetDlgItemTextA)*>(
55+ [](HWND, int, char* buf, int nmax) -> UINT {
56+ return sprintf_s(buf, nmax, "%d", dlgdata.videoinfo->fps);
57+ }), ex }
58+ };
59+
60+ std::remove_pointer<decltype(dlgdata.videoinfo)>::type data{ cx, cy, fps, freq };
61+ dlgdata.videoinfo = &data;
62+ SendMessageA(getExeditWindow(), WM_COMMAND, 1030, -1);
6163 }
6264
63- void SaveProject(const char* path)
65+ void OpenExoFile(const char* path)
6466 {
65- dlgdata.path = path;
66- IATModifier hook3{ "comdlg32.dll", "GetSaveFileNameA", static_cast<decltype(GetSaveFileNameA)*>([](LPOPENFILENAMEA pofn) -> BOOL {
67+ const IATModifier hook{ "comdlg32.dll", "GetOpenFileNameA", static_cast<decltype(GetOpenFileNameA)*>(
68+ [](LPOPENFILENAMEA pofn) -> BOOL {
6769 strcpy_s(pofn->lpstrFile, pofn->nMaxFile, dlgdata.path);
6870 return TRUE;
6971 }), GetModuleHandleA(nullptr) };
7072
71- SendMessageA(AviUtlUI::GetMainWindow(), WM_COMMAND, 1023, 0xFFFFFFFF);
73+ dlgdata.path = path;
74+ SendMessageA(getExeditWindow(), WM_COMMAND, 1037, -1);
7275 }
7376
74- void SwitchScene(size_t n)
77+ void SwitchScene(size_t scene_no)
7578 {
76- HMODULE ex = GetModuleHandleA("exedit.auf");
77- if(!ex || n < 0 || n >= 50) return;
78-
79- dlgdata.scene_no = n;
80- IATModifier hook1{ "user32.dll", "DialogBoxParamA", static_cast<decltype(DialogBoxParamA)*>([](HINSTANCE, LPCSTR, HWND, DLGPROC proc, LPARAM) -> INT_PTR {
81- proc(nullptr, WM_COMMAND, MAKEWPARAM(190, LBN_SELCHANGE), 0);
82- return dlgdata.scene_no;
83- }), ex };
84- IATModifier hook2{ "user32.dll", "SendDlgItemMessageA", static_cast<decltype(SendDlgItemMessageA)*>([](HWND, int, UINT, WPARAM, LPARAM) -> LRESULT {
85- return dlgdata.scene_no;
86- }), ex };
87-
79+ if(scene_no < 0 || scene_no >= 50) return;
80+
81+ const HMODULE ex{ GetModuleHandleA("exedit.auf") };
82+ const IATModifier hook[]{
83+ { "user32.dll", "DialogBoxParamA", static_cast<decltype(DialogBoxParamA)*>(
84+ [](HINSTANCE, LPCSTR, HWND, DLGPROC proc, LPARAM) -> INT_PTR {
85+ proc(nullptr, WM_COMMAND, MAKEWPARAM(190, LBN_SELCHANGE), 0);
86+ return dlgdata.scene_no;
87+ }), ex },
88+ { "user32.dll", "SendDlgItemMessageA", static_cast<decltype(SendDlgItemMessageA)*>(
89+ [](HWND, int, UINT, WPARAM, LPARAM) -> LRESULT {
90+ return dlgdata.scene_no;
91+ }), ex }
92+ };
93+
94+ dlgdata.scene_no = scene_no;
8895 SendMessageA(getExeditWindow(), WM_LBUTTONDOWN, MK_LBUTTON, 0);
8996 }
9097
91- void TransparentScene(bool b)
98+ void TransparentScene(bool transparency)
9299 {
93- HMODULE ex = GetModuleHandleA("exedit.auf");
94- if(!ex) return;
95-
96- dlgdata.transparent = b;
97- IATModifier hook1{ "user32.dll", "DialogBoxParamA", static_cast<decltype(DialogBoxParamA)*>([](HINSTANCE, LPCSTR, HWND, DLGPROC proc, LPARAM) -> INT_PTR {
98- proc(nullptr, WM_COMMAND, IDOK, 0);
99- return IDOK;
100- }), ex };
101- IATModifier hook2{ "user32.dll", "IsDlgButtonChecked", static_cast<decltype(IsDlgButtonChecked)*>([](HWND, int) -> UINT {
102- return dlgdata.transparent ? BST_CHECKED : BST_UNCHECKED;
103- }), ex };
104-
105- SendMessageA(getExeditWindow(), WM_COMMAND, 1096, 0xFFFFFFFF);
100+ const HMODULE ex{ GetModuleHandleA("exedit.auf") };
101+ const IATModifier hook[]{
102+ { "user32.dll", "DialogBoxParamA", static_cast<decltype(DialogBoxParamA)*>(
103+ [](HINSTANCE, LPCSTR, HWND, DLGPROC proc, LPARAM) -> INT_PTR {
104+ proc(nullptr, WM_COMMAND, IDOK, 0);
105+ return IDOK;
106+ }), ex },
107+ { "user32.dll", "IsDlgButtonChecked", static_cast<decltype(IsDlgButtonChecked)*>(
108+ [](HWND, int) -> UINT {
109+ return dlgdata.transparency ? BST_CHECKED : BST_UNCHECKED;
110+ }), ex }
111+ };
112+
113+ dlgdata.transparency = transparency;
114+ SendMessageA(getExeditWindow(), WM_COMMAND, 1096, -1);
106115 }
107-
108116 }
109117
110118 namespace
111119 {
112120 HWND getExeditWindow()
113121 {
114- HWND ret = nullptr;
115- EnumThreadWindows(GetCurrentThreadId(), static_cast<WNDENUMPROC>([](HWND hwnd, LPARAM data) -> BOOL {
116- static constexpr char head[] = "拡張編集";
122+ HWND ret{};
123+ EnumThreadWindows(GetCurrentThreadId(), static_cast<WNDENUMPROC>(
124+ [](HWND hwnd, LPARAM data) -> BOOL {
125+ static constexpr char head[]{"拡張編集"};
126+ static constexpr size_t size{ sizeof(head) - sizeof(head[0]) };
127+
117128 char buf[16];
118129 GetWindowTextA(hwnd, buf, std::size(buf));
119- if(std::memcmp(buf, head, sizeof(head)-1)) return TRUE;
130+ if(std::memcmp(buf, head, size)) return TRUE;
131+
120132 *reinterpret_cast<HWND*>(data) = hwnd;
121133 return FALSE;
122134 }), reinterpret_cast<LPARAM>(&ret));
--- a/command.h
+++ b/command.h
@@ -2,10 +2,13 @@
22
33 namespace AviUtlCommand
44 {
5+ void SaveProject(const char* path);
6+}
7+
8+namespace ExeditCommand
9+{
510 void CreateProject(size_t cx, size_t cy, size_t fps, size_t freq);
611 void OpenExoFile(const char* path);
7- void Quit();
8- void SaveProject(const char* path);
9- void SwitchScene(size_t n);
10- void TransparentScene(bool b);
12+ void SwitchScene(size_t scene_no);
13+ void TransparentScene(bool transparency);
1114 }
--- a/core.cpp
+++ b/core.cpp
@@ -1,64 +1,26 @@
11 #include "stdafx.h"
2+#include <memory>
23 #include <utility>
34 #include "command.h"
45 #include "core.h"
5-#include "parser.h"
6+#include "coreimp.h"
67 #include "ui.h"
78
89 namespace
910 {
10- struct patchdata{
11- size_t offset_buf;
12- size_t offset_loaded;
13- struct{
14- size_t offset;
15- void (*socketproc)(void*, const char*);
16- } engine;
17- struct{
18- size_t offset;
19- void* proc;
20- size_t bytes;
21- } patch[5];
22- };
23-
2411 BOOL init(FILTER*);
25- void applypatch(const patchdata*);
26- constexpr patchdata makeVer1Patch(size_t, size_t);
27- void ClearBuffer1();
28- void Reload1();
29- void Reset1();
30- void Loader1();
31- void Save1();
32- constexpr patchdata makeVer2Patch(size_t, size_t, size_t);
33- void Socket(void*, const char*);
34- void ClearBuffer2();
35- void Reload2();
36- void Reset2();
37- void Loader2();
38- void Save2();
39- size_t recalc(size_t, size_t, const char*);
40- bool is_aup_path(const char*);
12+ const ScriptEngineCoreImplement::patchdata* getpatch();
4113 inline const IMAGE_NT_HEADERS32* getNtHeaders(HMODULE);
4214 inline DWORD getTimeStamp(HMODULE);
4315 inline size_t getTextSectionSize(HMODULE);
44- const patchdata* getpatch();
4516 void writecaller(void*, const void*, size_t);
4617 inline void writeptr(void*, const void*);
4718 void modifycode(void*, const void*, size_t);
48-
49- char* scriptbuf;
50- size_t* ploaded;
51- size_t oldoffset;
52- void (*engineproc)();
53- void (*socketproc)(void*, const char*);
54-
55- constexpr size_t bufsize = 0x1000;
5619 }
5720
58-
5921 extern "C" const FILTER_DLL* CALLBACK GetFilterTable()
6022 {
61- static constexpr FILTER_DLL filter = {
23+ static constexpr FILTER_DLL filter{
6224 FILTER_FLAG_ALWAYS_ACTIVE | FILTER_FLAG_NO_CONFIG | FILTER_FLAG_IMPORT,
6325 0, 0, const_cast<char*>("Script Engine"), 0, nullptr, nullptr, 0, 0, 0, nullptr, nullptr, nullptr,
6426 init, nullptr, nullptr, AviUtlUI::WndProc, nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr
@@ -66,238 +28,76 @@ extern "C" const FILTER_DLL* CALLBACK GetFilterTable()
6628 return &filter;
6729 }
6830
69-namespace
31+void LoadScript(const char* path, void *editp)
7032 {
71- BOOL init(FILTER*)
72- {
73- const patchdata* p = getpatch();
74- if(!p) return FALSE;
75-
76- AviUtlUI::AddMenu();
77- applypatch(p);
78- return TRUE;
79- }
80-
81- constexpr patchdata makeVer1Patch(size_t offset_engine, size_t offset_saver, size_t offset_parser)
82- {
83- return { offset_parser + 0x48, offset_parser + 0x40,
84- { offset_engine, nullptr },
85- {
86- { offset_engine + 0x2D, ClearBuffer1, 5 },
87- { offset_parser + 0x07, Reload1, 6 },
88- { offset_parser + 0x2E, Reset1, 5 },
89- { offset_engine + 0x47, Loader1, 5 },
90- { offset_saver + 0x8E8, Save1, 6 }
91- }
92- };
93- }
94-
95- __declspec(naked) void ClearBuffer1()
96- {
97- __asm{
98- xor edx, edx
99- lea ecx, [esp+8]
100- mov [ecx], dl
101- pop edx
102- push ecx
103- push edx
104- ret
105- }
106- }
107-
108- __declspec(naked) void Reload1()
109- {
110- __asm{
111- push eax
112- push edx
113- mov eax, ploaded
114- push scriptbuf
115- push oldoffset
116- push [eax]
117- call recalc
118- add esp, 12
119- mov edi, ploaded
120- pop edx
121- mov [edi], eax
122- mov oldoffset, eax
123- pop eax
124- mov edi, [esp+0x14]
125- mov esi, ebp
126- ret
127- }
128- }
33+ ScriptEngineCoreImplement::core.loadscript(path, editp);
34+}
12935
130- __declspec(naked) void Reset1()
131- {
132- __asm{
133- xor ecx, ecx
134- mov oldoffset, ecx
135- cmp eax, bufsize
136- ret
137- }
138- }
36+namespace ScriptEngineCoreImplement
37+{
38+ coredata core;
13939
140- __declspec(naked) void Loader1()
40+ size_t recalc(size_t offset, size_t oldoffset, const char* buf)
14141 {
142- __asm{
143- lea edx, [esp+12]
144- push edx
145- push edx
146- call SubParser
147- add esp, 4
148- xor ecx, ecx
149- pop edx
150- test eax, eax
151- cmove edx, ecx
152- pop ecx
153- push edx
154- push ecx
155- ret
156- }
157- }
42+ if(!buf[0]) return offset;
43+ if(offset < bufsize) return offset;
15844
159- __declspec(naked) void Save1()
160- {
161- __asm{
162- cmp [ebp+0x4BC498], 0
163- jne SAVE_WAV
164- lea eax, [ebp+0x108]
165- push eax
166- call is_aup_path
167- add esp, 4
168- test eax, eax
169- jne SAVE_AUP
170- SAVE_WAV:
171- mov dl, [ebp+0x4BC198]
172- ret
173- SAVE_AUP:
174- lea eax, [ebp+0x108]
175- push eax
176- call AviUtlCommand::SaveProject
177- mov eax, [esp+4]
178- add esp, 4
179- add eax, 0x97
180- mov [esp], eax
181- ret
182- }
45+ offset = oldoffset;
46+ for(; offset < bufsize && buf[offset] && buf[offset] != '\n' && buf[offset] != '\r'; offset++);
47+ for(; offset < bufsize && (buf[offset] == '\n' || buf[offset] == '\r'); offset++);
48+ return offset;
18349 }
18450
185- constexpr patchdata makeVer2Patch(size_t offset_engine, size_t offset_saver, size_t offset_parser)
51+ bool is_aup_path(const char* path)
18652 {
187- return { offset_parser + 0x64, offset_parser + 0x5E,
188- { offset_engine, Socket },
189- {
190- { offset_engine + 0x42D, ClearBuffer2, 7 },
191- { offset_parser + 0x20, Reload2, 5 },
192- { offset_parser + 0x48, Reset2, 8 },
193- { offset_engine + 0x450, Loader2, 7 },
194- { offset_saver + 0xC8D, Save2, 7 }
195- }
196- };
197- }
53+ static constexpr char ext[]{".aup"};
54+ static constexpr size_t extlen{ std::size(ext) - 1 };
19855
199- void Socket(void* editp, const char* path)
200- {
201- __asm{
202- mov edx, path
203- mov ecx, editp
204- call engineproc
205- }
56+ size_t len = std::strlen(path);
57+ return len > extlen && !_strcmpi(path + len - extlen, ext);
20658 }
20759
208- __declspec(naked) void ClearBuffer2()
60+ char* erase_exe_name(char* cmdline)
20961 {
210- __asm{
211- xor ecx, ecx
212- lea edx, [esp+0x44C]
213- mov [edx], cl
214- ret
215- }
216- }
62+ static constexpr char ext[]{".exe"};
63+ static constexpr size_t extlen{ std::size(ext) - 1 };
21764
218- __declspec(naked) void Reload2()
219- {
220- __asm{
221- mov eax, ploaded
222- push ecx
223- push edx
224- push scriptbuf
225- push oldoffset
226- push [eax]
227- call recalc
228- add esp, 12
229- mov oldoffset, eax
230- pop edx
231- pop ecx
232- ret
233- }
234- }
65+ char* p = cmdline;
66+ while(*p == ' ') p++;
67+ if(!*p) return nullptr;
23568
236- __declspec(naked) void Reset2()
237- {
238- __asm{
239- xor eax, eax
240- mov oldoffset, eax
241- mov eax, dword ptr [ebp-8]
242- cmp eax, bufsize
243- ret
69+ char del = ' ';
70+ if(*p++ == '\"') del = '\"';
71+ while(*p){
72+ if(*p++ == del) break;
24473 }
245- }
246-
247- __declspec(naked) void Loader2()
248- {
249- __asm{
250- lea edx, [esp+0x44C]
251- push edx
252- push edx
253- call SubParser
254- add esp, 4
255- xor ecx, ecx
256- pop edx
257- test eax, eax
258- cmove edx, ecx
259- ret
74+ char* q = cmdline;
75+ if(p - q >= extlen + 1){
76+ if(!_memicmp(p - (extlen + 1), ext, extlen) || !memrchr(q, '.', p - q)){
77+ std::memset(q, ' ', p - q);
78+ }
26079 }
80+ return cmdline;
26181 }
26282
263- __declspec(naked) void Save2()
83+ const void* memrchr(const void *s, int c, size_t n)
26484 {
265- __asm{
266- cmp [ebx+0x4BC498], 0
267- jne SAVE_WAV
268- lea eax, [ebx+0x108]
269- push eax
270- call is_aup_path
271- add esp, 4
272- test eax, eax
273- jne SAVE_AUP
274- SAVE_WAV:
275- cmp byte ptr [ebx+0x4BC198], 0
276- ret
277- SAVE_AUP:
278- lea eax, [ebx+0x108]
279- push eax
280- call AviUtlCommand::SaveProject
281- mov eax, [esp+4]
282- add esp, 4
283- add eax, 0xC01
284- mov [esp], eax
285- ret
85+ const char* p{ static_cast<const char*>(s) };
86+ while(n-- > 0){
87+ if(p[n] == c) return p + n;
28688 }
89+ return nullptr;
28790 }
28891
289- void applypatch(const patchdata* p)
92+ void coredata::apply(const patchdata* p)
29093 {
291- HMODULE base = GetModuleHandleA(nullptr);
94+ HMODULE base{ GetModuleHandleA(nullptr) };
29295
29396 ploaded = *reinterpret_cast<size_t* const*>(reinterpret_cast<const char*>(base) + p->offset_loaded);
29497 scriptbuf = *reinterpret_cast<char* const*>(reinterpret_cast<const char*>(base) + p->offset_buf);
29598
296- engineproc = reinterpret_cast<void(*)()>(reinterpret_cast<const char*>(base) + p->engine.offset);
99+ engineproc = reinterpret_cast<const char*>(base) + p->engine.offset;
297100 socketproc = p->engine.socketproc;
298- if(!socketproc){
299- socketproc = reinterpret_cast<void(*)(void*, const char*)>(engineproc);
300- }
301101
302102 for(const auto& e : p->patch){
303103 writecaller(reinterpret_cast<char*>(base) + e.offset, e.proc, e.bytes);
@@ -305,53 +105,38 @@ namespace
305105 FlushInstructionCache(GetCurrentProcess(), base, getTextSectionSize(base));
306106 }
307107
308- size_t recalc(size_t offset, size_t oldoffset, const char* buf)
108+ void coredata::loadscript(const char* path, void *editp)
309109 {
310- if(!buf[0]) return offset;
311- if(offset < bufsize) return offset;
312-
313- offset = oldoffset;
314- for(; offset < bufsize && buf[offset] && buf[offset] != '\n' && buf[offset] != '\r'; offset++);
315- for(; offset < bufsize && (buf[offset] == '\n' || buf[offset] == '\r'); offset++);
316- return offset;
317- }
318-
319- bool is_aup_path(const char* path)
320- {
321- static constexpr char ext[] = ".aup";
322- static constexpr size_t extlen = sizeof(ext) - 1;
323-
324- size_t len = std::strlen(path);
325- return len > extlen && !_strcmpi(path + len - extlen, ext);
326- }
327-
328- inline const IMAGE_NT_HEADERS32* getNtHeaders(HMODULE base)
329- {
330- const IMAGE_DOS_HEADER* dos = reinterpret_cast<const IMAGE_DOS_HEADER*>(base);
331- return reinterpret_cast<const IMAGE_NT_HEADERS32*>(reinterpret_cast<const char*>(base) + dos->e_lfanew);
110+ oldoffset = 0;
111+ *ploaded = 0;
112+ scriptbuf[0] = '\0';
113+ socketproc(engineproc, path, editp);
332114 }
115+}
333116
334- inline DWORD getTimeStamp(HMODULE base)
117+namespace
118+{
119+ BOOL init(FILTER*)
335120 {
336- return getNtHeaders(base)->FileHeader.TimeDateStamp;
337- }
121+ const ScriptEngineCoreImplement::patchdata* p{getpatch()};
122+ if(!p) return FALSE;
338123
339- inline size_t getTextSectionSize(HMODULE base)
340- {
341- return getNtHeaders(base)->OptionalHeader.SizeOfCode;
124+ AviUtlUI::AddMenu();
125+ ScriptEngineCoreImplement::core.apply(p);
126+ return TRUE;
342127 }
343128
344- const patchdata* getpatch()
129+ const ScriptEngineCoreImplement::patchdata* getpatch()
345130 {
346- static constexpr patchdata VER_0_99_k = makeVer1Patch(0xC7F0, 0x14F60, 0x22A80);
347- static constexpr patchdata VER_0_99_k2 = makeVer1Patch(0xC830, 0x14F90, 0x22BF0);
348- static constexpr patchdata VER_0_99_l = makeVer1Patch(0xC8F0, 0x15120, 0x22DC0);
349- static constexpr patchdata VER_0_99_m = makeVer1Patch(0xC950, 0x151B0, 0x22EA0);
350- static constexpr patchdata VER_1_00 = makeVer1Patch(0xC990, 0x15260, 0x22F70);
131+ static auto VER_0_99_k = ScriptEngineCoreImplement::makeVer1Patch(0xC7F0, 0x14F60, 0x22A80);
132+ static auto VER_0_99_k2 = ScriptEngineCoreImplement::makeVer1Patch(0xC830, 0x14F90, 0x22BF0);
133+ static auto VER_0_99_l = ScriptEngineCoreImplement::makeVer1Patch(0xC8F0, 0x15120, 0x22DC0);
134+ static auto VER_0_99_m = ScriptEngineCoreImplement::makeVer1Patch(0xC950, 0x151B0, 0x22EA0);
135+ static auto VER_1_00 = ScriptEngineCoreImplement::makeVer1Patch(0xC990, 0x15260, 0x22F70);
351136
352- static constexpr patchdata VER_1_10_rc1 = makeVer2Patch(0xF910, 0x1A0A0, 0x2C010);
353- static constexpr patchdata VER_1_10_rc2 = makeVer2Patch(0xFAE0, 0x1A270, 0x2C1E0);
354- static constexpr patchdata VER_1_10 = makeVer2Patch(0xFA20, 0x1A1A0, 0x2C0F0);
137+ static auto VER_1_10_rc1 = ScriptEngineCoreImplement::makeVer2Patch(0xF910, 0x1A0A0, 0x2C010);
138+ static auto VER_1_10_rc2 = ScriptEngineCoreImplement::makeVer2Patch(0xFAE0, 0x1A270, 0x2C1E0);
139+ static auto VER_1_10 = ScriptEngineCoreImplement::makeVer2Patch(0xFA20, 0x1A1A0, 0x2C0F0);
355140
356141 switch(getTimeStamp(GetModuleHandleA(nullptr))){
357142 case 0x4F01F831: return &VER_0_99_k;
@@ -366,11 +151,28 @@ namespace
366151 return nullptr;
367152 }
368153
154+ inline const IMAGE_NT_HEADERS32* getNtHeaders(HMODULE base)
155+ {
156+ const auto dos{ reinterpret_cast<const IMAGE_DOS_HEADER*>(base) };
157+ return reinterpret_cast<const IMAGE_NT_HEADERS32*>(reinterpret_cast<const char*>(base) + dos->e_lfanew);
158+ }
159+
160+ inline DWORD getTimeStamp(HMODULE base)
161+ {
162+ return getNtHeaders(base)->FileHeader.TimeDateStamp;
163+ }
164+
165+ inline size_t getTextSectionSize(HMODULE base)
166+ {
167+ return getNtHeaders(base)->OptionalHeader.SizeOfCode;
168+ }
169+
369170 void writecaller(void* dest, const void* proc, size_t opsize)
370171 {
371- BYTE opcodes[] = {
372- 0xE8, '\0', '\0', '\0', '\0', 0x90, 0x90, 0x90,
373- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
172+ constexpr std::byte call{0xE8}, nop{0x90}, XXX{};
173+ std::byte opcodes[]{
174+ call, XXX, XXX, XXX, XXX, nop, nop, nop,
175+ nop , nop, nop, nop, nop, nop, nop, nop
374176 };
375177 writeptr(&opcodes[1], static_cast<const char*>(proc) - (reinterpret_cast<size_t>(dest) + 5));
376178 modifycode(dest, opcodes, opsize);
@@ -389,11 +191,3 @@ namespace
389191 VirtualProtect(dest, size, protect, &protect);
390192 }
391193 }
392-
393-void LoadScript(const char* path, void *editp)
394-{
395- oldoffset = 0;
396- *ploaded = 0;
397- scriptbuf[0] = '\0';
398- socketproc(editp, path);
399-}
--- /dev/null
+++ b/coreimp.h
@@ -0,0 +1,43 @@
1+#pragma once
2+
3+namespace ScriptEngineCoreImplement
4+{
5+ class coredata{
6+ private:
7+ char* scriptbuf;
8+ size_t* ploaded;
9+ size_t oldoffset;
10+ const void* engineproc;
11+ void (*socketproc)(const void*, const char*, void*);
12+
13+ public:
14+ void apply(const struct patchdata*);
15+ void loadscript(const char*, void*);
16+ };
17+
18+ struct patchdata{
19+ size_t offset_buf;
20+ size_t offset_loaded;
21+ struct{
22+ size_t offset;
23+ void (*socketproc)(const void*, const char*, void*);
24+ } engine;
25+ struct{
26+ size_t offset;
27+ const void* proc;
28+ size_t bytes;
29+ } patch[5];
30+ };
31+
32+ patchdata makeVer1Patch(size_t, size_t, size_t);
33+ patchdata makeVer2Patch(size_t, size_t, size_t);
34+
35+ size_t recalc(size_t, size_t, const char*);
36+ bool is_aup_path(const char*);
37+ char* erase_exe_name(char*);
38+ const void* memrchr(const void*, int, size_t);
39+
40+ static constexpr size_t bufsize{0x1000};
41+
42+ extern coredata core;
43+}
--- a/parser.cpp
+++ b/parser.cpp
@@ -1,69 +1,38 @@
11 #include "stdafx.h"
2-#include <commdlg.h>
3-#include <algorithm>
4-#include <typeinfo>
2+#include <cstdio>
3+#include <cctype>
54
6-#include "apihook.h"
75 #include "command.h"
8-#include "core.h"
96 #include "parser.h"
10-#include "ui.h"
117
128 namespace
139 {
1410 bool is_comment(const char*);
15- bool is_loading_script(const char*);
16- size_t starts_with(const char*, const char*);
17- size_t ends_with(const char*, const char*);
18- bool has_argument(const char*);
19- const char* skiparg(const char*);
2011 }
2112
2213 bool SubParser(const char* script)
2314 {
2415 if(is_comment(script)) return false;
25- if(is_loading_script(script)) return false;
2616
27- size_t match;
28- if(match = starts_with(script, "exedit ")){
29- HMODULE base = GetModuleHandleA("exedit.auf");
30- if(!base) return false;
17+ if(size_t offset{}; sscanf_s(script, "%*[Ee]%*[Xx]%*[Ee]%*[Dd]%*[Ii]%*[Tt] %n", &offset) >= 0 && offset > 0){
18+ if(!GetModuleHandleA("exedit.auf")) return false;
3119
32- script += match;
20+ script += offset;
3321
34- unsigned int params[4];
35- if(sscanf_s(script, "new %u, %u, %u, %u", &params[0], &params[1], &params[2], &params[3]) == 4){
36- AviUtlCommand::CreateProject(params[0], params[1], params[2], params[3]);
22+ if(size_t cx, cy, fps, freq; sscanf_s(script, "%*[Nn]%*[Ee]%*[Ww] %u , %u , %u , %u", &cx, &cy, &fps, &freq) == 4){
23+ ExeditCommand::CreateProject(cx, cy, fps, freq);
3724 return false;
3825 }
39- else if(match = starts_with(script, "openexo ")){
40- script += match;
41- AviUtlCommand::OpenExoFile(script);
26+ else if(size_t offset{}; sscanf_s(script, "%*[Oo]%*[Pp]%*[Ee]%*[Nn]%*[Ee]%*[Xx]%*[Oo] %n", &offset) >= 0 && offset > 0){
27+ ExeditCommand::OpenExoFile(script + offset);
4228 return false;
4329 }
44- else if(sscanf_s(script, "switchscene #%u", &params[0]) == 1){
45- AviUtlCommand::SwitchScene(params[0]);
30+ else if(size_t id; sscanf_s(script, "%*[Ss]%*[Ww]%*[Ii]%*[Tt]%*[Cc]%*[Hh]%*[Ss]%*[Cc]%*[Ee]%*[Nn]%*[Ee] #%u", &id) == 1){
31+ ExeditCommand::SwitchScene(id);
4632 return false;
4733 }
48- else if(match = starts_with(script, "transparentscene ")){
49- script += match;
50- AviUtlCommand::TransparentScene(script[0] != 'f');
51- return false;
52- }
53- }
54- else{
55- script = skiparg(script);
56- if((script[0] == '-' || script[0] == '/') && (script[1] == 'q' || script[1] == 'Q')){
57- script += 2;
58- if(!has_argument(script)){
59- AviUtlCommand::Quit();
60- return false;
61- }
62- }
63- else if((script[0] == '-' || script[0] == '/') && (script[1] == 'o' || script[1] == 'O')){
64- script += 2;
65- while(*script == ' ') script++;
66- AviUtlCommand::SaveProject(script);
34+ else if(size_t offset{}; sscanf_s(script, "%*[Tt]%*[Rr]%*[Aa]%*[Nn]%*[Ss]%*[Pp]%*[Aa]%*[Rr]%*[Ee]%*[Nn]%*[Tt]%*[Ss]%*[Cc]%*[Ee]%*[Nn]%*[Ee] %n", &offset) >= 0 && offset > 0){
35+ ExeditCommand::TransparentScene(std::toupper(script[offset]) != 'F');
6736 return false;
6837 }
6938 }
@@ -74,58 +43,9 @@ namespace
7443 {
7544 bool is_comment(const char* str)
7645 {
77- return str[0] == ';';
78- }
46+ static constexpr char head[]{"rem "};
47+ static constexpr size_t size{ sizeof(head) - sizeof(head[0]) };
7948
80- bool is_loading_script(const char* script)
81- {
82- script = skiparg(script);
83- while(*script){
84- if(*script != '-' && *script != '/'){
85- if(*script == '\"'){
86- if(ends_with(script, ".aus") || ends_with(script, ".aus\"")) return true;
87- }
88- else{
89- if(ends_with(script, ".aus") || ends_with(script, ".aus ")) return true;
90- }
91- }
92- script = skiparg(script);
93- }
94- return false;
95- }
96-
97- size_t starts_with(const char* str, const char* pat)
98- {
99- size_t n = std::strlen(pat);
100- if(!_strnicmp(pat, str, n)) return n;
101- return 0;
102- }
103-
104- size_t ends_with(const char* str, const char* pat)
105- {
106- size_t m = std::strlen(str);
107- size_t n = std::strlen(pat);
108- if(m >= n && !_strnicmp(pat, str + m - n, n)) return n;
109- return 0;
110- }
111-
112- bool has_argument(const char* script)
113- {
114- while(*script == ' ') script++;
115- return !!*script;
116- }
117-
118- const char* skiparg(const char* script)
119- {
120- while(*script == ' ') script++;
121- if(!*script) return script;
122-
123- char del = ' ';
124- if(*script++ == '\"') del = '\"';
125- while(*script){
126- if(*script++ == del) break;
127- }
128- while(*script == ' ') script++;
129- return script;
49+ return str[0] == ';' || !_memicmp(str, head, size);
13050 }
13151 }
--- a/ui.cpp
+++ b/ui.cpp
@@ -1,12 +1,14 @@
11 #include "stdafx.h"
22 #include <commdlg.h>
33 #include <algorithm>
4+#include <memory>
45 #include "core.h"
56 #include "ui.h"
67
78 namespace
89 {
9- int findmenu(HMENU, const char*, HMENU*);
10+ int findmenu(HMENU, const char*);
11+ void onImport(HWND, void*);
1012 }
1113
1214 namespace AviUtlUI
@@ -14,7 +16,8 @@ namespace AviUtlUI
1416 HWND GetMainWindow()
1517 {
1618 HWND ret = nullptr;
17- EnumThreadWindows(GetCurrentThreadId(), static_cast<WNDENUMPROC>([](HWND hwnd, LPARAM data) -> BOOL {
19+ EnumThreadWindows(GetCurrentThreadId(), static_cast<WNDENUMPROC>(
20+ [](HWND hwnd, LPARAM data) -> BOOL {
1821 char buf[16];
1922 GetClassNameA(hwnd, buf, std::size(buf));
2023 if(_strcmpi(buf, "AviUtl")) return TRUE;
@@ -23,22 +26,23 @@ namespace AviUtlUI
2326 return FALSE;
2427 }), reinterpret_cast<LPARAM>(&ret));
2528
26- while(HWND owner = GetWindow(ret, GW_OWNER)) ret = owner;
29+ while(HWND owner = GetWindow(ret, GW_OWNER)){
30+ ret = owner;
31+ }
2732
2833 return ret;
2934 }
3035
3136 void AddMenu()
3237 {
33- HMENU file = GetSubMenu(GetMenu(GetMainWindow()), 0);
34- HMENU imp = nullptr;
35- findmenu(file, "インポート", &imp);
36- const int delpos = findmenu(imp, "Script Engine", nullptr);
38+ const HMENU file = GetSubMenu(GetMenu(GetMainWindow()), 0);
39+ const HMENU imp = GetSubMenu(file, findmenu(file, "インポート"));
40+ const int delpos = findmenu(imp, "Script Engine");
3741 if(delpos < 0) return;
38- const int inspos = findmenu(file, "AVI出力 (Ctrl+S)", nullptr);
42+ const int inspos = findmenu(file, "AVI出力 (Ctrl+S)");
3943 if(inspos < 0) return;
4044
41- UINT id = GetMenuItemID(imp, delpos);
45+ const UINT id = GetMenuItemID(imp, delpos);
4246 DeleteMenu(imp, delpos, MF_BYPOSITION);
4347
4448 const MENUITEMINFOA load { sizeof(load), MIIM_ID | MIIM_TYPE, MFT_STRING, MFS_ENABLED, id, nullptr, nullptr, nullptr, 0, const_cast<char*>("スクリプト読み込み"), 0, nullptr };
@@ -51,11 +55,7 @@ namespace AviUtlUI
5155 BOOL WndProc(HWND hwnd, UINT msg, WPARAM, LPARAM, void* editp, FILTER*)
5256 {
5357 if(msg == WM_FILTER_IMPORT){
54- char path[MAX_PATH] = "";
55- OPENFILENAMEA ofn{ sizeof(ofn), hwnd, nullptr, "Script Files(*.aus)\0*.aus\0\0", nullptr, 0, 1, path, std::size(path), nullptr, 0, "", nullptr, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, 0, 0, "aus", 0, nullptr, nullptr, nullptr, 0, 0 };
56- if(!GetOpenFileNameA(&ofn)) return FALSE;
57-
58- LoadScript(path, editp);
58+ onImport(hwnd, editp);
5959 }
6060 return FALSE;
6161 }
@@ -63,20 +63,28 @@ namespace AviUtlUI
6363
6464 namespace
6565 {
66- int findmenu(HMENU menu, const char* name, HMENU* psub)
66+ int findmenu(HMENU menu, const char* name)
6767 {
68- char buf[128];
68+ const size_t size = std::strlen(name) + 3;
69+ const auto buf = std::make_unique<char[]>(size);
6970
70- int ncolumn = GetMenuItemCount(menu);
71+ const int ncolumn = GetMenuItemCount(menu);
7172 for(int i = 0; i < ncolumn; i++){
72- MENUITEMINFOA mi { sizeof(mi), MIIM_TYPE | MIIM_SUBMENU, 0, 0, 0, nullptr, nullptr, nullptr, 0, buf, std::size(buf), nullptr };
73+ MENUITEMINFOA mi { sizeof(mi), MIIM_TYPE, 0, 0, 0, nullptr, nullptr, nullptr, 0, buf.get(), size, nullptr };
7374 GetMenuItemInfoA(menu, i, TRUE, &mi);
74- if(mi.fType != MFT_STRING || std::strcmp(buf, name)) continue;
7575
76- if(psub) *psub = mi.hSubMenu;
76+ if(mi.fType != MFT_STRING || std::strcmp(buf.get(), name)) continue;
7777 return i;
7878 }
79- if(psub) *psub = nullptr;
8079 return -1;
8180 }
81+
82+ void onImport(HWND hwnd, void* editp)
83+ {
84+ char path[MAX_PATH] = "";
85+ OPENFILENAMEA ofn{ sizeof(ofn), hwnd, nullptr, "Script Files(*.aus)\0*.aus\0\0", nullptr, 0, 1, path, std::size(path), nullptr, 0, "", nullptr, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, 0, 0, "aus", 0, nullptr, nullptr, nullptr, 0, 0 };
86+ if(!GetOpenFileNameA(&ofn)) return;
87+
88+ LoadScript(path, editp);
89+ }
8290 }
--- /dev/null
+++ b/v1patch.cpp
@@ -0,0 +1,123 @@
1+#include "stdafx.h"
2+#include "command.h"
3+#include "coreimp.h"
4+#include "parser.h"
5+#include "ui.h"
6+
7+namespace
8+{
9+ void Socket(const void*, const char*, void*);
10+ void ClearBuffer();
11+ void Reload();
12+ void Reset();
13+ void Loader();
14+ void Save();
15+}
16+
17+namespace ScriptEngineCoreImplement
18+{
19+ patchdata makeVer1Patch(size_t offset_engine, size_t offset_saver, size_t offset_parser)
20+ {
21+ return { offset_parser + 0x48, offset_parser + 0x40,
22+ { offset_engine, Socket },
23+ {
24+ { offset_engine + 0x2D, ClearBuffer, 5 },
25+ { offset_parser + 0x07, Reload, 6 },
26+ { offset_parser + 0x2E, Reset, 5 },
27+ { offset_engine + 0x47, Loader, 5 },
28+ { offset_saver + 0x8E8, Save, 6 }
29+ }
30+ };
31+ }
32+}
33+
34+namespace
35+{
36+ void Socket(const void* proc, const char* path, void* editp)
37+ {
38+ reinterpret_cast<void(_cdecl*)(void*, const char*)>(proc)(editp, path);
39+ }
40+
41+ __declspec(naked) void ClearBuffer()
42+ {
43+ __asm{
44+ lea ecx, [esp+8]
45+ pop edx
46+ mov byte ptr [ecx], 0
47+ push ecx
48+ push edx
49+ ret
50+ }
51+ }
52+
53+ __declspec(naked) void Reload()
54+ {
55+ __asm{
56+ mov eax, (ScriptEngineCoreImplement::core.ploaded)
57+ push (ScriptEngineCoreImplement::core.scriptbuf)
58+ push (ScriptEngineCoreImplement::core.oldoffset)
59+ push [eax]
60+ call ScriptEngineCoreImplement::recalc
61+ mov edi, (ScriptEngineCoreImplement::core.ploaded)
62+ add esp, 12
63+ mov [edi], eax
64+ mov (ScriptEngineCoreImplement::core.oldoffset), eax
65+ mov edi, [esp+0x14]
66+ mov esi, ebp
67+ ret
68+ }
69+ }
70+
71+ __declspec(naked) void Reset()
72+ {
73+ __asm{
74+ mov (ScriptEngineCoreImplement::core.oldoffset), 0
75+ cmp eax, ScriptEngineCoreImplement::bufsize
76+ ret
77+ }
78+ }
79+
80+ __declspec(naked) void Loader()
81+ {
82+ __asm{
83+ lea edx, [esp+12]
84+ push edx
85+ push edx
86+ call SubParser
87+ add esp, 4
88+ test eax, eax
89+ je SKIP_PARSE
90+ call ScriptEngineCoreImplement::erase_exe_name
91+ SKIP_PARSE:
92+ add esp, 4
93+ pop edx
94+ push eax
95+ push edx
96+ ret
97+ }
98+ }
99+
100+ __declspec(naked) void Save()
101+ {
102+ __asm{
103+ cmp [ebp+0x4BC498], 0
104+ jne SAVE_AVI_OR_WAV
105+ lea eax, [ebp+0x108]
106+ push eax
107+ call ScriptEngineCoreImplement::is_aup_path
108+ add esp, 4
109+ test eax, eax
110+ jne SAVE_AUP
111+ SAVE_AVI_OR_WAV:
112+ mov dl, [ebp+0x4BC198]
113+ ret
114+ SAVE_AUP:
115+ lea eax, [ebp+0x108]
116+ add dword ptr [esp], 0x10B
117+ push eax
118+ call AviUtlCommand::SaveProject
119+ add esp, 4
120+ ret
121+ }
122+ }
123+}
--- /dev/null
+++ b/v2patch.cpp
@@ -0,0 +1,117 @@
1+#include "stdafx.h"
2+#include "command.h"
3+#include "coreimp.h"
4+#include "parser.h"
5+#include "ui.h"
6+
7+namespace
8+{
9+ void Socket(const void*, const char*, void*);
10+ void ClearBuffer();
11+ void Reload();
12+ void Reset();
13+ void Loader();
14+ void Save();
15+}
16+
17+namespace ScriptEngineCoreImplement
18+{
19+ patchdata makeVer2Patch(size_t offset_engine, size_t offset_saver, size_t offset_parser)
20+ {
21+ return { offset_parser + 0x64, offset_parser + 0x5E,
22+ { offset_engine, Socket },
23+ {
24+ { offset_engine + 0x42D, ClearBuffer, 7 },
25+ { offset_parser + 0x20, Reload, 5 },
26+ { offset_parser + 0x48, Reset, 8 },
27+ { offset_engine + 0x450, Loader, 7 },
28+ { offset_saver + 0xC8D, Save, 7 }
29+ }
30+ };
31+ }
32+}
33+
34+namespace
35+{
36+ void Socket(const void* proc, const char* path, void* editp)
37+ {
38+ reinterpret_cast<void(__fastcall*)(void*, const char*)>(proc)(editp, path);
39+ }
40+
41+ __declspec(naked) void ClearBuffer()
42+ {
43+ __asm{
44+ lea edx, [esp+0x44C]
45+ mov byte ptr [edx], 0
46+ ret
47+ }
48+ }
49+
50+ __declspec(naked) void Reload()
51+ {
52+ __asm{
53+ push ecx
54+ mov eax, (ScriptEngineCoreImplement::core.ploaded)
55+ push (ScriptEngineCoreImplement::core.scriptbuf)
56+ push (ScriptEngineCoreImplement::core.oldoffset)
57+ push [eax]
58+ call ScriptEngineCoreImplement::recalc
59+ add esp, 12
60+ mov (ScriptEngineCoreImplement::core.oldoffset), eax
61+ pop ecx
62+ ret
63+ }
64+ }
65+
66+ __declspec(naked) void Reset()
67+ {
68+ __asm{
69+ mov eax, dword ptr [ebp-8]
70+ mov (ScriptEngineCoreImplement::core.oldoffset), 0
71+ cmp eax, ScriptEngineCoreImplement::bufsize
72+ ret
73+ }
74+ }
75+
76+ __declspec(naked) void Loader()
77+ {
78+ __asm{
79+ lea edx, [esp+0x44C]
80+ push edx
81+ push edx
82+ call SubParser
83+ add esp, 4
84+ test eax, eax
85+ je SKIP_PARSE
86+ call ScriptEngineCoreImplement::erase_exe_name
87+ SKIP_PARSE:
88+ add esp, 4
89+ mov edx, eax
90+ ret
91+ }
92+ }
93+
94+ __declspec(naked) void Save()
95+ {
96+ __asm{
97+ cmp [ebx+0x4BC498], 0
98+ jne SAVE_AVI_OR_WAV
99+ lea eax, [ebx+0x108]
100+ push eax
101+ call ScriptEngineCoreImplement::is_aup_path
102+ add esp, 4
103+ test eax, eax
104+ jne SAVE_AUP
105+ SAVE_AVI_OR_WAV:
106+ cmp byte ptr [ebx+0x4BC198], 0
107+ ret
108+ SAVE_AUP:
109+ lea eax, [ebx+0x108]
110+ add dword ptr [esp], 0xC01
111+ push eax
112+ call AviUtlCommand::SaveProject
113+ add esp, 4
114+ ret
115+ }
116+ }
117+}