다음을 통해 공유


IRP_MJ_WRITE(FS 및 필터 드라이버)

보낸 경우

I/O 관리자 또는 파일 시스템 드라이버가 IRP_MJ_WRITE 요청을 보냅니다. 예를 들어 사용자 모드 애플리케이션이 WriteFile과 같은 Win32 함수를 호출하거나 커널 모드 구성 요소가 ZwWriteFile을 호출할 때 이 요청을 보낼 수 있습니다.

작업: 파일 시스템 드라이버

파일 시스템 드라이버는 파일 개체를 추출하고 디코딩하여 매개 변수 및 부 함수 코드를 결정해야 합니다.

MDL 쓰기 요청의 경우 파일 시스템은 부 함수 코드를 확인하여 요청된 작업을 결정해야 합니다. 다음은 캐시된 파일 I/O에만 사용할 수 있는 유효한 부 함수 코드입니다.

  • IRP_MN_COMPLETE
  • IRP_MN_COMPLETE_MDL
  • IRP_MN_COMPLETE_MDL_DPC
  • IRP_MN_COMPRESSED
  • IRP_MN_DPC
  • IRP_MN_MDL
  • IRP_MN_MDL_DPC
  • IRP_MN_NORMAL

이 IRP를 처리하는 방법에 대한 자세한 내용은 WDK(Windows 드라이버 키트)에 포함된 FASTFAT 샘플을 참조하세요.

작업: 레거시 파일 시스템 필터 드라이버

필터 드라이버는 필요한 처리를 수행해야 하며 필터의 특성에 따라 다음 작업 중 하나를 수행합니다.

  • IRP를 완료하거나 실패하거나
  • IRP를 스택의 다음 하위 드라이버로 전달합니다.

매개 변수

파일 시스템 또는 필터 드라이버는 지정된 IRP에 대해 IoGetCurrentIrpStackLocation을 호출하여 IRP의 자체 스택 위치에 대한 포인터를 가져옵니다. 다음 매개 변수에서 Irp는 IRP가리키고 IrpSp는 IO_STACK_LOCATION 가리킵니다. 드라이버는 IRP 및 IRP 스택 위치의 다음 멤버에 설정된 정보를 사용하여 만들기 요청을 처리할 수 있습니다.

  • DeviceObject 는 대상 디바이스 개체에 대한 포인터입니다.

  • Irp-AssociatedIrp.SystemBuffer>는 deviceObject-Flags>에서 DO_BUFFERED_IO 플래그가 설정된 경우 중간 시스템 버퍼로 사용할 시스템 제공 버퍼를 가리킵니다. 그렇지 않으면 이 멤버가 NULL설정됩니다.

  • Irp-IoStatus>는 요청된 작업에 대한 최종 완료 상태 및 정보를 수신하는 IO_STATUS_BLOCK 구조를 가리킵니다. IRP_MJ_WRITE 요청이 실패하면 파일 시스템의 쓰기 디스패치 루틴은 오류 NTSTATUS 값을 반환하고 Irp-IoStatus.Information>은 정의되지 않으므로 사용하면 안 됩니다.

  • Irp-MdlAddress>는 데이터를 쓸 페이지를 설명하는 MDL(메모리 설명자 목록)의 주소입니다.

  • IrpSp-FileObject>는 DeviceObject연결된 파일 개체를 가리킵니다. IrpSp-FileObject-Flags>>에서 FO_SYNCHRONOUS_IO 플래그가 설정된 경우 동기 I/O를 위해 파일 개체가 열렸습니다.

    IrpSp-FileObject> 매개 변수에는 FILE_OBJECT 구조인 RelatedFileObject 필드에 대한 포인터가 포함되어 있습니다. FILE_OBJECT 구조체의 RelatedFileObject 필드는 IRP_MJ_WRITE 처리하는 동안 유효하지 않으므로 사용하면 안 됩니다.

  • IrpSp-Flags>: SL_FORCE_DIRECT_WRITE 플래그가 설정된 경우 커널 모드 드라이버는 직접 쓰기 차단으로 인해 일반적으로 쓸 수 없는 볼륨 영역에 쓸 수 있습니다. Windows Vista 및 이후 운영 체제에서 보안상의 이유로 직접 쓰기 차단이 구현되었습니다. 이 플래그는 파일 시스템 계층과 스토리지 스택 계층 모두에서 확인됩니다. 직접 쓰기 차단에 대한 자세한 내용은 볼륨 및 디스크에 대한 직접 쓰기 작업 차단을 참조 하세요. SL_FORCE_DIRECT_WRITE 플래그는 Windows Vista 이상 버전의 Windows에서 사용할 수 있습니다.

  • IrpSp-MajorFunction>은 IRP_MJ_WRITE 설정됩니다.

  • IrpSp-MinorFunction>은 요청 중인 작업을 지정하고 다음 값 중 하나를 포함합니다. 부 함수 코드가 지정되지 않은 경우 작업은 표준 쓰기(IRP_MN_NORMAL 동일)입니다.

    MinorFunction 설명
    IRP_MN_NORMAL 쓰기 요청은 표준 쓰기 작업용입니다.
    IRP_MN_DPC 쓰기 요청은 DPC 루틴에서 가져옵니다.
    IRP_MN_MDL Irp-MdlAddress>에서 파일의 캐시된 데이터를 설명하는 MDL을 반환합니다. 호출자는 이 MDL을 사용하여 캐시에 직접 데이터를 씁니다.
    IRP_MN_COMPLETE 그 자체로는 사용되지 않습니다. 만 적어도 IRP_MN_MDL 함께 발생합니다. 설명 부분을 참조하세요.
    IRP_MN_COMPRESSED 쓰기 요청은 압축된 파일에 대한 것입니다.
    IRP_MN_MDL_DPC 쓰기 요청은 DPC 루틴에서 온 것이며 Irp-MdlAddress>에서 파일의 캐시된 데이터를 설명하는 MDL을 반환합니다.
    IRP_MN_COMPLETE_MDL MDL을 사용하여 캐시에 직접 데이터를 쓴 호출자가 MDL 사용을 완료했음을 나타냅니다.
    IRP_MN_COMPLETE_MDL_DPC MDL을 사용하여 캐시에 직접 데이터를 쓴 호출자가 MDL 사용을 완료했음을 나타냅니다. 쓰기 요청은 DPC 루틴에서 가져옵니다.
  • IrpSp-Parameters.Write.ByteOffset>은 쓸 데이터의 파일 내에서 시작 바이트 오프셋을 지정하는 LARGE_INTEGER 변수입니다.

    특정 상황에서 이 매개 변수에는 특수 값이 포함될 수 있습니다. 예를 들어 true인 경우 다음 조건은 명시적 파일 오프셋 값 대신 파일의 현재 끝을 사용해야 했음을 나타냅니다. IrpSp-Parameters.Write.ByteOffset.LowPart> == FILE_WRITE_TO_END_OF_FILE 및 IrpSp-Parameters.Write.ByteOffset.HighPart> == -1

  • IrpSp-Parameters.Write.Key>는 대상 파일의 바이트 범위 잠금과 연결된 키 값입니다.

  • IrpSp-Parameters.Write.Length>는 쓸 데이터의 길이(바이트)입니다. 쓰기 작업이 성공하면 기록된 바이트 수가 Irp-IoStatus>가 가리키는 IO_STATUS_BLOCK 구조체의 정보 멤버에 반환됩니다.

