33,311
社区成员
发帖
与我相关
我的任务
分享
192: BOOL
193: WINAPI
194: ReadFile(
195: HANDLE hFile,
196: LPVOID lpBuffer,
197: DWORD nNumberOfBytesToRead,
198: LPDWORD lpNumberOfBytesRead,
199: LPOVERLAPPED lpOverlapped
200: )
201:
202: /*++
203:
204: Routine Description:
205:
206: Data can be read from a file using ReadFile.
207:
208: This API is used to read data from a file. Data is read from the
209: file from the position indicated by the file pointer. After the
210: read completes, the file pointer is adjusted by the number of bytes
211: actually read. A return value of TRUE coupled with a bytes read of
212: 0 indicates that the file pointer was beyond the current end of the
213: file at the time of the read.
214:
215: Arguments:
216:
217: hFile - Supplies an open handle to a file that is to be read. The
218: file handle must have been created with GENERIC_READ access to
219: the file.
220:
221: lpBuffer - Supplies the address of a buffer to receive the data read
222: from the file.
223:
224: nNumberOfBytesToRead - Supplies the number of bytes to read from the
225: file.
226:
227: lpNumberOfBytesRead - Returns the number of bytes read by this call.
228: This parameter is always set to 0 before doing any IO or error
229: checking.
230:
231: lpOverlapped - Optionally points to an OVERLAPPED structure to be used with the
232: request. If NULL then the transfer starts at the current file position
233: and ReadFile will not return until the operation completes.
234:
235: If the handle hFile was created without specifying FILE_FLAG_OVERLAPPED
236: the file pointer is moved to the specified offset plus
237: lpNumberOfBytesRead before ReadFile returns. ReadFile will wait for the
238: request to complete before returning (it will not return
239: ERROR_IO_PENDING).
240:
241: When FILE_FLAG_OVERLAPPED is specified, ReadFile may return
242: ERROR_IO_PENDING to allow the calling function to continue processing
243: while the operation completes. The event (or hFile if hEvent is NULL) will
244: be set to the signalled state upon completion of the request.
245:
246: When the handle is created with FILE_FLAG_OVERLAPPED and lpOverlapped
247: is set to NULL, ReadFile will return ERROR_INVALID_PARAMTER because
248: the file offset is required.
249:
250:
251: Return Value:
252:
253: TRUE - The operation was successul.
254:
255: FALSE - The operation failed. Extended error status is available
256: using GetLastError.
257:
258: --*/
259:
260: {
261: NTSTATUS Status;
262: IO_STATUS_BLOCK IoStatusBlock;
263: PPEB Peb;
264: DWORD InputMode;
265:
266: if ( ARGUMENT_PRESENT(lpNumberOfBytesRead) ) {
267: *lpNumberOfBytesRead = 0;
268: }
269:
270: Peb = NtCurrentPeb();
271:
272: switch( HandleToUlong(hFile) ) {
273: case STD_INPUT_HANDLE: hFile = Peb->ProcessParameters->StandardInput;
274: break;
275: case STD_OUTPUT_HANDLE: hFile = Peb->ProcessParameters->StandardOutput;
276: break;
277: case STD_ERROR_HANDLE: hFile = Peb->ProcessParameters->StandardError;
278: break;
279: }
280:
281: if (CONSOLE_HANDLE(hFile)) {
282: if (ReadConsoleA(hFile,
283: lpBuffer,
284: nNumberOfBytesToRead,
285: lpNumberOfBytesRead,
286: lpOverlapped
287: )
288: ) {
289: Status = STATUS_SUCCESS;
290: if (!GetConsoleMode( hFile, &InputMode )) {
291: InputMode = 0;
292: }
293:
294: if (InputMode & ENABLE_PROCESSED_INPUT) {
295: try {
296: if (*(PCHAR)lpBuffer == 0x1A) {
297: *lpNumberOfBytesRead = 0;
298: }
299: }
300: except( EXCEPTION_EXECUTE_HANDLER ) {
301: Status = GetExceptionCode();
302: }
303: }
304:
305: if (NT_SUCCESS(Status)) {
306: return TRUE;
307: }
308: else {
309: BaseSetLastNTError(Status);
310: return FALSE;
311: }
312: }
313: else {
314: return FALSE;
315: }
316: }
317:
318: if ( ARGUMENT_PRESENT( lpOverlapped ) ) {
319: LARGE_INTEGER Li;
320:
321: lpOverlapped->Internal = (DWORD)STATUS_PENDING;
322: Li.LowPart = lpOverlapped->Offset;
323: Li.HighPart = lpOverlapped->OffsetHigh;
324: Status = NtReadFile(
325: hFile,
326: lpOverlapped->hEvent,
327: NULL,
328: (ULONG_PTR)lpOverlapped->hEvent & 1 ? NULL : lpOverlapped,
329: (PIO_STATUS_BLOCK)&lpOverlapped->Internal,
330: lpBuffer,
331: nNumberOfBytesToRead,
332: &Li,
333: NULL
334: );
335:
336:
337: if ( NT_SUCCESS(Status) && Status != STATUS_PENDING) {
338: if ( ARGUMENT_PRESENT(lpNumberOfBytesRead) ) {
339: try {
340: *lpNumberOfBytesRead = (DWORD)lpOverlapped->InternalHigh;
341: }
342: except(EXCEPTION_EXECUTE_HANDLER) {
343: *lpNumberOfBytesRead = 0;
344: }
345: }
346: return TRUE;
347: }
348: else
349: if (Status == STATUS_END_OF_FILE) {
350: if ( ARGUMENT_PRESENT(lpNumberOfBytesRead) ) {
351: *lpNumberOfBytesRead = 0;
352: }
353: BaseSetLastNTError(Status);
354: return FALSE;
355: }
356: else {
357: BaseSetLastNTError(Status);
358: return FALSE;
359: }
360: }
361: else
362: {
363: Status = NtReadFile(
364: hFile,
365: NULL,
366: NULL,
367: NULL,
368: &IoStatusBlock,
369: lpBuffer,
370: nNumberOfBytesToRead,
371: NULL,
372: NULL
373: );
374:
375: if ( Status == STATUS_PENDING) {
376: // Operation must complete before return & IoStatusBlock destroyed
377: Status = NtWaitForSingleObject( hFile, FALSE, NULL );
378: if ( NT_SUCCESS(Status)) {
379: Status = IoStatusBlock.Status;
380: }
381: }
382:
383: if ( NT_SUCCESS(Status) ) {
384: *lpNumberOfBytesRead = (DWORD)IoStatusBlock.Information;
385: return TRUE;
386: }
387: else
388: if (Status == STATUS_END_OF_FILE) {
389: *lpNumberOfBytesRead = 0;
390: return TRUE;
391: }
392: else {
393: if ( NT_WARNING(Status) ) {
394: *lpNumberOfBytesRead = (DWORD)IoStatusBlock.Information;
395: }
396: BaseSetLastNTError(Status);
397: return FALSE;
398: }
399: }
400: }