/* * IoByEvnt.c * * Sample code for Multithreading Applications in Win32 * This is from Chapter 6, Listing 6-2 * * Demonstrates how to use event objects instead of * file handles to signal multiple outstanding * overlapped operation on a file. */
#define WIN32_LEAN_AND_MEAN#include <stdio.h>#include <stdlib.h>#include <windows.h>#include "MtVerify.h"
//// Constants//#define MAX_REQUESTS 5#define READ_SIZE 512#define MAX_TRY_COUNT 5
//// Function prototypes//int QueueRequest(int nIndex, DWORD dwLocation, DWORD dwAmount);void CheckOsVersion();
//// Global variables//
// Need to keep the events in their own array// so we can wait on them.HANDLE ghEvents[MAX_REQUESTS];// Keep track of each individual I/O operationOVERLAPPED gOverlapped[MAX_REQUESTS];// Handle to the file of interest.HANDLE ghFile;// Need a place to put all this datachar gBuffers[MAX_REQUESTS][READ_SIZE];
int main(){ int i; BOOL rc; char szPath[MAX_PATH];
CheckOsVersion();
GetWindowsDirectory(szPath, sizeof(szPath)); strcat(szPath, "http://www.cnblogs.com/nanshouyong326/admin/file://WINHLP32.EXE/"); // Open the file for overlapped reads ghFile = CreateFile( szPath, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ); if (ghFile == INVALID_HANDLE_VALUE) { printf("Could not open %s\n", szPath); return -1; }
for (i=0; i<MAX_REQUESTS; i++) { // Read some bytes every few K QueueRequest(i, i*16384, READ_SIZE); }
printf("QUEUED!!\n");
// Wait for all the operations to complete. MTVERIFY( WaitForMultipleObjects( MAX_REQUESTS, ghEvents, TRUE, INFINITE ) != WAIT_FAILED );
// Describe what just happened. for (i=0; i<MAX_REQUESTS; i++) { DWORD dwNumread;
rc = GetOverlappedResult( ghFile, &gOverlapped[i], &dwNumread, FALSE ); printf("Read #%d returned %d. %d bytes were read.\n", i, rc, dwNumread); CloseHandle(gOverlapped[i].hEvent); }
CloseHandle(ghFile);
return EXIT_SUCCESS;}
/* * Call ReadFile to start an overlapped request. * Make sure we handle errors that are recoverable. * Properly set up the event object for this operation. */int QueueRequest(int nIndex, DWORD dwLocation, DWORD dwAmount){ int i; BOOL rc; DWORD dwNumread; DWORD err;
MTVERIFY( ghEvents[nIndex] = CreateEvent( NULL, // No security TRUE, // Manual reset - extremely important! FALSE, // Initially set Event to non-signaled state NULL // No name ) ); gOverlapped[nIndex].hEvent = ghEvents[nIndex]; gOverlapped[nIndex].Offset = dwLocation;
for (i=0; i<MAX_TRY_COUNT; i++) { rc = ReadFile( ghFile, gBuffers[nIndex], dwAmount, &dwNumread, &gOverlapped[nIndex] );
// Handle success if (rc) { printf("Read #%d completed immediately.\n", nIndex); return TRUE; }
err = GetLastError();
// Handle the error that isn't an error. rc is zero here. if (err == ERROR_IO_PENDING) { // asynchronous i/o is still in progress printf("Read #%d queued for overlapped I/O.\n", nIndex); return TRUE; }
// Handle recoverable error if ( err == ERROR_INVALID_USER_BUFFER || err == ERROR_NOT_ENOUGH_QUOTA || err == ERROR_NOT_ENOUGH_MEMORY ) { Sleep(50); // Wait around and try later continue; }
// Give up on fatal error. break; }
printf("ReadFile failed.\n"); return -1;}
//// Make sure we are running under an operating// system that supports overlapped I/O to files.//void CheckOsVersion(){ OSVERSIONINFO ver; BOOL bResult;
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
bResult = GetVersionEx((LPOSVERSIONINFO) &ver);
if ( (!bResult) || (ver.dwPlatformId != VER_PLATFORM_WIN32_NT) ) { fprintf(stderr, "IoByEvnt must be run under Windows NT.\n"); exit(EXIT_FAILURE); }
}
od\
00401000 /$ 81EC 0C020000 sub esp, 20C00401006 |. 53 push ebx00401007 |. 56 push esi00401008 |. 57 push edi00401009 |. E8 52030000 call 004013600040100E |. 8D4424 14 lea eax, dword ptr [esp+14]00401012 |. 68 04010000 push 104 ; /BufSize = 104 (260.)00401017 |. 50 push eax ; |Buffer00401018 |. FF15 24204000 call dword ptr [<&KERNEL32.GetWindows>; \GetWindowsDirectoryA0040101E |. BF FC304000 mov edi, 004030FC ; ASCII "\WINHLP32.EXE"00401023 |. 83C9 FF or ecx, FFFFFFFF00401026 |. 33C0 xor eax, eax00401028 |. 8D5424 14 lea edx, dword ptr [esp+14]0040102C |. F2:AE repne scas byte ptr es:[edi]0040102E |. F7D1 not ecx00401030 |. 2BF9 sub edi, ecx00401032 |. 50 push eax ; /hTemplateFile => NULL00401033 |. 8BF7 mov esi, edi ; |00401035 |. 8BD9 mov ebx, ecx ; |00401037 |. 8BFA mov edi, edx ; |00401039 |. 83C9 FF or ecx, FFFFFFFF ; |0040103C |. F2:AE repne scas byte ptr es:[edi] ; |0040103E |. 8BCB mov ecx, ebx ; |00401040 |. 4F dec edi ; |00401041 |. C1E9 02 shr ecx, 2 ; |00401044 |. F3:A5 rep movs dword ptr es:[edi], dword p>; |00401046 |. 68 00000040 push 40000000 ; |Attributes = OVERLAPPED0040104B |. 8BCB mov ecx, ebx ; |0040104D |. 6A 03 push 3 ; |Mode = OPEN_EXISTING0040104F |. 50 push eax ; |pSecurity => NULL00401050 |. 83E1 03 and ecx, 3 ; |00401053 |. 6A 03 push 3 ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE00401055 |. 8D4424 28 lea eax, dword ptr [esp+28] ; |00401059 |. 68 00000080 push 80000000 ; |Access = GENERIC_READ0040105E |. F3:A4 rep movs byte ptr es:[edi], byte ptr>; |00401060 |. 50 push eax ; |FileName00401061 |. FF15 20204000 call dword ptr [<&KERNEL32.CreateFile>; \CreateFileA00401067 |. 83F8 FF cmp eax, -10040106A |. A3 F0314000 mov dword ptr [4031F0], eax0040106F |. 75 20 jnz short 0040109100401071 |. 8D4C24 14 lea ecx, dword ptr [esp+14]00401075 |. 51 push ecx ; /<%s>00401076 |. 68 E8304000 push 004030E8 ; |format = "Could not open %s",LF,""0040107B |. FF15 40204000 call dword ptr [<&MSVCRTD.printf>] ; \printf00401081 |. 83C4 08 add esp, 800401084 |. 83C8 FF or eax, FFFFFFFF00401087 |. 5F pop edi00401088 |. 5E pop esi00401089 |. 5B pop ebx0040108A |. 81C4 0C020000 add esp, 20C00401090 |. C3 retn00401091 |> 33FF xor edi, edi00401093 |. 33F6 xor esi, esi00401095 |> 68 00020000 /push 2000040109A |. 56 |push esi0040109B |. 57 |push edi0040109C |. E8 2F010000 |call 004011D0004010A1 |. 83C4 0C |add esp, 0C004010A4 |. 81C6 00400000 |add esi, 4000004010AA |. 47 |inc edi004010AB |. 81FE 00400100 |cmp esi, 14000004010B1 |.^ 72 E2 \jb short 00401095004010B3 |. 68 DC304000 push 004030DC ; /format = "QUEUED!!",LF,""004010B8 |. FF15 40204000 call dword ptr [<&MSVCRTD.printf>] ; \printf004010BE |. 83C4 04 add esp, 4004010C1 |. 6A FF push -1 ; /Timeout = INFINITE004010C3 |. 6A 01 push 1 ; |WaitForAll = TRUE004010C5 |. 68 00324000 push 00403200 ; |pObjects = IoByEvnt.00403200004010CA |. 6A 05 push 5 ; |nObjects = 5004010CC |. FF15 1C204000 call dword ptr [<&KERNEL32.WaitForMul>; \WaitForMultipleObjects004010D2 |. 83F8 FF cmp eax, -1004010D5 |. 0F85 89000000 jnz 00401164004010DB |. FF15 18204000 call dword ptr [<&KERNEL32.GetLastErr>; [GetLastError004010E1 |. 6A 00 push 0 ; /Arguments = NULL004010E3 |. 8D5424 10 lea edx, dword ptr [esp+10] ; |004010E7 |. 6A 00 push 0 ; |BufSize = 0004010E9 |. 52 push edx ; |Buffer004010EA |. 6A 00 push 0 ; |LanguageId = 0 (LANG_NEUTRAL)004010EC |. 50 push eax ; |MessageId004010ED |. 6A 00 push 0 ; |pSource = NULL004010EF |. 68 00110000 push 1100 ; |Flags = ALLOCATE_BUFFER|FROM_SYSTEM|0004010F4 |. FF15 14204000 call dword ptr [<&KERNEL32.FormatMess>; \FormatMessageA004010FA |. 8B4424 0C mov eax, dword ptr [esp+C]004010FE |. 8D8C24 180100>lea ecx, dword ptr [esp+118]00401105 |. 50 push eax ; /<%s>00401106 |. 68 8C304000 push 0040308C ; |<%s> = "WaitForMultipleObjects( MAX_REQUESTS, ghEvents, TRUE, INFINITE ) != WAIT_FAILED"0040110B |. 68 80304000 push 00403080 ; |<%s> = "IoByEvnt.c"00401110 |. 6A 53 push 53 ; |<%d> = 53 (83.)00401112 |. 68 3C304000 push 0040303C ; |Format = LF,"The following call failed at line %d in %s:",LF,LF," %s",LF,LF,"Reason: %s",LF,""00401117 |. 51 push ecx ; |s00401118 |. FF15 7C204000 call dword ptr [<&USER32.wsprintfA>] ; \wsprintfA0040111E |. 8DBC24 300100>lea edi, dword ptr [esp+130]00401125 |. 83C9 FF or ecx, FFFFFFFF00401128 |. 33C0 xor eax, eax0040112A |. 83C4 18 add esp, 180040112D |. F2:AE repne scas byte ptr es:[edi]0040112F |. F7D1 not ecx00401131 |. 8D5424 10 lea edx, dword ptr [esp+10]00401135 |. 6A 00 push 0 ; /pOverlapped = NULL00401137 |. 49 dec ecx ; |00401138 |. 52 push edx ; |pBytesWritten00401139 |. 8D8424 200100>lea eax, dword ptr [esp+120] ; |00401140 |. 51 push ecx ; |nBytesToWrite00401141 |. 50 push eax ; |Buffer00401142 |. 6A F4 push -0C ; |/DevType = STD_ERROR_HANDLE00401144 |. FF15 10204000 call dword ptr [<&KERNEL32.GetStdHand>; |\GetStdHandle0040114A |. 50 push eax ; |hFile0040114B |. FF15 0C204000 call dword ptr [<&KERNEL32.WriteFile>>; \WriteFile00401151 |. 68 B80B0000 push 0BB8 ; /Timeout = 3000. ms00401156 |. FF15 08204000 call dword ptr [<&KERNEL32.Sleep>] ; \Sleep0040115C |. 6A 01 push 1 ; /status = 10040115E |. FF15 3C204000 call dword ptr [<&MSVCRTD.exit>] ; \exit00401164 |> 8B1D 04204000 mov ebx, dword ptr [<&KERNEL32.Close>; kernel32.CloseHandle0040116A |. 55 push ebp0040116B |. 8B2D 00204000 mov ebp, dword ptr [<&KERNEL32.GetOv>; kernel32.GetOverlappedResult00401171 |. 33FF xor edi, edi00401173 |. BE 303C4000 mov esi, 00403C3000401178 |> A1 F0314000 mov eax, dword ptr [4031F0]0040117D |. 8D4C24 10 lea ecx, dword ptr [esp+10]00401181 |. 6A 00 push 000401183 |. 8D56 F0 lea edx, dword ptr [esi-10]00401186 |. 51 push ecx00401187 |. 52 push edx00401188 |. 50 push eax00401189 |. FFD5 call ebp0040118B |. 8B4C24 10 mov ecx, dword ptr [esp+10]0040118F |. 51 push ecx ; /<%d>00401190 |. 50 push eax ; |<%d>00401191 |. 57 push edi ; |<%d>00401192 |. 68 10304000 push 00403010 ; |format = "Read #%d returned %d. %d bytes were read.",LF,""00401197 |. FF15 40204000 call dword ptr [<&MSVCRTD.printf>] ; \printf0040119D |. 8B16 mov edx, dword ptr [esi]0040119F |. 83C4 10 add esp, 10004011A2 |. 52 push edx004011A3 |. FFD3 call ebx004011A5 |. 83C6 14 add esi, 14004011A8 |. 47 inc edi004011A9 |. 81FE 943C4000 cmp esi, 00403C94004011AF |.^ 7C C7 jl short 00401178004011B1 |. A1 F0314000 mov eax, dword ptr [4031F0]004011B6 |. 50 push eax004011B7 |. FFD3 call ebx004011B9 |. 5D pop ebp004011BA |. 5F pop edi004011BB |. 5E pop esi004011BC |. 33C0 xor eax, eax004011BE |. 5B pop ebx004011BF |. 81C4 0C020000 add esp, 20C004011C5 \. C3 retn
ida
转载于:https://www.cnblogs.com/nanshouyong326/archive/2010/07/08/1773820.html
