
typedef int (WINAPI* LPSDOLInitialize)(const SDOLAppInfo* pAppInfo);
typedef int (WINAPI* LPSDOLGetModule)(REFIID riid, void** intf);
typedef int (WINAPI* LPSDOLTerminal)();
LPSDOLInitialize m_pfSDOLInitialize;
LPSDOLGetModule m_pfSDOLGetModule;
LPSDOLTerminal m_pfSDOLTerminal;
m_pfSDOLInitialize = (LPSDOLInitialize)GetProcAddress(m_hSDOLoginModule, "SDOLInitialize");
m_pfSDOLGetModule = (LPSDOLGetModule)GetProcAddress(m_hSDOLoginModule, "SDOLGetModule");
m_pfSDOLTerminal = (LPSDOLTerminal)GetProcAddress(m_hSDOLoginModule, "SDOLTerminal");
代码解释:
这段代码定义了三个函数指针类型的对象 m_pfSDOLInitialize、m_pfSDOLGetModule 和 m_pfSDOLTerminal,分别用于指向动态链接库(DLL)中的函数 SDOLInitialize、SDOLGetModule 和 SDOLTerminal。
然后,通过 GetProcAddress 函数,它尝试从 m_hSDOLoginModule 所代表的 DLL 中运行时候获取这三个函数的地址,并将这些地址分别赋值给 m_pfSDOLInitialize、m_pfSDOLGetModule 和 m_pfSDOLTerminal,使得这些函数指针指向了对应的函数。
这种方式允许你在运行时通过这些函数指针调用 DLL 中的函数,而不需要在编译时链接这些函数。这通常用于动态加载和调用 DLL 中的函数,以实现插件系统或模块化的应用程序架构。
typedef int (WINAPI* LPSDOLInitialize)(const SDOLAppInfo* pAppInfo);
typedef int (WINAPI* LPSDOLGetModule)(REFIID riid, void** intf);
typedef int (WINAPI* LPSDOLTerminal)();
bool Initial(){
WCHAR strExePath[MAX_PATH] = { 0 };
WCHAR strExeName[MAX_PATH] = { 0 };
WCHAR* strLastSlash = NULL;
GetModuleFileNameW(NULL, strExePath, MAX_PATH);
strExePath[MAX_PATH - 1] = 0;
strLastSlash = wcsrchr(strExePath, TEXT('\\'));
if (strLastSlash)
{ // 得到EXE所在路径
StringCchCopyW(strExeName, MAX_PATH, &strLastSlash[1]);
*strLastSlash = 0;
strLastSlash = wcsrchr(strExeName, TEXT('.'));
if (strLastSlash)
*strLastSlash = 0;
}
WCHAR strGameWidgetDll[MAX_PATH] = { 0 };
#ifdef _WIN64
StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry64.dll", strExePath);
#else
StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry.dll", strExePath);
#endif
if (GetFileAttributesW(strGameWidgetDll) == 0xFFFFFFFF) {
return false;
}
// string strEntry;
//#ifdef _WIN64
// strEntry = PathHelper::GetFullPath("..\\sdologinentry64.dll");
//#else
// strEntry = PathHelper::GetFullPath("..\\sdologinentry.dll");
//#endif
m_hSDOLoginModule = ::LoadLibraryW(strGameWidgetDll);
if (m_hSDOLoginModule == nullptr)
{
return false;
}
//Out-of-game login interface
m_pfSDOLInitialize = (LPSDOLInitialize)GetProcAddress(m_hSDOLoginModule, "SDOLInitialize");
m_pfSDOLGetModule = (LPSDOLGetModule)GetProcAddress(m_hSDOLoginModule, "SDOLGetModule");
m_pfSDOLTerminal = (LPSDOLTerminal)GetProcAddress(m_hSDOLoginModule, "SDOLTerminal");
if (m_pfSDOLInitialize == nullptr || m_pfSDOLGetModule == nullptr) return false;
SDOLAppInfo tmpAppInfo = {
sizeof(SDOLAppInfo), // 结构体大小,方便扩展
appId, // 接入应用ID,从开发者网站中申请
L"游戏名称", // 应用名称
L"0.1.2.0", // 应用客户端当前版本号
1, // 游戏区ID,不可用时传入-1
1 // 游戏组ID,不可用时传入-1
};
if (m_pfSDOLInitialize(&tmpAppInfo) == SDOL_ERRORCODE_OK)
{
m_pfSDOLGetModule(__uuidof(ISDOLLogin8), (void**)&m_pSDOLogin);
if (m_pSDOLogin == nullptr) return false;
}
else
{
return false;
}
m_pSDOLogin->SetLoginMode(LauncherLoginMode);
return CreateWorkerThread();
}
WCHAR strExePath[MAX_PATH] = { 0 };
- 1
WCHAR strExeName[MAX_PATH] = { 0 };
WCHAR* strLastSlash = NULL;
GetModuleFileNameW(NULL, strExePath, MAX_PATH);
strExePath[MAX_PATH - 1] = 0;
strLastSlash = wcsrchr(strExePath, TEXT(‘\’));
if (strLastSlash)
{ // 得到EXE所在路径
StringCchCopyW(strExeName, MAX_PATH, &strLastSlash[1]);
*strLastSlash = 0;
strLastSlash = wcsrchr(strExeName, TEXT(‘.’));
if (strLastSlash)
*strLastSlash = 0;
}
WCHAR strGameWidgetDll[MAX_PATH] = { 0 };
#ifdef _WIN64
StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry64.dll", strExePath);
#else
StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry.dll", strExePath);
#endif
if (GetFileAttributesW(strGameWidgetDll) == 0xFFFFFFFF) {
return false;
}
// string strEntry;
//#ifdef _WIN64
// strEntry = PathHelper::GetFullPath("..\\sdologinentry64.dll");
//#else
// strEntry = PathHelper::GetFullPath("..\\sdologinentry.dll");
//#endif
m_hSDOLoginModule = ::LoadLibraryW(strGameWidgetDll);
if (m_hSDOLoginModule == nullptr)
{
return false;
}
代码解释:
GetModuleFileNameW 函数获取当前执行程序**(.exe)**的路径,并将其存储在 strExePath 中。strExePath 中提取出执行程序的名称并存储在 strExeName 中。strExePath 中找到最后一个反斜杠 “” 的位置,然后将它替换为 NULL 终止字符以分隔目录路径和文件名。strGameWidgetDll 的路径:
strGameWidgetDll 路径,这是一个包含了 “sdologinentry.dll” 或 “sdologinentry64.dll” 的完整路径。GetFileAttributesW 函数检查 strGameWidgetDll 文件是否存在,如果文件不存在,就返回 false。LoadLibraryW 函数加载 strGameWidgetDll 指定的 DLL 文件。如果加载失败,返回 false。这段代码的目的是获取并加载一个特定的 DLL,该 DLL 位于与当前执行程序相同的目录下,根据操作系统架构选择加载 “sdologinentry.dll” 或 “sdologinentry64.dll”。如果加载成功,m_hSDOLoginModule 将包含该 DLL 的句柄,以便后续可以使用 GetProcAddress 来获取其中的函数地址。如果有任何错误发生,函数将返回 false。
m_pfSDOLInitialize = (LPSDOLInitialize)GetProcAddress(m_hSDOLoginModule, “SDOLInitialize”);
代码解释:
m_pfSDOLInitialize 是一个函数指针,它似乎被用来指向一个函数,该函数的名称是 “SDOLInitialize”,并且这个函数是从模块 m_hSDOLoginModule 中获取的。这种情况通常用于动态链接库(Dynamic Link Library,DLL)或共享库中的函数调用。m_pfSDOLInitialize 这个函数指针指向 m_hSDOLoginModule 模块中的 “SDOLInitialize” 函数,而m_hSDOLoginModule 模块是一个动态链接库中函数调用,以便后续可以通过该函数指针来调用 “SDOLInitialize” 函数,而不必直接链接到该函数的库。这种方式通常用于在运行时加载库并调用其中的函数,而不是在编译时链接到库。m_pfSDOLInitialize 这个函数指针之前,你需要确保 m_hSDOLoginModule 已经成功加载,并且 “SDOLInitialize” 函数已经在该模块中找到。否则,使用该函数指针可能导致运行时错误。m_pfSDOLGetModule = (LPSDOLGetModule)GetProcAddress(m_hSDOLoginModule, “SDOLGetModule”);
代码解释:
m_pfSDOLGetModule,并使用 GetProcAddress 函数从 m_hSDOLoginModule 模块中获取 “SDOLGetModule” 函数的地址,并将其分配给 m_pfSDOLGetModule。这意味着 m_pfSDOLGetModule 现在指向了 m_hSDOLoginModule 中的 “SDOLGetModule” 函数。m_pfSDOLGetModule 指向的函数之前,你需要确保 m_hSDOLoginModule 已成功加载,并且 “SDOLGetModule” 函数确实存在于该模块中,否则会导致运行时错误。m_pfSDOLTerminal = (LPSDOLTerminal)GetProcAddress(m_hSDOLoginModule, “SDOLTerminal”);
代码解释:
m_pfSDOLTerminal,并使用 GetProcAddress 函数从 m_hSDOLoginModule 模块中获取 “SDOLTerminal” 函数的地址,并将其分配给 m_pfSDOLTerminal。这样,m_pfSDOLTerminal 现在指向了 m_hSDOLoginModule 中的 “SDOLTerminal” 函数。m_pfSDOLTerminal 指向的函数之前,确保 m_hSDOLoginModule 已成功加载,且 “SDOLTerminal” 函数确实存在于该模块中,以避免运行时错误。这样的方式通常用于插件系统或需要在运行时加载不同模块的应用程序。if (m_pfSDOLInitialize == nullptr || m_pfSDOLGetModule == nullptr) return false;
代码解释:
m_pfSDOLInitialize 和 m_pfSDOLGetModule 这两个函数指针是否为空指针(nullptr)。如果其中任何一个为空,它返回 false,否则继续执行后续的操作。GetProcAddress 调用中,未能获取到 “SDOLInitialize” 或 “SDOLGetModule” 函数的地址,这些函数指针将会是空指针。因此,通过检查它们是否为空,你可以在继续使用这些函数指针之前确保它们已成功获取,以避免在尝试调用这些函数时引发未定义行为或错误。很明显由updatecore工程生成的sdologinentry.dll和sdologinentry64.dll的动态链接库。

