Fix: Repair task actions and harden machine management
Scheduled task actions never worked end to end: the server built task packets with Unicode-style lengths in a MultiByte build, the client had no dispatch for the run/stop/delete/create commands, and the directory column was derived by replacing every occurrence of the task name, which misplaced tasks whose name also appeared in a parent folder. Packets are now assembled with narrow strings, the four commands are routed to RunOrStopTask/DelTask/CreateTask, and the folder is taken from the task path suffix only. The task list reply is trimmed to its real length instead of sending the whole 32 KB scratch buffer. On the client side, thawing a process resumed a single thread, the inject output path was copied from a narrow string using a wide-character length, and an empty window list dereferenced a NULL buffer. The service list leaked its enumeration block and one service handle per skipped entry, and the description was copied without a bound. Service start and stop now validate every handle, initialize the status structure, and stop synchronously before the start that follows a restart request, which previously always failed because the service was still in STOP_PENDING. Deleting a process used to test only the low byte of the PID and leaked the process handle on early exits, and a failed path conversion kept the previous process image name. The IE history timestamp wrote minutes and seconds in the wrong order, the favorites reader queried and closed an uninitialized registry key, software enumeration never closed its subkeys, and the task scheduler objects were not released after use. The network state list now frees the module, snapshot, and extended tables on every exit path, uses HeapFree for tables allocated on the process heap, and no longer calls an export that may be missing. Growth failures everywhere keep the original buffer instead of overwriting the pointer, the hosts reader rejects an invalid file size, and the COM task walk releases definitions and folders. Co-Authored-By: deepseek-flash
This commit is contained in:
1 parent
c208b7368e
commit
6c8336b497
3 files changed
+435
-127
No files matched your search
+386
-96
@@ -122,6 +122,23 @@ void CMachineManager::OnReceive(PBYTE lpBuffer, ULONG nSize)
|
|||||||
case COMMAND_MACHINE_TASK:
|
case COMMAND_MACHINE_TASK:
|
||||||
GetRoot();
|
GetRoot();
|
||||||
break;
|
break;
|
||||||
|
// 计划任务动作:lpBuffer+1 起是 NUL 结尾的窄字符串(服务端按 MultiByte 组包)
|
||||||
|
case COMMAND_TASKSTART:
|
||||||
|
RunOrStopTask(lpBuffer + 1, TRUE);
|
||||||
|
GetRoot();
|
||||||
|
break;
|
||||||
|
case COMMAND_TASKSTOP:
|
||||||
|
RunOrStopTask(lpBuffer + 1, FALSE);
|
||||||
|
GetRoot();
|
||||||
|
break;
|
||||||
|
case COMMAND_TASKDEL:
|
||||||
|
DelTask(lpBuffer + 1);
|
||||||
|
GetRoot();
|
||||||
|
break;
|
||||||
|
case COMMAND_TASKCREAT:
|
||||||
|
CreateTask(lpBuffer + 1);
|
||||||
|
GetRoot();
|
||||||
|
break;
|
||||||
case COMMAND_MACHINE_HOSTS:
|
case COMMAND_MACHINE_HOSTS:
|
||||||
SendHostsList();
|
SendHostsList();
|
||||||
break;
|
break;
|
||||||
@@ -190,8 +207,13 @@ void CMachineManager::OnReceive(PBYTE lpBuffer, ULONG nSize)
|
|||||||
DebugPrivilege(SE_DEBUG_NAME, TRUE);
|
DebugPrivilege(SE_DEBUG_NAME, TRUE);
|
||||||
char strProcessName[MAX_PATH] = { 0 };
|
char strProcessName[MAX_PATH] = { 0 };
|
||||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, *(LPDWORD)(lpBuffer + 1));
|
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, *(LPDWORD)(lpBuffer + 1));
|
||||||
|
if (hProcess == NULL) {
|
||||||
|
DebugPrivilege(SE_DEBUG_NAME, FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
GetModuleFileNameEx(hProcess, NULL, strProcessName, MAX_PATH);
|
GetModuleFileNameEx(hProcess, NULL, strProcessName, MAX_PATH);
|
||||||
if (lpBuffer[1]) {
|
// PID 的第 2~4 字节非零时也要删除:只看 lpBuffer[1] 会把低字节为 0 的 PID 漏掉
|
||||||
|
if (*(LPDWORD)(lpBuffer + 1) != 0) {
|
||||||
char Tem_path[MAX_PATH];
|
char Tem_path[MAX_PATH];
|
||||||
char path_one[MAX_PATH];
|
char path_one[MAX_PATH];
|
||||||
char path_two[MAX_PATH];
|
char path_two[MAX_PATH];
|
||||||
@@ -218,10 +240,10 @@ void CMachineManager::OnReceive(PBYTE lpBuffer, ULONG nSize)
|
|||||||
DeleteFile(path_one); //删除目录(目录)
|
DeleteFile(path_one); //删除目录(目录)
|
||||||
Sleep(200);
|
Sleep(200);
|
||||||
if (GetFileAttributes(strProcessName) == -1) //检查文件不存在 退出
|
if (GetFileAttributes(strProcessName) == -1) //检查文件不存在 退出
|
||||||
return;
|
break;
|
||||||
n++;
|
n++;
|
||||||
if (n >= 10) //无法删除 一段时间后退出
|
if (n >= 10) //无法删除 一段时间后退出
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
@@ -282,11 +304,13 @@ void CMachineManager::OnReceive(PBYTE lpBuffer, ULONG nSize)
|
|||||||
while (b) {
|
while (b) {
|
||||||
if (th32.th32OwnerProcessID == Pid) {
|
if (th32.th32OwnerProcessID == Pid) {
|
||||||
HANDLE oth = OpenThread(THREAD_ALL_ACCESS, FALSE, th32.th32ThreadID);
|
HANDLE oth = OpenThread(THREAD_ALL_ACCESS, FALSE, th32.th32ThreadID);
|
||||||
::ResumeThread(oth);
|
if (oth) {
|
||||||
CloseHandle(oth);
|
::ResumeThread(oth);
|
||||||
break;
|
CloseHandle(oth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
::Thread32Next(hThreadSnap, &th32);
|
// 冻结挂起了全部线程,解冻也必须逐个恢复;这里不能 break,否则进程只会恢复一个线程
|
||||||
|
b = ::Thread32Next(hThreadSnap, &th32);
|
||||||
}
|
}
|
||||||
::CloseHandle(hThreadSnap);
|
::CloseHandle(hThreadSnap);
|
||||||
}
|
}
|
||||||
@@ -554,7 +578,11 @@ LPBYTE CMachineManager::getProcessList()
|
|||||||
pe32.dwSize = sizeof(PROCESSENTRY32);
|
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||||||
|
|
||||||
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024);
|
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024);
|
||||||
|
if (lpBuffer == NULL) {
|
||||||
|
CloseHandle(hSnapshot);
|
||||||
|
DebugPrivilege(SE_DEBUG_NAME, FALSE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
lpBuffer[0] = TOKEN_MACHINE_PROCESS;
|
lpBuffer[0] = TOKEN_MACHINE_PROCESS;
|
||||||
dwOffset = 1;
|
dwOffset = 1;
|
||||||
|
|
||||||
@@ -572,6 +600,8 @@ LPBYTE CMachineManager::getProcessList()
|
|||||||
if ((pe32.th32ProcessID != 0) && (pe32.th32ProcessID != 4) && (pe32.th32ProcessID != 8)) {
|
if ((pe32.th32ProcessID != 0) && (pe32.th32ProcessID != 4) && (pe32.th32ProcessID != 8)) {
|
||||||
EnumProcessModules(hProcess, &hModules, sizeof(hModules), &cbNeeded);
|
EnumProcessModules(hProcess, &hModules, sizeof(hModules), &cbNeeded);
|
||||||
|
|
||||||
|
// 每次循环都要清空:DosPathToNtPath 失败时不能沿用上一个进程的路径
|
||||||
|
memset(strProcessName, 0, sizeof(strProcessName));
|
||||||
if (0 == GetProcessImageFileName(hProcess, szImagePath, MAX_PATH)) {
|
if (0 == GetProcessImageFileName(hProcess, szImagePath, MAX_PATH)) {
|
||||||
lstrcpy(strProcessName, _T("---"));
|
lstrcpy(strProcessName, _T("---"));
|
||||||
} else if (!DosPathToNtPath(szImagePath, strProcessName)) {
|
} else if (!DosPathToNtPath(szImagePath, strProcessName)) {
|
||||||
@@ -590,8 +620,15 @@ LPBYTE CMachineManager::getProcessList()
|
|||||||
dwLength = sizeof(DWORD) * 5 + sizeof(bool) + MAX_PATH * sizeof(char) + lstrlen(pe32.szExeFile) * sizeof(char) +
|
dwLength = sizeof(DWORD) * 5 + sizeof(bool) + MAX_PATH * sizeof(char) + lstrlen(pe32.szExeFile) * sizeof(char) +
|
||||||
lstrlen(strProcessName) * sizeof(char) + lstrlen(strProcessUser) * sizeof(char) + 6;
|
lstrlen(strProcessName) * sizeof(char) + lstrlen(strProcessUser) * sizeof(char) + 6;
|
||||||
// 缓冲区太小,再重新分配下
|
// 缓冲区太小,再重新分配下
|
||||||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
if (LocalSize(lpBuffer) < (dwOffset + dwLength)) {
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew == NULL) {
|
||||||
|
// 扩容失败时原缓冲区仍然有效,结束收集并返回已拿到的记录
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(lpBuffer + dwOffset, &(pe32.th32ProcessID), sizeof(DWORD));
|
memcpy(lpBuffer + dwOffset, &(pe32.th32ProcessID), sizeof(DWORD));
|
||||||
dwOffset += sizeof(DWORD);
|
dwOffset += sizeof(DWORD);
|
||||||
@@ -653,7 +690,11 @@ LPBYTE CMachineManager::getProcessList()
|
|||||||
} while (Process32Next(hSnapshot, &pe32));
|
} while (Process32Next(hSnapshot, &pe32));
|
||||||
}
|
}
|
||||||
|
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
{
|
||||||
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew != NULL)
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
DebugPrivilege(SE_DEBUG_NAME, FALSE);
|
DebugPrivilege(SE_DEBUG_NAME, FALSE);
|
||||||
CloseHandle(hSnapshot);
|
CloseHandle(hSnapshot);
|
||||||
@@ -687,6 +728,13 @@ LPBYTE CMachineManager::getWindowsList()
|
|||||||
{
|
{
|
||||||
LPBYTE lpBuffer = NULL;
|
LPBYTE lpBuffer = NULL;
|
||||||
EnumWindows((WNDENUMPROC)EnumWindowsProc, (LPARAM)&lpBuffer);
|
EnumWindows((WNDENUMPROC)EnumWindowsProc, (LPARAM)&lpBuffer);
|
||||||
|
if (lpBuffer == NULL) {
|
||||||
|
// 一个可见窗口都没有时回调不会分配缓冲区:仍要回一个只带令牌的包,
|
||||||
|
// 否则下面写 lpBuffer[0] 就是空指针写,客户端会崩溃。
|
||||||
|
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1);
|
||||||
|
if (lpBuffer == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
lpBuffer[0] = TOKEN_MACHINE_WINDOWS;
|
lpBuffer[0] = TOKEN_MACHINE_WINDOWS;
|
||||||
return lpBuffer;
|
return lpBuffer;
|
||||||
}
|
}
|
||||||
@@ -739,13 +787,18 @@ bool CALLBACK CMachineManager::EnumWindowsProc(HWND hwnd, LPARAM lParam)
|
|||||||
::GetWindowText(hwnd, m_ibfo.strTitle, 1024);
|
::GetWindowText(hwnd, m_ibfo.strTitle, 1024);
|
||||||
|
|
||||||
if (lpBuffer == NULL) {
|
if (lpBuffer == NULL) {
|
||||||
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1);
|
|
||||||
dwOffset = 1;
|
dwOffset = 1;
|
||||||
|
lpBuffer = (LPBYTE)LocalAlloc(LPTR, dwOffset + sizeof(WINDOWSINFO));
|
||||||
|
if (lpBuffer == NULL)
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
dwOffset = (DWORD)LocalSize(lpBuffer);
|
dwOffset = (DWORD)LocalSize(lpBuffer);
|
||||||
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset + sizeof(WINDOWSINFO), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
// 分配失败时原缓冲区仍然有效,不能把指针覆盖成 NULL
|
||||||
|
if (lpNew == NULL)
|
||||||
|
return true;
|
||||||
|
lpBuffer = lpNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset + sizeof(WINDOWSINFO), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -853,8 +906,15 @@ LPBYTE CMachineManager::getSoftWareList()
|
|||||||
// 缓冲区太小,再重新分配下
|
// 缓冲区太小,再重新分配下
|
||||||
dwLength = lstrlen(regDisplayName) * sizeof(char) + lstrlen(regPublisher) * sizeof(char) + lstrlen(regDisplayVersion) *
|
dwLength = lstrlen(regDisplayName) * sizeof(char) + lstrlen(regPublisher) * sizeof(char) + lstrlen(regDisplayVersion) *
|
||||||
sizeof(char) + lstrlen(regInstallData) * sizeof(char) + lstrlen(regUninstallString) * sizeof(char) + 11;
|
sizeof(char) + lstrlen(regInstallData) * sizeof(char) + lstrlen(regUninstallString) * sizeof(char) + 11;
|
||||||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
if (LocalSize(lpBuffer) < (dwOffset + dwLength)) {
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew == NULL) {
|
||||||
|
// 扩容失败时原缓冲区仍然有效,跳过这一条并结束枚举
|
||||||
|
RegCloseKey(hSubKey);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(lpBuffer + dwOffset, regDisplayName, lstrlen(regDisplayName) * sizeof(char) + 2);
|
memcpy(lpBuffer + dwOffset, regDisplayName, lstrlen(regDisplayName) * sizeof(char) + 2);
|
||||||
dwOffset += lstrlen(regDisplayName) * sizeof(char) + 2;
|
dwOffset += lstrlen(regDisplayName) * sizeof(char) + 2;
|
||||||
@@ -870,11 +930,13 @@ LPBYTE CMachineManager::getSoftWareList()
|
|||||||
|
|
||||||
memcpy(lpBuffer + dwOffset, regUninstallString, lstrlen(regUninstallString) * sizeof(char) + 2);
|
memcpy(lpBuffer + dwOffset, regUninstallString, lstrlen(regUninstallString) * sizeof(char) + 2);
|
||||||
dwOffset += lstrlen(regUninstallString) * sizeof(char) + 2;
|
dwOffset += lstrlen(regUninstallString) * sizeof(char) + 2;
|
||||||
|
RegCloseKey(hSubKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return FALSE; //打开键失败
|
LocalFree(lpBuffer);
|
||||||
|
return NULL; //打开键失败
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
@@ -898,6 +960,7 @@ LPBYTE CMachineManager::getSoftWareList()
|
|||||||
// 取ParentKeyName键值,判断是否是补丁信息, 是补丁信息键值为"OperatingSystem"
|
// 取ParentKeyName键值,判断是否是补丁信息, 是补丁信息键值为"OperatingSystem"
|
||||||
RegQueryValueEx(hSubKey, _T("ParentKeyName"), 0, &dwType, (LPBYTE)regBufferValue, &dwRegSize);
|
RegQueryValueEx(hSubKey, _T("ParentKeyName"), 0, &dwType, (LPBYTE)regBufferValue, &dwRegSize);
|
||||||
if (lstrlen(regDisplayName) == 0 || lstrcmp(regBufferValue, _T("OperatingSystem")) == 0) { //判断是否是补丁信息
|
if (lstrlen(regDisplayName) == 0 || lstrcmp(regBufferValue, _T("OperatingSystem")) == 0) { //判断是否是补丁信息
|
||||||
|
RegCloseKey(hSubKey);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -935,8 +998,15 @@ LPBYTE CMachineManager::getSoftWareList()
|
|||||||
// 缓冲区太小,再重新分配下
|
// 缓冲区太小,再重新分配下
|
||||||
dwLength = lstrlen(regDisplayName) * sizeof(char) + lstrlen(regPublisher) * sizeof(char) + lstrlen(regDisplayVersion) *
|
dwLength = lstrlen(regDisplayName) * sizeof(char) + lstrlen(regPublisher) * sizeof(char) + lstrlen(regDisplayVersion) *
|
||||||
sizeof(char) + lstrlen(regInstallData) * sizeof(char) + lstrlen(regUninstallString) * sizeof(char) + 11;
|
sizeof(char) + lstrlen(regInstallData) * sizeof(char) + lstrlen(regUninstallString) * sizeof(char) + 11;
|
||||||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
if (LocalSize(lpBuffer) < (dwOffset + dwLength)) {
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew == NULL) {
|
||||||
|
// 扩容失败时原缓冲区仍然有效,跳过这一条并结束枚举
|
||||||
|
RegCloseKey(hSubKey);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(lpBuffer + dwOffset, regDisplayName, lstrlen(regDisplayName) * sizeof(char) + 2);
|
memcpy(lpBuffer + dwOffset, regDisplayName, lstrlen(regDisplayName) * sizeof(char) + 2);
|
||||||
dwOffset += lstrlen(regDisplayName) * sizeof(char) + 2;
|
dwOffset += lstrlen(regDisplayName) * sizeof(char) + 2;
|
||||||
@@ -952,15 +1022,23 @@ LPBYTE CMachineManager::getSoftWareList()
|
|||||||
|
|
||||||
memcpy(lpBuffer + dwOffset, regUninstallString, lstrlen(regUninstallString) * sizeof(char) + 2);
|
memcpy(lpBuffer + dwOffset, regUninstallString, lstrlen(regUninstallString) * sizeof(char) + 2);
|
||||||
dwOffset += lstrlen(regUninstallString) * sizeof(char) + 2;
|
dwOffset += lstrlen(regUninstallString) * sizeof(char) + 2;
|
||||||
|
RegCloseKey(hSubKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
return FALSE; //打开键失败
|
//打开键失败
|
||||||
|
LocalFree(lpBuffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
{
|
||||||
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew != NULL)
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
return lpBuffer;
|
return lpBuffer;
|
||||||
}
|
}
|
||||||
@@ -991,6 +1069,12 @@ LPBYTE CMachineManager::getIEHistoryList()
|
|||||||
DWORD dwOffset = 1;
|
DWORD dwOffset = 1;
|
||||||
DWORD dwLength = 0;
|
DWORD dwLength = 0;
|
||||||
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 10000);
|
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 10000);
|
||||||
|
if (lpBuffer == NULL) {
|
||||||
|
if (SUCCEEDED(hr) && puhs != NULL)
|
||||||
|
puhs->Release();
|
||||||
|
CoUninitialize();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
lpBuffer[0] = TOKEN_MACHINE_HTML;
|
lpBuffer[0] = TOKEN_MACHINE_HTML;
|
||||||
Browsinghistory m_Browsinghistory;
|
Browsinghistory m_Browsinghistory;
|
||||||
dwLength = sizeof(Browsinghistory);
|
dwLength = sizeof(Browsinghistory);
|
||||||
@@ -1012,12 +1096,20 @@ LPBYTE CMachineManager::getIEHistoryList()
|
|||||||
SYSTEMTIME st;
|
SYSTEMTIME st;
|
||||||
if (&su.ftLastVisited != NULL) {
|
if (&su.ftLastVisited != NULL) {
|
||||||
FileTimeToSystemTime(&su.ftLastVisited, &st);
|
FileTimeToSystemTime(&su.ftLastVisited, &st);
|
||||||
wsprintf(m_Browsinghistory.strTime, _T("%d-%d-%d %d:%d:%d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wSecond, st.wMinute);
|
wsprintf(m_Browsinghistory.strTime, _T("%d-%02d-%02d %02d:%02d:%02d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
|
||||||
} else {
|
} else {
|
||||||
wsprintf(m_Browsinghistory.strTime, _T("---"));
|
wsprintf(m_Browsinghistory.strTime, _T("---"));
|
||||||
}
|
}
|
||||||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
if (LocalSize(lpBuffer) < (dwOffset + dwLength)) {
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew == NULL) {
|
||||||
|
// 扩容失败时原缓冲区仍然有效,停止收集,返回已拿到的记录
|
||||||
|
CoTaskMemFree(su.pwcsUrl);
|
||||||
|
CoTaskMemFree(su.pwcsTitle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(lpBuffer + dwOffset, &m_Browsinghistory, sizeof(Browsinghistory));
|
memcpy(lpBuffer + dwOffset, &m_Browsinghistory, sizeof(Browsinghistory));
|
||||||
dwOffset += sizeof(Browsinghistory);
|
dwOffset += sizeof(Browsinghistory);
|
||||||
@@ -1028,11 +1120,15 @@ LPBYTE CMachineManager::getIEHistoryList()
|
|||||||
su.pwcsTitle = nullptr;
|
su.pwcsTitle = nullptr;
|
||||||
}
|
}
|
||||||
pesu->Release();
|
pesu->Release();
|
||||||
puhs->Release();
|
|
||||||
}
|
}
|
||||||
|
puhs->Release();
|
||||||
}
|
}
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
{
|
||||||
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew != NULL)
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
return lpBuffer;
|
return lpBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1053,15 +1149,22 @@ void CMachineManager::FindFavoritesUrl(char* searchfilename, PBYTE &lpFUBuffer,
|
|||||||
char tmpPath[MAX_PATH] = { 0 };
|
char tmpPath[MAX_PATH] = { 0 };
|
||||||
DWORD dwFULength = 0;
|
DWORD dwFULength = 0;
|
||||||
|
|
||||||
lstrcat(favpath, searchfilename);
|
// 拼接要限长:收藏夹目录较深时 searchfilename 可能已接近 MAX_PATH
|
||||||
|
if (lstrlen(searchfilename) + 4 >= MAX_PATH)
|
||||||
|
return;
|
||||||
|
lstrcpyn(favpath, searchfilename, MAX_PATH - 4);
|
||||||
lstrcat(favpath, _T("\\*.*"));
|
lstrcat(favpath, _T("\\*.*"));
|
||||||
|
|
||||||
WIN32_FIND_DATA fd;
|
WIN32_FIND_DATA fd;
|
||||||
ZeroMemory(&fd, sizeof(WIN32_FIND_DATA));
|
ZeroMemory(&fd, sizeof(WIN32_FIND_DATA));
|
||||||
|
|
||||||
HANDLE hFind = FindFirstFile(favpath, &fd); // 文件后缀都是 url
|
HANDLE hFind = FindFirstFile(favpath, &fd); // 文件后缀都是 url
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
|
return;
|
||||||
do {
|
do {
|
||||||
if (fd.cFileName[0] != _T('.')) {
|
if (fd.cFileName[0] != _T('.')) {
|
||||||
|
if (lstrlen(searchfilename) + 1 + lstrlen(fd.cFileName) >= MAX_PATH)
|
||||||
|
continue;
|
||||||
lstrcpy(tmpPath, searchfilename);
|
lstrcpy(tmpPath, searchfilename);
|
||||||
lstrcat(tmpPath, _T("\\"));
|
lstrcat(tmpPath, _T("\\"));
|
||||||
lstrcat(tmpPath, fd.cFileName);
|
lstrcat(tmpPath, fd.cFileName);
|
||||||
@@ -1074,8 +1177,13 @@ void CMachineManager::FindFavoritesUrl(char* searchfilename, PBYTE &lpFUBuffer,
|
|||||||
|
|
||||||
dwFULength = lstrlen(buf) * sizeof(char) + lstrlen(fd.cFileName) * sizeof(char) + 4;
|
dwFULength = lstrlen(buf) * sizeof(char) + lstrlen(fd.cFileName) * sizeof(char) + 4;
|
||||||
|
|
||||||
if (LocalSize(lpFUBuffer) < (dwFUOffset + dwFULength))
|
if (LocalSize(lpFUBuffer) < (dwFUOffset + dwFULength)) {
|
||||||
lpFUBuffer = (LPBYTE)LocalReAlloc(lpFUBuffer, (dwFUOffset + dwFULength) + 1024, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpFUBuffer, (dwFUOffset + dwFULength) + 1024, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
// 扩容失败时原缓冲区仍然有效:跳过这条记录,不能让指针变成 NULL
|
||||||
|
if (lpNew == NULL)
|
||||||
|
continue;
|
||||||
|
lpFUBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(lpFUBuffer + dwFUOffset, fd.cFileName, lstrlen(fd.cFileName) * sizeof(char) + 2);
|
memcpy(lpFUBuffer + dwFUOffset, fd.cFileName, lstrlen(fd.cFileName) * sizeof(char) + 2);
|
||||||
dwFUOffset += lstrlen(fd.cFileName) * sizeof(char) + 2;
|
dwFUOffset += lstrlen(fd.cFileName) * sizeof(char) + 2;
|
||||||
@@ -1094,21 +1202,32 @@ LPBYTE CMachineManager::getFavoritesUrlList()
|
|||||||
char favpath[MAX_PATH] = { 0 };
|
char favpath[MAX_PATH] = { 0 };
|
||||||
|
|
||||||
// 从注册表获取收藏夹所在位置
|
// 从注册表获取收藏夹所在位置
|
||||||
HKEY hKEY;
|
HKEY hKEY = NULL;
|
||||||
DWORD type = REG_SZ;
|
DWORD type = REG_SZ;
|
||||||
LPCTSTR path = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
|
LPCTSTR path = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
|
||||||
DWORD cbData = 80;
|
DWORD cbData = sizeof(favpath);
|
||||||
::RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_READ, &hKEY);
|
// RegOpenKeyEx 失败时 hKEY 是无效值,不能再拿它查值/关闭
|
||||||
::RegQueryValueEx(hKEY, _T("Favorites"), NULL, &type, (LPBYTE)favpath, &cbData);
|
if (::RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_READ, &hKEY) == ERROR_SUCCESS) {
|
||||||
::RegCloseKey(hKEY);
|
if (::RegQueryValueEx(hKEY, _T("Favorites"), NULL, &type, (LPBYTE)favpath, &cbData) != ERROR_SUCCESS)
|
||||||
|
favpath[0] = 0;
|
||||||
|
::RegCloseKey(hKEY);
|
||||||
|
}
|
||||||
|
favpath[MAX_PATH - 1] = 0;
|
||||||
|
|
||||||
LPBYTE lpFUBuffer = (LPBYTE)LocalAlloc(LPTR, 10000);
|
LPBYTE lpFUBuffer = (LPBYTE)LocalAlloc(LPTR, 10000);
|
||||||
|
if (lpFUBuffer == NULL)
|
||||||
|
return NULL;
|
||||||
lpFUBuffer[0] = TOKEN_MACHINE_FAVORITES;
|
lpFUBuffer[0] = TOKEN_MACHINE_FAVORITES;
|
||||||
|
|
||||||
int dwFUOffset = 1;
|
int dwFUOffset = 1;
|
||||||
FindFavoritesUrl(favpath, lpFUBuffer, dwFUOffset);
|
if (favpath[0] != 0)
|
||||||
|
FindFavoritesUrl(favpath, lpFUBuffer, dwFUOffset);
|
||||||
|
|
||||||
lpFUBuffer = (LPBYTE)LocalReAlloc(lpFUBuffer, dwFUOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
{
|
||||||
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpFUBuffer, dwFUOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew != NULL)
|
||||||
|
lpFUBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
return lpFUBuffer;
|
return lpFUBuffer;
|
||||||
}
|
}
|
||||||
@@ -1141,15 +1260,30 @@ LPBYTE CMachineManager::getServiceList(DWORD dwScType)
|
|||||||
DWORD dwSize = 1024 * 8;
|
DWORD dwSize = 1024 * 8;
|
||||||
|
|
||||||
sc = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
sc = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||||
|
if (sc == NULL) {
|
||||||
|
EnablePrivilege(SE_DEBUG_NAME, FALSE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//第一次调用来得到需要多大的内存区
|
//第一次调用来得到需要多大的内存区
|
||||||
EnumServicesStatus(sc, dwScType, SERVICE_STATE_ALL, lpServices, size, &size, &ret, NULL);
|
EnumServicesStatus(sc, dwScType, SERVICE_STATE_ALL, lpServices, size, &size, &ret, NULL);
|
||||||
//申请需要的内存
|
//申请需要的内存
|
||||||
lpServices = (LPENUM_SERVICE_STATUS)LocalAlloc(LPTR, size);
|
lpServices = (LPENUM_SERVICE_STATUS)LocalAlloc(LPTR, size);
|
||||||
|
if (lpServices == NULL) {
|
||||||
|
CloseServiceHandle(sc);
|
||||||
|
EnablePrivilege(SE_DEBUG_NAME, FALSE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
EnumServicesStatus(sc, dwScType, SERVICE_STATE_ALL, lpServices, size, &size, &ret, NULL);
|
EnumServicesStatus(sc, dwScType, SERVICE_STATE_ALL, lpServices, size, &size, &ret, NULL);
|
||||||
|
|
||||||
// 申请Buffer内存
|
// 申请Buffer内存
|
||||||
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024 * sizeof(char));
|
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024 * sizeof(char));
|
||||||
|
if (lpBuffer == NULL) {
|
||||||
|
LocalFree(lpServices);
|
||||||
|
CloseServiceHandle(sc);
|
||||||
|
EnablePrivilege(SE_DEBUG_NAME, FALSE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
lpBuffer[0] = TOKEN_MACHINE_SERVICE_LIST;
|
lpBuffer[0] = TOKEN_MACHINE_SERVICE_LIST;
|
||||||
dwOffset = 1;
|
dwOffset = 1;
|
||||||
|
|
||||||
@@ -1166,7 +1300,7 @@ LPBYTE CMachineManager::getServiceList(DWORD dwScType)
|
|||||||
// 描述
|
// 描述
|
||||||
memset(lpDescription, 0, sizeof(lpDescription));
|
memset(lpDescription, 0, sizeof(lpDescription));
|
||||||
if (((LPSERVICE_DESCRIPTION)szInfo)->lpDescription != NULL)
|
if (((LPSERVICE_DESCRIPTION)szInfo)->lpDescription != NULL)
|
||||||
lstrcpy(lpDescription, ((LPSERVICE_DESCRIPTION)szInfo)->lpDescription);
|
lstrcpyn(lpDescription, ((LPSERVICE_DESCRIPTION)szInfo)->lpDescription, sizeof(lpDescription));
|
||||||
|
|
||||||
// 状态
|
// 状态
|
||||||
memset(strState, 0, sizeof(strState));
|
memset(strState, 0, sizeof(strState));
|
||||||
@@ -1200,6 +1334,7 @@ LPBYTE CMachineManager::getServiceList(DWORD dwScType)
|
|||||||
ZeroMemory(szInfo, dwSize);
|
ZeroMemory(szInfo, dwSize);
|
||||||
dwSize = 1024 * 8;
|
dwSize = 1024 * 8;
|
||||||
if (!QueryServiceConfig(sh, (LPQUERY_SERVICE_CONFIG)szInfo, dwSize, &dwSize)) {
|
if (!QueryServiceConfig(sh, (LPQUERY_SERVICE_CONFIG)szInfo, dwSize, &dwSize)) {
|
||||||
|
CloseServiceHandle(sh);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 启动类型
|
// 启动类型
|
||||||
@@ -1234,8 +1369,15 @@ LPBYTE CMachineManager::getServiceList(DWORD dwScType)
|
|||||||
|
|
||||||
//==========================================================================================
|
//==========================================================================================
|
||||||
// 缓冲区太小,再重新分配下
|
// 缓冲区太小,再重新分配下
|
||||||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
if (LocalSize(lpBuffer) < (dwOffset + dwLength)) {
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
// 扩容失败时原缓冲区仍然有效,保留已收集的记录并结束枚举
|
||||||
|
if (lpNew == NULL) {
|
||||||
|
CloseServiceHandle(sh);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
// 显示名称
|
// 显示名称
|
||||||
memcpy(lpBuffer + dwOffset, lpServices[i].lpDisplayName, lstrlen(lpServices[i].lpDisplayName) * sizeof(char) + sizeof(char));
|
memcpy(lpBuffer + dwOffset, lpServices[i].lpDisplayName, lstrlen(lpServices[i].lpDisplayName) * sizeof(char) + sizeof(char));
|
||||||
@@ -1277,8 +1419,14 @@ LPBYTE CMachineManager::getServiceList(DWORD dwScType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CloseServiceHandle(sc);
|
CloseServiceHandle(sc);
|
||||||
|
LocalFree(lpServices);
|
||||||
|
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
{
|
||||||
|
// 收缩到实际长度;失败时原缓冲区仍有效,直接按原大小返回
|
||||||
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew != NULL)
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
EnablePrivilege(SE_DEBUG_NAME, FALSE);
|
EnablePrivilege(SE_DEBUG_NAME, FALSE);
|
||||||
return lpBuffer;
|
return lpBuffer;
|
||||||
}
|
}
|
||||||
@@ -1303,7 +1451,16 @@ void CMachineManager::SendHostsList()
|
|||||||
if (hFile == INVALID_HANDLE_VALUE)
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
return;
|
return;
|
||||||
dwSize = GetFileSize(hFile, NULL);
|
dwSize = GetFileSize(hFile, NULL);
|
||||||
|
// GetFileSize 失败返回 INVALID_FILE_SIZE:不加判断会按 0xFFFFFFFF 分配并读入
|
||||||
|
if (dwSize == INVALID_FILE_SIZE) {
|
||||||
|
CloseHandle(hFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
lpBuffer = (LPBYTE)LocalAlloc(LPTR, dwSize + 2);
|
lpBuffer = (LPBYTE)LocalAlloc(LPTR, dwSize + 2);
|
||||||
|
if (lpBuffer == NULL) {
|
||||||
|
CloseHandle(hFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!ReadFile(hFile, lpBuffer + 1, dwSize, &dwRead, NULL)) {
|
if (!ReadFile(hFile, lpBuffer + 1, dwSize, &dwRead, NULL)) {
|
||||||
LocalFree(lpBuffer);
|
LocalFree(lpBuffer);
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
@@ -1320,6 +1477,8 @@ void CMachineManager::SendHostsList()
|
|||||||
LPBYTE CMachineManager::getNetStateList()
|
LPBYTE CMachineManager::getNetStateList()
|
||||||
{
|
{
|
||||||
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024);
|
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024);
|
||||||
|
if (lpBuffer == NULL)
|
||||||
|
return NULL;
|
||||||
lpBuffer[0] = TOKEN_MACHINE_NETSTATE;
|
lpBuffer[0] = TOKEN_MACHINE_NETSTATE;
|
||||||
DWORD dwOffset = 1;
|
DWORD dwOffset = 1;
|
||||||
DWORD dwLength = 0;
|
DWORD dwLength = 0;
|
||||||
@@ -1329,36 +1488,52 @@ LPBYTE CMachineManager::getNetStateList()
|
|||||||
|
|
||||||
// 获取扩展函数的入口地址
|
// 获取扩展函数的入口地址
|
||||||
HMODULE hModule = ::LoadLibrary(_T("iphlpapi.dll"));
|
HMODULE hModule = ::LoadLibrary(_T("iphlpapi.dll"));
|
||||||
pAllocateAndGetTcpExTableFromStack =
|
pAllocateAndGetTcpExTableFromStack = hModule == NULL ? NULL :
|
||||||
(PFNAllocateAndGetTcpExTableFromStack)::GetProcAddress(hModule,
|
(PFNAllocateAndGetTcpExTableFromStack)::GetProcAddress(hModule,
|
||||||
"AllocateAndGetTcpExTableFromStack");
|
"AllocateAndGetTcpExTableFromStack");
|
||||||
|
|
||||||
pAllocateAndGetUdpExTableFromStack =
|
pAllocateAndGetUdpExTableFromStack = hModule == NULL ? NULL :
|
||||||
(PFNAllocateAndGetUdpExTableFromStack)::GetProcAddress(hModule,
|
(PFNAllocateAndGetUdpExTableFromStack)::GetProcAddress(hModule,
|
||||||
"AllocateAndGetUdpExTableFromStack");
|
"AllocateAndGetUdpExTableFromStack");
|
||||||
|
|
||||||
if (pAllocateAndGetTcpExTableFromStack != NULL || pAllocateAndGetUdpExTableFromStack != NULL) {
|
// 两个导出函数要么都有(XP/2003)、要么都没有(Vista+):用 && 避免只匹配到一个时空指针调用
|
||||||
|
if (pAllocateAndGetTcpExTableFromStack != NULL && pAllocateAndGetUdpExTableFromStack != NULL) {
|
||||||
// 调用扩展函数,获取TCP扩展连接表和UDP扩展监听表
|
// 调用扩展函数,获取TCP扩展连接表和UDP扩展监听表
|
||||||
PMIB_TCPEXTABLE pTcpExTable;
|
PMIB_TCPEXTABLE pTcpExTable = NULL;
|
||||||
PMIB_UDPEXTABLE pUdpExTable;
|
PMIB_UDPEXTABLE pUdpExTable = NULL;
|
||||||
|
|
||||||
// pTcpExTable和pUdpExTable所指的缓冲区自动由扩展函数在进程堆中申请
|
// pTcpExTable和pUdpExTable所指的缓冲区自动由扩展函数在进程堆中申请
|
||||||
if (pAllocateAndGetTcpExTableFromStack(&pTcpExTable, TRUE, GetProcessHeap(), 2, 2) != 0) {
|
if (pAllocateAndGetTcpExTableFromStack(&pTcpExTable, TRUE, GetProcessHeap(), 2, 2) != 0) {
|
||||||
|
if (pTcpExTable)
|
||||||
|
::HeapFree(GetProcessHeap(), 0, pTcpExTable);
|
||||||
|
::FreeLibrary(hModule);
|
||||||
|
LocalFree(lpBuffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (pAllocateAndGetUdpExTableFromStack(&pUdpExTable, TRUE, GetProcessHeap(), 2, 2) != 0) {
|
if (pAllocateAndGetUdpExTableFromStack(&pUdpExTable, TRUE, GetProcessHeap(), 2, 2) != 0) {
|
||||||
|
if (pTcpExTable)
|
||||||
|
::HeapFree(GetProcessHeap(), 0, pTcpExTable);
|
||||||
|
if (pUdpExTable)
|
||||||
|
::HeapFree(GetProcessHeap(), 0, pUdpExTable);
|
||||||
|
::FreeLibrary(hModule);
|
||||||
|
LocalFree(lpBuffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 给系统内的所有进程拍一个快照
|
// 给系统内的所有进程拍一个快照
|
||||||
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
if (hProcessSnap == INVALID_HANDLE_VALUE) {
|
if (hProcessSnap == INVALID_HANDLE_VALUE) {
|
||||||
|
if (pTcpExTable)
|
||||||
|
::HeapFree(GetProcessHeap(), 0, pTcpExTable);
|
||||||
|
if (pUdpExTable)
|
||||||
|
::HeapFree(GetProcessHeap(), 0, pUdpExTable);
|
||||||
|
::FreeLibrary(hModule);
|
||||||
|
LocalFree(lpBuffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char szLocalAddr[128];
|
char szLocalAddr[128];
|
||||||
char szRemoteAddr[128];
|
char szRemoteAddr[128];
|
||||||
char szProcessName[128];
|
|
||||||
in_addr inadLocal, inadRemote;
|
in_addr inadLocal, inadRemote;
|
||||||
char strState[128];
|
char strState[128];
|
||||||
DWORD dwRemotePort = 0;
|
DWORD dwRemotePort = 0;
|
||||||
@@ -1427,13 +1602,17 @@ LPBYTE CMachineManager::getNetStateList()
|
|||||||
// 打印出此入口的信息
|
// 打印出此入口的信息
|
||||||
char strProcessName[100] = { 0 };
|
char strProcessName[100] = { 0 };
|
||||||
const char* strType = _T("[TCP]");
|
const char* strType = _T("[TCP]");
|
||||||
lstrcpy(strProcessName, ProcessPidToName(hProcessSnap, pTcpExTable->table[i].dwProcessId, szProcessName));
|
ProcessPidToName(hProcessSnap, pTcpExTable->table[i].dwProcessId, strProcessName, sizeof(strProcessName));
|
||||||
|
|
||||||
dwLength = lstrlen(strProcessName) * sizeof(char) + sizeof(DWORD) + lstrlen(strType) * sizeof(char) +
|
dwLength = lstrlen(strProcessName) * sizeof(char) + sizeof(DWORD) + lstrlen(strType) * sizeof(char) +
|
||||||
lstrlen(szLocalAddr) * sizeof(char) + lstrlen(szRemoteAddr) * sizeof(char) + lstrlen(strState) *
|
lstrlen(szLocalAddr) * sizeof(char) + lstrlen(szRemoteAddr) * sizeof(char) + lstrlen(strState) *
|
||||||
sizeof(char) + 12;
|
sizeof(char) + 12;
|
||||||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
if (LocalSize(lpBuffer) < (dwOffset + dwLength)) {
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew == NULL)
|
||||||
|
break; // 扩容失败时保留原缓冲区,已收集的记录照常返回
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
||||||
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
||||||
@@ -1465,14 +1644,18 @@ LPBYTE CMachineManager::getNetStateList()
|
|||||||
const char* strType = _T("[UDP]");
|
const char* strType = _T("[UDP]");
|
||||||
const char* szRemoteAddr = _T("*.*.*.*:*");
|
const char* szRemoteAddr = _T("*.*.*.*:*");
|
||||||
const char* szUDPState = _T(" ");
|
const char* szUDPState = _T(" ");
|
||||||
lstrcpy(strProcessName, ProcessPidToName(hProcessSnap, pUdpExTable->table[i].dwProcessId, szProcessName));
|
ProcessPidToName(hProcessSnap, pUdpExTable->table[i].dwProcessId, strProcessName, sizeof(strProcessName));
|
||||||
|
|
||||||
dwLength = lstrlen(strProcessName) * sizeof(char) + sizeof(DWORD) + lstrlen(strType) * sizeof(char) +
|
dwLength = lstrlen(strProcessName) * sizeof(char) + sizeof(DWORD) + lstrlen(strType) * sizeof(char) +
|
||||||
lstrlen(szLocalAddr) * sizeof(char) + lstrlen(szRemoteAddr) * sizeof(char) + lstrlen(szUDPState) *
|
lstrlen(szLocalAddr) * sizeof(char) + lstrlen(szRemoteAddr) * sizeof(char) + lstrlen(szUDPState) *
|
||||||
sizeof(char) + 12;
|
sizeof(char) + 12;
|
||||||
|
|
||||||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
if (LocalSize(lpBuffer) < (dwOffset + dwLength)) {
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew == NULL)
|
||||||
|
break; // 扩容失败时保留原缓冲区,已收集的记录照常返回
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
||||||
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
||||||
@@ -1493,28 +1676,43 @@ LPBYTE CMachineManager::getNetStateList()
|
|||||||
dwOffset += lstrlen(szUDPState) * sizeof(char) + 2;
|
dwOffset += lstrlen(szUDPState) * sizeof(char) + 2;
|
||||||
}
|
}
|
||||||
::CloseHandle(hProcessSnap);
|
::CloseHandle(hProcessSnap);
|
||||||
::LocalFree(pTcpExTable);
|
// 扩展表是扩展函数在 GetProcessHeap() 上用 HeapAlloc 申请的,应对应用 HeapFree 释放
|
||||||
::LocalFree(pUdpExTable);
|
if (pTcpExTable)
|
||||||
|
::HeapFree(GetProcessHeap(), 0, pTcpExTable);
|
||||||
|
if (pUdpExTable)
|
||||||
|
::HeapFree(GetProcessHeap(), 0, pUdpExTable);
|
||||||
::FreeLibrary(hModule);
|
::FreeLibrary(hModule);
|
||||||
} else {
|
} else {
|
||||||
char szLocalAddr[128];
|
char szLocalAddr[128];
|
||||||
char szRemoteAddr[128];
|
char szRemoteAddr[128];
|
||||||
char szProcessName[128];
|
|
||||||
in_addr inadLocal, inadRemote;
|
in_addr inadLocal, inadRemote;
|
||||||
char strState[128];
|
char strState[128];
|
||||||
DWORD dwRemotePort = 0;
|
DWORD dwRemotePort = 0;
|
||||||
|
|
||||||
PMIB_TCPEXTABLE_VISTA pTcpTable_Vista;
|
PMIB_TCPEXTABLE_VISTA pTcpTable_Vista = NULL;
|
||||||
_InternalGetTcpTable2 pGetTcpTable = (_InternalGetTcpTable2)GetProcAddress(hModule, "InternalGetTcpTable2");
|
_InternalGetTcpTable2 pGetTcpTable = hModule == NULL ? NULL :
|
||||||
if (pGetTcpTable == NULL)
|
(_InternalGetTcpTable2)GetProcAddress(hModule, "InternalGetTcpTable2");
|
||||||
|
if (pGetTcpTable == NULL) {
|
||||||
|
::FreeLibrary(hModule);
|
||||||
|
LocalFree(lpBuffer);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (pGetTcpTable(&pTcpTable_Vista, GetProcessHeap(), 1))
|
if (pGetTcpTable(&pTcpTable_Vista, GetProcessHeap(), 1)) {
|
||||||
|
if (pTcpTable_Vista)
|
||||||
|
::HeapFree(GetProcessHeap(), 0, pTcpTable_Vista);
|
||||||
|
::FreeLibrary(hModule);
|
||||||
|
LocalFree(lpBuffer);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// 给系统内的所有进程拍一个快照
|
// 给系统内的所有进程拍一个快照
|
||||||
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
if (hProcessSnap == INVALID_HANDLE_VALUE) {
|
if (hProcessSnap == INVALID_HANDLE_VALUE) {
|
||||||
|
if (pTcpTable_Vista)
|
||||||
|
::HeapFree(GetProcessHeap(), 0, pTcpTable_Vista);
|
||||||
|
::FreeLibrary(hModule);
|
||||||
|
LocalFree(lpBuffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1580,13 +1778,17 @@ LPBYTE CMachineManager::getNetStateList()
|
|||||||
// 打印出此入口的信息
|
// 打印出此入口的信息
|
||||||
char strProcessName[100] = { 0 };
|
char strProcessName[100] = { 0 };
|
||||||
const char* strType = _T("[TCP]");
|
const char* strType = _T("[TCP]");
|
||||||
lstrcpy(strProcessName, ProcessPidToName(hProcessSnap, pTcpTable_Vista->table[i].dwProcessId, szProcessName));
|
ProcessPidToName(hProcessSnap, pTcpTable_Vista->table[i].dwProcessId, strProcessName, sizeof(strProcessName));
|
||||||
|
|
||||||
dwLength = lstrlen(strProcessName) * sizeof(char) + sizeof(DWORD) + lstrlen(strType) * sizeof(char) +
|
dwLength = lstrlen(strProcessName) * sizeof(char) + sizeof(DWORD) + lstrlen(strType) * sizeof(char) +
|
||||||
lstrlen(szLocalAddr) * sizeof(char) + lstrlen(szRemoteAddr) * sizeof(char) + lstrlen(strState) *
|
lstrlen(szLocalAddr) * sizeof(char) + lstrlen(szRemoteAddr) * sizeof(char) + lstrlen(strState) *
|
||||||
sizeof(char) + 12;
|
sizeof(char) + 12;
|
||||||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
if (LocalSize(lpBuffer) < (dwOffset + dwLength)) {
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew == NULL)
|
||||||
|
break; // 扩容失败时保留原缓冲区,已收集的记录照常返回
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
||||||
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
||||||
@@ -1610,7 +1812,7 @@ LPBYTE CMachineManager::getNetStateList()
|
|||||||
PMIB_UDPEXTABLE pUdpExTable = NULL;
|
PMIB_UDPEXTABLE pUdpExTable = NULL;
|
||||||
// 表明为 Vista 或者 7 操作系统
|
// 表明为 Vista 或者 7 操作系统
|
||||||
PFNInternalGetUdpTableWithOwnerPid pInternalGetUdpTableWithOwnerPid;
|
PFNInternalGetUdpTableWithOwnerPid pInternalGetUdpTableWithOwnerPid;
|
||||||
pInternalGetUdpTableWithOwnerPid =
|
pInternalGetUdpTableWithOwnerPid = hModule == NULL ? NULL :
|
||||||
(PFNInternalGetUdpTableWithOwnerPid)GetProcAddress(hModule, "InternalGetUdpTableWithOwnerPid");
|
(PFNInternalGetUdpTableWithOwnerPid)GetProcAddress(hModule, "InternalGetUdpTableWithOwnerPid");
|
||||||
if (pInternalGetUdpTableWithOwnerPid != NULL) {
|
if (pInternalGetUdpTableWithOwnerPid != NULL) {
|
||||||
if (pInternalGetUdpTableWithOwnerPid(&pUdpExTable, GetProcessHeap(), 1)) {
|
if (pInternalGetUdpTableWithOwnerPid(&pUdpExTable, GetProcessHeap(), 1)) {
|
||||||
@@ -1618,8 +1820,12 @@ LPBYTE CMachineManager::getNetStateList()
|
|||||||
HeapFree(GetProcessHeap(), 0, pUdpExTable);
|
HeapFree(GetProcessHeap(), 0, pUdpExTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::CloseHandle(hProcessSnap);
|
||||||
|
if (pTcpTable_Vista)
|
||||||
|
::HeapFree(GetProcessHeap(), 0, pTcpTable_Vista);
|
||||||
FreeLibrary(hModule);
|
FreeLibrary(hModule);
|
||||||
hModule = NULL;
|
hModule = NULL;
|
||||||
|
LocalFree(lpBuffer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1636,13 +1842,17 @@ LPBYTE CMachineManager::getNetStateList()
|
|||||||
const char* strType = _T("[UDP]");
|
const char* strType = _T("[UDP]");
|
||||||
const char* szRemoteAddr = _T("*.*.*.*:*");
|
const char* szRemoteAddr = _T("*.*.*.*:*");
|
||||||
const char* szUDPState = _T(" ");
|
const char* szUDPState = _T(" ");
|
||||||
lstrcpy(strProcessName, ProcessPidToName(hProcessSnap, pUdpExTable->table[i].dwProcessId, szProcessName));
|
ProcessPidToName(hProcessSnap, pUdpExTable->table[i].dwProcessId, strProcessName, sizeof(strProcessName));
|
||||||
|
|
||||||
dwLength = lstrlen(strProcessName) * sizeof(char) + sizeof(DWORD) + lstrlen(strType) * sizeof(char) +
|
dwLength = lstrlen(strProcessName) * sizeof(char) + sizeof(DWORD) + lstrlen(strType) * sizeof(char) +
|
||||||
lstrlen(szLocalAddr) * sizeof(char) + lstrlen(szRemoteAddr) * sizeof(char) + lstrlen(szUDPState) *
|
lstrlen(szLocalAddr) * sizeof(char) + lstrlen(szRemoteAddr) * sizeof(char) + lstrlen(szUDPState) *
|
||||||
sizeof(char) + 12;
|
sizeof(char) + 12;
|
||||||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
if (LocalSize(lpBuffer) < (dwOffset + dwLength)) {
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew == NULL)
|
||||||
|
break; // 扩容失败时保留原缓冲区,已收集的记录照常返回
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
||||||
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
||||||
@@ -1662,26 +1872,42 @@ LPBYTE CMachineManager::getNetStateList()
|
|||||||
memcpy(lpBuffer + dwOffset, szUDPState, lstrlen(szUDPState) * sizeof(char) + 2);
|
memcpy(lpBuffer + dwOffset, szUDPState, lstrlen(szUDPState) * sizeof(char) + 2);
|
||||||
dwOffset += lstrlen(szUDPState) * sizeof(char) + 2;
|
dwOffset += lstrlen(szUDPState) * sizeof(char) + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pUdpExTable)
|
||||||
|
::HeapFree(GetProcessHeap(), 0, pUdpExTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vista 分支的资源必须在这里释放:每次刷新网络列表都会走到这里
|
||||||
|
::CloseHandle(hProcessSnap);
|
||||||
|
if (pTcpTable_Vista)
|
||||||
|
::HeapFree(GetProcessHeap(), 0, pTcpTable_Vista);
|
||||||
|
::FreeLibrary(hModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
{
|
||||||
|
LPBYTE lpNew = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew != NULL)
|
||||||
|
lpBuffer = lpNew;
|
||||||
|
}
|
||||||
|
|
||||||
return lpBuffer;
|
return lpBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将进程ID号(PID)转化为进程名称
|
// 将进程ID号(PID)转化为进程名称
|
||||||
char* CMachineManager::ProcessPidToName(HANDLE hProcessSnap, DWORD ProcessId, char* ProcessName)
|
char* CMachineManager::ProcessPidToName(HANDLE hProcessSnap, DWORD ProcessId, char* ProcessName, int nSize)
|
||||||
{
|
{
|
||||||
PROCESSENTRY32 processEntry;
|
PROCESSENTRY32 processEntry;
|
||||||
processEntry.dwSize = sizeof(processEntry);
|
processEntry.dwSize = sizeof(processEntry);
|
||||||
|
if (ProcessName == NULL || nSize <= 0)
|
||||||
|
return ProcessName;
|
||||||
// 找不到的话,默认进程名为“???”
|
// 找不到的话,默认进程名为“???”
|
||||||
lstrcpy(ProcessName, _T("???"));
|
lstrcpyn(ProcessName, _T("???"), nSize);
|
||||||
if (!::Process32First(hProcessSnap, &processEntry))
|
if (!::Process32First(hProcessSnap, &processEntry))
|
||||||
return ProcessName;
|
return ProcessName;
|
||||||
do {
|
do {
|
||||||
if (processEntry.th32ProcessID == ProcessId) { // 就是这个进程
|
if (processEntry.th32ProcessID == ProcessId) { // 就是这个进程
|
||||||
lstrcpy(ProcessName, processEntry.szExeFile);
|
// szExeFile 最长 MAX_PATH,目标缓冲区可能只有 100 字节,必须限长拷贝
|
||||||
|
lstrcpyn(ProcessName, processEntry.szExeFile, nSize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (::Process32Next(hProcessSnap, &processEntry));
|
} while (::Process32Next(hProcessSnap, &processEntry));
|
||||||
@@ -1712,18 +1938,21 @@ BOOL CMachineManager::EnablePrivilege(LPCTSTR lpPrivilegeName, BOOL bEnable)
|
|||||||
void CMachineManager::DeleteService(LPBYTE lpBuffer, UINT nSize)
|
void CMachineManager::DeleteService(LPBYTE lpBuffer, UINT nSize)
|
||||||
{
|
{
|
||||||
EnablePrivilege(SE_DEBUG_NAME, TRUE);
|
EnablePrivilege(SE_DEBUG_NAME, TRUE);
|
||||||
SERVICE_STATUS status;
|
|
||||||
|
|
||||||
SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
|
SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||||
SC_HANDLE service = OpenService(scm, (char*)lpBuffer, SERVICE_ALL_ACCESS);
|
if (scm == NULL) {
|
||||||
|
EnablePrivilege(SE_DEBUG_NAME, FALSE);
|
||||||
DWORD _err = GetLastError();
|
return;
|
||||||
BOOL isSuccess = QueryServiceStatus(service, &status);
|
}
|
||||||
if (status.dwCurrentState != SERVICE_STOPPED) {
|
SC_HANDLE service = OpenService(scm, (char*)lpBuffer, SERVICE_ALL_ACCESS);
|
||||||
isSuccess = ControlService(service, SERVICE_CONTROL_STOP, &status);
|
if (service != NULL) {
|
||||||
|
SERVICE_STATUS status = { 0 };
|
||||||
|
if (QueryServiceStatus(service, &status) && status.dwCurrentState != SERVICE_STOPPED) {
|
||||||
|
ControlService(service, SERVICE_CONTROL_STOP, &status);
|
||||||
|
}
|
||||||
|
::DeleteService(service);
|
||||||
|
CloseServiceHandle(service);
|
||||||
}
|
}
|
||||||
isSuccess = ::DeleteService(service);
|
|
||||||
CloseServiceHandle(service);
|
|
||||||
CloseServiceHandle(scm);
|
CloseServiceHandle(scm);
|
||||||
|
|
||||||
// 稍稍Sleep下,防止出错
|
// 稍稍Sleep下,防止出错
|
||||||
@@ -1736,25 +1965,55 @@ void CMachineManager::DeleteService(LPBYTE lpBuffer, UINT nSize)
|
|||||||
void CMachineManager::MyControlService(LPBYTE lpBuffer, UINT nType)
|
void CMachineManager::MyControlService(LPBYTE lpBuffer, UINT nType)
|
||||||
{
|
{
|
||||||
EnablePrivilege(SE_DEBUG_NAME, TRUE);
|
EnablePrivilege(SE_DEBUG_NAME, TRUE);
|
||||||
SERVICE_STATUS status;
|
|
||||||
|
|
||||||
SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); // 打开服务管理对象
|
SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); // 打开服务管理对象
|
||||||
|
if (scm == NULL) {
|
||||||
|
EnablePrivilege(SE_DEBUG_NAME, FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SC_HANDLE service = OpenService(scm, (char*)lpBuffer, SERVICE_ALL_ACCESS); // 打开www服务
|
SC_HANDLE service = OpenService(scm, (char*)lpBuffer, SERVICE_ALL_ACCESS); // 打开服务
|
||||||
|
if (service == NULL) {
|
||||||
|
CloseServiceHandle(scm);
|
||||||
|
SendServicesList(m_dwServiceType);
|
||||||
|
EnablePrivilege(SE_DEBUG_NAME, FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SERVICE_STATUS status = { 0 };
|
||||||
BOOL isSuccess = QueryServiceStatus(service, &status);
|
BOOL isSuccess = QueryServiceStatus(service, &status);
|
||||||
|
|
||||||
switch (nType) {
|
switch (nType) {
|
||||||
case 0:
|
case 0: {
|
||||||
|
if (status.dwCurrentState == SERVICE_STOP_PENDING) {
|
||||||
|
// 服务端“重启服务”是 STOP 后 100ms 就发 START:这里等服务真正停下来,
|
||||||
|
// 否则 StartService 会以服务仍在停止中失败,表现为“重启后服务没起来”。
|
||||||
|
for (int i = 0; i < 50 && status.dwCurrentState == SERVICE_STOP_PENDING; i++) {
|
||||||
|
Sleep(100);
|
||||||
|
if (!QueryServiceStatus(service, &status))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (status.dwCurrentState == SERVICE_STOPPED) { //服务停止状态 就启动服务
|
if (status.dwCurrentState == SERVICE_STOPPED) { //服务停止状态 就启动服务
|
||||||
isSuccess = StartService(service, NULL, NULL);
|
isSuccess = StartService(service, NULL, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
}
|
||||||
|
case 1: {
|
||||||
if (status.dwCurrentState != SERVICE_STOPPED) {
|
if (status.dwCurrentState != SERVICE_STOPPED) {
|
||||||
isSuccess = ControlService(service, SERVICE_CONTROL_STOP, &status);
|
if (status.dwCurrentState != SERVICE_STOP_PENDING)
|
||||||
|
isSuccess = ControlService(service, SERVICE_CONTROL_STOP, &status);
|
||||||
|
// 同步等待停止完成(最多 5 秒),让紧随其后的 START 能成功
|
||||||
|
if (isSuccess || status.dwCurrentState == SERVICE_STOP_PENDING) {
|
||||||
|
for (int i = 0; i < 50 && status.dwCurrentState != SERVICE_STOPPED; i++) {
|
||||||
|
Sleep(100);
|
||||||
|
if (!QueryServiceStatus(service, &status))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 2:
|
case 2:
|
||||||
if (status.dwCurrentState == SERVICE_RUNNING) {
|
if (status.dwCurrentState == SERVICE_RUNNING) {
|
||||||
isSuccess = ControlService(service, SERVICE_CONTROL_PAUSE, &status);
|
isSuccess = ControlService(service, SERVICE_CONTROL_PAUSE, &status);
|
||||||
@@ -1817,7 +2076,10 @@ PBYTE CMachineManager::GetTaskAll(ITaskFolder* pFolder, PBYTE &data, int &offset
|
|||||||
|
|
||||||
pRegisteredTask->get_Definition(&pDefinition);
|
pRegisteredTask->get_Definition(&pDefinition);
|
||||||
if (pDefinition) {
|
if (pDefinition) {
|
||||||
|
// GetProgramPath 内部会 Release 传入的 ITaskDefinition(接管所有权),
|
||||||
|
// 这里不能再释放一次,否则是双重 Release,枚举任务时客户端直接崩溃。
|
||||||
GetProgramPath(pDefinition, &exepath);
|
GetProgramPath(pDefinition, &exepath);
|
||||||
|
pDefinition = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (taskState) {
|
switch (taskState) {
|
||||||
@@ -1870,6 +2132,7 @@ PBYTE CMachineManager::GetFolderAll(ITaskFolder* pFolder, PBYTE &data, int &offs
|
|||||||
//获取文件夹个数
|
//获取文件夹个数
|
||||||
hr = pFolders->get_Count(&Count);
|
hr = pFolders->get_Count(&Count);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
|
pFolders->Release();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1889,6 +2152,7 @@ PBYTE CMachineManager::GetFolderAll(ITaskFolder* pFolder, PBYTE &data, int &offs
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
GetFolderAll(ispFolder, data, offset);
|
GetFolderAll(ispFolder, data, offset);
|
||||||
|
ispFolder->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
pFolders->Release();
|
pFolders->Release();
|
||||||
@@ -1948,7 +2212,27 @@ PBYTE CMachineManager::GetRoot()
|
|||||||
lpList[0] = TOKEN_MACHINE_TASKLIST;
|
lpList[0] = TOKEN_MACHINE_TASKLIST;
|
||||||
int offset = 1;
|
int offset = 1;
|
||||||
GetFolderAll(pRootFolder, lpList, offset);
|
GetFolderAll(pRootFolder, lpList, offset);
|
||||||
Send((LPBYTE)lpList, (UINT)LocalSize(lpList));
|
|
||||||
|
// 只发实际数据,不要把 32KB 预分配缓冲区整个发出去。
|
||||||
|
// 服务端解析靠每条记录末尾的两个 NUL 判断结束,所以非空列表要多带 2 字节结束标记;
|
||||||
|
// 没有任务时只发令牌 1 字节(长度为 1 时服务端循环直接结束)。
|
||||||
|
UINT dwSend = 1;
|
||||||
|
if (offset > 1) {
|
||||||
|
dwSend = (UINT)(offset + 2);
|
||||||
|
if ((UINT)LocalSize(lpList) < dwSend) {
|
||||||
|
PBYTE lpNew = (PBYTE)LocalReAlloc(lpList, dwSend, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
if (lpNew != NULL)
|
||||||
|
lpList = lpNew;
|
||||||
|
}
|
||||||
|
if ((UINT)LocalSize(lpList) >= dwSend) {
|
||||||
|
lpList[offset] = 0;
|
||||||
|
lpList[offset + 1] = 0;
|
||||||
|
} else {
|
||||||
|
// 扩不出结束标记时只回令牌,避免服务端越界读
|
||||||
|
dwSend = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Send((LPBYTE)lpList, dwSend);
|
||||||
LocalFree(lpList);
|
LocalFree(lpList);
|
||||||
}
|
}
|
||||||
pRootFolder->Release();
|
pRootFolder->Release();
|
||||||
@@ -2012,15 +2296,18 @@ BOOL CMachineManager::CreateTask(LPBYTE lpBuffer)
|
|||||||
//设置被结束后自动延迟10分钟运行
|
//设置被结束后自动延迟10分钟运行
|
||||||
pSettings->put_StartWhenAvailable(VARIANT_TRUE);
|
pSettings->put_StartWhenAvailable(VARIANT_TRUE);
|
||||||
//创建触发器
|
//创建触发器
|
||||||
ITrigger* pTrigger;
|
ITrigger* pTrigger = NULL;
|
||||||
hr = pTriggers->Create(TASK_TRIGGER_LOGON, &pTrigger);
|
hr = pTriggers->Create(TASK_TRIGGER_LOGON, &pTrigger);
|
||||||
|
|
||||||
IAction* pAction;
|
IAction* pAction = NULL;
|
||||||
//设置执行
|
//设置执行
|
||||||
pActions->Create(TASK_ACTION_EXEC, &pAction);
|
pActions->Create(TASK_ACTION_EXEC, &pAction);
|
||||||
pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction);
|
if (pAction) {
|
||||||
//设置程序路径等信息
|
pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction);
|
||||||
pExecAction->put_Path(CharToBSTR(path));
|
//设置程序路径等信息
|
||||||
|
if (pExecAction)
|
||||||
|
pExecAction->put_Path(CharToBSTR(path));
|
||||||
|
}
|
||||||
//注册
|
//注册
|
||||||
hr = pRootFolder->RegisterTaskDefinition(CharToBSTR(taskname), pDefinition, TASK_CREATE_OR_UPDATE,
|
hr = pRootFolder->RegisterTaskDefinition(CharToBSTR(taskname), pDefinition, TASK_CREATE_OR_UPDATE,
|
||||||
_variant_t(), _variant_t(), TASK_LOGON_INTERACTIVE_TOKEN, _variant_t(L""), &pRegisteredTask);
|
_variant_t(), _variant_t(), TASK_LOGON_INTERACTIVE_TOKEN, _variant_t(L""), &pRegisteredTask);
|
||||||
@@ -2141,10 +2428,13 @@ void CMachineManager::SaveData(const std::string& taskname, const std::string& p
|
|||||||
sum = nameLEN + taskpathLEN + statusLEN + exeLEN + sizeof(DATE) * 2;
|
sum = nameLEN + taskpathLEN + statusLEN + exeLEN + sizeof(DATE) * 2;
|
||||||
// 动态扩展缓冲区
|
// 动态扩展缓冲区
|
||||||
if (LocalSize(lpList) < (offset + sum)) {
|
if (LocalSize(lpList) < (offset + sum)) {
|
||||||
lpList = (BYTE*)LocalReAlloc(lpList, LocalSize(lpList)+4*1024, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
int nNewSize = (int)LocalSize(lpList) + (int)sum + 4 * 1024;
|
||||||
if (!lpList) {
|
PBYTE lpNew = (BYTE*)LocalReAlloc(lpList, nNewSize, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||||||
|
// 分配失败时保留原缓冲区:lpList 是引用,绝不能把它改成 NULL,
|
||||||
|
// 否则调用方手里的缓冲区指针会丢失,后续写入就变成空指针写
|
||||||
|
if (!lpNew)
|
||||||
return;
|
return;
|
||||||
}
|
lpList = lpNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
//拷贝数据
|
//拷贝数据
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ private:
|
|||||||
HWND GetHwndByPid(DWORD dwProcessID);
|
HWND GetHwndByPid(DWORD dwProcessID);
|
||||||
bool Is64BitOS();
|
bool Is64BitOS();
|
||||||
bool Is64BitPorcess(DWORD dwProcessID);
|
bool Is64BitPorcess(DWORD dwProcessID);
|
||||||
char* ProcessPidToName(HANDLE hProcessSnap, DWORD ProcessId, char* ProcessName);
|
char* ProcessPidToName(HANDLE hProcessSnap, DWORD ProcessId, char* ProcessName, int nSize);
|
||||||
BOOL EnablePrivilege(LPCTSTR lpPrivilegeName, BOOL bEnable);
|
BOOL EnablePrivilege(LPCTSTR lpPrivilegeName, BOOL bEnable);
|
||||||
void DeleteService(LPBYTE lpBuffer, UINT nSize);
|
void DeleteService(LPBYTE lpBuffer, UINT nSize);
|
||||||
void MyControlService(LPBYTE lpBuffer, UINT nType);
|
void MyControlService(LPBYTE lpBuffer, UINT nType);
|
||||||
|
|||||||
@@ -721,8 +721,19 @@ void CMachineDlg::ShowTaskList()
|
|||||||
continue;
|
continue;
|
||||||
m_list.InsertItem(i, str);
|
m_list.InsertItem(i, str);
|
||||||
|
|
||||||
|
// 目录列:只去掉末尾“\任务名”。不能用 Replace 全量替换——任务名也可能出现在父目录里,
|
||||||
|
// 那样算出的目录是错的,执行/停止/删除任务会定位到错误的文件夹。
|
||||||
str = taskpath;
|
str = taskpath;
|
||||||
str.Replace(taskname, _T(""));
|
{
|
||||||
|
CString tail = _T("\\");
|
||||||
|
tail += taskname;
|
||||||
|
if (str.GetLength() >= tail.GetLength() &&
|
||||||
|
str.Right(tail.GetLength()).CompareNoCase(tail) == 0) {
|
||||||
|
str = str.Left(str.GetLength() - tail.GetLength());
|
||||||
|
if (str.IsEmpty())
|
||||||
|
str = _T("\\");
|
||||||
|
}
|
||||||
|
}
|
||||||
// 任务名/目录/程序路径来自客户端 BSTRToUTF8,为 UTF-8;状态为 GBK 字面量(运行中/已禁用…)
|
// 任务名/目录/程序路径来自客户端 BSTRToUTF8,为 UTF-8;状态为 GBK 字面量(运行中/已禁用…)
|
||||||
SetMachineItemText(m_list, i, 1, str.GetString(), CP_UTF8);
|
SetMachineItemText(m_list, i, 1, str.GetString(), CP_UTF8);
|
||||||
SetMachineItemText(m_list, i, 2, taskname, CP_UTF8);
|
SetMachineItemText(m_list, i, 2, taskname, CP_UTF8);
|
||||||
@@ -1006,7 +1017,8 @@ void CMachineDlg::ShowProcessList_menu()
|
|||||||
p_InjectData->dwProcessID = dwProcessID;
|
p_InjectData->dwProcessID = dwProcessID;
|
||||||
CString strexeis86 = m_list.GetItemText(nItem, 9);
|
CString strexeis86 = m_list.GetItemText(nItem, 9);
|
||||||
strexeis86 == _T("x86") ? p_InjectData->ExeIsx86 = 1 : p_InjectData->ExeIsx86 = 0;
|
strexeis86 == _T("x86") ? p_InjectData->ExeIsx86 = 1 : p_InjectData->ExeIsx86 = 0;
|
||||||
memcpy(p_InjectData->strpath, dlg.Str_remote, dlg.Str_remote.GetLength() * 2 + 2);
|
// Str_remote 是窄字符串、strpath 是 char[1024]:按字符数+1 拷贝;超长时截断,避免堆溢出
|
||||||
|
strncpy_s(p_InjectData->strpath, sizeof(p_InjectData->strpath), dlg.Str_remote, _TRUNCATE);
|
||||||
//读取文件
|
//读取文件
|
||||||
BYTE* lpBuffer = NULL;
|
BYTE* lpBuffer = NULL;
|
||||||
HANDLE hFile = CreateFile(dlg.Str_loacal, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
HANDLE hFile = CreateFile(dlg.Str_loacal, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
@@ -1412,16 +1424,18 @@ void CMachineDlg::ShowTaskList_menu()
|
|||||||
taskpath = m_list.GetItemText(nItem, 1);
|
taskpath = m_list.GetItemText(nItem, 1);
|
||||||
taskname = m_list.GetItemText(nItem, 2);
|
taskname = m_list.GetItemText(nItem, 2);
|
||||||
|
|
||||||
int nPacketLength = lstrlen(taskpath.GetBuffer()) * 2 + lstrlen(taskname.GetBuffer()) * 2 + 5;
|
// 服务端是 MultiByte 工程:按窄字符拼接,包长 = 1(令牌) + (目录+1) + (任务名+1)
|
||||||
|
int nPacketLength = lstrlen(taskpath.GetBuffer()) + lstrlen(taskname.GetBuffer()) + 3;
|
||||||
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, nPacketLength);
|
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, nPacketLength);
|
||||||
|
if (!lpBuffer) return;
|
||||||
lpBuffer[0] = COMMAND_TASKSTART;
|
lpBuffer[0] = COMMAND_TASKSTART;
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
memcpy(lpBuffer + offset, taskpath.GetBuffer(), lstrlen(taskpath.GetBuffer()) * 2 + 2);
|
memcpy(lpBuffer + offset, taskpath.GetBuffer(), lstrlen(taskpath.GetBuffer()) + 1);
|
||||||
offset += lstrlen(taskpath.GetBuffer()) * 2 + 2;
|
offset += lstrlen(taskpath.GetBuffer()) + 1;
|
||||||
|
|
||||||
memcpy(lpBuffer + offset, taskname.GetBuffer(), lstrlen(taskname.GetBuffer()) * 2 + 2);
|
memcpy(lpBuffer + offset, taskname.GetBuffer(), lstrlen(taskname.GetBuffer()) + 1);
|
||||||
offset += lstrlen(taskname.GetBuffer()) * 2 + 2;
|
offset += lstrlen(taskname.GetBuffer()) + 1;
|
||||||
|
|
||||||
m_ContextObject->Send2Client(lpBuffer, nPacketLength);
|
m_ContextObject->Send2Client(lpBuffer, nPacketLength);
|
||||||
|
|
||||||
@@ -1440,16 +1454,18 @@ void CMachineDlg::ShowTaskList_menu()
|
|||||||
taskpath = m_list.GetItemText(nItem, 1);
|
taskpath = m_list.GetItemText(nItem, 1);
|
||||||
taskname = m_list.GetItemText(nItem, 2);
|
taskname = m_list.GetItemText(nItem, 2);
|
||||||
|
|
||||||
int nPacketLength = lstrlen(taskpath.GetBuffer()) * 2 + lstrlen(taskname.GetBuffer()) * 2 + 5;
|
// 服务端是 MultiByte 工程:按窄字符拼接,包长 = 1(令牌) + (目录+1) + (任务名+1)
|
||||||
|
int nPacketLength = lstrlen(taskpath.GetBuffer()) + lstrlen(taskname.GetBuffer()) + 3;
|
||||||
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, nPacketLength);
|
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, nPacketLength);
|
||||||
|
if (!lpBuffer) return;
|
||||||
lpBuffer[0] = COMMAND_TASKSTOP;
|
lpBuffer[0] = COMMAND_TASKSTOP;
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
memcpy(lpBuffer + offset, taskpath.GetBuffer(), lstrlen(taskpath.GetBuffer()) * 2 + 2);
|
memcpy(lpBuffer + offset, taskpath.GetBuffer(), lstrlen(taskpath.GetBuffer()) + 1);
|
||||||
offset += lstrlen(taskpath.GetBuffer()) * 2 + 2;
|
offset += lstrlen(taskpath.GetBuffer()) + 1;
|
||||||
|
|
||||||
memcpy(lpBuffer + offset, taskname.GetBuffer(), lstrlen(taskname.GetBuffer()) * 2 + 2);
|
memcpy(lpBuffer + offset, taskname.GetBuffer(), lstrlen(taskname.GetBuffer()) + 1);
|
||||||
offset += lstrlen(taskname.GetBuffer()) * 2 + 2;
|
offset += lstrlen(taskname.GetBuffer()) + 1;
|
||||||
|
|
||||||
m_ContextObject->Send2Client(lpBuffer, nPacketLength);
|
m_ContextObject->Send2Client(lpBuffer, nPacketLength);
|
||||||
|
|
||||||
@@ -1468,16 +1484,18 @@ void CMachineDlg::ShowTaskList_menu()
|
|||||||
taskpath = m_list.GetItemText(nItem, 1);
|
taskpath = m_list.GetItemText(nItem, 1);
|
||||||
taskname = m_list.GetItemText(nItem, 2);
|
taskname = m_list.GetItemText(nItem, 2);
|
||||||
|
|
||||||
int nPacketLength = lstrlen(taskpath.GetBuffer()) * 2 + lstrlen(taskname.GetBuffer()) * 2 + 5;
|
// 服务端是 MultiByte 工程:按窄字符拼接,包长 = 1(令牌) + (目录+1) + (任务名+1)
|
||||||
|
int nPacketLength = lstrlen(taskpath.GetBuffer()) + lstrlen(taskname.GetBuffer()) + 3;
|
||||||
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, nPacketLength);
|
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, nPacketLength);
|
||||||
|
if (!lpBuffer) return;
|
||||||
lpBuffer[0] = COMMAND_TASKDEL;
|
lpBuffer[0] = COMMAND_TASKDEL;
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
memcpy(lpBuffer + offset, taskpath.GetBuffer(), lstrlen(taskpath.GetBuffer()) * 2 + 2);
|
memcpy(lpBuffer + offset, taskpath.GetBuffer(), lstrlen(taskpath.GetBuffer()) + 1);
|
||||||
offset += lstrlen(taskpath.GetBuffer()) * 2 + 2;
|
offset += lstrlen(taskpath.GetBuffer()) + 1;
|
||||||
|
|
||||||
memcpy(lpBuffer + offset, taskname.GetBuffer(), lstrlen(taskname.GetBuffer()) * 2 + 2);
|
memcpy(lpBuffer + offset, taskname.GetBuffer(), lstrlen(taskname.GetBuffer()) + 1);
|
||||||
offset += lstrlen(taskname.GetBuffer()) * 2 + 2;
|
offset += lstrlen(taskname.GetBuffer()) + 1;
|
||||||
|
|
||||||
m_ContextObject->Send2Client(lpBuffer, nPacketLength);
|
m_ContextObject->Send2Client(lpBuffer, nPacketLength);
|
||||||
|
|
||||||
@@ -1489,28 +1507,28 @@ void CMachineDlg::ShowTaskList_menu()
|
|||||||
DWORD offset = 0;
|
DWORD offset = 0;
|
||||||
CCreateTaskDlg* dlg = new CCreateTaskDlg(this);
|
CCreateTaskDlg* dlg = new CCreateTaskDlg(this);
|
||||||
if (IDOK == dlg->DoModal()) {
|
if (IDOK == dlg->DoModal()) {
|
||||||
// 计算字符串长度
|
// 服务端是 MultiByte 工程:5 个窄字符串各带 1 字节结束符,再加 1 字节令牌
|
||||||
len = lstrlen(dlg->m_TaskPath.GetBuffer()) * 2 + lstrlen(dlg->m_TaskNames.GetBuffer()) * 2 + lstrlen(dlg->m_ExePath.GetBuffer()) *
|
len = lstrlen(dlg->m_TaskPath.GetBuffer()) + lstrlen(dlg->m_TaskNames.GetBuffer()) + lstrlen(dlg->m_ExePath.GetBuffer()) +
|
||||||
2 + lstrlen(dlg->m_Author.GetBuffer()) * 2 + lstrlen(dlg->m_Description.GetBuffer()) * 2 + 12;
|
lstrlen(dlg->m_Author.GetBuffer()) + lstrlen(dlg->m_Description.GetBuffer()) + 6;
|
||||||
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, len);
|
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, len);
|
||||||
if (lpBuffer) {
|
if (lpBuffer) {
|
||||||
lpBuffer[0] = COMMAND_TASKCREAT;
|
lpBuffer[0] = COMMAND_TASKCREAT;
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
memcpy(lpBuffer + offset, dlg->m_TaskPath.GetBuffer(), lstrlen(dlg->m_TaskPath.GetBuffer()) * 2 + 2);
|
memcpy(lpBuffer + offset, dlg->m_TaskPath.GetBuffer(), lstrlen(dlg->m_TaskPath.GetBuffer()) + 1);
|
||||||
offset += lstrlen(dlg->m_TaskPath.GetBuffer()) * 2 + 2;
|
offset += lstrlen(dlg->m_TaskPath.GetBuffer()) + 1;
|
||||||
|
|
||||||
memcpy(lpBuffer + offset, dlg->m_TaskNames.GetBuffer(), lstrlen(dlg->m_TaskNames.GetBuffer()) * 2 + 2);
|
memcpy(lpBuffer + offset, dlg->m_TaskNames.GetBuffer(), lstrlen(dlg->m_TaskNames.GetBuffer()) + 1);
|
||||||
offset += lstrlen(dlg->m_TaskNames.GetBuffer()) * 2 + 2;
|
offset += lstrlen(dlg->m_TaskNames.GetBuffer()) + 1;
|
||||||
|
|
||||||
memcpy(lpBuffer + offset, dlg->m_ExePath.GetBuffer(), lstrlen(dlg->m_ExePath.GetBuffer()) * 2 + 2);
|
memcpy(lpBuffer + offset, dlg->m_ExePath.GetBuffer(), lstrlen(dlg->m_ExePath.GetBuffer()) + 1);
|
||||||
offset += lstrlen(dlg->m_ExePath.GetBuffer()) * 2 + 2;
|
offset += lstrlen(dlg->m_ExePath.GetBuffer()) + 1;
|
||||||
|
|
||||||
memcpy(lpBuffer + offset, dlg->m_Author.GetBuffer(), lstrlen(dlg->m_Author.GetBuffer()) * 2 + 2);
|
memcpy(lpBuffer + offset, dlg->m_Author.GetBuffer(), lstrlen(dlg->m_Author.GetBuffer()) + 1);
|
||||||
offset += lstrlen(dlg->m_Author.GetBuffer()) * 2 + 2;
|
offset += lstrlen(dlg->m_Author.GetBuffer()) + 1;
|
||||||
|
|
||||||
memcpy(lpBuffer + offset, dlg->m_Description.GetBuffer(), lstrlen(dlg->m_Description.GetBuffer()) * 2 + 2);
|
memcpy(lpBuffer + offset, dlg->m_Description.GetBuffer(), lstrlen(dlg->m_Description.GetBuffer()) + 1);
|
||||||
offset += lstrlen(dlg->m_Description.GetBuffer()) * 2 + 2;
|
offset += lstrlen(dlg->m_Description.GetBuffer()) + 1;
|
||||||
m_ContextObject->Send2Client(lpBuffer, len);
|
m_ContextObject->Send2Client(lpBuffer, len);
|
||||||
|
|
||||||
LocalFree(lpBuffer);
|
LocalFree(lpBuffer);
|
||||||
|
|||||||
Reference in new issue
Block a user