-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdll.cpp
More file actions
211 lines (178 loc) · 5.78 KB
/
Copy pathdll.cpp
File metadata and controls
211 lines (178 loc) · 5.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#include "dll.hpp" // 项目内导出
#include "nvdll_impl.h" // API 导出
// -- [sys] win
#include <stdlib.h> // _wsplitpath_s, _wmakepath_s
#include <strsafe.h> // StringCchPrintf
#include <sstream> // stringstream
#include <string> // wstring
#include <vector> // vector
// -- 3rd
#include "boysr.hpp"
#include "zdsr.hpp"
// -- [proj]
#include "log.hpp" // nvdll::log::; DLOG_F
namespace nvdll {
#pragma region 全局变量定义
/// DLL 所在文件夹路径
TCHAR DLL_DIR_PATH[MAX_PATH];
HMODULE dllHandle;
#pragma region
/**
* 打印 DLL 信息
*/
void printDllInfo()
{
spdlog::info("BaoYi-fake-nvdaControllerClient");
spdlog::info(" Github URL: https://github.com/sig-a11y/BaoYi-fake-nvdaControllerClient");
spdlog::info(" Author: inkydragon @ github");
// DLL 接口信息
spdlog::info("DLL Compiled at: {} {}", __DATE__, __TIME__);
spdlog::info(" NVDA Client API Version: {}", nvdll::NVDA_API_VERSION);
# ifdef FAKE_NVDA_ZDSR
spdlog::info(L" ZDSR Dll API Version: {}", zdsr_api::DLL_VERSION);
# else
spdlog::info(L" BaoYi Dll API Version: {}", boysr_api::DLL_VERSION);
# endif
}
/**
* @brief 获取并保存 DLL 所在文件夹路径.
* @param hinstDLL DLL 实例句柄
*/
void saveDllDirPath(HINSTANCE hinstDLL)
{
spdlog::info(L"Get DLL Path...");
/// DLL 路径
TCHAR DLL_PATH[MAX_PATH];
// 获取 DLL 完整路径
GetModuleFileName(hinstDLL, DLL_PATH, MAX_PATH);
// -- 打印完整路径
spdlog::debug(L" NVDA DLL Path:\t{}", DLL_PATH);
// -- 拆分路径
std::wstring filename;
/// 盘符
std::vector<wchar_t> disk(8);
/// 层级路径(不含盘符、最终文件名)
std::vector<wchar_t> dirname(1024);
filename = DLL_PATH;
_wsplitpath_s(
filename.c_str(),
disk.data(), _MAX_DRIVE,
dirname.data(), _MAX_DIR,
nullptr, 0,
nullptr, 0
);
// 拼接文件夹路径
_wmakepath_s(DLL_DIR_PATH, disk.data(), dirname.data(), NULL, NULL);
// 打印文件夹路径
spdlog::debug(L" DLL DIR PATH:\t{}", DLL_DIR_PATH);
// -- 拼接 DLL 完整路径
# ifdef FAKE_NVDA_ZDSR
StringCchPrintfW(zdsr::DLL_FULLPATH, MAX_PATH, L"%s\\%s", DLL_DIR_PATH, zdsr_api::DLL_NAME);
spdlog::info(L" SR DLL path:\t{}", zdsr::DLL_FULLPATH);
# else
StringCchPrintfW(boy::BOY_DLL_FULLPATH, MAX_PATH, L"%s\\%s", DLL_DIR_PATH, boysr_api::DLL_NAME);
spdlog::info(L" SR DLL path:\t{}", boy::BOY_DLL_FULLPATH);
# endif
}
/// 加载函数指针
FARPROC loadFunctionPtr(LPCSTR lpProcName)
{
if (nullptr == dllHandle)
{
spdlog::error("[loadFunctionPtr] nullptr == dllHandle, ret.");
return nullptr;
}
SPDLOG_DEBUG("[loadFunctionPtr] GetProcAddress(dllHandle={}, lpProcName={})",
(void*)dllHandle, lpProcName);
auto funcHandle = GetProcAddress(dllHandle, lpProcName);
if (!funcHandle)
{
spdlog::error("[loadFunctionPtr] Failed to get '{}'", lpProcName);
freeDll();
return nullptr;
}
SPDLOG_DEBUG("[loadFunctionPtr] load {} @ {}", lpProcName, (void*)funcHandle);
return funcHandle;
}
void loadDLL()
{
#ifdef FAKE_NVDA_ZDSR
nvdll::zdsr::loadDLL();
#else
nvdll::boy::loadDLL();
#endif
}
/// 释放 DLL
void freeDll()
{
SPDLOG_DEBUG("[freeDll] trying to free DLL: dllHandle={}", (void*)dllHandle);
if (nullptr != dllHandle)
{
bool freeRet = FreeLibrary(dllHandle);
// 成功,则返回值为非零值。
if (!freeRet) {
spdlog::error("[freeDll] FreeLibrary ret={}", (void*)dllHandle);
}
else
{
SPDLOG_DEBUG("[freeDll] FreeLibrary ret={}", (void*)dllHandle);
}
}
SPDLOG_DEBUG("[freeDll] After FreeLibrary: dllHandle={}", (void*)dllHandle);
}
} // nvdll::
#pragma region DLL 导出函数实现
error_status_t __stdcall testIfRunning_impl()
{
#ifdef FAKE_NVDA_ZDSR
return nvdll::zdsr::testIfRunning_impl();
#else
return nvdll::boy::testIfRunning_impl();
#endif
}
error_status_t __stdcall speakText_impl(const wchar_t* text)
{
#ifdef FAKE_NVDA_ZDSR
return nvdll::zdsr::speakText_impl(text);
#else
return nvdll::boy::speakText_impl(text);
#endif
}
error_status_t __stdcall cancelSpeech_impl()
{
#ifdef FAKE_NVDA_ZDSR
return nvdll::zdsr::cancelSpeech_impl();
#else
return nvdll::boy::cancelSpeech_impl();
#endif
}
error_status_t __stdcall brailleMessage_impl(const wchar_t* message)
{
return RPC_S_CANNOT_SUPPORT;
}
/* V2.0 functions */
error_status_t __stdcall getProcessId_impl(unsigned long* pid)
{
if (nullptr != pid)
{
spdlog::debug("[getProcessId_impl] *pid={}", *pid); // 发布版本输出
}
spdlog::debug("[getProcessId_impl] pid={}", (void*)pid); // 发布版本输出
return RPC_S_CANNOT_SUPPORT;
}
error_status_t __stdcall speakSsml_impl(
const wchar_t* ssml,
const enum SYMBOL_LEVEL symbolLevel = SYMBOL_LEVEL_UNCHANGED,
const enum SPEECH_PRIORITY priority = SPEECH_PRIORITY_NORMAL,
const bool asynchronous = true)
{
spdlog::debug(L"[speakSsml_impl] ssml={}, symbolLevel={}, priority={}, asynchronous={}",
ssml, (int)symbolLevel, (int)priority, asynchronous);
return RPC_S_CANNOT_SUPPORT;
}
error_status_t __stdcall setOnSsmlMarkReachedCallback_impl(onSsmlMarkReachedFuncType callback)
{
spdlog::debug("[setOnSsmlMarkReachedCallback_impl] callback={}", (void*)callback);
return RPC_S_CANNOT_SUPPORT;
}
#pragma endregion