서비스 제어 관리자

**서비스 제어 관리자** (**SCM : Service Control Manager**)는 윈도우 서비스 프로세스와 시작과 정지 및 상호작용 하는 윈도우 NT 하의 특별한 시스템 프로세스이다. `%SystemRoot%\System32\services.exe` 실행 파일에 위치한다. 서비스 프로세스들은 잘 정의된 API를 통해 SCM과 상호작용하며 이 API들은 또한 MMC snap-in `Services.msc` 와 명령 줄 서비스 제어 도구인 `sc.exe` 같은 윈도우 서비스 관리 도구들 내부적으로도 상호작용을 위해 사용된다.

## 구현
SCM 실행 파일인 `Services.exe`는 윈도우 콘솔 프로그램으로서 실행되며 시스템 시작 초기에 Wininit 프로세스에 의해 실행된다. 이것의 main 함수인 `SvcCtrlMain()`는 자동 시작으로 설정된 모든 서비스들을 실행시킨다. 먼저 설치된 서비스들의 내부적인 데이터베이스는 다음의 두 레지스트리 키들을 읽음으로써 초기화된다
* `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ServiceGroupOrder\List`는 서비스 그룹들의 이름과 순서를 포함한다. 각 서비스의 레지스트리 키는 선택적으로 `Group` 값을 갖는데 이것은 서비스나 장치 드라이버의 초기화 순서를 관리한다.
* `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services`는 서비스들과 장치 드라이버들의 실제 데이터베이스를 포함하며 SCM의 내부 데이터베이스로 읽혀진다. SCM은 모든 서비스의 `Group` 값 뿐만 아니라 다음 레지스트리 키에 존재하는 로드 순서 종속성도 읽는다 : `DependOnGroup`, `DependOnService`
다음으로 SCM의 main 함수 `SvcCtrlMain()` 는 함수 `ScGetBootAndSystemDriverState()` 를 호출하는데 이것은 부팅 또는 시스템 시작 시에 시작되었어야 할 장치 드라이버가 성공적으로 로드되었나 그리고 이것들의 실패가 다음 리스트에 저장되었나를 검사한다 : `ScFailedDrivers`. 그 후 명명된 파이프 `\Pipe\Ntsvcs`가 SCM과 특정한 서비스들과 상호작용하는 SCP(서비스 제어 프로세스)들 사이에 원격 프로시저 호출로서 생성된다.

다음으로 이것은 `ScAutoStartServices()` 함수를 호출하는데 이 함수는 자동 시작으로 표시된 모든 서비스들 사이에서 순환하면서 계산된 로드 순서 종속성을 감시한다. 지연된 자동 시작 서비스들에게 그루핑은 의미가 없으며 시스템 시작 이후 단계에 로드된다.

시작되길 원하는 각 서비스들을 위해 SCM은 `ScStartService()` 함수를 호출하는데 이것은 서비스의 프로세스로 실행하는 파일의 이름을 검사하고 서비스에 명시된 계정이 서비스 프로세스가 실행되는 계정과 같은지를 보장한다. `System` 계정으로서 실행되지 않는 모든 서비스들은 LSASS 함수 `[http://msdn.microsoft.com/en-us/library/aa378189(v=vs.85).aspx LogonUserEx()]`를 호출함으로써 로그인 된다. 이 때 LSASS 프로세스는 `HKLM\SECURITY\Policy\Secrets\`에 저장된 "secret" 비밀번호를 찾는데, 이 레지스트리 키는 SCP가 서비스가 초기에 설정되었을 때 `[http://msdn.microsoft.com/en-us/library/ms721818(v=vs.85).aspx LsaStorePrivateData()]` API를 사용해서 저장된다.

다음으로 `ScLogonAndStartImage()` 함수가 서비스 프로세스가 아직 실행되지 않은 모든 서비스들을 위해 호출된다. 서비스 프로세스들은 `[http://msdn.microsoft.com/en-us/library/ms682429(v=vs.85).aspx CreateProcessAsUser()]` API를 통해 대기 상태로서 생성된다. 서비스 프로세스의 실행이 재개되기 전에 명명된 파이프 `\Pipe\Net\NtControlPipeX` (X는 각 서비스 반복 시에 더해지는 숫자이다)가 생성되는데 이것은 SCM과 서비스 프로세스 사이의 통신 채널로서 동작한다. 서비스 프로세스는 `[http://msdn.microsoft.com/en-us/library/ms686324(VS.85).aspx StartServiceCtrlDispatcher()]` 함수를 호출함으로써 파이프와 연결되는데 이후 SCM은 서비스에게 "start" 명령어를 보낸다.

### 지연된 자동 시작 서비스
지연된 자동 시작 서비스는 지연된 시스템 시작 문제를 해결하고 지연되어서는 안되는 중요한 서비스들을 빨리 시작하기 위해 윈도우 비스타에서 추가되었다. 원래 서비스 초기화의 자동 시작 방식은 다른 애플리케이션이나 서비스들에게 중요한 시스템 서비스를 위해 설계되었다. SCM은 모든 비 지연 자동 시작 서비스들을 처리하자 마자 `ScInitDelayStart()` 함수를 호출함으로써 지연된 서비스를 초기화한다. 이 함수는 상응하는 작업 스레드와 연관된 지연된(디폴트로 120초) 작업 항목을 큐에 쌓는다.

### 장치 드라이버
`Type` 레지스트리 값이 `SERVICE_KERNEL_DRIVER` 또는 `SERVICE_FILE_SYSTEM_DRIVER` 인 서비스들은 특별하게 다루어진다: 이것은 장치 드라이버의 경우 `ScStartService()`가 `ScLoadDeviceDriver()` 함수를 호출한다는 것을 의미하며 일반적으로 확장자 `.sys`를 갖는 그리고 `%SystemRoot%\System32\Drivers\` 디렉토리에 위치하는 적절한 드라이버를 로드한다. 이 목적을 위해 `[http://msdn.microsoft.com/en-us/library/ff556539(VS.85).aspx NtLoadDriver]` 시스템 호출이 유발되며 `SeLoadDriverPrivilege`가 SMC의 프로세스에 추가된다.

### 네트워크 드라이버 문자
SCM은 윈도우 서비스와 완전히 관계 없는 추가적인 기능을 제공한다: 이것은 네트워크 드라이브 문자가 생성되거나 삭제되었을 때 윈도우 메시지 `WM_DEVICECHANGE`를 브로드캐스팅 함으로써 GUI 애플리케이션에 알린다.

## 같이 보기
* 윈도우 서비스
* 윈도우 서비스 목록
* 운영 체제 서비스 관리
* svchost.exe

## 각주

분류:윈도우 구성 요소