6-3

it2022-05-09  25

/* * IoByAPC.c * * Sample code for Multithreading Applications in Win32 * This is from Chapter 6, Listing 6-3 * * Demonstrates how to use APC's (asynchronous * procedure calls) instead of signaled objects * to service multiple outstanding overlapped * operations 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//void CheckOsVersion();int QueueRequest(int nIndex, DWORD dwLocation, DWORD dwAmount);

//// Global variables//

// Need a single event object so we know when all I/O is finishedHANDLE  ghEvent;// 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 nCompletionCount;

/* * I/O Completion routine gets called * when app is alertable (in WaitForSingleObjectEx) * and an overlapped I/O operation has completed. */VOID WINAPI FileIOCompletionRoutine(    DWORD dwErrorCode,  // completion code     DWORD dwNumberOfBytesTransfered,    // number of bytes transferred     LPOVERLAPPED lpOverlapped   // pointer to structure with I/O information     ){    // The event handle is really the user defined data    int nIndex = (int)(lpOverlapped->hEvent);    printf("Read #%d returned %d. %d bytes were read.\n",        nIndex,        dwErrorCode,        dwNumberOfBytesTransfered);

    if (++nCompletionCount == MAX_REQUESTS)        SetEvent(ghEvent);  // Cause the wait to terminate}

int main(){    int i;    char szPath[MAX_PATH];

    CheckOsVersion();

    // Need to know when to stop    MTVERIFY(        ghEvent = CreateEvent(                     NULL,    // No security                     TRUE,    // Manual reset - extremely important!                     FALSE,   // Initially set Event to non-signaled state                     NULL     // No name                    )    );

    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;    }

    // Queue up a few requests    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.    for (;;)    {        DWORD rc;        rc = WaitForSingleObjectEx(ghEvent, INFINITE, TRUE );        if (rc == WAIT_OBJECT_0)            break;        MTVERIFY(rc == WAIT_IO_COMPLETION);    }

    CloseHandle(ghFile);

    return EXIT_SUCCESS;}

