sdologinentry.dll与sdologinentry64.dll动态库关于执行强制更新的解释
- 函数入口:
int WINAPI igwInitialize(DWORD dwSdkVersion, const AppInfo* pAppInfo)
C++
int WINAPI igwInitialize(DWORD dwSdkVersion, const AppInfo* pAppInfo)
{
TRACET();
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);
AppInfo* pInfo = (AppInfo*)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<bool>("Expiration");
bool bSkipUpdate = LicenseManager::GetInstance()->GetValue<bool>("SkipUpdate");
if (!(bExpired == false && bSkipUpdate == true)) // !(未过期 && 跳过更新)
{
if (Update::GetInstance()->CheckLocalVersion())
{
TRACEI(_T("igwInitialize DownloadUpdate"));
if(!Update::GetInstance()->DownloadUpdate(pInfo->nAppID, pInfo->nAreaId, pInfo->nGroupId))
{
return SDOA_FALSE;
}
}
else
{
TRACEI(_T("igwInitialize ForceUpdate"));
if (!Update::GetInstance()->ForceUpdate(pInfo->nAppID, pInfo->nAreaId, pInfo->nGroupId))
{
return SDOA_FALSE;
}
}
}
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);
//g_hSdoLogin = LoadLibrary(_T("sdologinsdk.dll"));
LPigwInitialize pFun = (LPigwInitialize)GetProcAddress(g_hSdoLogin, "igwInitialize");
if(pFun)
{
return pFun(dwSdkVersion, pAppInfo);
}
return SDOA_FALSE;
}
-
这段代码是一个初始化函数
igwInitialize
,通常作为某个 SDK 或模块的入口点。下面是对代码的详细解释:-
首先,函数使用
GetEnvironmentVariable
获取当前环境变量中PATH
的值,并将其存储在path
变量中。然后,获取当前模块的文件路径,并将模块所在目录的路径添加到path
变量中。 -
接着,检查许可证的过期状态和是否跳过更新。许可证管理器
LicenseManager
用于管理许可证信息。如果许可证未过期且未跳过更新,则执行更新操作。 -
如果本地版本需要更新,则调用
Update::GetInstance()->DownloadUpdate
方法进行更新下载。如果下载失败,则返回SDOA_FALSE
。 -
如果本地版本无需更新,则调用
Update::GetInstance()->ForceUpdate
方法强制更新。如果更新失败,则返回SDOA_FALSE
。-
ForceUpdate代码定义:
C++bool Update::ForceUpdate(int appId,int areaId,int groupId) { TRACET(); OutputDebugStringW(L"ForceUpdate Enter"); m_AppId = appId; m_AreaId = areaId; m_GroupId = groupId; bool ret = false; CloseHandle(m_hProcessMutex); static const size_t buff_size = 0x1000; wchar_t buff[buff_size+1] = { 0 }; #ifdef _DEBUG swprintf(buff,L"ForceUpdate:[ProcessMutexName] %s",GetProcessMutexName()); OutputDebugStringW(buff); #endif m_hProcessMutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, GetProcessMutexName()); if(m_hProcessMutex) { return ret; } HANDLE hUpdateMutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, GetUpdateMutexName()); if(hUpdateMutex) { return ret; } Update::GetInstance()->SendLogReport(112, "%d$$$%s$$$execmdline", GetLastError(), ::GetCommandLineA()); hUpdateMutex = CreateMutexA(NULL, TRUE, GetUpdateMutexName()); WCHAR path[MAX_PATH+32]; WCHAR tmppath[MAX_PATH+32]; GetModuleFileNameW(g_hModule, path, MAX_PATH); GetModuleFileNameW(g_hModule, tmppath, MAX_PATH); wcscat(path, L"/../"); wcscat(tmppath, L"/../temp"); //.. // 将宽字符字符串转换为 ANSI 字符串 //std::wstring strPath(path); //std::wstring strTmpPath(tmppath); //std::string bufferPath(strPath.begin(), strPath.end()); //std::string bufferTmpPath(strTmpPath.begin(), strTmpPath.end()); 使用 MessageBoxA 函数显示路径 //MessageBoxA(NULL, bufferPath.c_str(), "Path", MB_OK); //MessageBoxA(NULL, bufferTmpPath.c_str(), "TmpPath", MB_OK); int version = 1; HANDLE handle = PtOpen(path, L"ver.bin", path, path); if(handle) { PtVersionInfo info; if(PtGetLatestVerInfo(handle, &info)) { version = (int)info.verId; // 将整数转换为字符串 //char buffer[256]; //sprintf(buffer, "Version: %d", version); //MessageBoxA(NULL,buffer,"version提示",0); } PtClose(handle); } TCHAR url[1024] = {0}; size_t size = _countof(url); //,,, // 打印 url、size 和 version 变量的值 //std::string msg = "url: " + std::string(url) + "\n" // + "size: " + std::to_string(size) + "\n" // + "version: " + std::to_string(version); //MessageBoxA(NULL, msg.c_str(), "Variables", MB_OK); // 打印 url、size 和 version 变量的值 //char buffer[1024]; //sprintf(buffer, "url: %s\nsize: %u\nversion: %d", url, size, version); //MessageBoxA(NULL, buffer, "Variables", MB_OK); Update::GetInstance()->GetUpdateUrl(url, size, version); #if 1 swprintf(buff,L"ForceUpdate:[UpdateUrl] %s",url); OutputDebugStringW(buff); // 将 TCHAR 类型的字符串转换为 ANSI 字符串 //std::string strUrl(url); //char bufferUrl[1024]; //strcpy_s(bufferUrl, strUrl.c_str()); 使用 MessageBoxA 函数显示 url //MessageBoxA(NULL, bufferUrl, "UpdateUrl提示", MB_OK); #endif wstring wurl = StringHelper::ANSIToUnicode(url); handle = PtOpen(wurl.c_str(), L"ver.bin", path, tmppath); // 将宽字符字符串转换为 ANSI 字符串 //std::string strWurl(wurl.begin(), wurl.end()); //const char* bufferWurl = strWurl.c_str(); 使用 MessageBoxA 函数显示 wurl //MessageBoxA(NULL, bufferWurl, "UpdateUrl (Unicode)提示", MB_OK); bool bRet = true; if(handle) { TRACEI(_T("ForceUpdate UpdateFiles---------")); CUpdateDlg dlg; bRet = dlg.UpdateFiles(g_hModule, handle); PtClose(handle); } ReleaseMutex(hUpdateMutex); CloseHandle(hUpdateMutex); // ret = true; // if (bRet) // { // if (!SetupUpdate()) // { // ret = false; // } // } // else // { // ret = false; // } #if 1 swprintf(buff,L"ForceUpdate:Finish"); OutputDebugStringW(buff); #endif return bRet; }
-
这段代码是
Update::ForceUpdate
方法的实现。一步步解释:-
函数签名和日志输出:
- 这个函数用于强制更新,传入三个参数:
appId
、areaId
和groupId
。 - 函数开始时通过
OutputDebugStringW
输出调试日志,指示函数已经被调用。
- 这个函数用于强制更新,传入三个参数:
-
初始化变量和互斥锁:
- 初始化一些变量,包括
ret
、buff
和path
、tmppath
等。 - 调用
CloseHandle
关闭之前的进程互斥锁m_hProcessMutex
。 - 然后通过
OpenMutex
和CreateMutexA
创建新的进程互斥锁m_hProcessMutex
和hUpdateMutex
。
- 初始化一些变量,包括
-
获取当前模块路径和版本信息:
-
使用
GetModuleFileNameW
获取当前模块的文件路径,分别存储在path
和tmppath
变量中。C++--------------------------- Path --------------------------- F:\ GL\Data\sdo2\sdologinentry.dll/../ --------------------------- 确定 --------------------------- --------------------------- TmpPath --------------------------- F:\ GL\Data\sdo2\sdologinentry.dll/../temp --------------------------- 确定 ---------------------------
-
根据路径拼接
ver.bin
文件的路径,调用PtOpen
函数打开ver.bin
文件,并获取其版本信息。-
C++
--------------------------- version提示 --------------------------- Version: 10903013 --------------------------- 确定 ---------------------------
-
-
-
获取更新地址:
-
调用
Update::GetInstance()->GetUpdateUrl
方法获取更新地址,并将地址存储在url
变量中。C++bool Update::GetUpdateUrl(TCHAR* url, size_t& size, int version) { //MessageBoxA(NULL,"11","GetUpdateUrl提示",0); if(url == NULL || size < 1) { return false; } url[0] = 0; TCHAR checkUrl[1024]; char checkValue[MD5LEN] = {0}; GetUpdateCheckValue(checkValue, version); _stprintf(checkUrl, UPDATE_CHECK_URL, m_AppId, m_AreaId, m_GroupId, m_ClientSign, version, checkValue); //.... // 将 TCHAR 类型的字符串转换为 ANSI 字符串 //std::string strCheckUrl(checkUrl); //const char* bufferCheckUrl = strCheckUrl.c_str(); 使用 MessageBoxA 函数显示 checkUrl //MessageBoxA(NULL, bufferCheckUrl, "CheckUrl提示GetUpdateUrl", MB_OK); char data[1024]; memset(data, 0, sizeof(data)); size_t bufferSize = _countof(data); if(GetUpdateServerUrl(checkUrl, data, bufferSize) && bufferSize > 0 && bufferSize < 1024) { data[bufferSize] = 0; TiXmlDocument document; document.Parse(data); TiXmlElement* pElement = document.FirstChildElement(_T("verbinurl")); if(pElement) { const char* value = pElement->GetText(); if(value) { _tcscpy(url, value); } } } if (strlen(url) < 1 || strcmp(url, "NULL") == 0) { SendLogReport(107, "%d$$$%s$$$Get Ver file url failed", GetLastError(), checkUrl); _stprintf(url, UPDATE_URL, m_AppId); } return true; }
-
这段代码是
Update::GetUpdateUrl
方法的实现。解释一下它的逻辑:
-
参数检查:
-
-
-
-
-
-