NtReadFile 함수(ntifs.h)
NtReadFile 루틴은 열려 있는 파일에서 데이터를 읽습니다.
구문
__kernel_entry NTSYSCALLAPI NTSTATUS NtReadFile(
[in] HANDLE FileHandle,
[in, optional] HANDLE Event,
[in, optional] PIO_APC_ROUTINE ApcRoutine,
[in, optional] PVOID ApcContext,
[out] PIO_STATUS_BLOCK IoStatusBlock,
[out] PVOID Buffer,
[in] ULONG Length,
[in, optional] PLARGE_INTEGER ByteOffset,
[in, optional] PULONG Key
);
매개 변수
[in] FileHandle
파일 개체에 대한 핸들입니다. 이 핸들은 NtCreateFile 또는 NtOpenFile 을 성공적으로 호출하여 생성 됩니다.
[in, optional] Event
필요에 따라 읽기 작업이 완료된 후 신호를 받은 상태로 설정할 이벤트 개체에 대한 핸들입니다. 디바이스 및 중간 드라이버는 이 매개 변수를 NULL로 설정해야 합니다.
[in, optional] ApcRoutine
이 매개 변수는 예약되어 있습니다. 디바이스 및 중간 드라이버는 이 포인터를 NULL로 설정해야 합니다.
[in, optional] ApcContext
이 매개 변수는 예약되어 있습니다. 디바이스 및 중간 드라이버는 이 포인터를 NULL로 설정해야 합니다.
[out] IoStatusBlock
최종 완료 상태 수신하는 IO_STATUS_BLOCK 구조체 및 요청된 읽기 작업에 대한 정보를 가리키는 포인터입니다. 정보 멤버는 파일에서 실제로 읽은 바이트 수를 받습니다.
[out] Buffer
파일에서 읽은 데이터를 수신하는 호출자가 할당한 버퍼에 대한 포인터입니다.
[in] Length
버퍼가 가리키는 버퍼의 크기(바이트)입니다.
[in, optional] ByteOffset
읽기 작업이 시작될 파일의 시작 바이트 오프셋을 지정하는 변수에 대한 포인터입니다. 파일의 끝부분에서 읽기를 시도하면 NtReadFile 에서 오류가 반환됩니다.
NtCreateFile에 대한 호출이 FILE_SYNCHRONOUS_IO_ALERT 또는 FILE_SYNCHRONOUS_IO_NONALERT CreateOptions 플래그 중 하나를 설정하는 경우 I/O 관리자는 현재 파일 위치를 유지합니다. 이 경우 NtReadFile 의 호출자는 명시적 ByteOffset 값 대신 현재 파일 위치 오프셋을 사용할 수 있도록 지정할 수 있습니다. 이 사양은 다음 방법 중 하나를 사용하여 만들 수 있습니다.
- HighPart 멤버가 -1로 설정되고 LowPart 멤버가 시스템 정의 값 FILE_USE_FILE_POINTER_POSITION 설정된 LARGE_INTEGER 값에 대한 포인터를 지정합니다.
- ByteOffset에 대한 NULL 포인터를 전달합니다.
NtReadFile 은 I/O 관리자가 유지 관리하는 현재 파일 위치를 사용하는 경우 읽기 작업을 완료할 때 읽은 바이트 수를 추가하여 현재 파일 위치를 업데이트합니다.
I/O 관리자가 현재 파일 위치를 유지 관리하는 경우에도 호출자는 명시적 ByteOffset 값을 NtReadFile에 전달하여 이 위치를 다시 설정할 수 있습니다. 이렇게 하면 현재 파일 위치가 해당 ByteOffset 값으로 자동으로 변경되고 읽기 작업이 수행된 다음 실제로 읽은 바이트 수에 따라 위치가 업데이트됩니다. 이 기술은 호출자에게 원자성 검색 및 읽기 서비스를 제공합니다.
[in, optional] Key
디바이스 및 중간 드라이버는 이 포인터를 NULL로 설정해야 합니다.
반환 값
NtReadFile 은 STATUS_SUCCESS 또는 적절한 NTSTATUS 오류 코드를 반환합니다.
설명
NtReadFile의 호출자는 DesiredAccess 매개 변수에 설정된 FILE_READ_DATA 또는 GENERIC_READ 값을 사용하여 NtCreateFile을 이미 호출해야 합니다.
NtCreateFile에 대한 이전 호출에서 CreateOptions 매개 변수의 FILE_NO_INTERMEDIATE_BUFFERING 플래그를 NtCreateFile로 설정하는 경우 Length 및 ByteOffset 매개 변수는 섹터 크기의 배수여야 합니다.
NtReadFile 은 지정된 ByteOffset 또는 현재 파일 위치에서 지정된 버퍼로 읽기 시작합니다. 다음 조건 중 하나에서 읽기 작업을 종료합니다.
- Length 매개 변수에 지정된 바이트 수를 읽었기 때문에 버퍼가 가득 찼습니다. 따라서 오버플로 없이는 더 이상 데이터를 버퍼에 배치할 수 없습니다.
- 읽기 작업 중에 파일의 끝에 도달하므로 버퍼로 전송할 파일에 더 이상 데이터가 없습니다.
호출자가 DesiredAccess에서 SYNCHRONIZE 플래그가 설정된 파일을 연 경우 호출 스레드는 파일 핸들 FileHandle을 대기하여 읽기 작업의 완료와 동기화할 수 있습니다. 핸들에서 실행된 I/O 작업이 완료될 때마다 핸들에 신호가 전송됩니다. 그러나 호출자는 동기 파일 액세스(FILE_SYNCHRONOUS_IO_NONALERT 또는 FILE_SYNCHRONOUS_IO_ALERT)를 위해 열린 핸들을 기다리면 안 됩니다. 이 경우 NtReadFile 은 호출자를 대신하여 대기하고 읽기 작업이 완료될 때까지 반환되지 않습니다. 호출자는 다음 세 가지 조건이 모두 충족되는 경우에만 파일 핸들을 안전하게 기다릴 수 있습니다.
- 비동기 액세스를 위해 핸들이 열렸습니다(즉, FILE_SYNCHRONOUS_IO_XXX 플래그가 지정되지 않음).
- 핸들은 한 번에 하나의 I/O 작업에만 사용됩니다.
- NtReadFile은 STATUS_PENDING 반환했습니다.
다음 조건이 있는 경우 드라이버는 시스템 프로세스의 컨텍스트에서 NtReadFile 을 호출해야 합니다.
- 드라이버는 NtReadFile에 전달하는 파일 핸들을 만들었습니다.
- NtReadFile 은 드라이버가 만든 이벤트를 통해 드라이버에 I/O 완료를 알립니다.
- NtReadFile 은 드라이버가 NtReadFile에 전달하는 APC 콜백 루틴을 통해 드라이버에 I/O 완료를 알립니다.
파일 및 이벤트 핸들은 핸들이 만들어지는 프로세스 컨텍스트에서만 유효합니다. 따라서 보안 허점을 방지하려면 드라이버가 있는 프로세스의 컨텍스트가 아닌 시스템 프로세스의 컨텍스트에서 NtReadFile 에 전달하는 파일 또는 이벤트 핸들을 만들어야 합니다.
마찬가지로 APC 는 I/O 요청을 발급하는 스레드의 컨텍스트에서 항상 발생하므로 APC를 통해 드라이버에 I/O 완료를 알립니다. 드라이버가 시스템 1이 아닌 프로세스의 컨텍스트에서 NtReadFile 을 호출하는 경우 APC가 무기한 지연되거나 전혀 실행되지 않을 수 있습니다.
파일 작업에 대한 자세한 내용은 드라이버에서 파일 사용을 참조하세요.
NtReadFile의 호출자는 IRQL = PASSIVE_LEVEL 및 특수 커널 APC를 사용하도록 설정된 상태에서 실행되어야 합니다.
이 함수에 대한 호출이 사용자 모드에서 발생하는 경우 "ZwReadFile" 대신 "NtReadFile"이라는 이름을 사용해야 합니다.
커널 모드 드라이버에서 호출하는 경우 Windows 네이티브 시스템 서비스 루틴의 NtXxx 및 ZwXxx 버전은 입력 매개 변수를 처리하고 해석하는 방식으로 다르게 동작할 수 있습니다. 루틴의 NtXxx 버전과 ZwXxx 버전 간의 관계에 대한 자세한 내용은 네이티브 시스템 서비스 루틴의 Nt 및 Zw 버전 사용을 참조하세요.
요구 사항
요구 사항 | 값 |
---|---|
지원되는 최소 클라이언트 | Windows 2000 |
대상 플랫폼 | 유니버설 |
헤더 | ntifs.h(Wdm.h, Ntddk.h, Ntifs.h 포함) |
라이브러리 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | PASSIVE_LEVEL(설명 섹션 참조) |
DDI 규정 준수 규칙 | BufAfterReqCompletedIntIoctlA, BufAfterReqCompletedIoctlA, BufAfterReqCompletedReadA, BufAfterReqCompletedWriteA, HwStorPortProhibitedDDIs, PowerIrpDDis |