int WINAPI SDOLInitialize(const SDOLAppInfo* pAppInfo)
{
TCHAR path[32768*2] = {0};
DWORD len = GetEnvironmentVariable(_T("PATH"), path, _countof(path));
TCHAR buffer[MAX_PATH] = {0};
GetModuleFileName(g_hModule, buffer, _countof(buffer));
_stprintf(path+len, _T(";%s\\..\\sdologin\\"), buffer);
SetEnvironmentVariable(_T("PATH"), path);
SDOLAppInfo* pInfo = (SDOLAppInfo*)pAppInfo;
// Skip update process or not
wchar_t buffer2[MAX_PATH] = {0};
wchar_t path2[MAX_PATH*2] = {0};
GetModuleFileNameW(g_hModule, buffer2, _countof(buffer2));
swprintf_s(path2, _countof(path2), L"%s\\..\\sdologin\\", buffer2);
LicenseManager::Initial(path2);
bool bExpired = LicenseManager::GetInstance()->GetValue("Expiration");
bool bSkipUpdate = LicenseManager::GetInstance()->GetValue("SkipUpdate");
if (!(bExpired == false && bSkipUpdate == true)) // !(未过期 && 跳过更新)
{
if (Update::GetInstance()->CheckLocalVersion())
{
if(!Update::GetInstance()->DownloadUpdate(pInfo->AppID, pInfo->AreaId, pInfo->GroupId))
{
return SDOA_FALSE;
}
}
else
{
if (!Update::GetInstance()->ForceUpdate(pInfo->AppID, pInfo->AreaId, pInfo->GroupId))
{
return SDOA_FALSE;
}
}
}
/*
#ifdef _WIN64
g_hSdoLogin = LoadLibrary(_T("sdologinsdk64.dll"));
#else
g_hSdoLogin = LoadLibrary(_T("sdologinsdk.dll"));
#endif
*/
GetModuleFileName(g_hModule, buffer, _countof(buffer));
#ifdef _WIN64
sprintf(buffer + strlen(buffer) - strlen("sdologinentry64.dll"), "sdologin\\sdologinsdk64.dll");
#else
sprintf(buffer + strlen(buffer) - strlen("sdologinentry.dll"), "sdologin\\sdologinsdk.dll");
#endif
g_hSdoLogin = LoadLibraryEx(buffer, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
LPSDOLInitialize pFun = (LPSDOLInitialize)GetProcAddress(g_hSdoLogin, "SDOLInitialize");
if(pFun)
{
return pFun(pAppInfo);
}
return SDOA_FALSE;
}
int WINAPI SDOLGetModule(REFIID riid, void** intf)
{
LPSDOLGetModule pFun = (LPSDOLGetModule)GetProcAddress(g_hSdoLogin, "SDOLGetModule");
if(pFun)
{
return pFun(riid, intf);
}
return false;
}
int WINAPI SDOLTerminal()
{
LPSDOLTerminal pFun = (LPSDOLTerminal)GetProcAddress(g_hSdoLogin, "SDOLTerminal");
int ret = SDOA_FALSE;
if(pFun)
{
ret = pFun();
}
FreeLibrary(g_hSdoLogin);
if(ret == SDOL_ERRORCODE_OK)
{
Update::GetInstance()->SetupUpdate();
}
Update::Destroy();
return ret;
}
int WINAPI SDOLInitialize(const SDOLAppInfo* pAppInfo)
{
TCHAR path[32768*2] = {0};
DWORD len = GetEnvironmentVariable(_T(“PATH”), path, _countof(path)); TCHAR buffer[MAX_PATH] = {0};
GetModuleFileName(g_hModule, buffer, _countof(buffer)); _stprintf(path+len, _T(“;%s\…\sdologin\”), buffer);
SetEnvironmentVariable(_T(“PATH”), path);
SDOLAppInfo* pInfo = (SDOLAppInfo*)pAppInfo;
SetEnvironmentVariable(_T(“PATH”), path);
SDOLAppInfo* pInfo = (SDOLAppInfo*)pAppInfo;
// Skip update process or not
wchar_t buffer2[MAX_PATH] = {0};
wchar_t path2[MAX_PATH*2] = {0};
GetModuleFileNameW(g_hModule, buffer2, _countof(buffer2));
swprintf_s(path2, _countof(path2), L"%s\…\sdologin\", buffer2); LicenseManager::Initial(path2);
bool bExpired = LicenseManager::GetInstance()->GetValue(“Expiration”);
bool bSkipUpdate = LicenseManager::GetInstance()->GetValue(“SkipUpdate”); if (!(bExpired == false && bSkipUpdate == true)) // !(未过期 && 跳过更新)
{
if (Update::GetInstance()->CheckLocalVersion())
{
if(!Update::GetInstance()->DownloadUpdate(pInfo->AppID, pInfo->AreaId, pInfo->GroupId))
{
return SDOA_FALSE;
}
}
else
{
if (!Update::GetInstance()->ForceUpdate(pInfo->AppID, pInfo->AreaId, pInfo->GroupId))
{
return SDOA_FALSE;
}
}
}/*
#ifdef _WIN64
g_hSdoLogin = LoadLibrary(_T(“sdologinsdk64.dll”));
#else
g_hSdoLogin = LoadLibrary(_T(“sdologinsdk.dll”));
#endif
*/ GetModuleFileName(g_hModule, buffer, _countof(buffer));
#ifdef _WIN64
sprintf(buffer + strlen(buffer) - strlen(“sdologinentry64.dll”), “sdologin\sdologinsdk64.dll”);
#else
sprintf(buffer + strlen(buffer) - strlen(“sdologinentry.dll”), “sdologin\sdologinsdk.dll”);
#endif g_hSdoLogin = LoadLibraryEx(buffer, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
LPSDOLInitialize pFun = (LPSDOLInitialize)GetProcAddress(g_hSdoLogin, “SDOLInitialize”);
if(pFun)
{
return pFun(pAppInfo);
}
return SDOA_FALSE;}
代码解释:
SDOLInitialize 的实现,以下是它的主要功能:
PATH,并向其中添加一个目录路径。这个目录路径是 sdologin 目录,它相对于当前执行程序的目录。LicenseManager,它的目的是获取和检查许可证信息。sdologinsdk.dll 或 sdologinsdk64.dll(取决于系统架构),同理并调用动态链接库中的 SDOLInitialize 函数。int WINAPI SDOLGetModule(REFIID riid, void** intf)
{
LPSDOLGetModule pFun = (LPSDOLGetModule)GetProcAddress(g_hSdoLogin, “SDOLGetModule”);
if(pFun)
{
return pFun(riid, intf);
}
return false;
}
代码解释:
SDOLGetModule 的实现,以下是它的主要功能:
GetProcAddress 函数尝试从同理并调用动态链接库中的加载的 g_hSdoLogin 动态链接库中获取名为 “SDOLGetModule” 的函数的地址,这个函数似乎是一个用于获取模块的接口(COM 接口)的函数。riid 和 intf 参数传递给它。pFun 调用的结果。false。SDOLGetModule 函数用于获取指定接口的模块。如果成功获取到并调用了模块中的 SDOLGetModule 函数,它将返回相应的结果,否则返回 false 表示失败。通常,这种方式用于插件系统或模块化的应用程序,可以在运行时加载不同的模块并获取它们的接口。int WINAPI SDOLTerminal()
{
LPSDOLTerminal pFun = (LPSDOLTerminal)GetProcAddress(g_hSdoLogin, “SDOLTerminal”);
int ret = SDOA_FALSE;
if(pFun)
{
ret = pFun();
} FreeLibrary(g_hSdoLogin);
if(ret == SDOL_ERRORCODE_OK)
{
Update::GetInstance()->SetupUpdate();
}
Update::Destroy(); return ret;
}
代码解释:
这段代码是一个函数 SDOLTerminal 的实现,以下是它的主要功能:
GetProcAddress 函数尝试从同理并调用动态链接库中的加载的 g_hSdoLogin 动态链接库中获取名为 “SDOLTerminal” 的函数的地址,似乎是一个用于终止模块操作的函数。ret 变量中。FreeLibrary 函数释放 g_hSdoLogin 动态链接库,即卸载模块。ret 的值等于 SDOL_ERRORCODE_OK,则表示成功执行模块操作,它会调用 Update::GetInstance()->SetupUpdate() 来设置更新,否则跳过这一步。Update::Destroy() 来释放更新相关的资源,并返回 ret 的值。这段代码的主要作用是在模块操作结束时,执行一些清理工作,包括释放动态链接库,进行更新设置,以及资源的销毁。这通常用于模块的初始化和终止过程。
解释如何调用到sdologinentry.dll或者sdologinentry64.dll库中的三个函数:
SDOLInitialize
SDOLGetModule
SDOLTerminal
LIBRARY "updatecore"
EXPORTS
igwInitialize
igwGetModule
igwTerminal
SDOLInitialize
SDOLGetModule
SDOLTerminal
资源解释:
LIBRARY "updatecore" 表示该动态链接库的名称为 “updatecore”。EXPORTS 下面列出了一系列函数名称,它们将会在该 DLL 中被导出,以便其他模块或程序可以调用这些函数。这些函数包括了 igwInitialize、igwGetModule、igwTerminal、SDOLInitialize、SDOLGetModule 以及 SDOLTerminal。GetProcAddress 函数来获取并调用这些函数,这使得你可以在运行时动态加载和使用这些功能。SDOLInitialize
SDOLGetModule
SDOLTerminal
很明显由sdk工程生成的sdologinsdk.dll和sdologinsdk64.dll的动态链接库。

static SDOLLogin* g_pSDOLLogin = NULL;
static SDOLInfo* g_pSDOLInfo = NULL;
bool _SDOLGetModule(REFIID riid, void** intf);
bool _igwGetModule(REFIID riid, void** intf);
int WINAPI SDOLInitializeInternal(const SDOLAppInfo* pAppInfo)
{
TRACET();
TRACEI(_T("pAppInfo[0x%x]\n"), pAppInfo);
if(pAppInfo == NULL || pAppInfo->Size != sizeof(SDOLAppInfo))
{
TRACEW("SDOLII pAppInfo error.");
return SDOL_ERRORCODE_INVALIDPARAM;
}
if(!ModuleLoginSDK::Initial(pAppInfo))
{
TRACEW("ModuleLoginSDK::Initial() failed.");
return SDOL_ERRORCODE_FAILED;
}
TRACEI(_T("AppID[%d] AppName[%s] AppVer[%s] AreaId[%d] GroupId[%d]\n"),
pAppInfo->AppID, pAppInfo->AppName, pAppInfo->AppVer, pAppInfo->AreaId, pAppInfo->GroupId);
//ModuleLoginSDK::GetInstance()->SetAppInfo(pAppInfo);
g_pSDOLLogin = new SDOLLogin();
g_pSDOLInfo = new SDOLInfo();
return SDOL_ERRORCODE_OK;
};
bool _InitObjects( const SDOLAppInfo& appInfo ) ;
int WINAPI SDOLInitialize(const SDOLAppInfo* pAppInfo)
{
TRACET();
TRACEI(_T("pAppInfo[0x%x]\n"), pAppInfo);
if (NULL != pAppInfo)
{
TRACEI(_T("pAppInfo->Size[%d]\n"), pAppInfo->Size);
TRACEI(_T("pAppInfo->AppID[%d]\n"), pAppInfo->AppID);
TRACEI(_T("pAppInfo->AppName[%s]\n"), pAppInfo->AppName);
TRACEI(_T("pAppInfo->AppVer[%s]\n"), pAppInfo->AppVer);
TRACEI(_T("pAppInfo->AreaId[%d]\n"), pAppInfo->AreaId);
}
// zlc bool res = _InitObjects(*pAppInfo);
SDOLAppInfo struAppInfo;
memcpy(&struAppInfo, pAppInfo, sizeof(SDOLAppInfo));
if (struAppInfo.AppID == 0)
struAppInfo.AppID = 791000388; //zlc here
bool res = _InitObjects(struAppInfo);
if (!res)
{
return SDOL_ERRORCODE_FAILED;
}
ModuleLoginSDK::GetInstance()->SetWindowMode(SetWindowModeReq::OutsideGame);
return SDOL_ERRORCODE_OK;
};
int WINAPI SDOLGetModule(REFIID riid, void** intf)
{
TRACET();
OLECHAR* guid = NULL;
StringFromIID(riid, &guid);
TRACEI(_T("0 SDOLGetModule riid[%s]"), guid);
bool res = false;
res = _SDOLGetModule(riid, intf);
if (!res)
{
res = _igwGetModule(riid, intf);
}
if (res)
{
OLECHAR* guid = NULL;
StringFromIID(riid, &guid);
TRACEI(_T("1 SDOLGetModule riid[%s]"), guid);
}
return res ? SDOL_ERRORCODE_OK:SDOL_ERRORCODE_FAILED;
};
int WINAPI SDOLTerminal()
{
TRACET();
TRACEI(_T(""));
int ret = ModuleLoginSDK::Destroy();
SAFE_DELETE(g_pSDOLLogin);
return ret == ShutdownSuccess ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
};
bool _SDOLGetModule(REFIID riid, void** intf)
{
TRACET();
TRACEI(_T(""));
if(riid == __uuidof(ISDOLLogin))
{
*intf = (void*)(ISDOLLogin*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin2))
{
*intf = (void*)(ISDOLLogin2*)g_pSDOLLogin;
return true;
}
if (riid == __uuidof(ISDOLInfo))
{
*intf = (void*)(ISDOLInfo*)g_pSDOLInfo;
return true;
}
if(riid == __uuidof(ISDOLLogin3))
{
*intf = (void*)(ISDOLLogin3*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin4))
{
*intf = (void*)(ISDOLLogin4*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin5))
{
*intf = (void*)(ISDOLLogin5*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin6))
{
*intf = (void*)(ISDOLLogin6*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin7))
{
*intf = (void*)(ISDOLLogin7*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin8))
{
*intf = (void*)(ISDOLLogin8*)g_pSDOLLogin;
return true;
}
return false;
};
static SDOLLogin* g_pSDOLLogin = NULL;
static SDOLInfo* g_pSDOLInfo = NULL;
bool _SDOLGetModule(REFIID riid, void** intf);
bool _igwGetModule(REFIID riid, void** intf);int WINAPI SDOLInitializeInternal(const SDOLAppInfo* pAppInfo)
{
TRACET();
TRACEI(_T(“pAppInfo[0x%x]\n”), pAppInfo); if(pAppInfo == NULL || pAppInfo->Size != sizeof(SDOLAppInfo))
{
TRACEW(“SDOLII pAppInfo error.”);
return SDOL_ERRORCODE_INVALIDPARAM;
} if(!ModuleLoginSDK::Initial(pAppInfo))
{
TRACEW(“ModuleLoginSDK::Initial() failed.”);
return SDOL_ERRORCODE_FAILED;
} TRACEI(_T(“AppID[%d] AppName[%s] AppVer[%s] AreaId[%d] GroupId[%d]\n”),
pAppInfo->AppID, pAppInfo->AppName, pAppInfo->AppVer, pAppInfo->AreaId, pAppInfo->GroupId); //ModuleLoginSDK::GetInstance()->SetAppInfo(pAppInfo);
g_pSDOLLogin = new SDOLLogin();
g_pSDOLInfo = new SDOLInfo(); return SDOL_ERRORCODE_OK;
};
代码解释:
这段代码定义了一个名为 SDOLInitializeInternal 的函数,以下是它的主要功能:
TRACEI 函数和 TRACEW 函数输出一些信息,用于调试和日志记录。pAppInfo 参数是否为 NULL 或其大小是否与 sizeof(SDOLAppInfo) 相符。如果不符合条件,函数会返回 SDOL_ERRORCODE_INVALIDPARAM 表示参数无效。ModuleLoginSDK::Initial(pAppInfo) 函数,尝试进行一些初始化操作。如果初始化失败,函数返回 SDOL_ERRORCODE_FAILED 表示初始化失败。pAppInfo 中的一些信息,包括了 AppID、AppName、AppVer、AreaId 和 GroupId。g_pSDOLLogin 和 g_pSDOLInfo,分别是 SDOLLogin 和 SDOLInfo 的实例。SDOL_ERRORCODE_OK 表示初始化成功。这段代码的主要目的是在应用程序的初始化过程中,根据传入的应用信息进行一些初始化工作,包括了调用 ModuleLoginSDK::Initial 函数,创建 SDOLLogin 和 SDOLInfo 的对象。如果初始化成功,函数返回成功状态码,否则返回失败状态码。
bool InitObjects( const SDOLAppInfo& appInfo ) ;
bool _InitObjects( const SDOLAppInfo& appInfo )
{
TRACET();
if(SDOLInitializeInternal(&appInfo) != SDOL_ERRORCODE_OK)
{
return false;
}
// if(g_pSDOAApp2 == NULL)
// {
// g_pSDOAApp2 = new SDOAApp2();
// }
if(g_pSDOAApp4 == NULL)
{
g_pSDOAApp4 = new SDOAApp4();
}
if(g_pSDOAAppEx == NULL)
{
g_pSDOAAppEx = new IGW2::SDOAAppEx();
}
if(g_pSDOAAppUtils == NULL)
{
g_pSDOAAppUtils = new SDOAAppUtils();
}
if(g_pSDOAClientService == NULL)
{
g_pSDOAClientService = new SDOAClientService();
}
return true;
}
代码解释:
_InitObjects 的函数,以下是它的主要功能:
TRACE 函数输出一些信息,用于调试和日志记录。SDOLInitializeInternal(&appInfo) 函数,尝试进行一些初始化操作。如果 SDOLInitializeInternal 返回的值不等于 SDOL_ERRORCODE_OK,表示初始化失败,函数返回 false 表示初始化对象失败。g_pSDOAApp4、g_pSDOAAppEx、g_pSDOAAppUtils 和 g_pSDOAClientService),如果其中有任何一个指针为空,它将分别创建对应的对象实例,这些对象可能是特定的应用程序对象。true 表示初始化对象成功。SDOLInitializeInternal 函数,通过这个函数调用到SDK中的初始化函数,以及创建特定的应用程序对象。如果初始化对象成功,函数返回 true,否则返回 false。这些对象通常用于应用程序的功能实现和操作。bool _InitObjects( const SDOLAppInfo& appInfo ) ;
int WINAPI SDOLInitialize(const SDOLAppInfo* pAppInfo)
{
TRACET();
TRACEI(_T(“pAppInfo[0x%x]\n”), pAppInfo);
if (NULL != pAppInfo)
{
TRACEI(_T(“pAppInfo->Size[%d]\n”), pAppInfo->Size);
TRACEI(_T(“pAppInfo->AppID[%d]\n”), pAppInfo->AppID);
TRACEI(_T(“pAppInfo->AppName[%s]\n”), pAppInfo->AppName);
TRACEI(_T(“pAppInfo->AppVer[%s]\n”), pAppInfo->AppVer);
TRACEI(_T(“pAppInfo->AreaId[%d]\n”), pAppInfo->AreaId);
} // zlc bool res = _InitObjects(*pAppInfo);
SDOLAppInfo struAppInfo;
memcpy(&struAppInfo, pAppInfo, sizeof(SDOLAppInfo));
if (struAppInfo.AppID == 0)
struAppInfo.AppID = 791000388; //zlc here
bool res = _InitObjects(struAppInfo);
if (!res)
{
return SDOL_ERRORCODE_FAILED;
} ModuleLoginSDK::GetInstance()->SetWindowMode(SetWindowModeReq::OutsideGame);
return SDOL_ERRORCODE_OK;
};
代码解释:
这段代码是一个名为 SDOLInitialize 的函数的实现,以下是它的主要功能:
TRACEI 函数调用来输出一些信息,这些信息包括了 pAppInfo 参数的各个成员的值,以便进行调试和日志记录。struAppInfo 的局部变量,并通过 memcpy 函数将 pAppInfo 的内容复制到 struAppInfo 中。然后,它检查 struAppInfo 中的 AppID 是否为 0,如果是,将其设置为 791000388。_InitObjects 函数,将 struAppInfo 作为参数传递给它。_InitObjects 函数可能用于初始化一些对象或资源,这部分的具体逻辑在 _InitObjects 函数中实现。_InitObjects 返回 true 表示初始化成功,它将调用 ModuleLoginSDK::GetInstance()->SetWindowMode(SetWindowModeReq::OutsideGame) 来设置某种窗口模式。窗口模式的设置可能与应用程序的显示方式有关。SDOL_ERRORCODE_OK,否则返回 SDOL_ERRORCODE_FAILED 表示初始化失败。总的来说,这段代码的目的是在应用程序初始化过程中,根据传入的应用信息进行一些初始化工作,包括了调用 _InitObjects 函数和设置窗口模式。如果初始化成功,返回成功状态码,否则返回失败状态码。
int WINAPI SDOLGetModule(REFIID riid, void** intf)
{
TRACET(); OLECHAR* guid = NULL;
StringFromIID(riid, &guid);
TRACEI(_T(“0 SDOLGetModule riid[%s]”), guid); bool res = false;
res = _SDOLGetModule(riid, intf);
if (!res)
{
res = _igwGetModule(riid, intf);
} if (res)
{
OLECHAR* guid = NULL;
StringFromIID(riid, &guid);
TRACEI(_T(“1 SDOLGetModule riid[%s]”), guid);
} return res ? SDOL_ERRORCODE_OK:SDOL_ERRORCODE_FAILED;
};
代码解释:
SDOLGetModule 的函数的实现,以下是它的主要功能:
TRACEI 函数和 StringFromIID 函数输出一些信息,包括 riid 参数的 GUID。guid 的指针,并通过 StringFromIID 函数将 riid 转换为字符串形式,并将结果存储在 guid 中。_SDOLGetModule 函数,传递 riid 和 intf 作为参数,以尝试获取模块。_SDOLGetModule 返回 false(表示获取模块失败),它接着调用 _igwGetModule 函数,再次尝试获取模块。riid 的信息,然后返回 SDOL_ERRORCODE_OK 表示成功。SDOL_ERRORCODE_FAILED 表示失败。_SDOLGetModule 尝试,如果失败再通过 _igwGetModule 尝试。如果成功获取到模块,它返回成功状态码,否则返回失败状态码。int WINAPI SDOLTerminal()
{
TRACET();
TRACEI(_T(“”)); int ret = ModuleLoginSDK::Destroy();
SAFE_DELETE(g_pSDOLLogin);
return ret == ShutdownSuccess ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
代码解释:
SDOLTerminal 的函数的实现,以下是它的主要功能:
TRACEI 函数输出一些信息,用于调试和日志记录。ModuleLoginSDK::Destroy() 函数,该函数可能用于销毁一些模块相关的资源和对象。ModuleLoginSDK::Destroy() 返回的结果存储在 ret 变量中,这个结果可能是一个表示销毁操作是否成功的值。SAFE_DELETE(g_pSDOLLogin) 来释放 g_pSDOLLogin 所指向的对象或资源。这个宏可能用于安全地删除指针,并将指针置为 nullptr。ret 的值等于 ShutdownSuccess,它返回 SDOL_ERRORCODE_OK 表示终止成功,否则返回 SDOL_ERRORCODE_FAILED 表示终止失败。bool _SDOLGetModule(REFIID riid, void** intf)
{
TRACET();
TRACEI(_T(“”)); if(riid == __uuidof(ISDOLLogin))
{
intf = (void)(ISDOLLogin*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin2))
{
intf = (void)(ISDOLLogin2*)g_pSDOLLogin;
return true;
}
if (riid == __uuidof(ISDOLInfo))
{
intf = (void)(ISDOLInfo*)g_pSDOLInfo;
return true;
}
if(riid == __uuidof(ISDOLLogin3))
{
intf = (void)(ISDOLLogin3*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin4))
{
intf = (void)(ISDOLLogin4*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin5))
{
intf = (void)(ISDOLLogin5*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin6))
{
intf = (void)(ISDOLLogin6*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin7))
{
intf = (void)(ISDOLLogin7*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin8))
{
intf = (void)(ISDOLLogin8*)g_pSDOLLogin;
return true;
} return false;
};
代码解释:
_SDOLGetModule 的函数的实现,以下是它的主要功能:
TRACEI 函数输出一些信息,用于调试和日志记录。riid 参数是否等于特定的接口类型的 UUID(GUID)。如果 riid 匹配某个特定接口类型的 UUID,它将将 *intf 指向相应的接口指针,并返回 true 表示成功。riid 不匹配任何已知的接口类型,它返回 false 表示失败。riid 参数,尝试获取对应的接口,并将接口指针存储在 *intf 中,以便其他部分的代码可以使用这些接口进行操作。如果 riid 匹配已知接口类型,则返回 true,否则返回 false。这通常用于实现 COM 接口的获取和对象的实例化。bool _igwGetModule(REFIID riid, void** intf)
{
if(riid == __uuidof(ISDOAApp))
{
intf = (void)(ISDOAApp*)g_pSDOAApp4;
return true;
}
if(riid == __uuidof(ISDOAApp2))
{
intf = (void)(ISDOAApp2*)g_pSDOAApp4;
return true;
}
if(riid == __uuidof(ISDOAApp3))
{
intf = (void)(ISDOAApp3*)g_pSDOAApp4;
return true;
}
if(riid == __uuidof(ISDOAApp4))
{
intf = (void)(ISDOAApp4*)g_pSDOAApp4;
return true;
}
if(riid == __uuidof(IGW2::ISDOAAppEx))
{
intf = (void)(IGW2::ISDOAAppEx*)g_pSDOAAppEx;
return true;
}
if(riid == __uuidof(ISDOAAppUtils))
{
intf = (void)(ISDOAAppUtils*)g_pSDOAAppUtils;
return true;
}
if(riid == __uuidof(ISDOAClientService))
{
intf = (void)(ISDOAClientService*)g_pSDOAClientService;
return true;
} if(riid == __uuidof(IGPLUSApp))
{
intf = (void)(IGPLUSApp*)CGPlusManager::GetInstance()->getGplusAppObject();
return true;
} //if(Dx7GetModule(riid, intf))
//{
// return true;
//}
if(Dx8GetModule(riid, intf))
{
return true;
}
if(Dx9GetModule(riid, intf))
{
return true;
}
if(Dx11GetModule(riid, intf))
{
return true;
}
if(GDIGetModule(riid, intf))
{
return true;
}
if(DDrawGetModule(riid, intf))
{
return true;
}
return false;}
代码解释:
这段代码是一个名为 _igwGetModule 的函数的实现,以下是它的主要功能:
riid 参数是否等于特定的接口类型的 UUID(GUID)。如果 riid 匹配某个特定接口类型的 UUID,它将将 *intf 指向相应的接口指针,并返回 true 表示成功。riid 不匹配已知的接口类型,它继续检查其他接口类型,包括 Dx8GetModule、Dx9GetModule、Dx11GetModule、GDIGetModule、DDrawGetModule 等。如果传入的 riid 匹配这些接口类型中的任何一个,它同样将 *intf 指向相应的接口指针,并返回 true 表示成功。false 表示没有匹配的接口。这段代码的主要目的是根据传入的 riid 参数,尝试获取对应的接口,并将接口指针存储在 *intf 中,以便其他部分的代码可以使用这些接口进行操作。这是一种通用的接口获取机制,用于获取不同接口类型的对象。如果 riid 匹配已知的接口类型,它返回 true,否则返回 false。这通常用于实现 COM 接口的获取和对象的实例化。
解释如何调用到sdologinsdk.dll或者sdologinsdk64.dll库中的三个函数:
LIBRARY “sdologinsdk”
EXPORTS
SDOLInitialize
SDOLGetModule
SDOLTerminal
igwInitialize
igwGetModule
igwTerminal
代码解释:
SDOLInitializeSDOLGetModuleSDOLTerminaligwInitializeigwGetModuleigwTerminal