설명

파일 시스템은 파일 끝부분에 기본 파일 스토리지 디바이스의 섹터 크기의 배수까지 쓰기 및 읽기 작업을 반올림합니다. 필터가 사전 읽기 또는 미리 쓰기 작업을 처리하는 경우, 버퍼를 할당하고 교환하는 필터는 할당된 버퍼의 크기를 연결된 디바이스의 섹터 크기의 배수로 반올림해야 합니다. 그렇지 않은 경우 기본 파일 시스템에서 전송되는 데이터의 길이가 버퍼의 할당된 길이를 초과합니다. 버퍼 교환에 대한 자세한 내용은 swapBuffers Minifilter 샘플을 참조 하세요.

다음 글머리 기호는 표준 쓰기와 IRP 기반 MDL 쓰기에 대해 설명합니다.

  • 표준 쓰기를 수행하려면 다음을 수행합니다.

    1. 발급자는 MajorFunction = IRP_MJ_WRITE, MinorFunction = IRP_MN_NORMAL(즉, 0)를 사용하여 IRP를 생성하고 Irp-AssociatedIrp.SystemBuffer>에 쓸 데이터를 제공합니다.
    2. IRP를 파일 시스템으로 보내면 쓸 데이터가 이미 IRP에 있습니다. 따라서 파일 시스템이 IRP 처리를 완료하면 쓰기가 완료됩니다. 예를 들어 캐시된 쓰기를 위해 버퍼에서 캐시로 데이터를 복사합니다.
  • IRP 기반 MDL 쓰기를 수행하려면 다음을 수행합니다.

    1. 발급자에서 MajorFunction = IRP_MJ_WRITE, MinorFunction = IRP_MN_MDL IRP를 생성하지만 데이터 버퍼는 제공하지 않습니다. 이 IRP를 파일 시스템으로 보냅니다.
    2. 파일 시스템은 MDL을 생성하고, IRP에 배치하고, IRP를 완료합니다.
    3. 발급자에서 해당 MDL을 사용하여 데이터를 파일의 캐시에 직접 복사합니다.
    4. 발급자의 캐시에 데이터 복사가 완료되면 MajorFunction = IRP_MJ_WRITE, MinorFunction = (IRP_MN_MDL | 을 사용하여 다른 IRP를 생성합니다. IRP_MN_COMPLETE)을 파일 시스템으로 보냅니다.
    5. 파일 시스템에서 MDL을 해제하고 쓰기 작업이 완료되었습니다.

참고 항목

CcMdlWriteComplete

CcPrepareMdlWrite

FLT_IO_PARAMETER_BLOCK

IO_STACK_LOCATION

IO_STATUS_BLOCK

IoGetCurrentIrpStackLocation

IRP

IRP_MJ_READ

IRP_MJ_WRITE(WDK 커널 참조)

ZwWriteFile