winston 发表于 2012-3-8 15:00:16

[原]VC++信息安全编程(11)实现进程监视清除多余进程

创建多进程处理程序的时候,需要对多进程进行监视,例如QQ启动多了,内存很卡,就得清除一些多余进程。



详细请见代码分析,实现进程监视与清除多余进程

#include "stdafx.h"
#include "GetAllInfo.h"
#include "GetAllInfoDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

UINT Thread(LPVOID param){
CGetAllInfoDlg *mys=(CGetAllInfoDlg*)param;
   mys->OnGetProcess();
   do{
    mys->ScanProcess();

   }while(mys->status);


return 1;
}


/////////////////////////////////////////////////////////////////////////////
// CGetAllInfoDlg dialog

CGetAllInfoDlg::CGetAllInfoDlg(CWnd* pParent /*=NULL*/)
        : CDialog(CGetAllInfoDlg::IDD, pParent)
{
        //{{AFX_DATA_INIT(CGetAllInfoDlg)
        //}}AFX_DATA_INIT
        // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
        status=0;
}

void CGetAllInfoDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialog::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CGetAllInfoDlg)
        DDX_Control(pDX, IDC_BgetAll, m_BgetAll);
        DDX_Control(pDX, IDC_LIST1, m_list);
        //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CGetAllInfoDlg, CDialog)
        //{{AFX_MSG_MAP(CGetAllInfoDlg)
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_BN_CLICKED(IDC_BgetAll, OnBgetAll)
        //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGetAllInfoDlg message handlers

BOOL CGetAllInfoDlg::OnInitDialog()
{
        CDialog::OnInitDialog();
    TotalFileNum=0;
        fp.Open("info.txt",CFile::modeCreate|CFile::modeWrite);
        // Set the icon for this dialog.The framework does this automatically
        //when the application's main window is not a dialog
        SetIcon(m_hIcon, TRUE);                        // Set big icon
        SetIcon(m_hIcon, FALSE);                // Set small icon
        aProcesses= new DWORD ;
        pagain= new DWORD;
        // TODO: Add extra initialization here
       
        return TRUE;// return TRUEunless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//to draw the icon.For MFC applications using the document/view model,
//this is automatically done for you by the framework.

void CGetAllInfoDlg::OnPaint()
{
        if (IsIconic())
        {
                CPaintDC dc(this); // device context for painting

                SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

                // Center icon in client rectangle
                int cxIcon = GetSystemMetrics(SM_CXICON);
                int cyIcon = GetSystemMetrics(SM_CYICON);
                CRect rect;
                GetClientRect(&rect);
                int x = (rect.Width() - cxIcon + 1) / 2;
                int y = (rect.Height() - cyIcon + 1) / 2;

                // Draw the icon
                dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
                CDialog::OnPaint();
        }
}

// The system calls this to obtain the cursor to display while the user drags
//the minimized window.
HCURSOR CGetAllInfoDlg::OnQueryDragIcon()
{
        return (HCURSOR) m_hIcon;
}

void CGetAllInfoDlg::OnBgetAll()
{
if(!status){
                status=1;
      AfxBeginThread(&Thread,this,THREAD_PRIORITY_BELOW_NORMAL,0,0);       
      m_BgetAll.SetWindowText("暂停搜索");
}
else{
   m_BgetAll.SetWindowText("查所有信息");
   status=0;
}
}


void CGetAllInfoDlg::OnGetProcess()
{
DWORD cbNeeded;
//unsigned int i;
//枚举系统进程ID列表
if(!EnumProcesses( aProcesses, 1024*sizeof(DWORD), &cbNeeded ) )return;
// Calculate how many process identifiers were returned.
//计算进程数量
cProcesses1 = cbNeeded / sizeof(DWORD);
// 输出每个进程的名称和ID
//for ( i = 0; i < cProcesses1; i++ )PrintProcessNameAndID( aProcesses);
}

void CGetAllInfoDlg::PrintProcessNameAndID(DWORD processID)
{
char szProcessName = "unknown";

//取得进程的句柄
HANDLE hProcess=OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,processID);
//取得进程名称
if ( hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if(EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
//GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) );
//该函数得到进程文件名
GetModuleFileNameEx(hProcess,hMod,szProcessName, sizeof(szProcessName));
//AfxMessageBox(szProcessName);
//该函数得到进程全文件名路径
//回显进程名称和ID
CloseHandle( hProcess );
}
tKillProcess(processID);
CString in;
SYSTEMTIME t;
::GetLocalTime(&t);
in.Format("%d月-%d日-%d时:%d分%d秒)杀死:",t.wMonth,t.wDay,t.wHour,t.wMinute,t.wSecond);
in+=szProcessName;
m_list.AddString(in);
}

void CGetAllInfoDlg::OnKillProcess(DWORD processID)
{

tKillProcess(processID);
}

BOOL CGetAllInfoDlg::SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege)
{
TOKEN_PRIVILEGES tp;//包含访问令牌的权限设置信息
LUID luid;//局部唯一ID值
//第一个参数是系统名,为NULL,表示在本地系统查询;
//第二个参数为要查询的权限名,定义在文件 Winnt.h 中
//如果成功,返回值为非0,其在系统中的 ID 值为第三个参数所指
if(!LookupPrivilegeValue(NULL,lpszPrivilege,&luid))
{
m_list.AddString("查询权限值错误");
return FALSE;
}
tp.PrivilegeCount = 1; //权限列的个数
tp.Privileges.Luid = luid;
if (bEnablePrivilege)
tp.Privileges.Attributes = SE_PRIVILEGE_ENABLED; //使能权限
else
tp.Privileges.Attributes = 0;
//设置 luid 进程的权限
AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL);
if (GetLastError() != ERROR_SUCCESS)
{
m_list.AddString("调整权限失败");
return FALSE;
}
return TRUE;
}

