디바이스 개체 초기화

IoCreateDevice가 반환되면 호출자에게 디바이스 확장에 대한 포인터가 포함된 DeviceObject에 대한 포인터를 제공하면 드라이버는 해당 물리적, 논리적 및/또는 가상 디바이스에 대해 디바이스 개체의 특정 필드를 설정해야 합니다.

IoCreateDevice 는 새로 만든 디바이스 개체의 StackSize 필드를 하나로 설정합니다. 최하위 수준의 드라이버는 이 필드를 무시할 수 있습니다. 상위 수준 드라이버가 IoAttachDeviceToDeviceStack 을 호출하여 다음 하위 드라이버에 자신을 연결하면 해당 루틴은 디바이스 개체의 StackSize 필드를 다음 하위 드라이버의 디바이스 개체와 1을 더한 값으로 자동으로 설정합니다. 그러나 일부 디바이스 유형의 경우 상위 수준 드라이버는 디바이스별 설명서에 설명된 대로 StackSize 필드를 더 큰 값으로 설정해야 할 수 있습니다. 스택 크기를 설정하면 상위 수준 드라이버로 전송된 IRP에 드라이버별 I/O 스택 위치와 체인의 모든 하위 수준 드라이버에 대한 올바른 I/O 스택 위치 수가 포함됩니다.

IoCreateDevice는 직접 I/O에 사용되는 버퍼가 올바르게 정렬되도록 새로 만든 디바이스 개체의 AlignmentRequirement 필드를 프로세서의 데이터 캐시 줄 크기에서 1을 뺀 값으로 설정합니다. IoCreateDevice가 반환된 후 가장 낮은 수준의 물리적 디바이스 드라이버는 다음을 수행해야 합니다.

  1. 디바이스의 맞춤 요구 사항에서 하나를 뺍니다.

  2. 1단계의 결과를 디바이스 개체의 AlignmentRequirement의 현재 값과 비교합니다.

  3. 디바이스의 맞춤 요구 사항이 더 큰 경우 AlignmentRequirement 를 1단계의 결과로 설정합니다. 그렇지 않으면 IoCreateDevice에서 설정한 AlignmentRequirement 값을 그대로 둡니다.

IoGetDeviceObjectPointer를 호출하여 상위 수준 드라이버가 다른 드라이버에 연결되면 상위 수준 드라이버는 새로 만든 디바이스 개체의 AlignmentRequirement 필드를 다음 하위 수준 드라이버의 디바이스 개체로 설정해야 합니다. 일반적으로 상위 수준 드라이버는 이 값을 변경하지 않아야 합니다. 상위 수준 드라이버가 IoAttachDevice 또는 IoAttachDeviceToDeviceStack을 호출하는 경우 해당 루틴은 디바이스 개체의 AlignmentRequirement 필드를 하위 수준 드라이버의 디바이스 개체에 대해 자동으로 설정합니다.

IoGetDeviceObjectPointer는 하위 수준 드라이버의 디바이스 개체와 연결된 파일 개체 모두에 대한 포인터를 반환합니다. FSD(또는 다른 최상위 드라이버)만 반환된 파일 개체 포인터를 사용할 수 있습니다. IoGetDeviceObjectPointer를 호출하는 중간 드라이버는 드라이버가 언로드될 때 ObDereferenceObject를 호출하여 역참조할 수 있도록 이 파일 개체 포인터를 저장해야 합니다.

FSD가 낮은 드라이버의 디바이스 개체를 나타내는 파일 개체가 포함된 볼륨을 탑재한 후에는 IoAttachDevice 또는 IoAttachDeviceToDeviceStack을 호출하여 중간 드라이버가 파일 시스템과 하위 드라이버 간에 자신을 연결할 수 없습니다. 또한 FSD는 탑재가 발생할 때 기본 볼륨 하드웨어의 기하 도형에 따라 디바이스 개체의 SectorSize 멤버를 설정할 수 있습니다. 자세한 내용은 DEVICE_OBJECT 참조하세요.

또한 중간 또는 최저 수준 드라이버는 DO_DIRECT_IO 사용하거나 만드는 모든 디바이스 개체의 DO_BUFFERED_IO 사용하여 디바이스 개체의 Flags 에 비트를 설정합니다. 드라이버 작성기에서 관련된 추가 작업이 더 나은 드라이버 성능에 결실을 맺을 것으로 판단하는 경우 논리 또는 가상 디바이스의 최고 수준 드라이버는 버퍼링된 I/O 또는 직접 I/O에 대한 플래그 설정을 방지할 수 있습니다. 중간 드라이버는 다음으로 낮은 드라이버의 디바이스 개체와 일치하도록 디바이스 개체의 Flags 필드를 설정해야 합니다.

DO_DIRECT_IO 또는 DO_BUFFERED_IO 사용하여 디바이스 개체 플래그 필드를 설정하면 I/O 관리자가 이후에 드라이버에 전송된 모든 데이터 전송 요청에서 사용자 버퍼에 대한 액세스를 전달하는 방법이 결정됩니다.

그런 다음, 드라이버는 디바이스 개체에서 다른 디바이스 종속 값을 설정할 수 있습니다. 예를 들어 이동식 미디어 디바이스에 대한 비 WDM 드라이버는 I/O 작업 중에 미디어의 변경을 감지(또는 의심하는 경우)DO_VERIFY_VOLUME 가진 디바이스 개체의 Flags 멤버를 OR해야 합니다. 자세한 내용은 이동식 미디어 지원을 참조하세요. inrush 전원이 필요한 디바이스의 드라이버는 또는 DO_POWER_INRUSH 있는 Flags 멤버여야 하며 시스템 페이징 경로에 없는 디바이스의 드라이버는 또는 DO_POWER_PAGABLE 있는 Flags 멤버여야 합니다. 함수 및 필터 드라이버는 DO_DEVICE_INITIALIZING 플래그를 지워야 합니다.

디바이스 개체를 초기화한 후 드라이버는 커널 정의 개체 및 디바이스 확장에 스토리지를 제공한 기타 시스템 정의 데이터 구조를 초기화할 수도 있습니다. 드라이버가 이러한 작업을 수행하는 정확한 시기는 디바이스, 개체 유형 및/또는 데이터의 특성에 따라 달라집니다. 일반적으로 PnP 시작 및 중지 요청을 통해 유지할 수 있는 개체 또는 데이터 구조는 AddDevice 루틴에서 초기화할 수 있습니다. PnP IRP_MN_START_DEVICE 요청과 함께 제공되는 리소스 정보가 필요하거나 디바이스가 중지 및/또는 다시 시작될 때 변경이 필요할 수 있는 리소스 정보는 드라이버가 IRP_MN_START_DEVICE 요청을 처리할 때 초기화되어야 합니다. AddDevice 루틴에 대한 자세한 내용은 AddDevice 루틴 작성을 참조하세요.