/* * Call ReadFileEx to start an overlapped request. * Make sure we handle errors that are recoverable. */int QueueRequest(int nIndex, DWORD dwLocation, DWORD dwAmount){    int i;    BOOL rc;    DWORD err;

    gOverlapped[nIndex].hEvent = (HANDLE)nIndex;    gOverlapped[nIndex].Offset = dwLocation;

    for (i=0; i<MAX_TRY_COUNT; i++)    {        rc = ReadFileEx(            ghFile,            gBuffers[nIndex],            dwAmount,            &gOverlapped[nIndex],            FileIOCompletionRoutine        );

        // Handle success        if (rc)        {            // asynchronous i/o is still in progress             printf("Read #%d queued for overlapped I/O.\n", nIndex);            return TRUE;        }

        err = GetLastError();

        // 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("ReadFileEx 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, "IoByAPC must be run under Windows NT.\n");  exit(EXIT_FAILURE);    }

}

od

 

00401040  /$  81EC 0C020000 sub     esp, 20C00401046  |.  56            push    esi00401047  |.  57            push    edi00401048  |.  E8 E3020000   call    004013300040104D  |.  6A 00         push    0                                ; /EventName = NULL0040104F  |.  6A 00         push    0                                ; |InitiallySignaled = FALSE00401051  |.  6A 01         push    1                                ; |ManualReset = TRUE00401053  |.  6A 00         push    0                                ; |pSecurity = NULL00401055  |.  FF15 28204000 call    dword ptr [<&KERNEL32.CreateEven>; \CreateEventA0040105B  |.  85C0          test    eax, eax0040105D  |.  A3 90314000   mov     dword ptr [403190], eax00401062  |.  0F85 80000000 jnz     004010E800401068  |.  FF15 24204000 call    dword ptr [<&KERNEL32.GetLastErr>; [GetLastError0040106E  |.  6A 00         push    0                                ; /Arguments = NULL00401070  |.  8D4C24 0C     lea     ecx, dword ptr [esp+C]           ; |00401074  |.  6A 00         push    0                                ; |BufSize = 000401076  |.  51            push    ecx                              ; |Buffer00401077  |.  6A 00         push    0                                ; |LanguageId = 0 (LANG_NEUTRAL)00401079  |.  50            push    eax                              ; |MessageId0040107A  |.  6A 00         push    0                                ; |pSource = NULL0040107C  |.  68 00110000   push    1100                             ; |Flags = ALLOCATE_BUFFER|FROM_SYSTEM|000401081  |.  FF15 20204000 call    dword ptr [<&KERNEL32.FormatMess>; \FormatMessageA00401087  |.  8B5424 08     mov     edx, dword ptr [esp+8]0040108B  |.  8D4424 10     lea     eax, dword ptr [esp+10]0040108F  |.  52            push    edx                              ; /<%s>00401090  |.  68 D8304000   push    004030D8                         ; |<%s> = "ghEvent = CreateEvent( NULL, TRUE, FALSE, NULL )"00401095  |.  68 CC304000   push    004030CC                         ; |<%s> = "IoByAPC.c"0040109A  |.  6A 55         push    55                               ; |<%d> = 55 (85.)0040109C  |.  68 88304000   push    00403088                         ; |Format = LF,"The following call failed at line %d in %s:",LF,LF,"    %s",LF,LF,"Reason: %s",LF,""004010A1  |.  50            push    eax                              ; |s004010A2  |.  FF15 7C204000 call    dword ptr [<&USER32.wsprintfA>]  ; \wsprintfA004010A8  |.  83C4 18       add     esp, 18004010AB  |.  8D4C24 0C     lea     ecx, dword ptr [esp+C]004010AF  |.  8D7C24 10     lea     edi, dword ptr [esp+10]004010B3  |.  33C0          xor     eax, eax004010B5  |.  6A 00         push    0                                ; /pOverlapped = NULL004010B7  |.  51            push    ecx                              ; |pBytesWritten004010B8  |.  83C9 FF       or      ecx, FFFFFFFF                    ; |004010BB  |.  8D5424 18     lea     edx, dword ptr [esp+18]          ; |004010BF  |.  F2:AE         repne   scas byte ptr es:[edi]           ; |004010C1  |.  F7D1          not     ecx                              ; |004010C3  |.  49            dec     ecx                              ; |004010C4  |.  51            push    ecx                              ; |nBytesToWrite004010C5  |.  52            push    edx                              ; |Buffer004010C6  |.  6A F4         push    -0C                              ; |/DevType = STD_ERROR_HANDLE004010C8  |.  FF15 1C204000 call    dword ptr [<&KERNEL32.GetStdHand>; |\GetStdHandle004010CE  |.  50            push    eax                              ; |hFile004010CF  |.  FF15 18204000 call    dword ptr [<&KERNEL32.WriteFile>>; \WriteFile004010D5  |.  68 B80B0000   push    0BB8                             ; /Timeout = 3000. ms004010DA  |.  FF15 14204000 call    dword ptr [<&KERNEL32.Sleep>]    ; \Sleep004010E0  |.  6A 01         push    1                                ; /status = 1004010E2  |.  FF15 40204000 call    dword ptr [<&MSVCRTD.exit>]      ; \exit004010E8  |>  53            push    ebx004010E9  |.  8D8424 140100>lea     eax, dword ptr [esp+114]004010F0  |.  68 04010000   push    104                              ; /BufSize = 104 (260.)004010F5  |.  50            push    eax                              ; |Buffer004010F6  |.  FF15 10204000 call    dword ptr [<&KERNEL32.GetWindows>; \GetWindowsDirectoryA004010FC  |.  BF 78304000   mov     edi, 00403078                    ;  ASCII "\WINHLP32.EXE"00401101  |.  83C9 FF       or      ecx, FFFFFFFF00401104  |.  33C0          xor     eax, eax00401106  |.  8D9424 140100>lea     edx, dword ptr [esp+114]0040110D  |.  F2:AE         repne   scas byte ptr es:[edi]0040110F  |.  F7D1          not     ecx00401111  |.  2BF9          sub     edi, ecx00401113  |.  50            push    eax                              ; /hTemplateFile => NULL00401114  |.  8BF7          mov     esi, edi                         ; |00401116  |.  8BD9          mov     ebx, ecx                         ; |00401118  |.  8BFA          mov     edi, edx                         ; |0040111A  |.  83C9 FF       or      ecx, FFFFFFFF                    ; |0040111D  |.  F2:AE         repne   scas byte ptr es:[edi]           ; |0040111F  |.  8BCB          mov     ecx, ebx                         ; |00401121  |.  4F            dec     edi                              ; |00401122  |.  C1E9 02       shr     ecx, 2                           ; |00401125  |.  F3:A5         rep     movs dword ptr es:[edi], dword p>; |00401127  |.  68 00000040   push    40000000                         ; |Attributes = OVERLAPPED0040112C  |.  8BCB          mov     ecx, ebx                         ; |0040112E  |.  6A 03         push    3                                ; |Mode = OPEN_EXISTING00401130  |.  50            push    eax                              ; |pSecurity => NULL00401131  |.  83E1 03       and     ecx, 3                           ; |00401134  |.  6A 03         push    3                                ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE00401136  |.  8D8424 280100>lea     eax, dword ptr [esp+128]         ; |0040113D  |.  68 00000080   push    80000000                         ; |Access = GENERIC_READ00401142  |.  F3:A4         rep     movs byte ptr es:[edi], byte ptr>; |00401144  |.  50            push    eax                              ; |FileName00401145  |.  FF15 0C204000 call    dword ptr [<&KERNEL32.CreateFile>; \CreateFileA0040114B  |.  83F8 FF       cmp     eax, -10040114E  |.  A3 94314000   mov     dword ptr [403194], eax00401153  |.  5B            pop     ebx00401154  |.  75 22         jnz     short 0040117800401156  |.  8D8C24 100100>lea     ecx, dword ptr [esp+110]0040115D  |.  51            push    ecx                              ; /<%s>0040115E  |.  68 64304000   push    00403064                         ; |format = "Could not open %s",LF,""00401163  |.  FF15 3C204000 call    dword ptr [<&MSVCRTD.printf>]    ; \printf00401169  |.  83C4 08       add     esp, 80040116C  |.  83C8 FF       or      eax, FFFFFFFF0040116F  |.  5F            pop     edi00401170  |.  5E            pop     esi00401171  |.  81C4 0C020000 add     esp, 20C00401177  |.  C3            retn00401178  |>  33FF          xor     edi, edi0040117A  |.  33F6          xor     esi, esi0040117C  |>  68 00020000   /push    20000401181  |.  56            |push    esi00401182  |.  57            |push    edi00401183  |.  E8 E8000000   |call    0040127000401188  |.  83C4 0C       |add     esp, 0C0040118B  |.  81C6 00400000 |add     esi, 400000401191  |.  47            |inc     edi00401192  |.  81FE 00400100 |cmp     esi, 1400000401198  |.^ 72 E2         \jb      short 0040117C0040119A  |.  68 58304000   push    00403058                         ; /format = "QUEUED!!",LF,""0040119F  |.  FF15 3C204000 call    dword ptr [<&MSVCRTD.printf>]    ; \printf004011A5  |.  8B15 90314000 mov     edx, dword ptr [403190]004011AB  |.  8B35 08204000 mov     esi, dword ptr [<&KERNEL32.WaitF>;  kernel32.WaitForSingleObjectEx004011B1  |.  83C4 04       add     esp, 4004011B4  |.  6A 01         push    1                                ; /fAlertable = TRUE004011B6  |.  6A FF         push    -1                               ; |Timeout = INFINITE004011B8  |.  52            push    edx                              ; |hObject => NULL004011B9  |.  FFD6          call    esi                              ; \WaitForSingleObjectEx004011BB  |.  85C0          test    eax, eax004011BD  |.  74 17         je      short 004011D6004011BF  |>  3D C0000000   /cmp     eax, 0C0004011C4  |.  75 28         |jnz     short 004011EE004011C6  |.  A1 90314000   |mov     eax, dword ptr [403190]004011CB  |.  6A 01         |push    1004011CD  |.  6A FF         |push    -1004011CF  |.  50            |push    eax004011D0  |.  FFD6          |call    esi004011D2  |.  85C0          |test    eax, eax004011D4  |.^ 75 E9         \jnz     short 004011BF004011D6  |>  8B0D 94314000 mov     ecx, dword ptr [403194]004011DC  |.  51            push    ecx                              ; /hObject => NULL004011DD  |.  FF15 04204000 call    dword ptr [<&KERNEL32.CloseHandl>; \CloseHandle004011E3  |.  5F            pop     edi004011E4  |.  33C0          xor     eax, eax004011E6  |.  5E            pop     esi004011E7  |.  81C4 0C020000 add     esp, 20C004011ED  |.  C3            retn004011EE  |>  FF15 24204000 call    dword ptr [<&KERNEL32.GetLastErr>; [GetLastError004011F4  |.  6A 00         push    0                                ; /Arguments = NULL004011F6  |.  8D5424 0C     lea     edx, dword ptr [esp+C]           ; |004011FA  |.  6A 00         push    0                                ; |BufSize = 0004011FC  |.  52            push    edx                              ; |Buffer004011FD  |.  6A 00         push    0                                ; |LanguageId = 0 (LANG_NEUTRAL)004011FF  |.  50            push    eax                              ; |MessageId00401200  |.  6A 00         push    0                                ; |pSource = NULL00401202  |.  68 00110000   push    1100                             ; |Flags = ALLOCATE_BUFFER|FROM_SYSTEM|000401207  |.  FF15 20204000 call    dword ptr [<&KERNEL32.FormatMess>; \FormatMessageA0040120D  |.  8B4424 08     mov     eax, dword ptr [esp+8]00401211  |.  8D4C24 10     lea     ecx, dword ptr [esp+10]00401215  |.  50            push    eax                              ; /<%s>00401216  |.  68 3C304000   push    0040303C                         ; |<%s> = "rc == WAIT_IO_COMPLETION"0040121B  |.  68 CC304000   push    004030CC                         ; |<%s> = "IoByAPC.c"00401220  |.  6A 78         push    78                               ; |<%d> = 78 (120.)00401222  |.  68 88304000   push    00403088                         ; |Format = LF,"The following call failed at line %d in %s:",LF,LF,"    %s",LF,LF,"Reason: %s",LF,""00401227  |.  51            push    ecx                              ; |s00401228  |.  FF15 7C204000 call    dword ptr [<&USER32.wsprintfA>]  ; \wsprintfA0040122E  |.  8D7C24 28     lea     edi, dword ptr [esp+28]00401232  |.  83C9 FF       or      ecx, FFFFFFFF00401235  |.  33C0          xor     eax, eax00401237  |.  83C4 18       add     esp, 180040123A  |.  F2:AE         repne   scas byte ptr es:[edi]0040123C  |.  F7D1          not     ecx0040123E  |.  8D5424 0C     lea     edx, dword ptr [esp+C]00401242  |.  6A 00         push    0                                ; /pOverlapped = NULL00401244  |.  49            dec     ecx                              ; |00401245  |.  52            push    edx                              ; |pBytesWritten00401246  |.  8D4424 18     lea     eax, dword ptr [esp+18]          ; |0040124A  |.  51            push    ecx                              ; |nBytesToWrite0040124B  |.  50            push    eax                              ; |Buffer0040124C  |.  6A F4         push    -0C                              ; |/DevType = STD_ERROR_HANDLE0040124E  |.  FF15 1C204000 call    dword ptr [<&KERNEL32.GetStdHand>; |\GetStdHandle00401254  |.  50            push    eax                              ; |hFile00401255  |.  FF15 18204000 call    dword ptr [<&KERNEL32.WriteFile>>; \WriteFile0040125B  |.  68 B80B0000   push    0BB8                             ; /Timeout = 3000. ms00401260  |.  FF15 14204000 call    dword ptr [<&KERNEL32.Sleep>]    ; \Sleep00401266  |.  6A 01         push    1                                ; /status = 100401268  |.  FF15 40204000 call    dword ptr [<&MSVCRTD.exit>]      ; \exit0040126E  |.  90            nop0040126F  |.  90            nop00401270  |$  53            push    ebx00401271  |.  55            push    ebp00401272  |.  56            push    esi00401273  |.  57            push    edi00401274  |.  8B7C24 14     mov     edi, dword ptr [esp+14]00401278  |.  8B4C24 18     mov     ecx, dword ptr [esp+18]0040127C  |.  8B5C24 1C     mov     ebx, dword ptr [esp+1C]00401280  |.  8B2D 2C204000 mov     ebp, dword ptr [<&KERNEL32.ReadF>;  kernel32.ReadFileEx00401286  |.  8D04BF        lea     eax, dword ptr [edi+edi*4]00401289  |.  33F6          xor     esi, esi0040128B  |.  C1E0 02       shl     eax, 20040128E  |.  89B8 B03B4000 mov     dword ptr [eax+403BB0], edi00401294  |.  8988 A83B4000 mov     dword ptr [eax+403BA8], ecx0040129A  |.  8D90 A03B4000 lea     edx, dword ptr [eax+403BA0]004012A0  |.  8BC7          mov     eax, edi004012A2  |.  C1E0 09       shl     eax, 9004012A5  |.  895424 14     mov     dword ptr [esp+14], edx004012A9  |.  8D88 A0314000 lea     ecx, dword ptr [eax+4031A0]004012AF  |.  894C24 18     mov     dword ptr [esp+18], ecx004012B3  |>  8B5424 14     /mov     edx, dword ptr [esp+14]004012B7  |.  8B4424 18     |mov     eax, dword ptr [esp+18]004012BB  |.  8B0D 94314000 |mov     ecx, dword ptr [403194]004012C1  |.  68 00104000   |push    00401000004012C6  |.  52            |push    edx004012C7  |.  53            |push    ebx004012C8  |.  50            |push    eax004012C9  |.  51            |push    ecx004012CA  |.  FFD5          |call    ebp004012CC  |.  85C0          |test    eax, eax004012CE  |.  75 3D         |jnz     short 0040130D004012D0  |.  FF15 24204000 |call    dword ptr [<&KERNEL32.GetLastEr>; [GetLastError004012D6  |.  3D F8060000   |cmp     eax, 6F8004012DB  |.  74 0C         |je      short 004012E9004012DD  |.  3D 18070000   |cmp     eax, 718004012E2  |.  74 05         |je      short 004012E9004012E4  |.  83F8 08       |cmp     eax, 8004012E7  |.  75 0E         |jnz     short 004012F7004012E9  |>  6A 32         |push    32                              ; /Timeout = 50. ms004012EB  |.  FF15 14204000 |call    dword ptr [<&KERNEL32.Sleep>]   ; \Sleep004012F1  |.  46            |inc     esi004012F2  |.  83FE 05       |cmp     esi, 5004012F5  |.^ 7C BC         \jl      short 004012B3004012F7  |>  68 34314000   push    00403134                         ; /format = "ReadFileEx failed.",LF,""004012FC  |.  FF15 3C204000 call    dword ptr [<&MSVCRTD.printf>]    ; \printf00401302  |.  83C4 04       add     esp, 400401305  |.  83C8 FF       or      eax, FFFFFFFF00401308  |.  5F            pop     edi00401309  |.  5E            pop     esi0040130A  |.  5D            pop     ebp0040130B  |.  5B            pop     ebx0040130C  |.  C3            retn0040130D  |>  57            push    edi                              ; /<%d>0040130E  |.  68 0C314000   push    0040310C                         ; |format = "Read #%d queued for overlapped I/O.",LF,""00401313  |.  FF15 3C204000 call    dword ptr [<&MSVCRTD.printf>]    ; \printf00401319  |.  83C4 08       add     esp, 80040131C  |.  B8 01000000   mov     eax, 100401321  |.  5F            pop     edi00401322  |.  5E            pop     esi00401323  |.  5D            pop     ebp00401324  |.  5B            pop     ebx00401325  \.  C3            retn

 

routu

 

00401000   .  8B4424 08     mov     eax, dword ptr [esp+8]00401004   .  8B5424 0C     mov     edx, dword ptr [esp+C]00401008   .  8B4C24 04     mov     ecx, dword ptr [esp+4]0040100C   .  50            push    eax                              ; /<%d>0040100D   .  8B42 10       mov     eax, dword ptr [edx+10]          ; |00401010   .  51            push    ecx                              ; |<%d>00401011   .  50            push    eax                              ; |<%d>00401012   .  68 10304000   push    00403010                         ; |format = "Read #%d returned %d. %d bytes were read.",LF,""00401017   .  FF15 3C204000 call    dword ptr [<&MSVCRTD.printf>]    ; \printf0040101D   .  A1 98314000   mov     eax, dword ptr [403198]00401022   .  83C4 10       add     esp, 1000401025   .  40            inc     eax00401026   .  83F8 05       cmp     eax, 500401029   .  A3 98314000   mov     dword ptr [403198], eax0040102E   .  75 0D         jnz     short 0040103D00401030   .  8B0D 90314000 mov     ecx, dword ptr [403190]00401036   .  51            push    ecx                              ; /hEvent => NULL00401037   .  FF15 00204000 call    dword ptr [<&KERNEL32.SetEvent>] ; \SetEvent0040103D   >  C2 0C00       retn    0C

 

 

ida

 

转载于:https://www.cnblogs.com/nanshouyong326/archive/2010/07/09/1774396.html


最新回复(0)