进程工作集WorkingSet (PSAPI 01)

0x01  相关API

1.QueryWorkingSet

得到刚加入指定进程工作集的页信息

BOOL QueryWorkingSet( 
  HANDLE hProcess , 
  PVOID pv , 
  DWORD cb 
);

参数:

hProcess - [in]进程句柄。句柄必须有PROCESS_QUERY_INFORMATION和PROCESS_VM_READ权限。
pv -       [out]指向接收信息的存储的指针。
cb -       [in]pv存储的大小,字节为单位。

返回值

成功返回非零值。失败返回0。可调用GetLastError得到错误信息。

2.GetWsChanges

检索自上次调用此函数或InitializeProcessForWsWatch函数以来已添加到指定进程的工作集的页面的信息 

BOOL WINAPI GetWsChanges(
  _In_HANDLE hProcess,
  _Out_ PPSAPI_WS_WATCH_INFORMATION lpWatchInfo,
  _In_ DWORD cb
);  

  参数:

hProcess    [in]处理过程的句柄。该句柄必须具有PROCESS_QUERY_INFORMATION 访问权限。有关更多信息,请参阅 进程安全和访问权限。
lpWatchInfo [out]指向用户分配的缓冲区的指针,该缓冲区接收PSAPI_WS_WATCH_INFORMATION结构数组 。该数组以FaultingPc成员为NULL 的结构终止。
cb          [in]lpWatchInfo缓冲区的大小,以字节为单位。

   返回值:

如果函数成功,则返回值为非零。

如果函数失败,返回值为零。要获得扩展错误信息,可调用 GetLastError

如果 lpWatchInfo缓冲区不足以包含所有工作集合更改记录,则GetLastError返回 ERROR_INSUFFICIENT_BUFFER ; 缓冲区返回空。为缓冲区重新分配一个更大的内存块并再次调用。

 

3.EmptyWorkingSet

从指定进程的工作集中删除尽可能多的页面。

BOOL WINAPI EmptyWorkingSet(
  _In_ HANDLE hProcess
);

参数:

hProcess [in] 处理过程的句柄。该句柄必须具有PROCESS_QUERY_INFORMATION或PROCESS_QUERY_LIMITED_INFORMATION访问权限和PROCESS_SET_QUOTA访问权限。

返回值:

如果函数成功,则返回值为非零。

如果函数失败,返回值为零。要获得扩展错误信息,可调用 GetLastError

// WorkingSet.cpp : 定义控制台应用程序的入口点。
// http://www.howsoftworks.net/windows/system-services/queryworkingset.html   



#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <fstream>
#include "psapi.h"
#define MAX_NUM 10000

#pragma comment ( lib, "psapi.lib" ) 

using namespace std;

ofstream fout("WorkingSetInformation.txt");

void ShowErrorMessage()
{
	DWORD dwErrorCode = GetLastError();

	HLOCAL hLocal = NULL;
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
		NULL,
		dwErrorCode,
		MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
		(PTSTR)&hLocal,
		0,
		NULL
	);

	fout << '	' << "ErrorCode    : " << dwErrorCode << endl;
	fout << '	' << "ErrorMessage : " << (char*)hLocal << endl;

	LocalFree(hLocal);
}


int main()
{
	//get notepad's PID from "Windows task maganent"

	DWORD dwProcessId = 10084; //change it

	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
	if (InitializeProcessForWsWatch(hProcess))
	{
		/******************************
		*       QueryWorkingSet
		*******************************/

		PVOID pv[MAX_NUM] = { 0 };

		if (!QueryWorkingSet(hProcess, pv, sizeof(pv)))
		{
			fout << "QueryWorkingSet Failed!" << endl;

			ShowErrorMessage();
		}
		else
		{
			for (unsigned int i = 0; i < MAX_NUM; i++)
			{
				if (pv[i] != NULL)
				{
					if (i == 0)
						fout << "TotalNum : " << hex << pv[i] << endl;

					else
						fout << '	' << i << "  pv : " << hex << pv[i] << endl;
				}
				else
				{
					break;
				}
			}
		}

		fout << endl << endl;

		/******************************
		*       GetWsChanges
		*******************************/

		cout << "5 Second Wait" << endl;

		Sleep(5000);

		PSAPI_WS_WATCH_INFORMATION WatchInfo[MAX_NUM] = { 0 };

		if (!GetWsChanges(hProcess, WatchInfo, sizeof(WatchInfo)))
		{
			fout << "GetWsChanges Failed!" << endl;

			ShowErrorMessage();
		}
		else
		{
			for (unsigned int i = 0; i < MAX_NUM; i++)
			{
				if (WatchInfo[i].FaultingPc != NULL || WatchInfo[i].FaultingVa != NULL)
				{
					fout << "Pc指针 : " << WatchInfo[i].FaultingPc << endl;
					fout << "Va缓冲区大小 : " << WatchInfo[i].FaultingVa << endl << endl;
				}
				else
				{
					break;
				}
			}
		}


		fout << endl << endl;


		/******************************
		*       EmptyWorkingSet
		*******************************/

		if (!EmptyWorkingSet(hProcess))
		{
			fout << "EmptyWorkingSet Failed!" << endl;

			ShowErrorMessage();
		}
		else
		{
			PVOID pv[MAX_NUM] = { 0 };

			if (!QueryWorkingSet(hProcess, pv, sizeof(pv)))
			{
				fout << "EmptyWorkingSet Failed!" << endl;

				ShowErrorMessage();
			}
			else
			{
				for (unsigned int i = 0; i < MAX_NUM; i++)
				{
					if (pv[i] != NULL)
					{
						if (i == 0)
							fout << "TotalNum : " << hex << pv[i] << endl;

						else
							fout << '	' << i << "  pv : " << hex << pv[i] << endl;
					}
					else
					{
						break;
					}
				}
			}
		}
	}

	CloseHandle(hProcess);

	return 0;
}

  

原文地址:https://www.cnblogs.com/lsh123/p/8125194.html