#include #include #include #include #include #include #include static void SplitString(const CStringA &src, CHAR sep, std::vector &dst) { dst.clear(); int len = src.GetLength(); CStringA str; bool inParam = false; for (int i = 0; i < len; ++i) { if (inParam || src[i] != sep) { str.AppendChar(src[i]); if ('\"' == src[i]) inParam = !inParam; } else { if (!str.IsEmpty()) { dst.push_back(str); str.Empty(); } } } if (!str.IsEmpty()) { dst.push_back(str); str.Empty(); } } static void RemoveQuotes(const CStringA& src, CStringA &dst) { dst = src; while (dst.GetLength() >= 2 && dst[0] == '\"' && dst[dst.GetLength() - 1] == '\"') { dst = dst.Mid(1, dst.GetLength() - 2); } } static CStringA GetInstallLocation(const CStringA& guid) { CStringA strInstallLoc; HKEY hKey = NULL; CStringA strSubKey; strSubKey.Format("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", (LPCSTR)guid); RegOpenKeyExA(HKEY_LOCAL_MACHINE, strSubKey, 0, KEY_QUERY_VALUE, &hKey); if (NULL != hKey) { CHAR szData[MAX_PATH] = { 0 }; DWORD cbData = MAX_PATH; if (ERROR_SUCCESS == RegQueryValueExA(hKey, "InstallLocation", NULL, NULL, (LPBYTE)szData, &cbData)) { strInstallLoc = szData; } RegCloseKey(hKey); } return strInstallLoc; } static CStringA GetUninstallString(const CStringA &guid) { CStringA strUninstall; HKEY hKey = NULL; CStringA strSubKey; strSubKey.Format("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", (LPCSTR)guid); RegOpenKeyExA(HKEY_LOCAL_MACHINE, strSubKey, 0, KEY_QUERY_VALUE, &hKey); if (NULL != hKey) { CHAR szData[MAX_PATH] = { 0 }; DWORD cbData = MAX_PATH; if (ERROR_SUCCESS == RegQueryValueExA(hKey, "UninstallString", NULL, NULL, (LPBYTE)szData, &cbData)) { strUninstall = szData; } RegCloseKey(hKey); } return strUninstall; } static bool AppIsRun(const CStringA &guid, const CStringA &appName) { CStringA strInstallLoc = GetInstallLocation(guid); if (strInstallLoc.IsEmpty()) { return false; } CStringW strAppPath2(strInstallLoc); CStringW strAppName2(appName); bool ret = false; HANDLE hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot != INVALID_HANDLE_VALUE) { PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); BOOL bFindFirstProcess = ::Process32First(hSnapshot, &pe); if (bFindFirstProcess) { do { WCHAR exeFullPath[1024] = { 0 }; HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe.th32ProcessID); if (NULL != hProcess) { ::GetModuleFileNameExW(hProcess, NULL, exeFullPath, 1024); ::CloseHandle(hProcess); } CStringW strExeFullPath(exeFullPath); int pos = strExeFullPath.ReverseFind('\\'); if (-1 != pos) { CStringW strExeName = strExeFullPath.Right(strExeFullPath.GetLength() - pos - 1); strExeFullPath.MakeLower(); strAppPath2.MakeLower(); if (0 == _wcsicmp(strExeName, strAppName2) && NULL != wcsstr(strExeFullPath, strAppPath2)) { ret = true; break; } } } while (::Process32Next(hSnapshot, &pe)); } ::CloseHandle(hSnapshot); } return ret; } static int UninstallApp(const CStringA &guid) { CStringA strUninstall = GetUninstallString(guid); if (strUninstall.IsEmpty()) { return 0; } int ret = 1; std::vector cmdList; SplitString(strUninstall, ' ', cmdList); if (!cmdList.empty()) { CStringA exePath; RemoveQuotes(cmdList[0], exePath); int pos = exePath.ReverseFind('\\'); if (-1 == pos) pos = exePath.ReverseFind('/'); if (-1 != pos) { CStringA exeDir = exePath.Left(pos + 1); CStringA exeName = exePath.Right(exePath.GetLength() - pos - 1); CHAR tmpPath[MAX_PATH] = { 0 }; GetTempPathA(MAX_PATH, tmpPath); if (tmpPath[strlen(tmpPath) - 1] != '\\') strcat_s(tmpPath, "\\"); CStringA tmpDir; tmpDir.Format("%s{72A421E1-88A8-4D5C-97FA-F76B5B8A05E8}\\", tmpPath); SHCreateDirectoryExA(NULL, tmpDir, NULL); CopyFileA(exeDir + exeName, tmpDir + exeName, FALSE); CopyFileA(exeDir + "ISSetup.dll", tmpDir + "ISSetup.dll", FALSE); CopyFileA(exeDir + "0x0804.ini", tmpDir + "0x0804.ini", FALSE); CopyFileA(exeDir + "Setup.ilg", tmpDir + "Setup.ilg", FALSE); CopyFileA(exeDir + "setup.ini", tmpDir + "setup.ini", FALSE); PROCESS_INFORMATION ProcessInfo; STARTUPINFOA StartupInfo; ZeroMemory(&StartupInfo, sizeof(StartupInfo)); StartupInfo.cb = sizeof(StartupInfo); char command[256]; sprintf_s(command, "%s%s -l0x0804 -removeonly", (LPCSTR)tmpDir, (LPCSTR)exeName); if (CreateProcessA(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo)) { WaitForSingleObject(ProcessInfo.hProcess, INFINITE); CloseHandle(ProcessInfo.hThread); CloseHandle(ProcessInfo.hProcess); CStringA strUninstall = GetUninstallString(guid); if (strUninstall.IsEmpty()) { ret = 0; } } } } return ret; } static int UninstallDriver(const CStringA &guid) { CStringA strUninstall = GetUninstallString(guid); if (strUninstall.IsEmpty()) { return 0; } int ret = 1; PROCESS_INFORMATION ProcessInfo; STARTUPINFOA StartupInfo; ZeroMemory(&StartupInfo, sizeof(StartupInfo)); StartupInfo.cb = sizeof(StartupInfo); char command[256]; sprintf_s(command, "MsiExec.exe /x %s", (LPCSTR)guid); if (CreateProcessA(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo)) { WaitForSingleObject(ProcessInfo.hProcess, INFINITE); CloseHandle(ProcessInfo.hThread); CloseHandle(ProcessInfo.hProcess); CStringA strUninstall = GetUninstallString(guid); if (strUninstall.IsEmpty()) { ret = 0; } } return ret; } static BOOL DeleteDirectory(LPCSTR lpszDir) { if (NULL == lpszDir || '\0' == lpszDir[0]) { return FALSE; } if (!PathFileExistsA(lpszDir)) { return FALSE; } WIN32_FIND_DATAA wfd = { 0 }; CHAR szFile[MAX_PATH] = { 0 }; CHAR szDelDir[MAX_PATH] = { 0 }; lstrcpyA(szDelDir, lpszDir); if (lpszDir[lstrlenA(lpszDir) - 1] != L'\\') { _snprintf_s(szDelDir, _countof(szDelDir) - 1, "%s\\", lpszDir); } else { strncpy_s(szDelDir, lpszDir, _countof(szDelDir) - 1); } _snprintf_s(szFile, _countof(szFile) - 1, "%s*.*", szDelDir); HANDLE hFindFile = FindFirstFileA(szFile, &wfd); if (INVALID_HANDLE_VALUE == hFindFile) { return FALSE; } do { if (lstrcmpiA(wfd.cFileName, ".") == 0 || lstrcmpiA(wfd.cFileName, "..") == 0) { continue; } _snprintf_s(szFile, _countof(szFile) - 1, "%s%s", szDelDir, wfd.cFileName); if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { DeleteDirectory(szFile); } else { DeleteFileA(szFile); } } while (FindNextFileA(hFindFile, &wfd)); FindClose(hFindFile); RemoveDirectoryA(szDelDir); return TRUE; } int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { CStringW strCmdLine(lpCmdLine); CStringA strAppGuid, strAppName; if (-1 != strCmdLine.Find(L"OEM_HANWANG")) { strAppGuid = "InstallShield_{D6F0C80E-A058-485D-AA12-49D0656EC2BE}"; strAppName = "HanvonScan.exe"; } else if (-1 != strCmdLine.Find(L"OEM_LISICHENG")) { strAppGuid = "InstallShield_{EA98728C-9793-4B3B-8D6C-3FAE94648972}"; strAppName = "LanxumScan.exe"; } else if (-1 != strCmdLine.Find(L"OEM_CANGTIAN")) { return 0; } else if (-1 != strCmdLine.Find(L"OEM_ZHONGJING")) { return 0; } else if (-1 != strCmdLine.Find(L"OEM_ZIGUANG")) { return 0; } else if (-1 != strCmdLine.Find(L"OEM_NEUTRAL")) { return 0; } else { strAppGuid = "InstallShield_{6BE74035-CDC8-4CBF-937C-EBC08A9D6233}"; strAppName = "HuaGoScan.exe"; } if (AppIsRun(strAppGuid, strAppName)) { return 2; } CStringA strInstallPath = GetInstallLocation(strAppGuid); int ret = UninstallApp(strAppGuid); if (0 == ret) { DeleteDirectory(strInstallPath); CHAR progPath[MAX_PATH]; SHGetSpecialFolderPathA(NULL, progPath, CSIDL_COMMON_PROGRAMS, FALSE); CStringA strProgPath = progPath; if (-1 != strCmdLine.Find(L"OEM_HANWANG")) DeleteDirectory(strProgPath + "\\LanXum"); else if (-1 != strCmdLine.Find(L"OEM_LISICHENG")) DeleteDirectory(strProgPath + "\\汉王科技股份有限公司"); else DeleteDirectory(strProgPath + "\\HuaGaoChina"); CHAR desktopPath[MAX_PATH]; SHGetSpecialFolderPathA(NULL, desktopPath, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE); CStringA strDesktopPath = desktopPath; if (-1 != strCmdLine.Find(L"OEM_HANWANG")) DeleteFileA(strDesktopPath + "\\HanvonScan.lnk"); else if (-1 != strCmdLine.Find(L"OEM_LISICHENG")) DeleteFileA(strDesktopPath + "\\LanxumScan.lnk"); else DeleteFileA(strDesktopPath + "\\HuaGoScan.lnk"); CStringA strDriverGuid1, strDriverGuid2; if (-1 != strCmdLine.Find(L"OEM_HANWANG")) { strDriverGuid1 = "{3D15346F-3E17-494E-B14B-5F221CD284B4}"; strDriverGuid2 = "{3D15346F-3E17-494E-B14B-5F221CD284B4}"; } else if (-1 != strCmdLine.Find(L"OEM_LISICHENG")) { strDriverGuid1 = "{0C317880-F6D9-4293-92F2-0AA9CD260420}"; strDriverGuid2 = "{0C317880-F6D9-4293-92F2-0AA9CD260420}"; } else { strDriverGuid1 = "{BDCDADB8-188F-4013-9591-BF231C595731}"; strDriverGuid2 = "{BD75DE93-2574-4EF8-B8DE-41023AB03C5B}"; } ret = 1; if (0 == UninstallDriver(strDriverGuid1) && 0 == UninstallDriver(strDriverGuid2)) ret = 0; } return ret; }