mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
293 lines
5.8 KiB
C++
293 lines
5.8 KiB
C++
// Local JDI Host
|
|
|
|
#include "pch.h"
|
|
|
|
#ifdef _WINDOWS
|
|
BOOL APIENTRY DllMain( HMODULE hModule,
|
|
DWORD ul_reason_for_call,
|
|
LPVOID lpReserved
|
|
)
|
|
{
|
|
switch (ul_reason_for_call)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
// TODO: Check ImageBase.
|
|
|
|
/* Required by HLE Subsystem */
|
|
//if ((uint64_t)hInstance > 0x400000)
|
|
//{
|
|
// UI::DolwinError(_T("Error"), _T("Image base must be below or equal 0x400`000. Required by HLE Subsystem for artifical CPU `CallVM` opcode."));
|
|
// return -1;
|
|
//}
|
|
|
|
EMUCtor();
|
|
break;
|
|
case DLL_PROCESS_DETACH:
|
|
EMUDtor();
|
|
break;
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
#endif // _WINDOWS
|
|
|
|
#define endl ( line[p] == 0 )
|
|
#define space ( line[p] == 0x20 )
|
|
#define quot ( line[p] == '\'' )
|
|
#define dquot ( line[p] == '\"' )
|
|
|
|
static void Tokenize(const char* line, std::vector<std::string>& args)
|
|
{
|
|
int p, start, end;
|
|
p = start = end = 0;
|
|
|
|
args.clear();
|
|
|
|
// while not end line
|
|
while (!endl)
|
|
{
|
|
// skip space first, if any
|
|
while (space) p++;
|
|
if (!endl && quot)
|
|
{ // single quotation, need special case
|
|
p++;
|
|
start = p;
|
|
while (1)
|
|
{
|
|
if (endl)
|
|
{
|
|
throw "Open single quotation";
|
|
return;
|
|
}
|
|
|
|
if (quot)
|
|
{
|
|
end = p;
|
|
p++;
|
|
break;
|
|
}
|
|
else p++;
|
|
}
|
|
|
|
args.push_back(std::string(line + start, end - start));
|
|
}
|
|
else if (!endl && dquot)
|
|
{ // double quotation, need special case
|
|
p++;
|
|
start = p;
|
|
while (1)
|
|
{
|
|
if (endl)
|
|
{
|
|
throw "Open double quotation";
|
|
return;
|
|
}
|
|
|
|
if (dquot)
|
|
{
|
|
end = p;
|
|
p++;
|
|
break;
|
|
}
|
|
else p++;
|
|
}
|
|
|
|
args.push_back(std::string(line + start, end - start));
|
|
}
|
|
else if (!endl)
|
|
{
|
|
start = p;
|
|
while (1)
|
|
{
|
|
if (endl || space || quot || dquot)
|
|
{
|
|
end = p;
|
|
break;
|
|
}
|
|
|
|
p++;
|
|
}
|
|
|
|
args.push_back(std::string(line + start, end - start));
|
|
}
|
|
}
|
|
}
|
|
|
|
#undef space
|
|
#undef quot
|
|
#undef dquot
|
|
#undef endl
|
|
|
|
#ifdef _WINDOWS
|
|
extern "C" __declspec(dllexport)
|
|
#endif
|
|
Json::Value* __cdecl CallJdi(const char* request)
|
|
{
|
|
std::vector<std::string> args;
|
|
|
|
Tokenize(request, args);
|
|
|
|
return JDI::Hub.Execute(args);
|
|
}
|
|
|
|
#ifdef _WINDOWS
|
|
extern "C" __declspec(dllexport)
|
|
#endif
|
|
bool __cdecl CallJdiNoReturn(const char* request)
|
|
{
|
|
CallJdi(request);
|
|
return true;
|
|
}
|
|
|
|
#ifdef _WINDOWS
|
|
extern "C" __declspec(dllexport)
|
|
#endif
|
|
bool __cdecl CallJdiReturnInt(const char* request, int* valueOut)
|
|
{
|
|
if (!valueOut)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Json::Value* value = CallJdi(request);
|
|
if (!value)
|
|
{
|
|
return false;
|
|
}
|
|
if (value->type != Json::ValueType::Int)
|
|
{
|
|
delete value;
|
|
return false;
|
|
}
|
|
|
|
*valueOut = (int)value->value.AsInt;
|
|
delete value;
|
|
|
|
return true;
|
|
}
|
|
|
|
#ifdef _WINDOWS
|
|
extern "C" __declspec(dllexport)
|
|
#endif
|
|
bool __cdecl CallJdiReturnString(const char* request, char* valueOut, size_t valueSize)
|
|
{
|
|
if (!valueOut)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Json::Value* value = CallJdi(request);
|
|
if (!value)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// String are returned in form of: [ "string" ]
|
|
|
|
if (value->type != Json::ValueType::Array)
|
|
{
|
|
delete value;
|
|
return false;
|
|
}
|
|
|
|
if (value->children.size() < 1)
|
|
{
|
|
delete value;
|
|
return false;
|
|
}
|
|
|
|
Json::Value* child = value->children.front();
|
|
|
|
if (child->type != Json::ValueType::String )
|
|
{
|
|
delete value;
|
|
return false;
|
|
}
|
|
|
|
// Check string size
|
|
|
|
size_t sizeInChars = _tcslen(child->value.AsString);
|
|
size_t sizeInBytes = sizeInChars * sizeof(TCHAR);
|
|
if (sizeInBytes >= valueSize)
|
|
{
|
|
delete value;
|
|
return false;
|
|
}
|
|
|
|
// Copy out
|
|
|
|
TCHAR* tstrPtr = child->value.AsString;
|
|
char* valuePtr = valueOut;
|
|
|
|
for (size_t i = 0; i < sizeInChars; i++)
|
|
{
|
|
*valuePtr++ = (char)*tstrPtr++;
|
|
}
|
|
*valuePtr++ = 0;
|
|
|
|
delete value;
|
|
|
|
return true;
|
|
}
|
|
|
|
#ifdef _WINDOWS
|
|
extern "C" __declspec(dllexport)
|
|
#endif
|
|
bool __cdecl CallJdiReturnBool(const char* request, bool* valueOut)
|
|
{
|
|
if (!valueOut)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Json::Value* value = CallJdi(request);
|
|
if (!value)
|
|
{
|
|
return false;
|
|
}
|
|
if ( ! (value->type == Json::ValueType::Int || value->type == Json::ValueType::Bool) )
|
|
{
|
|
delete value;
|
|
return false;
|
|
}
|
|
|
|
if (value->type == Json::ValueType::Bool)
|
|
{
|
|
*valueOut = value->value.AsBool;
|
|
}
|
|
else
|
|
{
|
|
*valueOut = value->value.AsInt != 0;
|
|
}
|
|
|
|
delete value;
|
|
|
|
return true;
|
|
}
|
|
|
|
#ifdef _WINDOWS
|
|
extern "C" __declspec(dllexport)
|
|
#endif
|
|
void __cdecl JdiAddNode(const char* filename, JDI::JdiReflector reflector)
|
|
{
|
|
JDI::Hub.AddNode(Util::StringToWstring(filename), reflector);
|
|
}
|
|
|
|
#ifdef _WINDOWS
|
|
extern "C" __declspec(dllexport)
|
|
#endif
|
|
void __cdecl JdiRemoveNode(const char* filename)
|
|
{
|
|
JDI::Hub.RemoveNode(Util::StringToWstring(filename));
|
|
}
|
|
|
|
#ifdef _WINDOWS
|
|
extern "C" __declspec(dllexport)
|
|
#endif
|
|
void __cdecl JdiAddCmd(const char* name, JDI::CmdDelegate command)
|
|
{
|
|
JDI::Hub.AddCmd(name, command);
|
|
}
|