윈도우즈 시스템 프로그래밍

윈도우즈 시스템 프로그래밍 6장 - 커널 오브젝트와 핸들의 종속관계

111-000-111 2021. 7. 24. 14:37

 

 

윈도우즈 시스템 프로그래밍이라는 책과 해당 책의 저자이신 윤성우님의 강의를 통해 공부한 내용을 정리하는 글입니다.

 

 


 

 

커널 오브젝트의 종속 관계

 

⦁ 커널 오브젝트는 프로세스에 종속적인 것이 아니라, 운영체제에 종속적인 관계로 커널 오브젝트의 소멸시점은 운영체제에 의해서 결정된다.

⦁ 그러므로 여러 프로세스에 의해서 접근이 가능하다.

 

 

 

핸들의 종속 관계

 

⦁ 핸들은 운영체제에 종속적이지 않고 프로세스에 종속적이다.

 

 

 

예제를 통한 종속 관계의 이해

 

⦁ 이번 예제의 시나리오 : A 프로세스가 B 프로세스를 생성한다. 그러자 B 프로세스는 자신의 우선순위를 높인다. 잠시 후 A 프로세스는 B 프로세스의 우선순위를 원래대로 돌려 놓는다.

 

 

KerObjShare.cpp

#include <stdio.h>
#include <tchar.h>
#include <windows.h>


int _tmain(int argc, TCHAR* argv[])
{
	STARTUPINFO si = { 0, };
	PROCESS_INFORMATION pi;
	si.cb = sizeof(si);

	TCHAR command[] = _T("Operation2.exe");

	CreateProcess(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);

	DWORD timing = 0;
	while (1)
	{
		for (DWORD i = 0; i < 10000; i++)
			for (DWORD i = 0; i < 10000; i++);

		_fputts(_T("Parent \n"), stdout);

		timing += 1;
		if (timing == 2)
                    SetPriorityClass(pi.hProcess, NORMAL_PRIORITY_CLASS);
	}
	return 0;
}

 

 

Operation2.cpp는 실행과 동시에 자신의 우선순위를 높이도록 구현되어 있다. 우선 순위를 높이기 위해서는 핸들을 이용해서 커널 오브젝트에 접근해야 하므로 GetCurrentProcess 함수를 통해서 핸들 정보를 얻었다.

 

위 예제에서 선언된 구조체 변수 pi의 멤버에 대해 알아보기 위해 구조체 PROCESS_INFORMATION의 정의를 먼저 보도록 하자

 

typedef struct _PROCESS_INFORMATION
{
    HANDLE hProcess;		// 프로세스의 핸들
    HANDLE hThread;		// 쓰레드 핸들
    DWORD dwProcessId;		// 프로세스의 ID
    DWORD dwThreadId;		// 쓰레드 ID
} PROCESS_INFORMATION;

 

hProcess는 새로 생성된 프로세스의 핸들 정보로 채워지게 된다.

 

위 예제에서는 프로세스 생성 시 얻은 프로세스의 핸들을 통해서 Operation2.exe의 커널 오브젝트에 접근하고 있는 상황이다.

결과적으로 한번은 우선순위를 높이기 위해서, 또 한번은 우선순위를 되돌리기 위해서 두 개의 프로세스가 하나의 커널 오브젝트에 순서대로 접근한 것을 알 수 있다.

또한, 같은 커널 오브젝트에 접근하더라도 핸들을 얻는 방법에는 상황에 따라 차이가 있다.

 

 

 

 

PROCESS_INFORMATION 구조체

 

 

typedef struct _PROCESS_INFORMATION
{
    HANDLE hProcess;		// 프로세스의 핸들
    HANDLE hThread;		// 쓰레드 핸들
    DWORD dwProcessId;		// 프로세스의 ID
    DWORD dwThreadId;		// 쓰레드 ID
} PROCESS_INFORMATION;

 

위에서 제시했던 PROCESS_INFORMATION 구조체의 정의이다.

 

세 번째 멤버 dwProcessId는 새로 생성되는 프로세스ID 정보로 채워지게 된다.

프로세스 핸들과 프로세스 ID 차이점 : 프로세스 핸들은 프로세스의 커널 오브젝트를 가리키기 위한 것이고, 프로세스 ID는 커널 오브젝트가 아니라 프로세스 자체를 구분짓기 위한 것이다.

두 번째, 네 번째 멤버는 CreateProcess 함수를 통해 프로세스를 생성하면 쓰레드라는 시스템 리소스가 더불어 생성되는데, 이 쓰레드의 핸들과 ID 정보가 각각 해당된다.