2.1.ReactOS源码分析ReadFile函数分解
2.1.ReactOS源码分析ReadFile函数分解
ReadFile函数的分析
BOOL WINAPI ReadFile(HANDLE,PVOID,DWORD,PDWORD,LPOVERLAPPED);
ReadFile函数的声明
BOOL STDCALL
ReadFile(IN HANDLE hFile,
IN LPVOID lpBuffer,
IN DWORD nNumberOfBytesToRead,
OUT LPDWORD lpNumberOfBytesRead OPTIONAL,
IN LPOVERLAPPED lpOverlapped OPTIONAL)
{
NTSTATUS Status;
DPRINT("ReadFile(hFile %x)\n", hFile);
if (lpNumberOfBytesRead != NULL)
{
*lpNumberOfBytesRead = 0;
}
if (IsConsoleHandle(hFile))
{
return ReadConsoleA(hFile,
lpBuffer,
nNumberOfBytesToRead,
lpNumberOfBytesRead,
NULL);
}
if (lpOverlapped != NULL)
{
LARGE_INTEGER Offset;
PVOID ApcContext;
Offset.u.LowPart = lpOverlapped->Offset;
Offset.u.HighPart = lpOverlapped->OffsetHigh;
lpOverlapped->Internal = STATUS_PENDING;
ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped);
Status = NtReadFile(hFile,
lpOverlapped->hEvent,
NULL,
ApcContext,
(PIO_STATUS_BLOCK)lpOverlapped,
lpBuffer,
nNumberOfBytesToRead,
&Offset,
NULL);
/* return FALSE in case of failure and pending operations! */
if (!NT_SUCCESS(Status) || Status == STATUS_PENDING)
{
if (Status == STATUS_END_OF_FILE &&
lpNumberOfBytesRead != NULL)
{
*lpNumberOfBytesRead = 0;
}
SetLastErrorByStatus(Status);
return FALSE;
}
if (lpNumberOfBytesRead != NULL)
{
*lpNumberOfBytesRead = lpOverlapped->InternalHigh;
}
}
else
{
IO_STATUS_BLOCK Iosb;
Status = NtReadFile(hFile,
NULL,
NULL,
NULL,
&Iosb,
lpBuffer,
nNumberOfBytesToRead,
NULL,
NULL);
/* wait in case operation is pending */
if (Status == STATUS_PENDING)
{
Status = NtWaitForSingleObject(hFile,
FALSE,
NULL);
if (NT_SUCCESS(Status))
{
Status = Iosb.Status;
}
}
if (Status == STATUS_END_OF_FILE)
{
/* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
check that case either and crashes (only after the operation
completed) */
*lpNumberOfBytesRead = 0;
return TRUE;
}
if (NT_SUCCESS(Status))
{
/* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
check that case either and crashes (only after the operation
completed) */
*lpNumberOfBytesRead = Iosb.Information;
}
else
{
SetLastErrorByStatus(Status);
return FALSE;
}
}
DPRINT("ReadFile() succeeded\n");
return TRUE;
}
ReadFile函数的核心代码
BOOL STDCALL
ReadFile(IN HANDLE hFile,
IN LPVOID lpBuffer,
IN DWORD nNumberOfBytesToRead,
OUT LPDWORD lpNumberOfBytesRead OPTIONAL,
IN LPOVERLAPPED lpOverlapped OPTIONAL)
{
NTSTATUS Status;
// ...
Status = NtReadFile(hFile,
NULL,
NULL,
NULL,
&Iosb,
lpBuffer,
nNumberOfBytesToRead,
NULL,
NULL);
//...
return TRUE;
}
1,ReadFile函数的分析,转变为对函数NtReadFile函数的分析。
NtReadFile函数的分析请看本专栏NtReadFile函数的分析