#include "pch.h" #include "misc.h" #include "usrerr.h" #include #include #include TCHAR *binToHexString(TCHAR *p, const unsigned char *cp, unsigned int count) { static const TCHAR hex_asc[] = TEXT("0123456789abcdef"); while (count) { const unsigned char c = *cp++; /* put lowercase hex digits */ *p++ = static_cast(0x20 | hex_asc[c >> 4]); *p++ = static_cast(0x20 | hex_asc[c & 0xf]); count--; } return p; } void RemoveTailLineBreak(TCHAR *pInputStr, int strSize) { size_t length; if (pInputStr) { if (StringCbLength(pInputStr, strSize, &length) == S_OK && length > 0) { if (pInputStr[length - 2] == '\r' && pInputStr[length - 1] == '\n') { pInputStr[length - 2] = pInputStr[length - 1] = 0; } else if (pInputStr[length - 1] == '\n') { pInputStr[length - 1] = 0; } } } } int RunCommand(TCHAR *pszCmd, TCHAR *pszResultBuffer, int dwResultBufferSize, unsigned long *pRetCode) { BOOL bRet; HANDLE hReadPipe = nullptr; HANDLE hWritePipe = nullptr; DWORD retCode; STARTUPINFO si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES securityAttributes; if (pszCmd == nullptr) { SPDLOG_ERROR(TEXT("Input params Error: [{0}]"), pszCmd); return -ERR_INPUT_PARAMS; } if (pszResultBuffer && dwResultBufferSize > 0) { memset(pszResultBuffer, 0, dwResultBufferSize); } memset(&si, 0, sizeof(STARTUPINFO)); memset(&pi, 0, sizeof(PROCESS_INFORMATION)); // 设定管道的安全属性 securityAttributes.bInheritHandle = TRUE; securityAttributes.nLength = sizeof(securityAttributes); securityAttributes.lpSecurityDescriptor = nullptr; // 创建匿名管道 bRet = ::CreatePipe(&hReadPipe, &hWritePipe, &securityAttributes, 0); if (FALSE == bRet) { SPDLOG_ERROR(TEXT("CreatePipe Error")); return -ERR_SYS_CALL; } // 设置新进程参数 si.cb = sizeof(si); si.hStdError = hWritePipe; si.hStdOutput = hWritePipe; si.wShowWindow = SW_HIDE; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // 创建新进程执行命令, 将执行结果写入匿名管道中 bRet = ::CreateProcess(nullptr, (pszCmd), nullptr, nullptr, TRUE, 0, nullptr, nullptr, &si, &pi); if (FALSE == bRet) { SPDLOG_ERROR(TEXT("CreateProcess Error")); return -ERR_CREATE_PROCESS; } // 等待命令执行结束 //::WaitForSingleObject(pi.hThread, INFINITE); ::WaitForSingleObject(pi.hThread, 3000); ::WaitForSingleObject(pi.hProcess, 3000); if (pszResultBuffer) { // 从匿名管道中读取结果到输出缓冲区 ::RtlZeroMemory(pszResultBuffer, dwResultBufferSize); ::ReadFile(hReadPipe, pszResultBuffer, dwResultBufferSize, nullptr, nullptr); } // 获取调用程序返回值 if (pRetCode) { if (GetExitCodeProcess(pi.hProcess, &retCode)) { *pRetCode = retCode; } } // 关闭句柄, 释放内存 ::CloseHandle(pi.hThread); ::CloseHandle(pi.hProcess); ::CloseHandle(hWritePipe); ::CloseHandle(hReadPipe); RemoveTailLineBreak(pszResultBuffer, dwResultBufferSize); //pszResultBuffer[dwResultBufferSize - 1] = 0; return ERR_SUCCESS; } void ShowWindowsErrorMessage(const TCHAR *pMsgHead) { LPVOID buf; if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, nullptr, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, nullptr)) { SPDLOG_ERROR(TEXT("{0} Error({1}): {2}"), pMsgHead, GetLastError(), buf); LocalFree(buf); } else { SPDLOG_ERROR(TEXT("{0} Unknown Error{1}."), pMsgHead, GetLastError()); } } void StringReplaceAll(TCHAR *pOrigin, const TCHAR *pOldStr, const TCHAR *pNewStr) { using namespace std; const int maxSize = lstrlen(pOrigin); auto src = string(pOrigin); for (string::size_type pos(0); pos != string::npos; pos += lstrlen(pNewStr)) { if ((pos = src.find(pOldStr, pos)) != string::npos) { src.replace(pos, lstrlen(pOldStr), pNewStr); } else { break; } } memset(pOrigin, 0, maxSize); StringCbCopyA(pOrigin, maxSize, src.c_str()); } void StringRemoveAll(TCHAR *pOrigin, const TCHAR *pString) { StringReplaceAll(pOrigin, pString, ""); } int FindFile(const TCHAR *pPath, PFILE_LIST pFileList, const bool exitWhenMatchOne) { std::vector pathList; TCHAR rootPath[MAX_PATH]; HANDLE hFind; WIN32_FIND_DATA ffd; hFind = FindFirstFile(pPath, &ffd); if (INVALID_HANDLE_VALUE == hFind) { return ERR_ITEM_UNEXISTS; } StringCbCopy(rootPath, MAX_PATH, pPath); PathRemoveFileSpec(rootPath); do { if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, "..") == 0) { continue; } } else { TCHAR tmp[MAX_PATH]; PathCombine(tmp, rootPath, ffd.cFileName); pathList.push_back(_strdup(tmp)); if (exitWhenMatchOne) { break; } } } while (FindNextFile(hFind, &ffd) != 0); FindClose(hFind); if (GetLastError() != ERROR_NO_MORE_FILES) { return -ERR_FIND_FILE; } pFileList->pFilePath = static_cast(HeapAlloc(GetProcessHeap(), 0, pathList.size() * sizeof(FILE_PATH))); if (pFileList->pFilePath == nullptr) { SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), pathList.size() * sizeof(FILE_PATH)); return -ERR_MALLOC_MEMORY; } pFileList->nItems = static_cast(pathList.size()); memset(pFileList->pFilePath, 0, pathList.size() * sizeof(FILE_PATH)); for (size_t i = 0; i < pathList.size(); i++) { StringCbCopy(pFileList->pFilePath[i].path, MAX_PATH, pathList.at(i)); } for (auto iter = pathList.begin(); iter != pathList.end(); ++iter) { if (*iter != nullptr) { free(*iter); (*iter) = nullptr; } } pathList.clear(); std::vector tmpSwapVector; tmpSwapVector.swap(pathList); return ERR_SUCCESS; } int GetWindowsServiceStatus(const TCHAR *pSvrName, PDWORD pStatus) { SC_HANDLE schSCManager; SC_HANDLE schService; SERVICE_STATUS_PROCESS ssStatus; DWORD dwBytesNeeded = 0; if (pSvrName == nullptr || lstrlen(pSvrName) == 0) { SPDLOG_ERROR(TEXT("Input pSvrName params error")); return -ERR_INPUT_PARAMS; } if (pStatus == nullptr) { SPDLOG_ERROR(TEXT("Input pStatus params error")); return -ERR_INPUT_PARAMS; } // Get a handle to the SCM database. schSCManager = OpenSCManager(nullptr, // local computer nullptr, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (nullptr == schSCManager) { SPDLOG_ERROR(TEXT("OpenSCManager failed {0}"), GetLastError()); return -ERR_OPEN_SCM; } // Get a handle to the service. schService = OpenService(schSCManager, // SCM database pSvrName, // name of service SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS); // full access if (schService == nullptr) { SPDLOG_ERROR(TEXT("OpenService failed {0}"), GetLastError()); CloseServiceHandle(schSCManager); return -ERR_OPEN_SERVICE; } // Check the status in case the service is not stopped. if (!QueryServiceStatusEx(schService, // handle to service SC_STATUS_PROCESS_INFO, // information level reinterpret_cast(&ssStatus), // address of structure sizeof(SERVICE_STATUS_PROCESS), // size of structure &dwBytesNeeded)) // size needed if buffer is too small { SPDLOG_ERROR(TEXT("QueryServiceStatusEx failed {0}"), GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return -ERR_GET_SERVICESSTATUS; } else { *pStatus = ssStatus.dwCurrentState; } return ERR_SUCCESS; } int WideCharToTChar(const WCHAR *pWStr, TCHAR *pOutStr, int maxOutLen) { if constexpr (sizeof(TCHAR) == sizeof(WCHAR)) { if (wcslen(pWStr) * sizeof(WCHAR) >= maxOutLen) { SPDLOG_ERROR(TEXT("Output buffer is to short: {0} need {1}"), maxOutLen, wcslen(pWStr) * sizeof(WCHAR)); return -ERR_INPUT_PARAMS; } memcpy(pOutStr, pWStr, wcslen(pWStr)); } else { int len = WideCharToMultiByte(CP_ACP, 0, pWStr, static_cast(wcslen(pWStr)), nullptr, 0, nullptr, nullptr); if (len >= maxOutLen) { SPDLOG_ERROR(TEXT("Output buffer is to short: {0} need {1}"), maxOutLen, len); return -ERR_INPUT_PARAMS; } WideCharToMultiByte(CP_ACP, 0, pWStr, static_cast(wcslen(pWStr)), pOutStr, len, nullptr, nullptr); pOutStr[len] = 0; return ERR_SUCCESS; } } int TCharToWideChar(const TCHAR *pTStr, WCHAR *pOutStr, int maxOutLen) { if constexpr (sizeof(TCHAR) == sizeof(WCHAR)) { if (lstrlen(pTStr) * sizeof(WCHAR) >= maxOutLen) { SPDLOG_ERROR(TEXT("Output buffer is to short: {0} need {1}"), maxOutLen, lstrlen(pTStr) * sizeof(WCHAR)); return -ERR_INPUT_PARAMS; } memcpy(pOutStr, pTStr, lstrlen(pTStr)); } else { int len = MultiByteToWideChar(CP_ACP, 0, pTStr, lstrlen(pTStr), nullptr, 0); //int len = WideCharToMultiByte(CP_ACP, 0, pWStr, static_cast(wcslen(pWStr)), nullptr, 0, nullptr, nullptr); if (len >= maxOutLen) { SPDLOG_ERROR(TEXT("Output buffer is to short: {0} need {1}"), maxOutLen, len); return -ERR_INPUT_PARAMS; } MultiByteToWideChar(CP_ACP, 0, pTStr, lstrlen(pTStr), pOutStr, len); pOutStr[len] = 0; return ERR_SUCCESS; } }