객체 관리자

**객체 관리자**(, 내부적으로 **Ob**로 사용)는 윈도우의 자원을 관리하는 역할을 하는, 윈도우 NT 아키텍처의 한 부분으로서 구현된 하위 시스템이다. 논리적 객체들로 표면화된 각 자원은 범주화를 위해 Namespace(이름공간) 안에 상주한다. 자원은 물리적 장치일 수도 있으며 파일이나 폴더 또는 실행 중인 프로세스의 윈도우 레지스트리일 수도 있다. 자원을 표현하는 모든 객체들은 자원에 대한 `Object Type` 속성과 메타데이터를 가지고 있다. 객체 관리자는 공유된 자원이며 자원을 처리하는 모든 하위 시스템들은 객체 관리자를 통해야 한다.

## 아키텍처
객체 관리자는 프로세스에 할당된 자원들을 추적하는 윈도우 NT의 집중된 자원 중개인이다. 이것은 자원에 상관없이 어떠한 종류의 자원도 관리할 수 있다. 모든 자원들은 객체들로 표현되며, 각각은 범주화를 위한 논리적 Namespace에 속한다. 그리고 자원의 종류를 표현하는 type을 가지는데, 이것은 속성을 통해 성능과 기능을 보여준다. 객체는 자원을 사용하는 모든 프로세스가 완료할 때까지 계속 유지된다. 객체 관리자는 참조 횟수 계산 방식을 통해 어떤 객체들이 현재 사용되고 있는 지와 소유자 정보에 대한 기록을 유지한다. 프로세스들에 대한 자원 할당 상태를 바뀌게 하는 어떤 시스템 호출도 객체 관리자를 통해야 한다.

객체는 커널 객체 또는 Executive 객체일 수 있다. 커널 객체들은 물리장치나 서비스, 동기화 같이 OS 서비스를 구현하는 기본형의 자원들을 표현한다. 커널 객체들은 사용자 모드 코드에 노출되지 않으며, 커널 코드에 제한된다. 응용 프로그램과 서비스들은 윈도우 NT 아키텍처를 통해 노출된 Executive 객체들을 이용해 커널 외부에서 실행된다. Executive 객체들은 하나나 그 이상의 커널 객체들을 캡슐화하고, 커널과 그것에 관련된 자원 뿐만 아니라 확장된 서비스들의 집합까지도 노출한다. 응용 프로그램 스스로는 하나나 그 이상의 Executive 객체들을 감싸고 특정한 서비스들을 제공하는 객체들을 드러낸다. Executive 객체들은 또한 Win32 하위 시스템 같은 환경 하위 시스템에 의해 각각의 기능을 구현하기 위해 쓰인다.

객체가 생성되거나 열릴 때마다, 핸들이라고 하는 인스턴스에 대한 참조가 생성된다. 객체 관리자는 이름과 핸들을 통해 객체들의 색인을 만든다. 그러나 이름 변환 과정이 빠지므로 객체의 핸들을 통해 참조하는 것이 더 빠르다. 핸들들은 프로세스들에 의해 관련되며 프로세스들 사이에 넘겨질 수 있다. 프로세스는 객체를 사용하기 전에 꼭 핸들을 소유하고 있어야 한다. 생성 과정 동안 프로세스는 default 객체들의 핸들을 얻게 된다. 파일 핸들이라든지, 이벤트 핸들 같이 다른 타입의 핸들이 존재하지만 객체 관리자는 오직 그 핸들의 종류를 구별하는 것만 도와주기 때문에 얼마나 다양한 객체 타입들이 다뤄지는 지에 대한 일관성을 유지할 수 있다. 핸들 생성과 분해는 오직 객체 관리자에 의해 중재되기 때문에 어떤 자원도 간과되지 않는다.

윈도우 NT에 의해 노출되는 Executive 객체들의 타입:

