mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-11-30 17:15:38 +08:00
fmt
This commit is contained in:
parent
b0b1fe4417
commit
7324cf4229
@ -4,11 +4,25 @@
|
|||||||
// 8/23/2013 jichi
|
// 8/23/2013 jichi
|
||||||
// Branch: ITH/common.h, rev 128
|
// Branch: ITH/common.h, rev 128
|
||||||
|
|
||||||
enum { STRING = 12, MESSAGE_SIZE = 500, PIPE_BUFFER_SIZE = 50000, SHIFT_JIS = 932, MAX_MODULE_SIZE = 120, PATTERN_SIZE = 30, HOOK_NAME_SIZE = 60, FIXED_SPLIT_VALUE = 0x10001 ,
|
enum
|
||||||
HOOKCODE_LEN=500};
|
{
|
||||||
enum WildcardByte { XX = 0x11 };
|
STRING = 12,
|
||||||
|
MESSAGE_SIZE = 500,
|
||||||
|
PIPE_BUFFER_SIZE = 50000,
|
||||||
|
SHIFT_JIS = 932,
|
||||||
|
MAX_MODULE_SIZE = 120,
|
||||||
|
PATTERN_SIZE = 30,
|
||||||
|
HOOK_NAME_SIZE = 60,
|
||||||
|
FIXED_SPLIT_VALUE = 0x10001,
|
||||||
|
HOOKCODE_LEN = 500
|
||||||
|
};
|
||||||
|
enum WildcardByte
|
||||||
|
{
|
||||||
|
XX = 0x11
|
||||||
|
};
|
||||||
|
|
||||||
enum HostCommandType {
|
enum HostCommandType
|
||||||
|
{
|
||||||
HOST_COMMAND_NEW_HOOK,
|
HOST_COMMAND_NEW_HOOK,
|
||||||
HOST_COMMAND_REMOVE_HOOK,
|
HOST_COMMAND_REMOVE_HOOK,
|
||||||
HOST_COMMAND_FIND_HOOK,
|
HOST_COMMAND_FIND_HOOK,
|
||||||
@ -17,7 +31,8 @@ enum HostCommandType {
|
|||||||
HOST_COMMAND_DETACH
|
HOST_COMMAND_DETACH
|
||||||
};
|
};
|
||||||
|
|
||||||
enum HostNotificationType {
|
enum HostNotificationType
|
||||||
|
{
|
||||||
HOST_NOTIFICATION_TEXT,
|
HOST_NOTIFICATION_TEXT,
|
||||||
HOST_NOTIFICATION_NEWHOOK,
|
HOST_NOTIFICATION_NEWHOOK,
|
||||||
HOST_NOTIFICATION_FOUND_HOOK,
|
HOST_NOTIFICATION_FOUND_HOOK,
|
||||||
@ -76,7 +91,6 @@ enum HookParamType : uint64_t
|
|||||||
NEXT_MASK(HOOK_EMPTY),
|
NEXT_MASK(HOOK_EMPTY),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum HookFontType : unsigned
|
enum HookFontType : unsigned
|
||||||
{
|
{
|
||||||
DECLARE_VALUE(NOT_HOOK_FONT, 0),
|
DECLARE_VALUE(NOT_HOOK_FONT, 0),
|
||||||
|
@ -35,7 +35,8 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @addr
|
// @addr
|
||||||
if (!std::regex_match(RCode, match, std::wregex(L"@([[:xdigit:]]+)"))) return {};
|
if (!std::regex_match(RCode, match, std::wregex(L"@([[:xdigit:]]+)")))
|
||||||
|
return {};
|
||||||
hp.address = std::stoull(match[1], nullptr, 16);
|
hp.address = std::stoull(match[1], nullptr, 16);
|
||||||
return hp;
|
return hp;
|
||||||
}
|
}
|
||||||
@ -43,7 +44,8 @@ namespace
|
|||||||
std::optional<HookParam> ParseHCode(std::wstring HCode, std::optional<HookParam> hpo = {})
|
std::optional<HookParam> ParseHCode(std::wstring HCode, std::optional<HookParam> hpo = {})
|
||||||
{
|
{
|
||||||
auto hp = hpo ? hpo.value() : HookParam{};
|
auto hp = hpo ? hpo.value() : HookParam{};
|
||||||
if(HCode[0]=='L'){
|
if (HCode[0] == 'L')
|
||||||
|
{
|
||||||
hp.type |= HOOK_RETURN;
|
hp.type |= HOOK_RETURN;
|
||||||
HCode.erase(0, 1);
|
HCode.erase(0, 1);
|
||||||
}
|
}
|
||||||
@ -112,7 +114,6 @@ namespace
|
|||||||
hp.type |= FULL_STRING;
|
hp.type |= FULL_STRING;
|
||||||
HCode.erase(0, 1);
|
HCode.erase(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// [N]
|
// [N]
|
||||||
@ -141,7 +142,13 @@ namespace
|
|||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
int value = 0;
|
int value = 0;
|
||||||
try { value = std::stoi(HCode, &size, 16); } catch (std::invalid_argument) {}
|
try
|
||||||
|
{
|
||||||
|
value = std::stoi(HCode, &size, 16);
|
||||||
|
}
|
||||||
|
catch (std::invalid_argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
HCode.erase(0, size);
|
HCode.erase(0, size);
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
@ -171,8 +178,10 @@ namespace
|
|||||||
hp.split_index = ConsumeHexInt();
|
hp.split_index = ConsumeHexInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(hp.jittype==JITTYPE::UNITY){
|
if (hp.jittype == JITTYPE::UNITY)
|
||||||
if(HCode[0]!=L'@')return {};
|
{
|
||||||
|
if (HCode[0] != L'@')
|
||||||
|
return {};
|
||||||
HCode.erase(0, 1);
|
HCode.erase(0, 1);
|
||||||
HCode = HCode.substr(0, HCode.size() - wcslen(L":JIT:UNITY"));
|
HCode = HCode.substr(0, HCode.size() - wcslen(L":JIT:UNITY"));
|
||||||
hp.argidx = hp.offset;
|
hp.argidx = hp.offset;
|
||||||
@ -184,10 +193,12 @@ namespace
|
|||||||
wcscpy(hp.module, L"");
|
wcscpy(hp.module, L"");
|
||||||
strcpy(hp.unityfunctioninfo, wcasta(HCode).c_str());
|
strcpy(hp.unityfunctioninfo, wcasta(HCode).c_str());
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
|
|
||||||
// @addr[:module[:func]]
|
// @addr[:module[:func]]
|
||||||
if (!std::regex_match(HCode, match, std::wregex(L"^@([[:xdigit:]]+)(:.+?)?(:.+)?"))) return {};
|
if (!std::regex_match(HCode, match, std::wregex(L"^@([[:xdigit:]]+)(:.+?)?(:.+)?")))
|
||||||
|
return {};
|
||||||
hp.address = std::stoull(match[1], nullptr, 16);
|
hp.address = std::stoull(match[1], nullptr, 16);
|
||||||
if (match[2].matched)
|
if (match[2].matched)
|
||||||
{
|
{
|
||||||
@ -202,10 +213,13 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ITH has registers offset by 4 vs AGTH: need this to correct
|
// ITH has registers offset by 4 vs AGTH: need this to correct
|
||||||
if (hp.offset < 0) hp.offset -= 4;
|
if (hp.offset < 0)
|
||||||
if (hp.split < 0) hp.split -= 4;
|
hp.offset -= 4;
|
||||||
|
if (hp.split < 0)
|
||||||
|
hp.split -= 4;
|
||||||
|
|
||||||
if(hp.jittype!=JITTYPE::PC){
|
if (hp.jittype != JITTYPE::PC)
|
||||||
|
{
|
||||||
hp.emu_addr = hp.address;
|
hp.emu_addr = hp.address;
|
||||||
hp.argidx = hp.offset;
|
hp.argidx = hp.offset;
|
||||||
hp.offset = 0;
|
hp.offset = 0;
|
||||||
@ -245,11 +259,11 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ParseHCode(code, hp);
|
return ParseHCode(code, hp);
|
||||||
|
|
||||||
}
|
}
|
||||||
std::wstring HexString(int64_t num)
|
std::wstring HexString(int64_t num)
|
||||||
{
|
{
|
||||||
if (num < 0) return FormatString(L"-%I64X", -num);
|
if (num < 0)
|
||||||
|
return FormatString(L"-%I64X", -num);
|
||||||
return FormatString(L"%I64X", num);
|
return FormatString(L"%I64X", num);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +280,8 @@ namespace
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
RCode += L'S';
|
RCode += L'S';
|
||||||
if (hp.codepage != 0) RCode += std::to_wstring(hp.codepage) + L'#';
|
if (hp.codepage != 0)
|
||||||
|
RCode += std::to_wstring(hp.codepage) + L'#';
|
||||||
}
|
}
|
||||||
|
|
||||||
RCode += L'@' + HexString(hp.address);
|
RCode += L'@' + HexString(hp.address);
|
||||||
@ -295,14 +310,12 @@ namespace
|
|||||||
else if (hp.type & EMBED_AFTER_OVERWRITE)
|
else if (hp.type & EMBED_AFTER_OVERWRITE)
|
||||||
HCode += L"O";
|
HCode += L"O";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (hp.type & BREAK_POINT)
|
if (hp.type & BREAK_POINT)
|
||||||
HCode += L"B";
|
HCode += L"B";
|
||||||
else
|
else
|
||||||
HCode += L"H";
|
HCode += L"H";
|
||||||
|
|
||||||
|
|
||||||
if (hp.type & USING_STRING)
|
if (hp.type & USING_STRING)
|
||||||
{
|
{
|
||||||
if (hp.type & SPECIAL_JIT_STRING)
|
if (hp.type & SPECIAL_JIT_STRING)
|
||||||
@ -328,29 +341,41 @@ namespace
|
|||||||
HCode += L'B';
|
HCode += L'B';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hp.text_fun || hp.filter_fun) HCode += L'X';
|
if (hp.text_fun || hp.filter_fun)
|
||||||
|
HCode += L'X';
|
||||||
|
|
||||||
if (hp.type & FULL_STRING) HCode += L'F';
|
if (hp.type & FULL_STRING)
|
||||||
|
HCode += L'F';
|
||||||
|
|
||||||
if (hp.type & NO_CONTEXT) HCode += L'N';
|
if (hp.type & NO_CONTEXT)
|
||||||
|
HCode += L'N';
|
||||||
|
|
||||||
if (hp.codepage != 0 && !(hp.type & CODEC_UTF8)&&!(hp.type & CODEC_UTF16)&&!(hp.type & CODEC_UTF32) ) HCode += std::to_wstring(hp.codepage) + L'#';
|
if (hp.codepage != 0 && !(hp.type & CODEC_UTF8) && !(hp.type & CODEC_UTF16) && !(hp.type & CODEC_UTF32))
|
||||||
|
HCode += std::to_wstring(hp.codepage) + L'#';
|
||||||
|
|
||||||
if (hp.padding) HCode += HexString(hp.padding) + L'+';
|
if (hp.padding)
|
||||||
|
HCode += HexString(hp.padding) + L'+';
|
||||||
|
|
||||||
if (hp.offset < 0) hp.offset += 4;
|
if (hp.offset < 0)
|
||||||
if (hp.split < 0) hp.split += 4;
|
hp.offset += 4;
|
||||||
|
if (hp.split < 0)
|
||||||
|
hp.split += 4;
|
||||||
|
|
||||||
if(hp.jittype==JITTYPE::PC){
|
if (hp.jittype == JITTYPE::PC)
|
||||||
|
{
|
||||||
HCode += HexString(hp.offset);
|
HCode += HexString(hp.offset);
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
HCode += HexString(hp.argidx);
|
HCode += HexString(hp.argidx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hp.type & DATA_INDIRECT) HCode += L'*' + HexString(hp.index);
|
if (hp.type & DATA_INDIRECT)
|
||||||
if (hp.type & USING_SPLIT) HCode += L':' + HexString(hp.split);
|
HCode += L'*' + HexString(hp.index);
|
||||||
if (hp.type & SPLIT_INDIRECT) HCode += L'*' + HexString(hp.split_index);
|
if (hp.type & USING_SPLIT)
|
||||||
|
HCode += L':' + HexString(hp.split);
|
||||||
|
if (hp.type & SPLIT_INDIRECT)
|
||||||
|
HCode += L'*' + HexString(hp.split_index);
|
||||||
|
|
||||||
// Attempt to make the address relative
|
// Attempt to make the address relative
|
||||||
if (hp.jittype == JITTYPE::PC)
|
if (hp.jittype == JITTYPE::PC)
|
||||||
@ -366,17 +391,21 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
HCode += L'@' + HexString(hp.address);
|
HCode += L'@' + HexString(hp.address);
|
||||||
if (hp.type & MODULE_OFFSET) HCode += L':' + std::wstring(hp.module);
|
if (hp.type & MODULE_OFFSET)
|
||||||
if (hp.type & FUNCTION_OFFSET) HCode += L':' + StringToWideString(hp.function);
|
HCode += L':' + std::wstring(hp.module);
|
||||||
|
if (hp.type & FUNCTION_OFFSET)
|
||||||
|
HCode += L':' + StringToWideString(hp.function);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(hp.jittype== JITTYPE::UNITY){
|
if (hp.jittype == JITTYPE::UNITY)
|
||||||
|
{
|
||||||
HCode += L'@';
|
HCode += L'@';
|
||||||
HCode += acastw(hp.unityfunctioninfo);
|
HCode += acastw(hp.unityfunctioninfo);
|
||||||
HCode += L":JIT:UNITY";
|
HCode += L":JIT:UNITY";
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
|
|
||||||
HCode += L'@' + HexString(hp.emu_addr);
|
HCode += L'@' + HexString(hp.emu_addr);
|
||||||
switch (hp.jittype)
|
switch (hp.jittype)
|
||||||
@ -405,12 +434,16 @@ namespace HookCode
|
|||||||
{
|
{
|
||||||
std::optional<HookParam> Parse(std::wstring code)
|
std::optional<HookParam> Parse(std::wstring code)
|
||||||
{
|
{
|
||||||
if (code[0] == L'/') code.erase(0, 1);
|
if (code[0] == L'/')
|
||||||
|
code.erase(0, 1);
|
||||||
code.erase(std::find(code.begin(), code.end(), L'/'), code.end()); // legacy/AGTH compatibility
|
code.erase(std::find(code.begin(), code.end(), L'/'), code.end()); // legacy/AGTH compatibility
|
||||||
Trim(code);
|
Trim(code);
|
||||||
if (code[0] == L'R') return ParseRCode(code);
|
if (code[0] == L'R')
|
||||||
else if (code[0] == L'E') return ParseECode(code);
|
return ParseRCode(code);
|
||||||
else return ParseHCode(code);
|
else if (code[0] == L'E')
|
||||||
|
return ParseECode(code);
|
||||||
|
else
|
||||||
|
return ParseHCode(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring Generate(HookParam hp, DWORD processId)
|
std::wstring Generate(HookParam hp, DWORD processId)
|
||||||
|
@ -9,7 +9,8 @@ LPCSTR reverse_search_begin(const char *s, int maxsize )
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class CharT>
|
template <class CharT>
|
||||||
inline bool all_ascii_impl(const CharT* s,int maxsize){
|
inline bool all_ascii_impl(const CharT *s, int maxsize)
|
||||||
|
{
|
||||||
if (s)
|
if (s)
|
||||||
for (int i = 0; i < maxsize && *s; i++, s++)
|
for (int i = 0; i < maxsize && *s; i++, s++)
|
||||||
if ((unsigned)*s > 127)
|
if ((unsigned)*s > 127)
|
||||||
@ -18,24 +19,27 @@ inline bool all_ascii_impl(const CharT* s,int maxsize){
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class StringT>
|
template <class StringT>
|
||||||
inline void strReplace_impl(StringT& str, const StringT& oldStr, const StringT& newStr){
|
inline void strReplace_impl(StringT &str, const StringT &oldStr, const StringT &newStr)
|
||||||
|
{
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
while ((pos = str.find(oldStr, pos)) != StringT::npos) {
|
while ((pos = str.find(oldStr, pos)) != StringT::npos)
|
||||||
|
{
|
||||||
str.replace(pos, oldStr.length(), newStr);
|
str.replace(pos, oldStr.length(), newStr);
|
||||||
pos += newStr.length();
|
pos += newStr.length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class StringT>
|
template <class StringT>
|
||||||
inline std::vector<StringT> strSplit_impl(const StringT& s, const StringT& delim){
|
inline std::vector<StringT> strSplit_impl(const StringT &s, const StringT &delim)
|
||||||
|
{
|
||||||
StringT item;
|
StringT item;
|
||||||
std::vector<StringT> tokens;
|
std::vector<StringT> tokens;
|
||||||
|
|
||||||
StringT str = s;
|
StringT str = s;
|
||||||
|
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
while ((pos = str.find(delim)) != StringT::npos) {
|
while ((pos = str.find(delim)) != StringT::npos)
|
||||||
|
{
|
||||||
item = str.substr(0, pos);
|
item = str.substr(0, pos);
|
||||||
tokens.push_back(item);
|
tokens.push_back(item);
|
||||||
str.erase(0, pos + delim.length());
|
str.erase(0, pos + delim.length());
|
||||||
@ -45,22 +49,25 @@ inline std::vector<StringT> strSplit_impl(const StringT& s, const StringT& deli
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class StringT>
|
template <class StringT>
|
||||||
inline bool endWith_impl(const StringT& s,const StringT& s2) {
|
inline bool endWith_impl(const StringT &s, const StringT &s2)
|
||||||
if ((s.size() > s2.size()) && (s.substr(s.size() - s2.size(), s2.size()) == s2)) {
|
{
|
||||||
|
if ((s.size() > s2.size()) && (s.substr(s.size() - s2.size(), s2.size()) == s2))
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class StringT>
|
template <class StringT>
|
||||||
inline bool startWith_impl(const StringT& s,const StringT& s2) {
|
inline bool startWith_impl(const StringT &s, const StringT &s2)
|
||||||
if ((s.size() > s2.size()) && (s.substr(0, s2.size()) == s2)) {
|
{
|
||||||
|
if ((s.size() > s2.size()) && (s.substr(0, s2.size()) == s2))
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool all_ascii(const char *s, int maxsize) { return all_ascii_impl<char>(s, maxsize); }
|
bool all_ascii(const char *s, int maxsize) { return all_ascii_impl<char>(s, maxsize); }
|
||||||
bool all_ascii(const wchar_t *s, int maxsize) { return all_ascii_impl<wchar_t>(s, maxsize); }
|
bool all_ascii(const wchar_t *s, int maxsize) { return all_ascii_impl<wchar_t>(s, maxsize); }
|
||||||
|
|
||||||
@ -79,33 +86,38 @@ typedef HRESULT(WINAPI* CONVERTINETMULTIBYTETOUNICODE)(
|
|||||||
LPCSTR lpSrcStr,
|
LPCSTR lpSrcStr,
|
||||||
LPINT lpnMultiCharCount,
|
LPINT lpnMultiCharCount,
|
||||||
LPWSTR lpDstStr,
|
LPWSTR lpDstStr,
|
||||||
LPINT lpnWideCharCount
|
LPINT lpnWideCharCount);
|
||||||
);
|
|
||||||
typedef HRESULT(WINAPI *CONVERTINETUNICODETOMULTIBYTE)(
|
typedef HRESULT(WINAPI *CONVERTINETUNICODETOMULTIBYTE)(
|
||||||
LPDWORD lpdwMode,
|
LPDWORD lpdwMode,
|
||||||
DWORD dwEncoding,
|
DWORD dwEncoding,
|
||||||
LPCWSTR lpSrcStr,
|
LPCWSTR lpSrcStr,
|
||||||
LPINT lpnWideCharCount,
|
LPINT lpnWideCharCount,
|
||||||
LPSTR lpDstStr,
|
LPSTR lpDstStr,
|
||||||
LPINT lpnMultiCharCount
|
LPINT lpnMultiCharCount);
|
||||||
);
|
|
||||||
|
|
||||||
std::optional<std::wstring> StringToWideString(const std::string &text, UINT encoding)
|
std::optional<std::wstring> StringToWideString(const std::string &text, UINT encoding)
|
||||||
{
|
{
|
||||||
std::vector<wchar_t> buffer(text.size() + 1);
|
std::vector<wchar_t> buffer(text.size() + 1);
|
||||||
if(disable_mbwc){
|
if (disable_mbwc)
|
||||||
int _s = text.size(); int _s2 = buffer.size();
|
{
|
||||||
|
int _s = text.size();
|
||||||
|
int _s2 = buffer.size();
|
||||||
auto h = LoadLibrary(TEXT("mlang.dll"));
|
auto h = LoadLibrary(TEXT("mlang.dll"));
|
||||||
if(h==0)return {};
|
if (h == 0)
|
||||||
|
return {};
|
||||||
auto ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddress(h, "ConvertINetMultiByteToUnicode");
|
auto ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddress(h, "ConvertINetMultiByteToUnicode");
|
||||||
if(ConvertINetMultiByteToUnicode==0)return {};
|
if (ConvertINetMultiByteToUnicode == 0)
|
||||||
|
return {};
|
||||||
auto hr = ConvertINetMultiByteToUnicode(0, encoding, text.c_str(), &_s, buffer.data(), &_s2);
|
auto hr = ConvertINetMultiByteToUnicode(0, encoding, text.c_str(), &_s, buffer.data(), &_s2);
|
||||||
if(SUCCEEDED(hr)){
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
return std::wstring(buffer.data(), _s2);
|
return std::wstring(buffer.data(), _s2);
|
||||||
}
|
}
|
||||||
else return{};
|
else
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
if (int length = MultiByteToWideChar(encoding, 0, text.c_str(), text.size() + 1, buffer.data(), buffer.size()))
|
if (int length = MultiByteToWideChar(encoding, 0, text.c_str(), text.size() + 1, buffer.data(), buffer.size()))
|
||||||
return std::wstring(buffer.data(), length - 1);
|
return std::wstring(buffer.data(), length - 1);
|
||||||
return {};
|
return {};
|
||||||
@ -120,19 +132,26 @@ std::wstring StringToWideString(const std::string& text)
|
|||||||
std::string WideStringToString(const std::wstring &text, UINT cp)
|
std::string WideStringToString(const std::wstring &text, UINT cp)
|
||||||
{
|
{
|
||||||
std::vector<char> buffer((text.size() + 1) * 4);
|
std::vector<char> buffer((text.size() + 1) * 4);
|
||||||
if(disable_wcmb){
|
if (disable_wcmb)
|
||||||
int _s = text.size(); int _s2 = buffer.size();
|
{
|
||||||
|
int _s = text.size();
|
||||||
|
int _s2 = buffer.size();
|
||||||
auto h = LoadLibrary(TEXT("mlang.dll"));
|
auto h = LoadLibrary(TEXT("mlang.dll"));
|
||||||
if(h==0)return {};
|
if (h == 0)
|
||||||
|
return {};
|
||||||
auto ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddress(h, "ConvertINetUnicodeToMultiByte");
|
auto ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddress(h, "ConvertINetUnicodeToMultiByte");
|
||||||
if(ConvertINetUnicodeToMultiByte==0)return {};
|
if (ConvertINetUnicodeToMultiByte == 0)
|
||||||
|
return {};
|
||||||
auto hr = ConvertINetUnicodeToMultiByte(0, cp, text.c_str(), &_s, buffer.data(), &_s2);
|
auto hr = ConvertINetUnicodeToMultiByte(0, cp, text.c_str(), &_s, buffer.data(), &_s2);
|
||||||
if(SUCCEEDED(hr)){
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
return std::string(buffer.data(), _s2);
|
return std::string(buffer.data(), _s2);
|
||||||
}
|
}
|
||||||
else return{};
|
else
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
WideCharToMultiByte(cp, 0, text.c_str(), -1, buffer.data(), buffer.size(), nullptr, nullptr);
|
WideCharToMultiByte(cp, 0, text.c_str(), -1, buffer.data(), buffer.size(), nullptr, nullptr);
|
||||||
return buffer.data();
|
return buffer.data();
|
||||||
}
|
}
|
||||||
@ -152,17 +171,20 @@ inline unsigned int convertUTF32ToUTF16(unsigned int cUTF32, unsigned int& h, un
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::basic_string<uint32_t> utf16_to_utf32(const wchar_t* u16str,size_t size){
|
std::basic_string<uint32_t> utf16_to_utf32(const wchar_t *u16str, size_t size)
|
||||||
|
{
|
||||||
std::basic_string<uint32_t> utf32String;
|
std::basic_string<uint32_t> utf32String;
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
auto u16c = u16str[i];
|
auto u16c = u16str[i];
|
||||||
if (u16c - 0xd800u < 2048u)
|
if (u16c - 0xd800u < 2048u)
|
||||||
if((u16c&0xfffffc00==0xd800)&&(i<size-1)&&(u16str[i+1]&0xfffffc00==0xdc00)){
|
if ((u16c & 0xfffffc00 == 0xd800) && (i < size - 1) && (u16str[i + 1] & 0xfffffc00 == 0xdc00))
|
||||||
|
{
|
||||||
utf32String += (u16c << 10) + u16str[i + 1] - 0x35fdc00;
|
utf32String += (u16c << 10) + u16str[i + 1] - 0x35fdc00;
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
// error invalid u16 char
|
// error invalid u16 char
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -171,9 +193,11 @@ std::basic_string<uint32_t> utf16_to_utf32(const wchar_t* u16str,size_t size){
|
|||||||
return utf32String;
|
return utf32String;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring utf32_to_utf16(uint32_t* u32str,size_t size){
|
std::wstring utf32_to_utf16(uint32_t *u32str, size_t size)
|
||||||
|
{
|
||||||
std::wstring u16str;
|
std::wstring u16str;
|
||||||
for(auto i=0;i<size;i++){
|
for (auto i = 0; i < size; i++)
|
||||||
|
{
|
||||||
unsigned h, l;
|
unsigned h, l;
|
||||||
convertUTF32ToUTF16(u32str[i], h, l);
|
convertUTF32ToUTF16(u32str[i], h, l);
|
||||||
if (h)
|
if (h)
|
||||||
@ -183,30 +207,38 @@ std::wstring utf32_to_utf16(uint32_t* u32str,size_t size){
|
|||||||
return u16str;
|
return u16str;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t u32strlen(uint32_t* data){
|
size_t u32strlen(uint32_t *data)
|
||||||
|
{
|
||||||
size_t s = 0;
|
size_t s = 0;
|
||||||
while (data[s])
|
while (data[s])
|
||||||
s++;
|
s++;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string wcasta(const std::wstring x){
|
std::string wcasta(const std::wstring x)
|
||||||
|
{
|
||||||
std::string xx;
|
std::string xx;
|
||||||
for (auto c : x)
|
for (auto c : x)
|
||||||
xx += c;
|
xx += c;
|
||||||
return xx;
|
return xx;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring acastw(const std::string x){
|
std::wstring acastw(const std::string x)
|
||||||
|
{
|
||||||
std::wstring xx;
|
std::wstring xx;
|
||||||
for (auto c : x)
|
for (auto c : x)
|
||||||
xx += c;
|
xx += c;
|
||||||
return xx;
|
return xx;
|
||||||
}
|
}
|
||||||
std::optional<std::wstring> commonparsestring(void* data,size_t length,void* php,DWORD df){
|
std::optional<std::wstring> commonparsestring(void *data, size_t length, void *php, DWORD df)
|
||||||
|
{
|
||||||
auto hp = (HookParam *)php;
|
auto hp = (HookParam *)php;
|
||||||
if (hp->type & CODEC_UTF16) return std::wstring((wchar_t*)data, length / sizeof(wchar_t));
|
if (hp->type & CODEC_UTF16)
|
||||||
else if(hp->type&CODEC_UTF32)return (std::move(utf32_to_utf16((uint32_t*)data,length/ sizeof(uint32_t))));
|
return std::wstring((wchar_t *)data, length / sizeof(wchar_t));
|
||||||
else if (auto converted = StringToWideString(std::string((char*)data, length), (hp->type&CODEC_UTF8)?CP_UTF8:(hp->codepage ? hp->codepage :df))) return (converted.value());
|
else if (hp->type & CODEC_UTF32)
|
||||||
else return {};
|
return (std::move(utf32_to_utf16((uint32_t *)data, length / sizeof(uint32_t))));
|
||||||
|
else if (auto converted = StringToWideString(std::string((char *)data, length), (hp->type & CODEC_UTF8) ? CP_UTF8 : (hp->codepage ? hp->codepage : df)))
|
||||||
|
return (converted.value());
|
||||||
|
else
|
||||||
|
return {};
|
||||||
}
|
}
|
@ -1,10 +1,14 @@
|
|||||||
#ifndef __LUNA_STRINGUILTS_H
|
#ifndef __LUNA_STRINGUILTS_H
|
||||||
#define __LUNA_STRINGUILTS_H
|
#define __LUNA_STRINGUILTS_H
|
||||||
|
|
||||||
enum { VNR_TEXT_CAPACITY = 1500 }; // estimated max number of bytes allowed in VNR, slightly larger than VNR's text limit (1000)
|
enum
|
||||||
|
{
|
||||||
|
VNR_TEXT_CAPACITY = 1500
|
||||||
|
}; // estimated max number of bytes allowed in VNR, slightly larger than VNR's text limit (1000)
|
||||||
|
|
||||||
template <class StringT>
|
template <class StringT>
|
||||||
StringT stolower(StringT s){
|
StringT stolower(StringT s)
|
||||||
|
{
|
||||||
std::transform(s.begin(), s.end(), s.begin(), tolower);
|
std::transform(s.begin(), s.end(), s.begin(), tolower);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -41,8 +45,10 @@ inline void Trim(ST& text)
|
|||||||
text.erase(std::find_if_not(text.rbegin(), text.rend(), iswspace).base(), text.end());
|
text.erase(std::find_if_not(text.rbegin(), text.rend(), iswspace).base(), text.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline auto FormatArg(T arg) { return arg; }
|
template <typename T>
|
||||||
template <typename C> inline auto FormatArg(const std::basic_string<C>& arg) { return arg.c_str(); }
|
inline auto FormatArg(T arg) { return arg; }
|
||||||
|
template <typename C>
|
||||||
|
inline auto FormatArg(const std::basic_string<C> &arg) { return arg.c_str(); }
|
||||||
|
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4996)
|
#pragma warning(disable : 4996)
|
||||||
|
@ -12,7 +12,8 @@ inline std::atomic<bool (*)(LPVOID addr, hook_stack* stack)> trigger_fun = nullp
|
|||||||
|
|
||||||
// jichi 9/25/2013: This class will be used by NtMapViewOfSectionfor
|
// jichi 9/25/2013: This class will be used by NtMapViewOfSectionfor
|
||||||
// interprocedure communication, where constructor/destructor will NOT work.
|
// interprocedure communication, where constructor/destructor will NOT work.
|
||||||
struct EmbedSharedMem{
|
struct EmbedSharedMem
|
||||||
|
{
|
||||||
uint64_t use[10];
|
uint64_t use[10];
|
||||||
uint64_t addr[10];
|
uint64_t addr[10];
|
||||||
uint64_t ctx1[10];
|
uint64_t ctx1[10];
|
||||||
@ -60,6 +61,9 @@ private:
|
|||||||
ALIGNPTR(uint64_t __3, BYTE *local_buffer);
|
ALIGNPTR(uint64_t __3, BYTE *local_buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { MAX_HOOK = 2500};
|
enum
|
||||||
|
{
|
||||||
|
MAX_HOOK = 2500
|
||||||
|
};
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
class WinMutex // Like CMutex but works with scoped_lock
|
class WinMutex // Like CMutex but works with scoped_lock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WinMutex(std::wstring name = L"", LPSECURITY_ATTRIBUTES sa = nullptr) : m(CreateMutexW(sa, FALSE, name.empty() ? NULL : name.c_str())) {}
|
WinMutex(std::wstring name = L"", LPSECURITY_ATTRIBUTES sa = nullptr) : m(CreateMutexW(sa, FALSE, name.empty() ? NULL : name.c_str())) {}
|
||||||
void lock() { if (m) WaitForSingleObject(m, INFINITE); }
|
void lock()
|
||||||
void unlock() { if (m) ReleaseMutex(m); }
|
{
|
||||||
|
if (m)
|
||||||
|
WaitForSingleObject(m, INFINITE);
|
||||||
|
}
|
||||||
|
void unlock()
|
||||||
|
{
|
||||||
|
if (m)
|
||||||
|
ReleaseMutex(m);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AutoHandle<> m;
|
AutoHandle<> m;
|
||||||
@ -17,9 +24,7 @@ inline SECURITY_ATTRIBUTES allAccess = std::invoke([] // allows non-admin proces
|
|||||||
static SECURITY_DESCRIPTOR sd = {};
|
static SECURITY_DESCRIPTOR sd = {};
|
||||||
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
|
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
|
||||||
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
|
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
|
||||||
return SECURITY_ATTRIBUTES{ sizeof(SECURITY_ATTRIBUTES), &sd, FALSE };
|
return SECURITY_ATTRIBUTES{ sizeof(SECURITY_ATTRIBUTES), &sd, FALSE }; });
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
struct hook_stack
|
struct hook_stack
|
||||||
{
|
{
|
||||||
@ -60,23 +65,27 @@ struct hook_stack
|
|||||||
uintptr_t retaddr;
|
uintptr_t retaddr;
|
||||||
BYTE base[1];
|
BYTE base[1];
|
||||||
};
|
};
|
||||||
uintptr_t get_base(){
|
uintptr_t get_base()
|
||||||
|
{
|
||||||
return (uintptr_t)this + sizeof(hook_stack) - sizeof(uintptr_t);
|
return (uintptr_t)this + sizeof(hook_stack) - sizeof(uintptr_t);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline hook_stack* get_hook_stack(uintptr_t lpDataBase){
|
inline hook_stack *get_hook_stack(uintptr_t lpDataBase)
|
||||||
|
{
|
||||||
return (hook_stack *)(lpDataBase - sizeof(hook_stack) + sizeof(uintptr_t));
|
return (hook_stack *)(lpDataBase - sizeof(hook_stack) + sizeof(uintptr_t));
|
||||||
}
|
}
|
||||||
// jichi 3/7/2014: Add guessed comment
|
// jichi 3/7/2014: Add guessed comment
|
||||||
|
|
||||||
#define ALIGNPTR(Y,X) union { \
|
#define ALIGNPTR(Y, X) \
|
||||||
|
union \
|
||||||
|
{ \
|
||||||
##Y; \
|
##Y; \
|
||||||
##X; \
|
##X; \
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class JITTYPE
|
||||||
enum class JITTYPE{
|
{
|
||||||
PC, // not a jit
|
PC, // not a jit
|
||||||
YUZU,
|
YUZU,
|
||||||
PPSSPP,
|
PPSSPP,
|
||||||
@ -108,7 +117,8 @@ struct HookParam
|
|||||||
ALIGNPTR(uint64_t __9, const wchar_t *newlineseperator);
|
ALIGNPTR(uint64_t __9, const wchar_t *newlineseperator);
|
||||||
char name[HOOK_NAME_SIZE];
|
char name[HOOK_NAME_SIZE];
|
||||||
wchar_t hookcode[HOOKCODE_LEN];
|
wchar_t hookcode[HOOKCODE_LEN];
|
||||||
HookParam(){
|
HookParam()
|
||||||
|
{
|
||||||
ZeroMemory(this, sizeof(HookParam));
|
ZeroMemory(this, sizeof(HookParam));
|
||||||
}
|
}
|
||||||
ALIGNPTR(uint64_t __10, uintptr_t emu_addr);
|
ALIGNPTR(uint64_t __10, uintptr_t emu_addr);
|
||||||
|
@ -6,15 +6,26 @@ constexpr bool x64 = true;
|
|||||||
constexpr bool x64 = false;
|
constexpr bool x64 = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T, typename... Xs> struct ArrayImpl { using Type = std::tuple<T, Xs...>[]; };
|
template <typename T, typename... Xs>
|
||||||
template <typename T> struct ArrayImpl<T> { using Type = T[]; };
|
struct ArrayImpl
|
||||||
template <typename... Ts> using Array = typename ArrayImpl<Ts...>::Type;
|
{
|
||||||
|
using Type = std::tuple<T, Xs...>[];
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct ArrayImpl<T>
|
||||||
|
{
|
||||||
|
using Type = T[];
|
||||||
|
};
|
||||||
|
template <typename... Ts>
|
||||||
|
using Array = typename ArrayImpl<Ts...>::Type;
|
||||||
|
|
||||||
template <auto F> using Functor = std::integral_constant<std::remove_reference_t<decltype(F)>, F>; // shouldn't need remove_reference_t but MSVC is bugged
|
template <auto F>
|
||||||
|
using Functor = std::integral_constant<std::remove_reference_t<decltype(F)>, F>; // shouldn't need remove_reference_t but MSVC is bugged
|
||||||
|
|
||||||
struct PermissivePointer
|
struct PermissivePointer
|
||||||
{
|
{
|
||||||
template <typename T> operator T*() { return (T*)p; }
|
template <typename T>
|
||||||
|
operator T *() { return (T *)p; }
|
||||||
void *p;
|
void *p;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -24,11 +35,23 @@ class AutoHandle
|
|||||||
public:
|
public:
|
||||||
AutoHandle(HANDLE h) : h(h) {}
|
AutoHandle(HANDLE h) : h(h) {}
|
||||||
operator HANDLE() { return h.get(); }
|
operator HANDLE() { return h.get(); }
|
||||||
PHANDLE operator&() { static_assert(sizeof(*this) == sizeof(HANDLE)); assert(!h); return (PHANDLE)this; }
|
PHANDLE operator&()
|
||||||
|
{
|
||||||
|
static_assert(sizeof(*this) == sizeof(HANDLE));
|
||||||
|
assert(!h);
|
||||||
|
return (PHANDLE)this;
|
||||||
|
}
|
||||||
operator bool() { return h.get() != NULL && h.get() != INVALID_HANDLE_VALUE; }
|
operator bool() { return h.get() != NULL && h.get() != INVALID_HANDLE_VALUE; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct HandleCleaner { void operator()(void* h) { if (h != INVALID_HANDLE_VALUE) HandleCloser()(PermissivePointer{ h }); } };
|
struct HandleCleaner
|
||||||
|
{
|
||||||
|
void operator()(void *h)
|
||||||
|
{
|
||||||
|
if (h != INVALID_HANDLE_VALUE)
|
||||||
|
HandleCloser()(PermissivePointer{h});
|
||||||
|
}
|
||||||
|
};
|
||||||
std::unique_ptr<void, HandleCleaner> h;
|
std::unique_ptr<void, HandleCleaner> h;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,45 +86,59 @@ void SpawnThread(const F& f) // works in DllMain unlike std thread
|
|||||||
{
|
{
|
||||||
(*(F*)copy)();
|
(*(F*)copy)();
|
||||||
delete (F*)copy;
|
delete (F*)copy;
|
||||||
return 0UL;
|
return 0UL; }, copy, 0, nullptr));
|
||||||
}, copy, 0, nullptr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline struct // should be inline but MSVC (linker) is bugged
|
inline struct // should be inline but MSVC (linker) is bugged
|
||||||
{
|
{
|
||||||
inline static BYTE DUMMY[100];
|
inline static BYTE DUMMY[100];
|
||||||
template <typename T> operator T*() { static_assert(sizeof(T) < sizeof(DUMMY)); return (T*)DUMMY; }
|
template <typename T>
|
||||||
|
operator T *()
|
||||||
|
{
|
||||||
|
static_assert(sizeof(T) < sizeof(DUMMY));
|
||||||
|
return (T *)DUMMY;
|
||||||
|
}
|
||||||
} DUMMY;
|
} DUMMY;
|
||||||
|
|
||||||
inline auto Swallow = [](auto &&...) {};
|
inline auto Swallow = [](auto &&...) {};
|
||||||
|
|
||||||
template <typename T> std::optional<std::remove_cv_t<T>> Copy(T* ptr) { if (ptr) return *ptr; return {}; }
|
template <typename T>
|
||||||
|
std::optional<std::remove_cv_t<T>> Copy(T *ptr)
|
||||||
|
{
|
||||||
|
if (ptr)
|
||||||
|
return *ptr;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
inline std::optional<std::wstring> getModuleFilename(DWORD processId, HMODULE module = NULL)
|
inline std::optional<std::wstring> getModuleFilename(DWORD processId, HMODULE module = NULL)
|
||||||
{
|
{
|
||||||
std::vector<wchar_t> buffer(MAX_PATH);
|
std::vector<wchar_t> buffer(MAX_PATH);
|
||||||
if (AutoHandle<> process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId))
|
if (AutoHandle<> process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId))
|
||||||
if (GetModuleFileNameExW(process, module, buffer.data(), MAX_PATH)) return buffer.data();
|
if (GetModuleFileNameExW(process, module, buffer.data(), MAX_PATH))
|
||||||
|
return buffer.data();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::optional<std::wstring> getModuleFilename(HMODULE module = NULL)
|
inline std::optional<std::wstring> getModuleFilename(HMODULE module = NULL)
|
||||||
{
|
{
|
||||||
std::vector<wchar_t> buffer(MAX_PATH);
|
std::vector<wchar_t> buffer(MAX_PATH);
|
||||||
if (GetModuleFileNameW(module, buffer.data(), MAX_PATH)) return buffer.data();
|
if (GetModuleFileNameW(module, buffer.data(), MAX_PATH))
|
||||||
|
return buffer.data();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct SafeFptr {
|
struct SafeFptr
|
||||||
|
{
|
||||||
T ptr;
|
T ptr;
|
||||||
uintptr_t errorvalue;
|
uintptr_t errorvalue;
|
||||||
SafeFptr(T _ptr, uintptr_t v = {NULL}) : ptr(_ptr), errorvalue(v) {}
|
SafeFptr(T _ptr, uintptr_t v = {NULL}) : ptr(_ptr), errorvalue(v) {}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
std::invoke_result_t<T, Args...> operator()(Args... args) {
|
std::invoke_result_t<T, Args...> operator()(Args... args)
|
||||||
if (!ptr) return (std::invoke_result_t<T, Args...>)(errorvalue);
|
{
|
||||||
|
if (!ptr)
|
||||||
|
return (std::invoke_result_t<T, Args...>)(errorvalue);
|
||||||
return ptr(std::forward<Args>(args)...);
|
return ptr(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -10,6 +10,7 @@ class win_event
|
|||||||
|
|
||||||
win_event(const _Self &);
|
win_event(const _Self &);
|
||||||
_Self &operator=(const _Self &);
|
_Self &operator=(const _Self &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef __native_handle_type native_handle_type;
|
typedef __native_handle_type native_handle_type;
|
||||||
typedef __native_string_type native_string_type;
|
typedef __native_string_type native_string_type;
|
||||||
@ -18,8 +19,8 @@ public:
|
|||||||
: _M_name(name)
|
: _M_name(name)
|
||||||
{
|
{
|
||||||
_M_handle = create ? // lpEventAttributes, bManualReset, bInitialState, lpName
|
_M_handle = create ? // lpEventAttributes, bManualReset, bInitialState, lpName
|
||||||
::CreateEventA(nullptr, TRUE, FALSE, name) :
|
::CreateEventA(nullptr, TRUE, FALSE, name)
|
||||||
::OpenEventA(EVENT_ALL_ACCESS, FALSE, name); // dwDesiredAccess, bInheritHandle, lpName
|
: ::OpenEventA(EVENT_ALL_ACCESS, FALSE, name); // dwDesiredAccess, bInheritHandle, lpName
|
||||||
}
|
}
|
||||||
|
|
||||||
~win_event() { ::CloseHandle(_M_handle); }
|
~win_event() { ::CloseHandle(_M_handle); }
|
||||||
@ -30,9 +31,13 @@ public:
|
|||||||
bool valid() const { return _M_handle; }
|
bool valid() const { return _M_handle; }
|
||||||
|
|
||||||
bool signal(bool t)
|
bool signal(bool t)
|
||||||
{ return t ? ::SetEvent(_M_handle) : ::ResetEvent(_M_handle); }
|
{
|
||||||
|
return t ? ::SetEvent(_M_handle) : ::ResetEvent(_M_handle);
|
||||||
|
}
|
||||||
|
|
||||||
/// Return true only if when it is wake up by notify instead of timeout
|
/// Return true only if when it is wake up by notify instead of timeout
|
||||||
bool wait(DWORD msec = INFINITE)
|
bool wait(DWORD msec = INFINITE)
|
||||||
{ return WAIT_OBJECT_0 == ::WaitForSingleObject(_M_handle, msec); }
|
{
|
||||||
|
return WAIT_OBJECT_0 == ::WaitForSingleObject(_M_handle, msec);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user