I/O 스택 위치

I/O 관리자는 계층화된 드라이버 체인의 각 드라이버에 설정한 모든 IRP에 대한 I/O 스택 위치를 제공합니다. 각 I/O 스택 위치는 IO_STACK_LOCATION 구조로 구성됩니다.

I/O 관리자는 계층화된 드라이버 체인의 각 드라이버에 해당하는 배열 요소를 사용하여 각 IRP에 대한 I/O 스택 위치 배열을 만듭니다. 각 드라이버는 패킷의 스택 위치 중 하나를 소유하고 IoGetCurrentIrpStackLocation 을 호출하여 I/O 작업에 대한 드라이버 관련 정보를 가져옵니다.

이러한 체인의 각 드라이버는 IoGetNextIrpStackLocation을 호출한 다음, 다음으로 낮은 드라이버의 I/O 스택 위치를 설정해야 합니다. 상위 수준 드라이버의 I/O 스택 위치는 드라이버의 IoCompletion 루틴이 정리 작업을 수행할 수 있도록 작업에 대한 컨텍스트를 저장하는 데 사용할 수도 있습니다.

계층화된 드라이버의 처리 IRP 그림에는 두 개의 드라이버, 파일 시스템 드라이버 및 대용량 스토리지 디바이스 드라이버가 표시되기 때문에 원래 IRP의 두 I/O 스택 위치가 표시됩니다. 계층화된 드라이버의 처리 IRP 에서 드라이버 할당 IRP 그림에 생성된 FSD(파일 시스템 드라이버)에 대한 스택 위치가 없습니다. 하위 수준 드라이버에 대해 IRP를 할당하는 상위 수준 드라이버는 다음 하위 드라이버 디바이스 개체의 StackSize 값에 따라 새 IRP에 있어야 하는 I/O 스택 위치 수를 결정합니다.

다음 그림에서는 IRP의 내용을 자세히 보여 줍니다.

irp에서 i/o 스택 위치의 내용을 보여 주는 다이어그램

그림에 표시된 것처럼 IRP의 각 드라이버별 I/O 스택 위치에는 다음과 같은 일반 정보가 포함됩니다.

  • 드라이버가 수행해야 하는 기본 작업을 나타내는 주 함수 코드(IRP_MJ_XXX)입니다.

  • FSD, 상위 수준 SCSI 드라이버 및 모든 PnP 드라이버에서 처리하는 일부 주요 함수 코드의 경우 드라이버가 수행해야 하는 기본 작업의 하위 버전을 나타내는 부 함수 코드(IRP_MN_XXX)입니다.

  • 드라이버가 데이터를 전송할 버퍼의 길이 및 시작 위치와 같은 작업별 인수 집합

  • 요청된 작업에 대한 대상(물리적, 논리적 또는 가상) 디바이스를 나타내는 드라이버에서 만든 디바이스 개체에 대한 포인터입니다.

  • 열려 있는 파일, 디바이스, 디렉터리 또는 볼륨을 나타내는 파일 개체에 대한 포인터입니다.

    파일 시스템 드라이버는 IDP의 I/O 스택 위치를 통해 파일 개체에 액세스합니다. 다른 드라이버는 일반적으로 파일 개체를 무시합니다.

특정 드라이버가 처리하는 IRP 주 및 부 함수 코드 집합은 디바이스 유형별 코드일 수 있습니다. 그러나 가장 낮은 수준의 드라이버 및 중간 드라이버(PnP 함수 및 필터 드라이버 포함)는 일반적으로 다음과 같은 기본 요청 집합을 처리합니다.

  • IRP_MJ_CREATE - 대상 디바이스 개체를 열어 I/O 작업에 사용할 수 있음을 나타냅니다.

  • IRP_MJ_READ - 디바이스에서 데이터 전송

  • IRP_MJ_WRITE - 디바이스로 데이터 전송

  • IRP_MJ_DEVICE_CONTROL - IOCTL(시스템 정의 디바이스 유형별 I/O 제어 코드)에 따라 디바이스를 설정(또는 다시 설정)합니다.

  • IRP_MJ_CLOSE - 대상 디바이스 개체 닫기

  • IRP_MJ_PNP - 디바이스에서 플러그 앤 플레이 작업을 수행합니다. PnP 관리자가 I/O 관리자를 통해 IRP_MJ_PNP 요청을 보냅니다.

  • IRP_MJ_POWER - 디바이스에서 전원 작업을 수행합니다. IRP_MJ_POWER 요청은 I/O 관리자를 통해 전원 관리자에 의해 전송됩니다.

드라이버에서 처리해야 하는 주요 IRP 함수 코드에 대한 자세한 내용은 IRP 주요 함수 코드를 참조하세요.

일반적으로 I/O 관리자는 파일 시스템이 대용량 스토리지 디바이스용 다른 드라이버보다 계층화되어 있기 때문에 I/O 스택 위치가 두 개 이상 있는 IRP를 대용량 스토리지 디바이스 드라이버로 보냅니다. I/O 관리자는 단일 스택 위치의 IRP를 위에 계층화된 다른 드라이버가 없는 드라이버로 보냅니다.

그러나 I/O 관리자는 시스템의 모든 기존 드라이버 체인에 새 드라이버를 추가하도록 지원합니다. 예를 들어 지정된 디스크 파티션에서 데이터를 백업하는 중간 미러 드라이버는 파일 시스템 드라이버와 계층화된 드라이버의 처리 IRP 그림에 표시된 최하위 수준 드라이버와 같은 드라이버 쌍 사이에 삽입될 수 있습니다. 이 새 드라이버가 디바이스 스택에 연결되면 I/O 관리자는 파일 시스템, 미러 및 최하위 수준 드라이버로 보내는 모든 IRP에서 I/O 스택 위치 수를 조정합니다. 계층화된 드라이버 그림에서 처리 IRP의 파일 시스템에 할당된 모든 IRP에는 이러한 새 미러 드라이버에 대한 다른 I/O 스택 위치도 포함됩니다.

기존 체인에 새 드라이버를 추가하기 위한 이러한 지원은 IRP의 I/O 스택 위치에 대한 특정 드라이버의 액세스에 대한 특정 제한을 의미합니다.

  • 계층화된 드라이버 체인의 상위 수준 드라이버는 모든 IRP에서 자체 및 다음 하위 수준 드라이버의 I/O 스택 위치만 안전하게 액세스할 수 있습니다. 이러한 드라이버는 IDP에서 다음 하위 수준 드라이버에 대한 I/O 스택 위치를 설정해야 합니다. 그러나 이러한 상위 수준 드라이버를 디자인할 때 새 드라이버가 드라이버 바로 아래의 기존 체인에 추가될 시기를 예측할 수 없습니다.

    따라서 이후에 추가된 모든 드라이버가 변위된 다음 하위 수준 드라이버와 동일한 IRP 주 함수 코드(IRP_MJ_XXX)를 처리한다고 가정해야 합니다.

  • 계층화된 드라이버 체인의 최저 수준 드라이버는 모든 IRP에서 자체 I/O 스택 위치에만 안전하게 액세스할 수 있습니다. 이러한 드라이버를 디자인할 때 새 드라이버가 디바이스 드라이버 위의 기존 체인에 추가될 시기를 예측할 수 없습니다.

    최저 수준 드라이버를 디자인할 때 드라이버는 지정된 IRP의 원래 원본과 그 위에 계층화된 드라이버가 무엇이든 간에 자체 I/O 스택 위치에 전달된 정보를 사용하여 IRP를 계속 처리할 수 있다고 가정합니다.