### 객체 구조
객체 관리자에 의해 관리되는 각 객체는 헤더와 바디를 가지고 있다. 헤더는 객체 관리자에 의해 사용되는 상태 정보를 가지며, 바디는 object-specific한 데이터와 노출하는 서비스들에 대한 정보를 가진다. 객체 헤더는  `Properties` 로 노출되는 특정한 데이터를 가지는데 그것들은 아래와 같다.  `Object Name` 은 객체를 구별하며, `Object Directory` 는 객체가 속한 카테고리, `Security Descriptors`는 객체에 대한 접근 권한, `Quota Charges`는 객체를 위한 자원 사용 정보, `Open handle count`는 열려있는 핸들의 수, `Open handle list` 객체에 대한 유효한 참조를 가진 프로세스들의 목록, `Reference count`는 객체에 대한 유효한 참조의 수, `Type`은 객체 바디의 구조를 식별하는 객체 등이 있다.

`Type` 객체는 객체의 타입에 대한 유일하고 객체에 의해 제공된 서비스를 구현하는 정적인 메소드 속성들을 포함한다. 객체 관리자에 의해 관리되는 객체들은 적어도 미리 정의된 서비스들의 세트를 제공하여야 한다. 그것들은 아래와 같다. `Close` (객체에 대한 핸들을 닫는다), `Duplicate` (또 다른 프로세스가 해당 객체에 대해 공유하는 접근을 할 수 있도록 하는 또다른 객체에 대한 핸들을 생성), `Query object`(속성들과 요소들에 관한 정보를 모은다), `Query security`(객체의 security descriptor를 얻는다), `Set security`(보안 접근을 바꾼다), 그리고 `Wait`(특정한 이벤트를 통해 하나 이상의 객체들을 동기화 한다). Type 객체들은 또한 특정한 공통된 속성들을 가지는데 이것은 타입 이름, 접근 권한, 동기화 정보 등이다. 같은 타입의 모든 인스턴스들은 같은 Type 객체를 공유하며 type 객체는 오직 한 번 구현된다.

`Object name` 은 색인(index)을 지원하기 위해 즉, 객체에게 기술적인 구별을 주기 위해 사용된다. 객체 관리자는 이미 객체에게 부여된 이름들의 목록을 유지한다. 대부분의 객체 접근이 핸들을 통해 이루어지기 때문에 객체 참조를 위해 이름을 찾는 것이 항상 필요한 것은 아니다. 색인은 오직 객체가 생성되거나 프로세스가 이름으로 참조할 경우에 수행된다. `Object directories` 는 타입 별로 범주화하기 위해 사용된다. 미리 정의된 디렉토리는 `\??`(장치 이름), `\BaseNamedObjects` (뮤텍스, 이벤트, 세마포어, waitable timers, 섹션 객체들), `\Callback` (콜백 함수들), `\Device`, `\Drivers`, `\FileSystem`, `\KnownDlls`, `\Nls` (language tables), `\ObjectTypes` (타입 객체들), `\RPC Controls`(RPC 포트들), `\Security`(보안 서브시스템 객체들) 그리고 `\Window` (윈도윙 서브시스템 객체들)을 포함한다. 객체들은 또한 *Namespace*에 포함된다. 각 유저 세션에는 다른 Namespace가 배정된다. 모든 세션들 사이에 공유되는 객체들은 *GLOBAL* Namespace, 그리고 session-specific 객체들은 특정한 세션 Namespace에 존재한다.

OBJECT_ATTRIBUTES 구조:
```c
typedef struct _OBJECT_ATTRIBUTES {
  ULONG Length;
  HANDLE RootDirectory;
  PUNICODE_STRING ObjectName;
  ULONG Attributes;
  PSECURITY_DESCRIPTOR SecurityDescriptor;
  PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
```
속성 멤버들은 0이 될 수 있으며, 또한 아래 플래그들의 조합이 될 수도 있다.
 OBJ_INHERIT
 OBJ_PERMANANT
 OBJ_EXCLUSIVE
 OBJ_CASE_INSENSITIVE
 OBJ_OPENIF
 OBJ_OPENLINK
 OBJ_KERNEL_HANDLE

## 같이 보기
* 윈도우 NT 아키텍처

## 외부 링크
* [Object Manager Routines (Windows Drivers)](https://web.archive.org/web/20151201151543/https://msdn.microsoft.com/en-us/library/windows/hardware/ff557759(v=vs.85).aspx)
* Channel9 Interview

분류:윈도우 구성 요소
분류:윈도우 NT 아키텍처