6-2

/*
 * 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 operation
OVERLAPPED gOverlapped[MAX_REQUESTS];
// Handle to the file of interest.
HANDLE ghFile;
// Need a place to put all this data
char 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, 20C
00401006  |.  53            push    ebx
00401007  |.  56            push    esi
00401008  |.  57            push    edi
00401009  |.  E8 52030000   call    00401360
0040100E  |.  8D4424 14     lea     eax, dword ptr [esp+14]
00401012  |.  68 04010000   push    104                              ; /BufSize = 104 (260.)
00401017  |.  50            push    eax                              ; |Buffer
00401018  |.  FF15 24204000 call    dword ptr [<&KERNEL32.GetWindows>; \GetWindowsDirectoryA
0040101E  |.  BF FC304000   mov     edi, 004030FC                    ;  ASCII "\WINHLP32.EXE"
00401023  |.  83C9 FF       or      ecx, FFFFFFFF
00401026  |.  33C0          xor     eax, eax
00401028  |.  8D5424 14     lea     edx, dword ptr [esp+14]
0040102C  |.  F2:AE         repne   scas byte ptr es:[edi]
0040102E  |.  F7D1          not     ecx
00401030  |.  2BF9          sub     edi, ecx
00401032  |.  50            push    eax                              ; /hTemplateFile => NULL
00401033  |.  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 = OVERLAPPED
0040104B  |.  8BCB          mov     ecx, ebx                         ; |
0040104D  |.  6A 03         push    3                                ; |Mode = OPEN_EXISTING
0040104F  |.  50            push    eax                              ; |pSecurity => NULL
00401050  |.  83E1 03       and     ecx, 3                           ; |
00401053  |.  6A 03         push    3                                ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
00401055  |.  8D4424 28     lea     eax, dword ptr [esp+28]          ; |
00401059  |.  68 00000080   push    80000000                         ; |Access = GENERIC_READ
0040105E  |.  F3:A4         rep     movs byte ptr es:[edi], byte ptr>; |
00401060  |.  50            push    eax                              ; |FileName
00401061  |.  FF15 20204000 call    dword ptr [<&KERNEL32.CreateFile>; \CreateFileA
00401067  |.  83F8 FF       cmp     eax, -1
0040106A  |.  A3 F0314000   mov     dword ptr [4031F0], eax
0040106F  |.  75 20         jnz     short 00401091
00401071  |.  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>]    ; \printf
00401081  |.  83C4 08       add     esp, 8
00401084  |.  83C8 FF       or      eax, FFFFFFFF
00401087  |.  5F            pop     edi
00401088  |.  5E            pop     esi
00401089  |.  5B            pop     ebx
0040108A  |.  81C4 0C020000 add     esp, 20C
00401090  |.  C3            retn
00401091  |>  33FF          xor     edi, edi
00401093  |.  33F6          xor     esi, esi
00401095  |>  68 00020000   /push    200
0040109A  |.  56            |push    esi
0040109B  |.  57            |push    edi
0040109C  |.  E8 2F010000   |call    004011D0
004010A1  |.  83C4 0C       |add     esp, 0C
004010A4  |.  81C6 00400000 |add     esi, 4000
004010AA  |.  47            |inc     edi
004010AB  |.  81FE 00400100 |cmp     esi, 14000
004010B1  |.^ 72 E2         \jb      short 00401095
004010B3  |.  68 DC304000   push    004030DC                         ; /format = "QUEUED!!",LF,""
004010B8  |.  FF15 40204000 call    dword ptr [<&MSVCRTD.printf>]    ; \printf
004010BE  |.  83C4 04       add     esp, 4
004010C1  |.  6A FF         push    -1                               ; /Timeout = INFINITE
004010C3  |.  6A 01         push    1                                ; |WaitForAll = TRUE
004010C5  |.  68 00324000   push    00403200                         ; |pObjects = IoByEvnt.00403200
004010CA  |.  6A 05         push    5                                ; |nObjects = 5
004010CC  |.  FF15 1C204000 call    dword ptr [<&KERNEL32.WaitForMul>; \WaitForMultipleObjects
004010D2  |.  83F8 FF       cmp     eax, -1
004010D5  |.  0F85 89000000 jnz     00401164
004010DB  |.  FF15 18204000 call    dword ptr [<&KERNEL32.GetLastErr>; [GetLastError
004010E1  |.  6A 00         push    0                                ; /Arguments = NULL
004010E3  |.  8D5424 10     lea     edx, dword ptr [esp+10]          ; |
004010E7  |.  6A 00         push    0                                ; |BufSize = 0
004010E9  |.  52            push    edx                              ; |Buffer
004010EA  |.  6A 00         push    0                                ; |LanguageId = 0 (LANG_NEUTRAL)
004010EC  |.  50            push    eax                              ; |MessageId
004010ED  |.  6A 00         push    0                                ; |pSource = NULL
004010EF  |.  68 00110000   push    1100                             ; |Flags = ALLOCATE_BUFFER|FROM_SYSTEM|0
004010F4  |.  FF15 14204000 call    dword ptr [<&KERNEL32.FormatMess>; \FormatMessageA
004010FA  |.  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                              ; |s
00401118  |.  FF15 7C204000 call    dword ptr [<&USER32.wsprintfA>]  ; \wsprintfA
0040111E  |.  8DBC24 300100>lea     edi, dword ptr [esp+130]
00401125  |.  83C9 FF       or      ecx, FFFFFFFF
00401128  |.  33C0          xor     eax, eax
0040112A  |.  83C4 18       add     esp, 18
0040112D  |.  F2:AE         repne   scas byte ptr es:[edi]
0040112F  |.  F7D1          not     ecx
00401131  |.  8D5424 10     lea     edx, dword ptr [esp+10]
00401135  |.  6A 00         push    0                                ; /pOverlapped = NULL
00401137  |.  49            dec     ecx                              ; |
00401138  |.  52            push    edx                              ; |pBytesWritten
00401139  |.  8D8424 200100>lea     eax, dword ptr [esp+120]         ; |
00401140  |.  51            push    ecx                              ; |nBytesToWrite
00401141  |.  50            push    eax                              ; |Buffer
00401142  |.  6A F4         push    -0C                              ; |/DevType = STD_ERROR_HANDLE
00401144  |.  FF15 10204000 call    dword ptr [<&KERNEL32.GetStdHand>; |\GetStdHandle
0040114A  |.  50            push    eax                              ; |hFile
0040114B  |.  FF15 0C204000 call    dword ptr [<&KERNEL32.WriteFile>>; \WriteFile
00401151  |.  68 B80B0000   push    0BB8                             ; /Timeout = 3000. ms
00401156  |.  FF15 08204000 call    dword ptr [<&KERNEL32.Sleep>]    ; \Sleep
0040115C  |.  6A 01         push    1                                ; /status = 1
0040115E  |.  FF15 3C204000 call    dword ptr [<&MSVCRTD.exit>]      ; \exit
00401164  |>  8B1D 04204000 mov     ebx, dword ptr [<&KERNEL32.Close>;  kernel32.CloseHandle
0040116A  |.  55            push    ebp
0040116B  |.  8B2D 00204000 mov     ebp, dword ptr [<&KERNEL32.GetOv>;  kernel32.GetOverlappedResult
00401171  |.  33FF          xor     edi, edi
00401173  |.  BE 303C4000   mov     esi, 00403C30
00401178  |>  A1 F0314000   mov     eax, dword ptr [4031F0]
0040117D  |.  8D4C24 10     lea     ecx, dword ptr [esp+10]
00401181  |.  6A 00         push    0
00401183  |.  8D56 F0       lea     edx, dword ptr [esi-10]
00401186  |.  51            push    ecx
00401187  |.  52            push    edx
00401188  |.  50            push    eax
00401189  |.  FFD5          call    ebp
0040118B  |.  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>]    ; \printf
0040119D  |.  8B16          mov     edx, dword ptr [esi]
0040119F  |.  83C4 10       add     esp, 10
004011A2  |.  52            push    edx
004011A3  |.  FFD3          call    ebx
004011A5  |.  83C6 14       add     esi, 14
004011A8  |.  47            inc     edi
004011A9  |.  81FE 943C4000 cmp     esi, 00403C94
004011AF  |.^ 7C C7         jl      short 00401178
004011B1  |.  A1 F0314000   mov     eax, dword ptr [4031F0]
004011B6  |.  50            push    eax
004011B7  |.  FFD3          call    ebx
004011B9  |.  5D            pop     ebp
004011BA  |.  5F            pop     edi
004011BB  |.  5E            pop     esi
004011BC  |.  33C0          xor     eax, eax
004011BE  |.  5B            pop     ebx
004011BF  |.  81C4 0C020000 add     esp, 20C
004011C5  \.  C3            retn

 ida

 

 

posted @ 2010-07-08 16:26  南守拥  阅读(218)  评论(0编辑  收藏  举报