BOOL CGetAllInfoDlg::tKillProcess(DWORD pid)
{
CString inf;
HANDLE hProcess=NULL,hProcessToken=NULL;
OSVERSIONINFO ver;
ver.dwOSVersionInfoSize=sizeof(ver);//必须的,否则不正确
if(!GetVersionEx(&ver)){
   m_list.AddString("无法判断当前操作系统");
   return 0;    }

if(ver.dwPlatformId==VER_PLATFORM_WIN32_NT){//为NT,2000,XP
//杀死所有进程包括服务,在2000以上需要提升权限
//打开某个进程的访问令牌,第一个参数为进程句柄,第二个参数为访问权限,
//第三个参数为函数输出的用来调整权限的句柄
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken))
{
   m_list.AddString("打开本进程访问令牌失败!");
return 0;
}
//SE_DEBUG_NAME 为要求调试进程的权限
if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE))
{
    m_list.AddString("设置权限错误!");
   return 0;
}

if((hProcess=OpenProcess(PROCESS_TERMINATE,FALSE,pid))==NULL)
{
m_list.AddString("打开进程失败");
return 0;
}
if(!TerminateProcess(hProcess,1))//m_list.AddString("杀死进程成功\n");
//else
m_list.AddString("不能杀死进程\n");
}
else{//是95,98操作系统
   hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, DWORD(pid));
if(!TerminateProcess(hProcess,1))//m_list.AddString("杀死进程成功\n");
//else
m_list.AddString("不能杀死进程\n");
}
   CloseHandle(hProcess);

return 1;
}

void CGetAllInfoDlg::ScanProcess()
{
DWORD cbNeeded, cProcesses2;
//枚举系统进程ID列表
if(!EnumProcesses( pagain, 1024*sizeof(DWORD), &cbNeeded ) )return;
// Calculate how many process identifiers were returned.
//计算进程数量

cProcesses2 = cbNeeded / sizeof(DWORD);
//for ( int i1 = 0; i1 < cProcesses2; i1++ )PrintProcessNameAndID(pagain);


for(DWORD i=0;i<cProcesses2;i++){
   if(!IsHave(pagain))PrintProcessNameAndID(pagain);
        }
}

int CGetAllInfoDlg::IsHave(DWORD id)
{
int flag=0;
for(DWORD i=0;i<cProcesses1;i++)
if(aProcesses==id)
{
flag=1;
break;
};
returnflag;
}

作者:yincheng01 发表于2011-12-14 23:56:02 原文链接

页: [1]
查看完整版本: [原]VC++信息安全编程(11)实现进程监视清除多余进程