windows源码ReadFile函数的实现
windows源码ReadFile函数的实现
文章目录
ReadFile
BOOL
WINAPI
ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
)
/*++
Routine Description:
Data can be read from a file using ReadFile.
This API is used to read data from a file. Data is read from the
file from the position indicated by the file pointer. After the
read completes, the file pointer is adjusted by the number of bytes
actually read. A return value of TRUE coupled with a bytes read of
0 indicates that the file pointer was beyond the current end of the
file at the time of the read.
Arguments:
hFile - Supplies an open handle to a file that is to be read. The
file handle must have been created with GENERIC_READ access to
the file.
lpBuffer - Supplies the address of a buffer to receive the data read
from the file.
nNumberOfBytesToRead - Supplies the number of bytes to read from the
file.
lpNumberOfBytesRead - Returns the number of bytes read by this call.
This parameter is always set to 0 before doing any IO or error
checking.
lpOverlapped - Optionally points to an OVERLAPPED structure to be used with the
request. If NULL then the transfer starts at the current file position
and ReadFile will not return until the operation completes.
If the handle hFile was created without specifying FILE_FLAG_OVERLAPPED
the file pointer is moved to the specified offset plus
lpNumberOfBytesRead before ReadFile returns. ReadFile will wait for the
request to complete before returning (it will not return
ERROR_IO_PENDING).
When FILE_FLAG_OVERLAPPED is specified, ReadFile may return
ERROR_IO_PENDING to allow the calling function to continue processing
while the operation completes. The event (or hFile if hEvent is NULL) will
be set to the signalled state upon completion of the request.
When the handle is created with FILE_FLAG_OVERLAPPED and lpOverlapped
is set to NULL, ReadFile will return ERROR_INVALID_PARAMTER because
the file offset is required.
Return Value:
TRUE - The operation was successul.
FALSE - The operation failed. Extended error status is available
using GetLastError.
--*/
{
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
PPEB Peb;
DWORD InputMode;
if ( ARGUMENT_PRESENT(lpNumberOfBytesRead) ) {
*lpNumberOfBytesRead = 0;
}
Peb = NtCurrentPeb();
switch( HandleToUlong(hFile) ) {
case STD_INPUT_HANDLE: hFile = Peb->ProcessParameters->StandardInput;
break;
case STD_OUTPUT_HANDLE: hFile = Peb->ProcessParameters->StandardOutput;
break;
case STD_ERROR_HANDLE: hFile = Peb->ProcessParameters->StandardError;
break;
}
if (CONSOLE_HANDLE(hFile)) {
if (ReadConsoleA(hFile,
lpBuffer,
nNumberOfBytesToRead,
lpNumberOfBytesRead,
lpOverlapped
)
) {
Status = STATUS_SUCCESS;
if (!GetConsoleMode( hFile, &InputMode )) {
InputMode = 0;
}
if (InputMode & ENABLE_PROCESSED_INPUT) {
try {
if (*(PCHAR)lpBuffer == 0x1A) {
*lpNumberOfBytesRead = 0;
}
}
except( EXCEPTION_EXECUTE_HANDLER ) {
Status = GetExceptionCode();
}
}
if (NT_SUCCESS(Status)) {
return TRUE;
}
else {
BaseSetLastNTError(Status);
return FALSE;
}
}
else {
return FALSE;
}
}
if ( ARGUMENT_PRESENT( lpOverlapped ) ) {
LARGE_INTEGER Li;
lpOverlapped->Internal = (DWORD)STATUS_PENDING;
Li.LowPart = lpOverlapped->Offset;
Li.HighPart = lpOverlapped->OffsetHigh;
Status = NtReadFile(
hFile,
lpOverlapped->hEvent,
NULL,
(ULONG_PTR)lpOverlapped->hEvent & 1 ? NULL : lpOverlapped,
(PIO_STATUS_BLOCK)&lpOverlapped->Internal,
lpBuffer,
nNumberOfBytesToRead,
&Li,
NULL
);
if ( NT_SUCCESS(Status) && Status != STATUS_PENDING) {
if ( ARGUMENT_PRESENT(lpNumberOfBytesRead) ) {
try {
*lpNumberOfBytesRead = (DWORD)lpOverlapped->InternalHigh;
}
except(EXCEPTION_EXECUTE_HANDLER) {
*lpNumberOfBytesRead = 0;
}
}
return TRUE;
}
else
if (Status == STATUS_END_OF_FILE) {
if ( ARGUMENT_PRESENT(lpNumberOfBytesRead) ) {
*lpNumberOfBytesRead = 0;
}
BaseSetLastNTError(Status);
return FALSE;
}
else {
BaseSetLastNTError(Status);
return FALSE;
}
}
else
{
Status = NtReadFile(
hFile,
NULL,
NULL,
NULL,
&IoStatusBlock,
lpBuffer,
nNumberOfBytesToRead,
NULL,
NULL
);
if ( Status == STATUS_PENDING) {
// Operation must complete before return & IoStatusBlock destroyed
Status = NtWaitForSingleObject( hFile, FALSE, NULL );
if ( NT_SUCCESS(Status)) {
Status = IoStatusBlock.Status;
}
}
if ( NT_SUCCESS(Status) ) {
*lpNumberOfBytesRead = (DWORD)IoStatusBlock.Information;
return TRUE;
}
else
if (Status == STATUS_END_OF_FILE) {
*lpNumberOfBytesRead = 0;
return TRUE;
}
else {
if ( NT_WARNING(Status) ) {
*lpNumberOfBytesRead = (DWORD)IoStatusBlock.Information;
}
BaseSetLastNTError(Status);
return FALSE;
}
}
}
标签:Status,return,file,windows,ReadFile,lpOverlapped,源码,lpNumberOfBytesRead,hFile
From: https://blog.csdn.net/zhyjhacker/article/details/142427109