       

     16 

       ,     ,     
  ! :  ,    
 ,     .  ,  , 
?   ?       !    ifvi goto. 
            ,    
    (structured exception handling, SEH). 
 SEH  ,        
  .      , 
      . 
            SEH 
,    "6      
,     . 
    ,  Microsoft   Win32  SEH,    
  Windows 95  Windows NT     
 .   SEH     . 
        SEH   ,    
 .          
 (exception blocks),      
  SEH   _ ,    
       .     
   (stack frames)    , 
  .   SEH    
   ,   ,  -  
        Win32. 
       ,    -  SEH   
.  ,       ,  
      SEH. 
       SEH      
    SEH.     
   ,  
Microsoft.           
   ,    SEH  . 
       Microsoft Visual C++. 

    517 

    518 _____________________________Windows   


    /\ 
      SEH     C++,    
    ,      
 C++: catch  throw. Microsoft       
Visual C++,    2.0.  Microsoft Visual C++  
  SEH,      
 Windows. 

    SEH  2  :   
(termination handling)    (exception handling). 

      

      ,    ( ) 
    ,        
   .       
 Microsoft Visual C++  : 

    __try { 
    //   
    } 
    finally { 
    //   
    } 

       _try  _finally  2   
.         
    ,    _finally  
     ,     
 .  ,        
return, goto   longjump       . 
   : 

    // 1.     __try 
    __try { 
    // 2.     __try 
    } 
    finally { 
    // 3.     finally 
    } 
    // 4.     finally 


        

       SEH      
    ,  ,   ,  
  SEH       
       . 

    _________________ 16.    519 

           ,  
      ,     
    . 

    Funcenstem 1 

         ,  
  : 

    DWORD Funcensteini (void) { 
    DWORD dwTemp: 
    // 1. -   
    try { 
    // 2.     
    //   ,     
    WaitForSingleObject(g_hSem, INFINITE); 
    -fcdwProtectedData = 5; 
    dwTemp = g_dwProtectedData; 
    i 
    f 
    __finally { 
    // 3,       
    ReleaseSemaphore(g_hSe(n, 1, NULL); 
    ! 
    // 4.  -  
    return(dwTemp): 
    } 

      Funcensteini  try-finally      
.    ,    , 
      dwTemp     
 . 

    Funcensfen2 

     -     ,  : 

    DWORD Funcenstein2 (void) { 
    DWORD dwTemp; 
    // 1. -   
    __try { 
    // 2.     
    //   ,     
    WaltForSingleObject(g_hSem, INFINITE); 
    g_dwProtectedData = 5; 
    dwTemp = g_dwProtectedData; 

    . . . 

    520 _____________________________Windows   


    //    
    return(dwTemp); 
    ! 
    finally { 
    // 3.       
    ReleaseSemaphore(g_hSem, 1, NULL): 
    > 
    // 4.  -  -    
    //       
    dwTemp = 9; 
    return(dwTemp): 
    } 

       try   Funcenstein2   return.  
 ,          
 dwTemp (    5). ,    return, 
     ,       
 .         
:  ,  ,      
  . 
      ,     
  return.  return      
try,  ,        finally,  
  ,   return   try    
  .  Releasesemaphore    (  
Funcenstein2)         
           
   . 
       finally    .  
   finally  ,      
  try.     5    9. 
          finally     
fry?    .   ,  ,   
 return   try.    ,   
  (   5)      
.      ,   
 finally,      (local unwind). , 
  ,     finally  
    try.   , 
 ,      
   finally. 
     ,    ,    
 ,      .   
      -. 
,  MIPS, Alpha  PowerPC     
   ,      try  
   finally.     ,  
    try  ,    
    .     
  _leave,     ,   
 . 
          ,  
    (     ).  
 -     ,     
,    SEH. 

    _________________ 16.    521 

    :       try   
(  Funcensteini),     finally .  
  Microsoft   86    finally  
   try          
       .   , 
     ,   
    ,   Funcenstein2. 

    Funcenstein3 

       : 

    DWORD Funcenstein3 (void) { 
    DWORD dwTemp; 
    // 1. -   
    __try { 
    // 2.     
    //   ,     
    WaitForSingleObject(g_hSem, INFINITE); 
    g_dwProtectedData = 5; 
    dwTemp = g_dwProtectedData; 
    //     finally 
    goto ReturnValue; 
    i 
    finally { 
    // 3.       
    ReleaseSemaphore(g_hSem, 1, NULL); 
    i 
    dwTemp = 9; 
    // 4.  -  
    ReturnValue: 
    return(dwTemp); 
    } 

       try  Funcenstein3  goto,  
    ,     finally. 
     finally  ,    
ReturnValue,      "     try,   
 finally.     5.  ,    
     try  finally,   
          . 

    FuncfurterI 

        ,     
 : 

    DWORD Funcfurter-l (void) { 
    DWORD dwTemp; 

    . . . 

    522 _____________________________Windows   


    // 1. -   
    _ _ '- i           1 
    // 2.     
    //   ,     
    WaitForSingleObject(g_hSeni, INFINITE): 
    dwTemp = Funcinator(g_dwProtectedData); 
    finally { 
    // 3.       
    ReleaseSemaphore(g_hSem, 1, NULL); 
    } 
    // 4.  -  
    return(dwTemp): 
    / 

    ,   Funcinator,    try,  , - 
     .    16- 
Windows           
Application Error ( ).       
.        32-   
try-finally     -      
Funcinator,           
       .   
ReleaseSemaphore   finally   ,   
      -  . 
          ,   
  -    ,   
   ,      setjump'/longjump  
   break  continue. 

     : FuncaDood/eDoo 

    ,   ,     : 

    DWORD FuncaDoodleDoo (void) { 
    DWORD dwTemp = 0; 
    while (dwTemp < 10) { 
    __try { 
    if (dwTemp == 2) 
    continue; 
    if (dwTemp == 3) 
    break; 
    i 
    finally { 
    dwTemp++; 
    } 


    _________________ 16.    523 


    dwTe[iip++; 
    } 
    dwTemp += 10; 
    return(dwTemp); 
    } 

         .  dwTemp  0. 
   try ,        if   
TRUE,         finally,  
dwTemp   1.     finally  
  dwTemp,   2. 
        dwTemp  2,    
continue   try.   ,   
  finally    try,     
    while,  dwTemp      
    !       
,   continue      try, 
    finally.  dwTemp     3, 
      ,      
 continue,      . 
        .       
 if  FALSE,     TRUE.     
    try     finally.  
dwTemp   4.     break,  
   .  ,    finally 
(   ),  . ,    , 
 10   dwTemp,     J 4,      
.          ,   
FuncaDoodleDoo.   continue  break   ,   
   . 
          ,   
   try   ,      
 finally     .  ExitThread  
ExitProcess         -  
  finally. To   ,       - 
,     TerminateThread  TerminateProcess. 
     ( abort),    
 ExitProcess,     finally. He  
 -     ,      
   ExitThread  ExitProcess. 

    Funcenstein4 

         . 

    DWORD Funcenstein4 (void) { 
    DWORD dwTemp; 
    // 1. -   
    __try { 
    // 2.     
    //   ,     
    WaitForSingleObject(g_hSem, INFINITE); 

    . . . 


    524 ______________________________Windows   


    g_dwProtectedData = 5; 
    dwTemp = g_dwProtectedData; 
    //    
    return(dwTemp); 
    i 
    __finally { 
    // 3       
    ReleaseSemaphore(g_hSem, 1, NULL); 
    return(103); 
    i           ^-- -   
    ( 
    // 4.  -  -   
    //    
    dwTemp = 9: 
    return(dwTe[np); 
    } 

     try  Funcenstein4     dwTemp (5) 
,  Funcenstein4.       
Funcenstein2,      try  
 ,       
,  .      finally. 
,    Funcenstein2     finally  return. 
:   Funcenstein4  5  103? : 103,    
return   finally     103     
,     5.    finally  
   (103)  ,  Funcenstein4. 
    ,  ,     
   try,      ,  
     try.     
,       try  
.        return, continue, break, goto 
(  )    try,     finally.   
     (    
 try  ),    (   
   ).        . 

    Funcarama ? 

              
 .    ,    
    .   ,  
     : 

    BOOL Funcaramal (void) { 
    HANDLE hFile = INVALID_HANDLE_VALUE; 
    LPVOID IpBuf = NULL; 
    DWORD dwNumBytesRead; 
    BOOL fOk; 
    hFile = CreateFileC'SOMEDATA.DAT", GENERIC_READ, 
    FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 


    __________________ 16.    525 


    if (hFile == INVALID_HANDLE_VALUE) { 
    return(FALSE); 
    } 
    IpBuf = VirtualAlloc(NULL, 1024, MEM_COMMIT, PAGE_READWRITE); 
    if (IpBuf == NULL) < 
    CloseHandle(hFile); 
    return(FALSE); 
    1 
    fOk = ReadFile(hFile, IpBuf, 1024, &dwNumBytesRead, NULL); 
    if (!f0k :; (dwNumBytesRead ==0)) { 
    VirtualFreedpBuf, MEM_RELEASE : MEM_DECOMMIT); 
    CloseHandle(hFile); 
    return(FALSE); 
    f 
    // -    
    //    
    VirtualFreedpBuf, MEM_RELEASE : MEM_DECOMMIT); 
    CloseHandle(hFile); 
    return(TRUE); 
    } 

        Funcaramal    ,  
  ,   . 

    Funcarama2 

    ,   Funcaramal ,    : 

    BOOL Funcarama2 (void) { 
    HANDLE hFile = INVALID_HANDLE_VALUE: 
    LPVOID IpBuf = NULL; 
    DWORD dwNumBytesRead; 
    BOOL fOk, fSuccess = FALSE; 
    hFile = CreateFileC'SOMEDATA.DAT", GENERIC_READ, 
    FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 
    if (hFile != INVALID_HANDLE_VALUE) { 
    IpBuf = VirtualAlloc(NULL, 1024, MEM_COMMIT, PAGE_READWRITE): 
    if (IpBuf != NULL) { 
    fOk = ReadFile(hFile, IpBuf, 1024, &dwNumBytesRead, NULL); 
    if (fOk && (dwNumBytesRead != 0)) { 
    // -    
    fSuccess = TRUE; 
    } 
    VirtualFreedpBuf, MEM_RELEASE ; MEM_DECOMMIT); 
    } 

    . . . 

    526 _____________________________Windows   


    CloseHandle(hFile); 
    return(fSuccess); 
    } 

    Vuncarama.2   ,  -     
.  ,        
   ;        
            
   5 ! 

    FuncaramaS 

    -     (Funcaramal),  
  : 

    BOOL FuncaramaS (void) { 
    HANDLE hFile = INVALID_HANDLE_VALUE; 
    LPVOID IpBuf = NULL; 
    __try { 
    DWORD dwNumBytesRead; 
    BOOL fOk; 
    hFile = CreateFileC'SOMEDATA.DAT", GENERIC_READ, 
    FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 
    if (hFile == INVALID_HANDLE_VALUE) { 
    return(FALSE); 
    }   """' 
    IpBuf = VirtualAlloc(NULL, 1024, MEM_COMMIT, PAGE_READWRITE); 
    if (IpBuf == NULL) { 
    return(FALSE); 
    } 
    fOk = ReadFile(hFile, IpBuf, 1024, &dwNumBytesRead, NULL); 
    if (!f0k ;: (dwNumBytesRead != 1024)) { 
    return(FALSE): 
    // -    
    finally { 
    //    
    if (IpBuf != NULL) 
    VirtualFreedpBuf, MEM_RELEASE : MEM_DECOMMIT); 
    if (hFile != INVALID_HANDLE_VALUE) 
    CloseHandle(hFile); 
    } 
    //  -  
    return(TRUE); 
    } 

    _________________ 16.    527 


        ,   ,  , 
       finally.    -   
,    -      finally 
           
     . 

    Funcarama4:   

       Funcarama3    .   : 
    return   try. 
       , Microsoft      
   C++: _leave.    (Funcarama4),   
   : 

    BOOL Funcarama4 (void) { 
    HANDLE hFile = INVALID_HANDLE_VALUE; 
    LPVOID IpBuf = NULL; 
    // ,      
    BOOL fFunctionOk = FALSE; 
    __try { 
    DWORD dwNumBytesRead; 
    BOOL fOk; 
    hFile = CreateFile("SOMEDATA.DAT", GENERIC_READ, 
    FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL): 
    if (hFile == INVALID_HANDLE_VALUE) < 
    leave; 
    IpBuf = VirtualAlloc(NULL, 1024, MEM_COMMIT, PAGE_READWRITE); 
    if (IpBuf == NULL) { 
    leave; 
    i 
    fOk = ReadFile(hFile, IpBuf, 1024, &dwNumBytesRead, NULL); 
    if (!f0k ;; (dwNumBytesRead == 0)) { __leave; 
    // -    
    //    
    fFunctionOk = TRUE; 
    } 
    finally { 
    //    
    if (IpBuf != NULL) 
    VirtualFreedpBuf, MEM_RELEASE ; MEM_DECOMMIT): 

    . . . 


    528 _____________________________Windows   


    if (hFile != INVALID_HANDLE_VALUE) 
    CloseHandle(hFile): 
    } 
    //  -  
    return(fFunctionOk); 
    } 

      _leave   try      . 
          try. 
     ,      try    
 finally   . ,   
   fFunctionOk,    : 
   . 
     ,     , 
         
 try.    finally  ,    , 
   ,      .  
   ,  ,  
     .  finally  
     ,    . 

        finally 

            2 ,   
  finally. 
          try   finally, 
            try (goto, 
longjump, continue, break, return  . .),    
  finally. 
         (global unwind)    
 .  Funcfurterl.   try    
Funcinator.       Funcinator   
   finally  Funcfurterl.     
        . 
        finally     
   ,   .  ,  
     finally,   ' AbnormalTermination: 

    BOOL AbnormalTermination(VOID); 

          finally,    , 
,       try,    
 finally.  ,       
try  finally, AbnormalTermination  FALSE.     
    -  ,   
goto, return, break  continue,  -  ,  
   ,    AbnormalTermination  TRUE.  
   TRUE, ,     finally  
   ,  . 
    1.   ,  .   
         .  
    (    /Oi). 
  ,       
 .         
.  AbnormalTermination    ,   
   . 

    _________________ 16.    529 


    Funcfurter2 

          
Abnormal

    Termination: 
    DWORD Funcfurter2 (void) { 
    DWORD dwTemp; 
    // 1. -   
    __try { 
    // 2.     
    //   ,     
    WaitForSingleObject(g_hSem, INFINITE); 
    dwTemp = Funcinator(g_dwProtectedData); 
    .finally { 
    // 3.       
    ReleaseSemaphore(g_hSem, 1, NULL); 
    if (!AbnormalTermination()) { 
    //   try    -  
    //    finally   
    } else { 
    
    // -  , ,     try 
    //  ,      
    // ,  finally  -  
    //  
    
    //     try   goto,   
    //  ,    
    
    // 4.  -  
    } 

      ,    .   , 
       ,        
 .      ,    
  .    : 
               ; 
       ; 
       ; 
               
  . 

    530 _____________________________Windows   


    - SEHTerm 

     SEHTerm (SEHTERM.EXE) (.   . 16-1)  
  ,     , 
    .        
    SEHTERM  -,   . 
 Dlg_CountWordsInFile     : 
    1.  . 
    2.   . 
    3.          . 2. 
    4.       . 
    5.     . 
          : 
    1.   . 
    2.  . 
    3.      (    -1). 
             1-4   
.   , ,    -1  
,      .   
  . 
      SEHTerm,    : 

    . Results of execution 
    (7 opening of tile succeeds; 
    ' 3? Setting tils size succeeds 
    1 Memory allocation succeeds               Ii ! 
    ?.<ecutB  [ 
    ^ Oata read succeeds 
    Execution log; 

      Results Of Execution ( )  , 
     ,    . :  
  ,  ;       ,  
     .  -      
 ,  ,    ,   
 . 
        4 ,   Execute 
().    Dlg_CountWordsInFik   
  1  4.      try.    
-   ,   try   
_leave,       finally,     try. 

    ________________ 16.    531 

       finally   ,   
  hFile  IpvFileData,     
 .   Execution Log ( )   
   SEH Termination Handler Test (  
 SEH)     ,   Dlg_CountWordsInFile. 
         4   .   
   Execute ,    .  
        Execution Log: 

    : Results of execution 
    P Opening of file succeeds 
    ' F getting tile size succeeds                                 : 
     Memory allocation succeeds                   \; -.- ..............................1 
    I Execute |j : 
    P Data read succeeds 
    Execution IOQ: 
    Starting execution 
    : File open: OK 
    4 File size: OK 
    II Memory allocation: OK 
    I File read: OK 
    J Calculating the number of words 
    |il Cleaning up 
    "'': Freeing memory                                               .. 
    Closing file                                                   "y 
    Result: Words in file'37                                     'tt 

      ,    ,  
   .      . 
 : 

    ' 1^ Opening of file succeeds                                  ^ 
    17 Getting file size succeeds                                 : 
    f Memory allocation succeeds                   ?........ ....................rj 
    | Execute j 
    P Date read succeed?                                , j 
    Execution IO.Q: 
    Starting execution 
    File open: OK 
    File size: OK                                                           '..';' 
    Memory allocation: Fail                                     '^ 
    Cleaning up                                                  
    Closing file                                                       'g| 
    Error occurred in function,                                           :t| 

      ,        
.        ,  
    try   finally.   hFile, 
   finally ,   ,     CloseHandle. 
       finally    IpvFileData,  
,     .    IpvFileData  
NULL,     

    532 ______________________________Windows   

         Freeing memory ( )   
Execution Log     . 
     ,   -1,    .    
   Error occurred in function (   ). 
        .     ,   
   .      try 
,       .    
   ,      
finally. ,  , ,    ,    
,     . 

    Results of execution     . 
    " Opening of file succeeds                                  ; 
    17 Getting file size succeeds                                   j 
    : R Memory allocation succeeds                    i..................................,..| 
    | Execute j 
    : p Data read succeeds 
    Execution lofl: 
    Starting execution 
    File open: Fail 
    Cleaning up 
    Error occurred in function. 

          ,   
 . ,       
Execution Log.     ,    
,        SEHTerm. 

    SEHTERM.C                      ^lq1^^H^^l 
    ;;:**;;:*"**""*""""""*"""*"^^^^^^^
    : Copyright  1995-1997,   (Jeffrey Richter)   ^^^^^^^^^^^^ 
    
    tfinclude ". .\CffinHdr, H"              /* .   */            
        "^^^^^^^ 
    ffinclude <windows.h>                                                      
     "'^^^^^^^1 
    ftinclude <windowsx.h>                                                     
    lifl^^^^^^^H 
    ftinclude <tchar.h>                                                        
       '^^^^^^H 
    ttinolude <stdio.h>                                                        
       .'^^^^^^1 
    ffinclude "Resource. H"                                                    
        ||^^^^^^^1 
    
ltl!ltl|ll!/llll/lll!///lll!^/ll!//////!ii////!'i!///^l/"!/i!!!!!^!"'!/:lll  ''^^^^P 
    //     SIMULATION.                   
     '^fl^^^^^B 
    //    ,                     
    - "^ 
    - '"fSSSSSSS^i^iSiit 

    . . . 

    . 16-1.   SEHTerm 


    _________________ 16.    533 


    . 16-1   () 
    
    II   ,      
    //   . 
    ftdefine SIMULATION 
    
    I I Illllilllllllllllllllllllllllllllllllllllllllllfill/.111111/111111111111111111 
    BOOL Dlg_OnInitDialog (HWND hwnd, HWND hwndFocus, LPARAM IParam) { 
    
    //      
    chSETDLGICONS(hwnd, IDI_SEHTERM, IDI_SEHTERM); 
    Button_SetCheck(GetDlgItem(hwnd, IDC_OPENSUCCEEDS), TRUE): 
    Button_SetCheck(GetDlgItem(hwnd, IDC_SIZESUCCEEDS), TRUE); 
    Button_SetCheck(GetDlgItem(hwnd, IDC_MEMSUCCEEDS), TRUE); 
    Button_SetCheck(GetDlgItem(hwnd, IDC_READSUCCEEDS), TRUE); 
    return(TRUE); 
    } 
    11111111111111111111111111111111/llllllilllilllll/llilllllllllllllllll/llllllll 
    LONG Dlg_CountWordsInFile (HWND hwndLog, BOOL fOpenSucceeds, 
    BOOL fFileSizeSucceeds, BOOL fMemSucceeds, BOOL fReadSucceeds) { 
    HANDLE hFile = INVALID_HANDLE_VALUE: 
    DWORD dwFileSize = 0; 
    LPVOID IpvFileData = NULL; 
    BOOL  fFileReadOk = FALSE; 
    LONG  INumWords = -1; 
    DWORD dwLastError; 
    try { 
    
    //    Execution Log 
    ListBox_ResetContent(hwndLog); 
    ListBox_AddString(hwndLog, __TEXT("Start ing execution")); 
    
    //   
    ftifdef SIMULATION 
    hFile = (fOpenSucceeds ? (HANDLE) !INVALID_HANDLE_VALUE : 
    INVALID_HANDLE_VALUE); 
    ffelse 
    hFile = CreateFile(...); 
    ftendif 
    
    if (hFile == INVALID_HANDLE_VALUE) { 
    //     
    ListBox_AddString(hwndLog, __TEXT("   File open: Fail")); 
    leave: 
    } else { 
    ListBox_AddString(hwndLog, __TEXT("   File open: OK")): 
    i 
    / 
    (.'-. . . 


    534 ____________________________Windows   


    . 16-1  () 
    
    II    
    Wifdef SIMULATION 
    dwLastError = fFileSizeSucceeds ? NO_ERROR : !NO_ERROR; 
    ftelse 
    dwFileSize = GetFileSize(hFile); 
    dwLastError = GetLastError(); 
    #endif 
    if (dwLastError != NO_ERROR) { 
    //      
    ListBox_AddString(hwndLog, __TEXT("   File size: Fail")); 
    __leave; 
    } else { 
    ListBox_AddString(hwndLog, __TEXT("   File size: OK")); 
    ( 
    
    //        
    (tifdef SIMULATION 
    IpvFileData = fMemSucceeds ? !NULL : NULL; 
    ftelse 
    IpvFileData = HeapAlloc(GetProcessHeap(), 0, dwFileSize): 
    ffendif 
    if (IpvFileData == NULL) { 
    
    //     
    ListBox_AddString(hwndLog, __TEXT("   Memory allocation: Fail")); 
    __leave; 
    } else { 
    ListBox_AddString(riwndLog, __TEXT("   Memory allocation: OK")); 
    > 
    //     
    ffifdef SIMULATION 
    fReadSucceeds = fReadSucceeds; 
    ffelse 
    fReadSucceeds = ReadFile(hFile, IpvFileData, dwFileSize, NULL, NULL); 
    ttendif 
    if (!fReadSucceeds) { 
    
    //        
    ListBox_AddString(hwndLog, __TEXT("   File read: Fail")); 
    leave; 
    } else { 
    ListBox_AddString(hwndLog, __TEXT("   File read: OK")); 
    fFileReadOk = TRUE; 
    } 
    //     .    
    //     .    

    . . . 

    __________________ 16.    535 


    . 16-1  () 

    /I    INumWords 37. 
    ListBox_AddString(hwndLog, __TEXT("   Calculating the number of words")); 
    INumWords = 37: 
    i // try 
    finally { 
    //   ,    
    ListBox_AddString(hwndLog, __TEXT("   Gleaning up")); 
    //    
    if (IpvFileData != NULL) { 
    ListBox_AddString(hwndLog, __TEXT("   Freeing memory")); 
    ffifndef SIMULATION 
    HeapFree(GetProcessHeap(), 0, IpvFileData); 
    #endif 
    } 
    // ,    
    if (hFile != INVALID_HANDLE_VALUE) { 
    ListBox_AddString(hwndLog, __TEXT("   Closing file")); 
    ftifndef SIMULATION 
    CloseHandle(hFile): 
    ffendif 
    } 
    } // finally 
    return(lNumWords); 
    ) 
    l/l/ll//lllllllllll//llll/il//IH/IIIHIII/IIIHIII/ll/l/IIIIIIIHIIIIIIIIIIIIt 
    void DlgOnCommand (HWNO hwnd, int id, HWND nwndCtI, UINT codeNotify) { 
    TCHAR szBuf[100]; 
    LONG INumWords; 
    
    switch (id) { 
    case IDOK: 
    INumWords = Dlg_CountWordsInFile( 
    Get01gltem(hwnd, IOC_LOG), 
    
    Button_GetCheck(GetDlgItem(hwnd, IDC_OPENSUCCEEDS)), 
    Button_GetCneck(GetDlgIten)(hwnd, IDC_SIZESUCCEEDS)), 
    Button_GetCheck(Get01gItem(hwnd, IDC_MEMSUCCEEDS)), 
    Bu t tan_Ge tCfieck(Ge t01gltef!f(fimd, IOC_READSUCCEEOS)) 
    ): 

    . . . 


    536 _____________________________Windows   


    . 16-1   () 

    if (INumWords == -1) { 
    ListBox_AddString(GetDlgItem(hwnd, IDC_LOG), 
    __TEXT("Error occurred in function.")); 
    } else { 
    _stprintf(szBuf, __TEXT("Result: Words in file = %d"), INumWords); 
    ListBox_AddString(GetDlgItein(hwnd, IOC_LOG), szBuf); 
    } 
    break; 
    case IDCANCEL: 
    EndDialog(hwnd, id); 
    break; 
      
    Illll/lltllllllllllllllllllllllllllllll/llllillllllllllllllllll'/Illl/llllli'llii 
    BOOL CALLBACK DIgProc (HWND hwnd. UINT uMsg, WPARAM wParam, LPARAM 
IParani) { switch (uMsg) { 
    chHANDLE_DLGMSG(hwnd, WM_INITDIALOG. DIgJMnitDialog); 
    chHANDLEJ)LGMSG(hwnd, WM_COMMAND, DlgJ)nCommand); 
    } 
    return(FALSE); 
    } 
    IIIIIIIIIIIIHIIIIIIIIIIIIIIIIIIIIIIIItllllllllllllllllllilllllllllllllllllllll 
    int WINAPI _tWinMain (HINSTANCE hinstExe, 
    HINSTANCE hinstPrev, LPTSTR pszCmdLine, int nCindShow) { 
    chWARNIFUNICODEUNOERWIN95(); 
    DialogBox(hinstExe, MAKEINTRESOURCE(IDD_SEHTERM), NULL. DIgProc); 
    return(O); 
    Illltllllllllllllll/llllllllllllll   I t I I I I I I I I I I I I 


        

       ,    .    
          
 .      .      
        , 
      . ,  
,   (hardware exception).   ,  
        
  (software exceptions). 

    __________________ 16.    537 

           
          
.    : 

    __try { 
    //   
    > 
    __except ( ) { 
    //   

         _except.   try   
   finally,   except.    try  
    finally,   except,     try   
   finally  except.  try-except   
 try-finally,  . 

          

        ,     
         
 .   6   ,    
 try-except,        
,  ,        . 

    Funcmeister] 

         try-except 

    DWORD Funcmeister-1 (void) { 
    DWORD dwTemp: 
    // 1. -   
    __try { 
    // 2.  -  
    dwTemp = 0; 
    } 
    except (EXGEPTION_EXECUTE_HANOLER) { 
    //  ;   
    //    
    // 3.  -  
    return(dwTemp): 
    } 

      try  Funcmeisteri    0  
dwTemp.      ,      except 
  .     :  
try-finally   . 

    538 _____________________________Windows   

        dwTemp  0,   
  return. 
       return, goto, continue  break   try 
    ,     
try           
  .      try,   
 except,    ,   . 

    Funcmeister2 

         ,  : 
    DWORD Funcmeister2 (void) { 
    DWORD dwTemp; 
    // 1, -   
    __1'  i 
    // 2.  -  
    dwTemp = 5 / dwTemp;   //   
    dwTemp += 10:          //    
    } __except ( /* 3.   */ EXCEPTION_EXECUTE_HANDLER) { 
    // 4.   
    MessageBeep(O); 
    // 5.  -  
    return(dwTemp); 
    } 

       try  Funcmeister2   5  
0.   ,    .  
     except   ,  
   ;       , 
    Win32 .: 

                                  

    EXCEPTION_EXECUTE_HANDLER               1 
    EXCEPTION_CONTINUE_SEARCH               0 
    EXCEPTION_CONTINUE_EXECUTION           -1 
    EXCEPTION_EXECUTE_HANDLER 

        Funcmeister2   
EXCEPTION_EXECUTE_HANDLER.        : 
   ;   ,   -  ;   
    ,     

     16.    539 

     .        except 
(  ),       
      . 
     ,        16- Windows,  
       System Error ( 
),        .  
32-    ,    
      ,   - . 
        ? ,   
 . 
     .     ,  
.   Funcmeister2     , 
   dwTemp  10.  ,      
    ,     
  . 
          ,  Funcmeister2  
   .      ,  
,   ,   ,    
 . ,     ,   
;     , ,    
.      ,    ,  
   . 
       ,       
,  .    ,    
Funcmeister2, : 

    malloc(5 / dwTemp): 

         ,   
,       malloc.    
  ,  ()   .  
  -  ,    . 
     , Microsoft        , 
    .       
  . 
     .      ,   
.    .      except 
 : 

    dwTemp = 2; 

              
.       5  2,      
 .  ,  -      
 ,  . ,   ,  
     (     ). 
    ,  ,       
-. ,    except.    ,  
    EXCEPTION_EXECUTE_HANDLER.   
    except        . 

    EXCEPTION_CONTINUE_EXECUTION 

       ,        
,   ..  Funcmeister2  
EXCEPTION_EXECUTE_HANDLER  ( )    ,   
   ,     . : 

    540 _____________________________Windows   


    char g_szBuffer[100]; 
    void FunclinRooseveltl (void) { 
    int x = 0: 
    char *lpBuffer = NULL; 
    __try { 
    IpBuffer = 'J'; 
    x = 5 / x: 
    __except (OilFilter1(&lpBuffer)) { 
    MessageBox(NULL, "An exception occurred", NULL, MB_OK); 
    } 
    MessageBox(NULL, "Function completed", NULL. MB_OK); 
    i 
    LONG OilFilter-l (char **lplpBuffer) { 
    if (*lplpBuffer == NULL) { 
    *lplpBuffer = g_szBuffer; 
    return(EXCEPTION_CONTINUE_EXECUTION); 
    f 
    return(EXCEPTION_EXECUTE_HANDLER); 
    } 

        ,     '/'  , 
   IpBuffer.  ,    IpBuffer  
     g_szBuffer       
NULL.          
except,    try,     .   
except   IpBuffer   OilFilterI. 
     , OilFilterI ,    *lplpBuffer  
NULL, ,  ,   ,       
g_szBuffer.    EXCEPTION_CONTINUE_EXECUTION.  
    ,    , 
 ,     .      
,  '/       g_szBuffer. 
       ,       try  
    .      .  
  *lplpBuffer   NULL,   OilFilterI  
EXCEPTION_EXECUTE_HANDLER,        except, 
       An exception occurred ( ). 
     ,        . 
, ,         . 

       EXCEPTION_CONTINUE_EXECUTION 

              
      ,    
,  ,        
 ,   ,  . 
       2    : 

    IpBuffer = 'J': 


    _________________ 16.    541 

        IpBuffer  ,     
   ,     .    
  .  ,  ,   
 IpBuffer      .    
,      ,     
IpBuffer,        .   
 ! 
       ,   
 ,   ,     . 
    ,    ,   
  ,     , 
   . :  - , 
 EXCEPTION_CONTINUE_EXECUTION   . 

    EXCEPTION_CONTINUE_SEARCH 

            ,    
.   ,   : 

    void FunclinRoosevelt2 (void) { 
    char *lpBuffer = NULL: 
    -_try { 
    FuncSinatra2(lpBuffer): 
    } 
    except (OilFilter2(&lpBuffer)) { 
    MessageBox(NULL, ...); 
    } 
    void FuncSinatra2 (char *sz) { 
    *sz = 0; 
    } 
    
    LONG OiiFilter2(char **ipipBuffer) { 
    if (*lplpBuffer == NULL) { 
    *lplpBuffer = g_szBuffer; 
    return(EXCEPTION_CONTINUE_EXECUTION); 
    } 
    return(EXCEPTION_EXECUTE_HANDLER): 
    } 

      FunclinRoosevelt2  FuncSinatra2,  
 NULL.    .   ,  
    ,     
 try.      try  FunclinRoosevelt2,   
       OUFilter2   
   FuncSinatra2.    ,   
 try-except. 

    void FunclinRooseveltS (void) { 
    char *lpBuffer = NULL; 
    try { 
    FuricSinatra3( IpBuffer); 
    } 

    . . . 


    542 _____________________________Windows   


    except (OilFilter3(&lpBuffer)) { 
    MessageBox(NULL, ...); 
    } 
    void FuncSinatra3 (char *sz) { 
    __try { 
    *sz = 0; 
    } 
    except (EXCEPTION_CONTINUE_SEARGH) { 
    //      
    LONG OilFilter3 (char **lplpBuffer) { 
    if (*lplpBuffer == NULL) { 
    *lplpBuffer = g_szBuffer; 
    return(EXCEPTION_CONTINUE_EXECUTION); 
    } 
    return(EXCEPTION_EXECUTE_HANDLER); 
    } 

    ,  FuncSinatra3   0   NULL, - 
 ,        
FuncSinatra3.       
EXCEPTION_CONTINUE_SEARCH.       
  try,    except,    . 
        FuncSinatra3  EXCEPTION_CONTINUE_SEARCH,  
    try (  FunclinRoosevelt3)   
  OilFilter3. ,   IpBuffer  NULL, OilFilter3 
 ,      ,    
   ,  .   
    try  FuncSinatra3, , ,   
sz          .  
 ! 
    ,  ,       
 try,    except,    .  
,    try,    finally (  
except), ,   , .  :  
 finally   ,       . 
     FuncSinatra3   except  finally, 
       OilFilter3  FunclinRoosevelt3. 
    -  . 16-2  ,    
 . 

      

          , , 
    EXCEPTION_EXECUTE_HANDLER.    
     try-finally,  
     try-except,   . 
     (. . 544): 

    544 _____________________________Windows   


    void FuncOStimpyI (void) { 
    // 1. -   
    __try i 
    // 2.    
    FuncORen1( ); 
    //      
    i 
    except ( /* 6.    */ EXCEPTION_EXECUTE_HANDLER) { 
    // 8.      
    MessageBox(NULL, ...): 
    } 
    // 9.   -   
    void FuncORenI (void) { 
    DWORD dwTemp = 0; 
    // 3. -   
    __iry { 
    // 4.        
    WaitForSingleObject(g_hSem, INFINITE); 
    // 5.  ,     
    g_dwProtectedData = 5 / dwTemp; 
    } 
    finally { 
    // 7.   ,   
    //   EXCEPTION_EXECL)TE_HANDLER 
    //       
    ReleaseSemaphore(g_hSem, 1, NULL); 
    i. 
    //  ;     

    FuncOStimpyI  FuncORenI      
 .       
,    , ,   . 
    FuncOStimpyI       try   FuncORenI. 
     try   .  ,   
    g_dwProtectedData.     
 . 

    _________________ 16.    545 

    ,  ,   try,    
except.   fry  FuncORenI   finally, 
      fry  FuncOStimpyI,     
  except. 
            except  
FuncOStimpyI. ,    EXCEPTION_EXECUTE_HANDLER,   
    finally   FuncORenI. :  
      except  FuncOStimpyI.  
 ,       
fry     try,    finally.   
  finally    FuncORenI. 
     SEH - ,     finally  
FuncORenI. -    ,     
   .    Releasesemaphore   
finally ,     . 
       finally,      
finally.     .    except,  
,       .   
   ,        except. 
    -  . 16-3 ,     . 
          . -, SEH  
    :      
 .     ,  ; 
     ,    . 
,  -  . 16-2  16-3,     SEH. 

       

     ,  ,  ,   
 finally   return. : 

    void FuncMonkey (void) { 
    __try { 
    FuncFish(); 
    } 
    except (EXCEPTION_EXECUTE_HANDLER) { 
    MessageBeep(O): 
    } 
    MessageBox(.,. ) } 
    void FuncFish (void) { 
    FuncPheasantO; 
    MessageBox(...); 
    } 
    void FuncPheasant (voici) { 
    try { 
    strcpy(NULL, NULL); 
    i 
    __finally { 
    return:                                                                 / 
    } 


    546 ______________________________Windows   


        >   |   f 
      j  fry,       gi        
 ; 
    EXCEPTION EXECUTE_HANDLER' 
    җ-' 
          fry 
    \ 
        \                             /
    ,        \                     
      L^__      fry,    ^ 
          1            ^.                  .^ 
    f               -S^ ? ^^^ 
     
    \ 
                               . 
    ,     '          __ .- _^      
             fry       ^  >             -    . 
    ^s^        [ II      ^                   fry 
    -S^    hnally?   ^^ 
     
        finally 

    . 16-3.      

      strcpy   try  FuncPheasant -,  
    .    ,  
  ,   ,    
. ,    FuncMonkey   ,  
   . 
            finally  
FuncPheasant.      return.    
 ,  

    ________________ 16.    547 

    FuncPheasant     FuncFish,   
  .  FuncFish   FuncMonkey,   
 MessageBox. 
    :   except  FuncMonkey    MessageBeep. 
 return   finally  FuncPheasant    
 ,     ,    . 
    Microsoft    SEH  .    
     .    
     .  ,     
 return   finally. 

          

         ,   
,    . ,    , 
     ,   ,     
 .          
 . 
       ,    : 

    __try { 
     = 0; 
     = 4 / ; 
    except ((GetExceptionCodeO == EXCEPTION_INT_DIVIDE_BY_ZERO) ? 
    EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { 
    //     

      GetExceptionCode    : 

    DWORD GetExceptionCode(VOID); 

            
   (     Win32).  
     Win32 WINBASE.H. 
    EXCEPT10N_ACCESS_VIOLAT10N       
 ,      . 
    EXCEPTION_ARRAY_BOUNDS_EXCEEDED      
,      ;    
    . 
    EXCEPTION_BREAKPOINT   . 
    EXCEPTION_DATATYPE_MISAL1GNMENT      
   ,     
. , 16-      
 , 32     . . 
    EXCEPTION_FLT_DENORMAL_OPERAND        
  .   ,   
      . 
    EXCEPTION_FLT_DIVIDE_BY_ZERO       
     ,  0. 

    548 _____________________________Windows   

    EXCEPTION_FLT_INEXACT_RESULT       
     . 
    EXCEPTION_FLT_INVALID_OPERATION   ,   
   ,     . 
    EXCEPTION_FLT_OVERFLOW       
      . 
    EXCEPTION_FLT_STACK_CHECK        
       . 
    EXCEPTION_FLT_UNDERFLOW       
      . 
    EXCEPTION_GUARD_PAGE        
  PAGE_GUARD.   ,   
 . 
    EXCEPTION_ILLEGAL_INSTRUCTION    .  
    ;   
   ,    . 
    EXCEPTION_IN_PAGE_ERROR    ,   
        . 
    EXCEPTION_INT_DIVIDE_BY_ZERO       0. 
    EXCEPTION_INT_OVERFLOW        
 . 
    EXCEPTION_INVALID_DISPOSITION    , 
  
    EXCEPTION_EXECUTE_HANDLER, EXCEPTION_CONTINUE_SEARCH  EXCEPTION_
    CONTINUE_EXECUTION. 
    EXCEPTION_NONCONTINUABLE_EXCEPTION     
   (noncontinuable exception). 
    EXCEPTION_PRIV_INSTRUCTION    , 
    . 
    EXCEPTION_SINGLE_STEP      
        .       __ 
    EXCEPTION_STACK_OVERFLOW ,  , . 
      GetExceptionCode      
 ( ,    _except)    
. ,   : 

    __try { 
     = 0; 
     - 4 / : 
    __except { 
    ((GetExceptlonCodeO == EXCEPTION_ACCESS_VIOLATION) :; 
    (GetExceptlonCodeO == EXCEPTION_INT_DIVIDE_BY_ZERO)) ? 
    EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { 


    _________________ 16.    549 


    switch (GetExceptionCodeO) { 
    case EXCEPTION_ACCESS_VIOLATION: 
    //      
    break; 
    case EXCEPTION_INT_DIVIDE_BY_ZERO: 
    //       
    break; 
    | 
    ) 

    GetExceptionCode      .  
        ,   
 , ,  : 

    __try { 
     = 0; 
     = 4 / ; 
    } 
    except (CoffeeFilter-0) { 
    //   
    LONG CoffeeFilter (void) { 
    
    //   :   GetExceptionCode 
    return((GetExceptionCodeO == EXCEPTION_ACCESS_VIOLATION) ? 
    EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH); 
    } 

       ,   : 

    __try { 
     -- 0; 
     = 4 / ; 
    __except (CoffeeFilter(GetExceptionCodeO)) { 
    //   
    LONG CoffeeFilter(DWORD dwExceptionCode) { 
    return((dwExceptionCode == EXCEPTION_ACCESS_VIOLATION) ? 
    EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH); 
    } 

            Win32,  
  WINERROR.H.    DWORD   ,  
  : 

    550 _____________________________Windows   

            31-30             29-28            27-16          15-0 

    : 
                                      

     (severity)                          (facility code) 

    :     0 =               29                     
     Microsoft          Microsoft       
    1 =       0 = Microsoft 
    2 =    1 =  
    3 =             28  
    (  0) 

          : 

                    

    FACILITY_NULL                  
    FACILITY_RPC                  1 
    FACILITY_DISPATCH             2 
    FACILITY_STORAGE              3 
    FACILITYJTF                   4 
    FACILITY_WIN32                7 
    FACILITY_WINDOWS            8 
    FACILITY_CONTROL             10 

         ,   : 

                                                       
    EXCEPTION_ACCESS_VIOLATION                OxCOOOOOOS         
    EXCEPTION_ARRAY_BOUNDS_EXCEEDED          OxC000008C         
    EXCEPTION_BREAKPOINT                      080000003         

 _ 

    EXCEPTION_DATATYPE_MISALIGNMENT          080000002          
    EXCEPTION_FLT_DENORMAL_OPERAND          OxC000008D         
    EXCEPTION_FLT_DIVIDE_BY_ZERO               OxCOOOOOSE         
    EXCEPTION_FLT_INEXACT_RESULT               OxC000008F         
    EXCEPTION_FLT_INVALID_OPERATION                     
    EXCEPTION_FLT_OVERFLOW                    OxC0000091          
    EXCEPTION_FLT_STACK_CHECK                 OxC0000032         
    EXCEPTION_FLT_UNDERFLOW                           
    EXCEPTION_GUARD_PAGE                      080000001          
    EXCEPTION JLLEGALJNSTRUCTION             OxCOOOOOlD         
    EXCEPTION JN_PAGE_ERROR                            
    EXCEPTION_INT_DIVIDE_BY_ZERO               OxC0000094         
    EXCEPTION JNT_OVERFLOW                    OxC0000035         
    
    . . . 

    _________________ 16.    551 


    () 

                                                  
    
    EXCEPTION_INVALID_DISPOSITION               OxC0000026          
    EXCEPT10N_NONCONTINUABLE_EXCEPTION      OxC0000025          
    EXCEPTION_PRIV_INSTRUCTION                 OxC0000096          
    EXCEPTION_SINGLE_STEP                       080000004          
    EXCEPTION_STACK_OVERFLOW                  OxCOOOOOFD         


     GetExceptionlnformation 

      ,      
   EXCEPTION_RECORD, CONTEXT  EXCEPTION_POINTERS. 
    EXCEPTION_RECORD    ,    
, a CONTEXT  -    .  
 EXCEPTION_POINTERS  2        
 EXCEPTION_RECORD  CONTEXT: 

    typedef struct _EXCEPTION_POINTERS { 
    PEXCEPTION_RECORD ExceptionRecord; 
    PCONTEXT ContextRecord; 
    } EXCEPTION_POINTERS; 

            ,  GetExceptionlnformation: 

    LPEXCEPTION_POINTERS GetExceptionlnformation(VOID); 

           EXCEPTION_POINTERS. 
       GetExceptionlnformation ,       
    ,    CONTEXT, 
EXCEPTION_RECORD  EXCEPTION_POINTERS      
 .      , 
   . 
              , 
  EXCEPTION_RECORD / CONTEXT (   
  EXCEPTION_POINTERS)    .  
   : 

    void FuncSkunk (void) { 
    
    //  ,      
    //      (  ) 
    EXCEPTION_RECORD SavedExceptRec; 
    
    GOTEXT SavedContext; 
    try { 
    except { 
    
    SavedExceptRec = *(GetExceptionInformation())->ExceptionRecord, 
    SavedContext = *(GetExceptionInformation())->ContextRecord, 
    EXGEPnON_EXECUTE_HANDLER) { 

    . . . 

    552 _____________________________Windows   


    //      SavedExceptRec 
    //  SavedContext     
    switch (SavedExceptRec.ExceptionCode) { 
    ( 
    } 

        - (,)     
   .   ,  ,  
,    .     
       . 
     FuncSkunk    ,     
    EXCEPTION_RECORD    
SavedExceptRec.     SavedExceptRec.   
,   ,  .    
     CONTEXT    
SavedContext.      SavedContext  ,  
  .   EXCEPTION_EXECUTE_HANDLER    
     . 
        EXCEPTION_EXECUTE_HANDLER,    
 except.     SavedExceptRec  SavedContext  
,       . ,  
 SavedExceptRec  SavedContext     try. 
    ,  ,   ExceptionRecord  
EXCEPTION_POINTERS    EXCEPTION_RECORD: 

    typedef struct _EXCEPTION_RECORD { 
    DWORD ExceptionCode; 
    DWORD ExceptionFlags; 
    struct _EXCEPTION_RECORD *ExceptionRecord; 
    PVOID ExceptionAddress; 
    DWORD NumberParameters; 
    DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; 
    } EXCEPTIONJECORD: 

     EXCEPTIONJRECORD   - 
   : 
     ExceptionCode   .  ,   GetExceptionCode. 
     ExceptionFlags   .      2 
: 0 ( )  EXCEPTION_NONCONTINUABLE 
( ).      
      EXCEPTION_NONCONTINUABLE_EXCEPTION. 
     ExceptionRecord    EXCEPTION_RECORD,  
    .     
  . ,      
    .     
,         . 
  ,      .  
   ExceptionRecord  NULL. 

    _________________ 16.    553 

     ExceptionAddress    ,    
 . 
     NumberParameters   ,   .  
     Exceptionlnformation. 
     Exceptionlnformation    32- , 
 .       
  . 
        EXCEPTION_RECORD   
   .      
  : EXCEPTION_ACCESS_VIOLATION.     
   NumberParameters.  ,  ,  
      . 
      EXCEPTION_ACCESS_VIOLATION  Exceptioninformation [0] 
 ,   ,   .   
  0,      ; 1  
    . Exceptionlnformation [1]  
   . 
         ,   
    .  , ,  : 

    __try { 
    except (ExpFltr(GetExceptionInformation()-> ExceptionRecord)) { 
    
    LONG ExpFltr (LPEXCEPTION_RECORD IpER) { 
    char szBuf[300], *p; 
    
    DWORD dwExceptionGode = lpER->ExceptionCode: 
    
    sprintf(szBuf, "Code = %x, Address = %x", 
    dwExceptionCode, lpER->ExceptionAddress); 
    
    //    
     = strchr(szBuf, 0); 
    
    //    switch   ,  Microsoft 
    //         
    switch (dwExceptionCode) { 
    
    case EXCEPTION_ACCESS_VIOLATION; 
    
    sprintf(p, "Attempt to %s data at address %x", 
    
    lpER->ExceptionInformation[0] ? "write" : "read", 
    lpER->ExceptionInformation[1]); 
    break; 
    default; 
    break; 
    MessageBox(NULL, szBuf, "Exception", MB_OK ; MB_ICONEXCLAMATION); 
    return(EXCEPTION_CONTINUE_SEARCH); 


    554 ____________________________Windows   

     ContextRecord  EXCEPTION_POINTERS    
CONTEXT,      . ,  
 8: 

    typedef struct CONTEXT { 
    // ,    CONTEXT 
    DWORD ContextFlags; 
    
    //   
    DWORD DrO; 
    DWORD Dr1; 
    DWORD Dr2; 
    DWORD Dr3; 
    DWORD Dr6; 
    DWORD Dr7; 
    //     
    FLOATING_SAVE_AREA FloatSave: 
    //   
    DWORD SegGs: 
    DWORD SegFs; 
    DWORD SegEs; 
    DWORD SegDs; 
    //   
    DWORD Edi; 
    DWORD Esi; 
    DWORD Ebx; 
    DWORD Edx; 
    DWORD Ecx; 
    DWORD Eax; 
    
    //   
    DWORD Ebp: 
    DWORD Eip; 
    DWORD SegCs; 
    DWORD EFlags; 
    DWORD Esp; 
    DWORD SegSs; 
    } CONTEXT: 

       ,        
  ,      
 . ,    - , 
         
 CONTEXT.        #ifdefw\z 
  .  CONTEXT   86, MIPS, Alpha  
PowerPC     WINNT.H. 

    - SEHExcpt 

     SEHExcpt (SEHEXCPT. ) (.   . 16-4) 
     .   
     

    _________________ 16.    555 

        SEHEXCPT  -,   
.  .    : 

    Clicking Execute reserves an array of  4-KB structures and          | 
randomly writes to elements in the array. 
    Number of writes to perform:      IjTifflIExecute| Execution loa: 

       Execute   VirtualAlloc,  
      ,  
    50 ,   4 . :  , 
 . 
     ,      
.    ,      
 Number Of Writes To Perform (  ). 
              
 ,    ,   .   
        ExpFilter  
 SEHEXCPT.. 
          VirtualAlloc,     
 _,      . 
    ,  ,    
,        . 
    ,       .  
 ,   ,     
,      .     
 - ,    EXCEPTION_CONTINUE_SEARCH. 
     ExpFilter ,      
 ,    : 
    1.      EXCEPTION_ACCESS_VIOLATION? 
    2.        ? ( 
    .) 
    3.   ,     ,  
    ? 
     -    , ,     
  ;   EXCEPTION_CONTINUE_SEARCH.   
  3 ,  ,      ,  
  CommitMemory.  ,      
 ,   ,     Execution Log.  
   

    556 _____________________________Windows   

      .   CommitMemory  VirtualAlloc  
    ,    . 
     CommitMemory    ,   
EXCEPTION_CONTINUE_EXECUTION.      , 
 .        ,    . 
      ,     ,    
TION_CONTINUE_EXECUTION,     ,   
       C/C++.    
     .    
         
  ,       
,        . 0', 
  ,     . 

    Clicking Execute reserves an array of 50 4-KB structures and randomly 
writes to elements in the array, 
    lumber of writes to perform:      |i  ["' Execute '1 
    Execution log: 
    Execution started3 
    Writing index: A                                               ^ 
    > Committing memory (write attempted) 
    Writing index: 11 
    > Committing memory (write attempted) 
    Writing index: 11                                                  " 
    > Committing memory (write attempted)                        " 
    Writing index: 25 
    > Committing memory (write attempted) 
    Writing index: 9 
    > Committing memory (write attempted) 
    Writing index: 25 
    Writing index: 21 
    > Committing memory (write attempted) 
    Writing index. 20                                              J-J 

       100     .  
   ,       
      4, 11, 41, 25  9.    
    25.       ,  
 .     : 

    Clicking Execute reserves an array of 50 4-KB structures end  randomly 
writes to elements in the array. 
    ^Limber of writes to perform:      h Q\~\f""^pp^g"""'| 
    Execution loo; 
    Writing ndex: AS                                            3 ) 
    Writing ndex: 13                                                j 
    Writing ndex: 21 
    Writing ndex: 1                                                  | 
    Writing ndex: 27 
    Writing ndex: 15                                             j 
    > Committing memory (write attempted) 
    Writing ndex: 33 
    Writing ndex: 13                                           ' 
    Writing ndex: A2                                               
    Writing ndex: 21                                             ^l| 
    Writing ndex: 1                                                 " | 
    Writing index: At                                              , 
    Writing index; 9 
    Execution ended                                        3 


    _________________ 16.    557 

        100      ,  
          
 . 
         ,       
ExpFilter  try-finally.  ,  :  SEH  
       .    
 try-finally  tryexcept   finally  except,  , 
    try-finally  try-except   .  
          
  SEHSoft. 
        SEHTerm,   SEHExcpt,   
  ,  ,       
 . 

    SEHEXCPT.C 
    : SEHExcpt. 
    : Copyright  1995-1997,   (Jeffrey Richter) 
    *******.***..*....,*,,**,.**.******,*..**.**..**,.*.*.*,..**..*.,..*..**../ 
    Sinclude ".,\CmnHdr,H"           /* .   */ 
    ftinclude <windows,h> 
    #include <windowsx.h> 
    ftinclude <tchar.h> 
    Binclude <stdio.h>               //  sprintf 
    ^include <stdlib.n>              //  rand 
    ^include "Resource.H" 
    IIIIIIIIIIIIIIIIIIIIIHIIIIIItlllllllllllllllllllllllltlllllllHIIIIIIIIIIIIII/ 
    define NUMELEMENTS    (50) 
    
    //       4  
    typedef struct { 
    BYTE bReserved[4 * 1024]; 
    } ELEMENT, *LPELEMENT; 
    IIIIIIIIIIHIIIIIIIIIIIIIIItllllll/lllllllllllllllllllllll/lll/llllllllllllllll 
    void CommitMemory (HWND hwndLog, LPEXCEPTION_POINTERS IpEP, 
    LPBYTE IpbAttemptedAddr) { 
    BOOL fAttemptedWrite; 
    TCHAR szBur[100]; 
    // ,       
    fAttemptedWrite = (BOOL) lpEP->ExceptionRecord->ExceptionInformation[0]; 
    
    //      Execution Log 
    _stprintf(szBuf, __TEXT("--> Committing memory (%s attempted)"), 
    fAttemptedWrite ? __TEXT("write") : __TEXT("read")); 

    . . . 

    . 16-4.   SEHExcpt 

    558 _____________________________Windows   

    . 16-4  () 

    ListBox_AddString(hwndLog, szBuf); 
    
    //        ,   
    //     .     
    //      . 
    VirtualAllocdpbAttemptedAddr, sizeot'(ELEMENT), MEM_COMMIT, PAGE_REAOWRITE): 
    \ 
    f 
    ///////////////////////// /////////////////////////// /////////////////////////// 
    
    int ExpFilter (LPEXCEPTION_POINTERS IpEP, LPBYTE IpbArray, 
    LONG INumBytesInArray, HWND hwndLog) { 
    LPBYTE IpbAtteffiptedAddr = NULL; 
    
    //   ,     
    DWORD dwExceptionCode = lpEP->ExceptionRecord->ExceptionCode; 
    
    // ,        
    //      
    int nFilterResult = EXCEPTION_CONTINUE_SEARCH; 
    __try { 
    
    //   ,    
    // -     .   
    //       . 
    
    if (dwExceptionCode != EXCEPTION_ACCESS_VIOLATION) { 
    
    //        , 
    //         . 
    //      . 
    nFilterResult = EXCEPTION_CONTINUE_SEARCH; 
    __leave; 
    i 
    ! 
    if (IpbArray == NULL) { 
    //       
    //  ,      
    nFilterResult = EXCEPTION_CONTINUE_SEARCH: 
    __leave; 
    } 
    
    //  ,      
    IpbAttemptedAddr = (LPBYTE) 
    1->ExceptionRecord->Except ion In format ion[1]; 
    if ((IpbAttemptedAddr < IpbArray) ;'. 
    ((IpbArray + INumBytesInArray) < IpbAttemptedAddr)) { 

    . . . 

    _________________ 16.    559 


    . 16-4  () 
    
    I /       
    //    ,    
    // .     
    // -  . 
    nFilterResult = EXCEPTION_CONTINUE_SEARCH; 
    __leave: 
    i 
    J 
    
    //     
    CommitMemory(hwndLog, IpEP, IpbAttemptedAddr); 
    
    //   .    , 
    //    .       
    //     . 
    nFilterResult = EXCEPTION_CONTINUE_EXECUTION: 
    } 
    finally { 
    } 
    
    // ,   ,     
    //  ,      
    return(nFilterResult); 
    } 
    l/lllll lllllllillllll lllllllll/111/llllll/IHIIHIIIIIIIIIIHIIIIIIIIIIIIIIIIII 
    void Dlg_ReserveArrayAndAccessIt (HWND hwndLog, int nNumAccesses) { 
    LPELEMENT IpArray = NULL; 
    ELEMENT Element; 
    TCHAR szBuf[100]; 
    int nElementNum; 
    const LONG INumBytesInArray = sizeof(ELEMENT) * NUMELEMENTS; 
    
    //    Execution Log 
    ListBox_ResetContent(hwndLog); 
    ListBox_AddString(hwndLog, __TEXT("Execution started")): 
    __try { 
    //   ,  
    //   NUMELEMENTS  ELEMENT 
    IpArray = VirtualAlloc(NULL, INumBytesInArray, MEM_RESERVE, PAGE_NOACCESS); 
    while (nNumAccesses--) { 
    
    //     
    nElementNum = rand() % NUMELEMENTS: 

    . . . 

    560 ______________________________Windows   


    . 16-4  () 
    
    I /   
    _stprintf(szBuf, __( "Writing index: %d"), nElementNum); 
    ListBox_AddString(hwndLog, szBuf); 
    
    //      
    lpArray[nElementNum] = Element: 
    } // while 
    
    //   
    ListBox_AddString(hwndLog, __TEXT("Execution ended")); 
    
    //       ELEMENTS 
    VirtualFreedpArray, , MEM_RELEASE); 
    } // -_try 
    __except ( 
    
    ExpFilter(GetExceptionInfomiation(), (LPBYTE) IpArray, 
    INumBytesInArray, hwndLog)) { 
    
    //      
    // EXCEPTION_EXECUTE_HANDLER,  
    //    except   
    } // except 
    } 
    /////////////////////////////////////////////////////////////////////////////// 
    BOOL Dlg_OnInitDialog (HWND hwnd, HWND hwndFocus, LPARAM IParam) { 
    
    //      
    chSETDLGICONS(hwnd, IDI_SEHEXCPT, IDI_SEHEXCPT); 
    
    // no     - 100 
    SetDlgItemInt(hwnd, IDC_NUMACCESSES, 100. FALSE); 
    return(TRUE); 
    } 
    IIIIIIII/II/IIIIIIIII!IIIIIHIII/III!III//I/I/II//IIIIIIIIIIIIIIIII/II/IIIIIII/ 
    
    void Dlg_OnCo(iimand (HWND hwnd, int id, HWND hwndCtI, UINT codeNotify) { 
    int nNumAccesses: 
    BOOL fTranslated; 
    
    switch (id) { 
    case IDOK; 
    
    nNumAccesses = GetDlgItemInt(hwnd, IDC_NUMACGESSES, 
    &fTranslated, FALSE); 

    . . . 

    _________________ 16.    561 


    . 16-4  () 

    111111111111111111111/11111111/1111111111111111111/11111111111/1111111111111111 
    BOOL CALLBACK Dlg_Proc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM 
IParam) { 
    switch (uMsg) { 
    chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog); 
    chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCo(nmand); 
    } 
    return(FALSE); 
    } 
    lllll l/IIIIIHIIIIHIIIIIIII/ll tll///il/// ll/lllllll/lllll lll/ll/llllll ii/lllli 
    int WINAPI _tWinMain (HINSTANCE hinstExe, 
    HINSTANCE hinstPrev, LPTSTR pszCmdLine, int nCmdShow) { 
    chWARNIFUNICODEUNDERWIN95(); 
    DialogBox(hinstExe, MAKEINTRESOURCE(IDD_SEHEXCPT), NULL, Dlg_Proc); 
    return(O); 
    i i 
    11111111111/1111111111111111111111   111111111111111111111111111111111 


    - SEHSum 

     SEHSum (SEHSUM.EXE) (.   . 16-5)  
        
  .         
   SEHSUM  -,   . , 
         7,  , 
   . 
        0  ,    ,  . 
,        Sum,     : 

    Sum = ( * ( + 1)) / 2; 

           Sum . 

    562 _____________________________Windows   

        : 

    Calculate the sum of the numbers ◗ 
    from 0 through & where x Is:       |i 
    .Calculate| Answer:  ? 

             Calculate (). 
  ,        
 0  x.   ,   ,  
WaitForSingkObject,       . 
   ,      
 .   ,      
 GetExitCode Thread,          
,      -,     . 
           .  
  UINT_MAX, ,  :     
  ;        
.       UINT_MAX,   
 ;      .    
        . 
        .    SumThreadFunc.  
          
 ,   .     
 uSum  UINT_MAX, . .  ,  
    . SumThreadFunc  SEH , 
   ,    .  
         Sum. 
       , SumThreadFunc   
  uSum;      . ,   
 Sum  ,      
 .  ,   FilterFunc,   
 .        
EXCEPTION_STACK_OVERFLOW.  ,    
,   ,      0 
 44000. 
      FilterFunc  .   ,  
       .    
EXCEPTION_CONTINUE_SEARCH,   ,    . 
   ,      
EXCEPTION_STACK_OVERFLOW.     EXCEPTION_EXECUTE_HANDLER.  
 ,            
 except.     TION_EXECUTE_HANDLER   , 
      Sum,     
,  UINT_MAX (  uSumNum),    ,  Sum 
  . 
     ,    :     Sum  
   ,    SEH-     
 Sum    try.    3 . 
    -,  ,   ,     
 1 .     Sum   ,   
    ,        
 . ,         
  .    ?   
,  Sum      ^ 

    _________________ 16.    563 

     1000     -      
, ,      0  750.  , 
  Sum  ,     ,  
  . 
       ,       
  .     Sum       
 ,         
.            
   ,        
    PAGE_GUARD.    ,  
 Sum  ,      . 
      ,   
      . 
     ,     :  , 
  ,  .   :  
  Sum      0  30000.   
      .   
       5000.  ,  
    ,    .   
      .     
       .     
 SumThreadFunc,     , 
  . 

    SEHSUM.C 
    /.*,.*****.,***..***..,.,**.*.*,,*.**..,,*.***.....***.*.*.***..*.,*,.*,*,*. 
    : SEHSum.C 
    : Copyright  1995-1997,   (Jeffrey Richter) 
    ..*,..*.**..*.**.*,**..*,*..,.***...,.**.........*,...,****.,.,.,*...**,.*/ 
    ftinclude "..\CmnHdr.H"              /* .   */ 
    ftinclude <windows.h> 
    ftinclude <windowsx.h> 
    tfinclude <limits.h> 
    tfinclude <process.h>                //  _Peginthreadex 
    ftinclude <tchar.h> 
    include "Resource.H" 
    ////////////////////////////////////1//////'///,//////,'//.'// '///7// './:,''/// 
    
    II   Sum  uNum    9 
    // uNum: 0123456789... 
    // Sum: 0 1 3 6 10 15 21 28 36 45 ... 
    UINT Sum (UINT uNum) { 
    if (uNum == 0) 
    return(O); 
    //   Sum 
    return(uNum + Su(n(uNuin - 1)); 
    } 

    . . . 

    . 16-5.   SEHSum 

    564 _____________________________Windows   

    . 16-5  () 
    1111111111111111111111111111111111111111111111111111111111111111111111111111111 
    long FilterFunc (DWORD dwExceptionCode) { 
    
    // ,   ,   
    //  ;    
    //   
    long IRet = EXCEPTION_CONTINUE_SEARCH; 
    
    if (dwExceptionCode == STATUS_STACK_OVERFLOW) { 
    //    -  
    // ,   ,    
    IRet = EXCEPTION_EXECUTE_HANDLER; 
    1 
    return(lRet); 
    } 
    lllll lllllllllll lllllllllll lllllllllll lllllliili illllllllil/' HIHIII Iiiililliil 
    
    II  ,    . 
    //      : 
    
    // 1,       . 
    // 2.       . 
    // 3. ,   ,    . 
    DWORD WINAPI SumThreadFunc (PVOID p) { 
    
    //   ( DINT)  
    //    
    UINT uSumNuffi = (UINT) ; 
    
    // uSum     0  uSumNum.    
    //  ,   UINT_MAX. 
    UINT uSufn = UINT_MAX; 
    try { 
    //    " " 
    //  Sum    SEH- 
    uSum = Sum(uSumNum); 
    } 
    __except (FilterFunc(GetExceptionCodeO)) { 
    //    ,   ,   
    //  .    ,  
    //     . ,   
    //       ,  
    //    . 

    . . . 

    . 16.    565 

    . 16-5  () 
    
    I /        uSumNum 
    // ,  UINT_MAX     
    return(uSum); 
    } 
    
    /ll//l//IIIHII/ll/l/ll///l///llllllllll/l/lll/ll/l/llllllill/llll///ll//lli/ll 
    BOOL Dlg_OnInitDialog (HWND hwnd, HWND hwndFocus, LPARAM IParam) { 
    
    //      
    chSETDLGICONS(hwnd. IDI_SEHSUM, IDI_SEHSUM); 
    return(TRUE); 
    } 
    11 /111 /111 II I / / I /1 /! I! I! /1 / i / / i ' !! / /! /1 / i! i! 
    void Dlg_OnCo[iimand (HWND hwnd, int id, HWND hwndCtl. UINT codeNotify) { 
    DINT uSumNum, uSum; 
    BOOL fTranslated; 
    DWORD dwThreadId; 
    HANDLE hThread; 
    switch (id) { 
    case IDC_CALC: 
    //    ,  
    //    
    uSumNum = GetDlgItemInt(hwnd, IDC_SUMNUM, &fTranslated, FALSE); 
    :           //   (  ), 
    //    
    hThread = chBEGINTHREADEX(NULL, 0, SumThreadFunc, 
    (PVOID) uSumNum, 0, &dwThreadId): 
    //   -   
    
    //   ,    
    WaitForSingleObject(hThread, INFINITE); 
    
    //       
    GetExitCodeThread(hThread, (PDWORD) &uSum): 
    // ,   , 
    //     - 
    CloseHandle(hThread); 
    //     
    if (uSum == UINT_MAX) { 

    566 _________________________...__. Windows   


    . 16-5  () 

    I /     - UINT_MAX, , 
    //   .   
    //    . 
    SetDlgItemText(hwnd, IDCANSWER, __TEXT("Error")); 
    chMB(_TEXT("The number is too big, ") 
    __TEXT("please enter a smaller number")); 
    } else { 
    //   : 
    //    
    SetDlgIteniInt(hwnd, IDC_ANSWER. uSum. FALSE): 
    } 
    break; 
    case IDCANCEL: 
    EndDialog(hwnd, id); 
    break: 
    } 
    /////////////////7/////////7////'/////7///////////////////7///////////////////'/ 
    BOOL CALLBACK Dlg_Proc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM IParam) { 
    switch (uMsg) { 
    chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, 01g_OnInitDialog); 
    chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand); 
    } 
    return(FALSE): 
    } 
    /////////////////////'//////////////////////////////////////////'/////////////// 
    int WINAPI tWinMain (HINSTANCE hinstExe, 
    HINSTANCE hinstPrev, LPTSTR pszCmdLine, int nCmdShow) { 
    chWARNIFUNICODEUNDERWIN95(); 
    DialogBox(hinstExe, MAKEINTRESOURCE(IDO_SUMMATION), NULL, Dlg_Proc); 
    return(O); 
    } 
    111/lllll////llltl/lll//l//lll/lll   / I I I I I / I f / I I I I 


      

           ,   
     .   
  ;       
  

    _________________ 16.    567 

     .     .     
  HEAP_GENERATE_EXCEPTIONS,   ,    
   ,    STATUS_NO_MEMORY. 
       ,    try ,  
    ;        
          except,  
   ,   try  finally. 
      ,    :  
 ,    try-except  try-finally    
 .        
   ,    .     RaiseException: 

    VOID RaiseException(DWORD dwExceptionCode, DWORD dwExceptlonFlags, DWORD 
cArguments, LPDWORD IpArguments); 

     , dwExceptionCode,    .  
      STATUS_NO_MEMORY.  
  ,     , 
  Win32 (.         ). 
       ,  4    
DWORD :  31  30     ,  29 
  1 (0   ,  Microsoft; 
, STATUS_NO_MEMORY   HeapAlloc),  28   0,   
27  16     (    
 Microsoft),    15    - ,   
   ,    . 
       RaiseException  dwExceptionFlags    
 ,  EXCEPTION_NONCONTINUABLE.    , 
       . 
    ,    
() . 
    HeapAlloc   EXCEPTION_NONCONTINUABLE   
 STATUS_NO_MEMORY,   :   
,        
EXCEPTION_CONTINUE_EXECUTION.     ,  
    TION_CONTINUE_EXECUTION,   
  EXCEPTION_NONCONTINUABLE_EXCEPTION. 
     :        
  .     .     
, ,          
finally,    ,    .   
 ,    .   
GetExceptionInformation7     EXCEPTION_POINTERS.  
 ExceptionRecord    EXCEPTION_RECORD,   
     ExceptionRecord.     
 EXCEPTION_RECORD,      . 
          ,  
ExceptionRecord  NULL.       
 ,         
,    ExceptionRecord      
    .     
 ,       
 EXCEPTION_RECORD,  ,    . 

    568 _____________________________Windows   

        (cArguments  IpArguments)   
    .     , 
 NULL  IpArguments,  RaiseException   
cArguments.      , cArguments  
      DWORD,    
IpArguments.  cArguments     
EXCEPTION_MAXIMUM_PARAMETERS (  WINNT.H    15). 
              
cArguments  IpArguments      NumberParameters  
ExceptionInformation  EXCEPTION_RECORD. 
             
. ,        
 (system event log).        
- ,   RaiseException;    
     ,       
         ,     
.        
      .   , 
        . 

    - SEHSoft 

     SEHSoft (SEHSOFT.EXE) (.   . 16-6) , 
      .  
          SEHSOFT  
-,   .       
 SEHExcpt.   SEHSoft     : 

    ||Clicking Execute reserves an array of 50 ^"KB structures and 
    ijpandomly reads and writes to elements in the army 
    
    ;||yumberof reads/writes to perlornr      ||ExecuteI 
    : execution lofl: 

           SEHExcpt,   
      ,     . 
       Dlg_ReserveArrayAndAccessIt (   
 )  ,       . 
   ,         
  . 

    _________________ 16.    569 

          ,    ? 
  ,     ,    
  ,       .  
    . 
      CommitMemory   ExpFilter,    SEHExcpt,  
     try.     except, 
   try, ,      
 CommitMemory       SE_ZERO_ELEM. 
    SE_ZERO_ELEM   #define    
,       SEHSOFT.C: 
    
    //         
    ffdefine MAKESOFTWAREEXCEPTION(Severity, Facility, Exception) \ 
    
    ((DWORD) ( \ 
    /*   "" */         (Severity      ) ! \ 
    /* MS(0)  ^)*/      (1         29) : \ 
    /* () */             (0         28) ! \ 
    /*   */                (Facility 16) ', \ 
    /*   */                (Exception  0))) 
    
    //    .  , 
    //       . 
    ftdefine SE_ZERO_ELEM\ 
    MAKESOFTWAREEXCEPTION(ERROR_SEVERITY_ERROR,\ 
    FACILITY_NULL, 1) 
         : 
    except ((GetExceptionCodeO == SE_ZERO_ELEM) ? 
    (Saved ExceptRec = *((Get Except ion Information())->Except ion Record), 
    FXCEPTION_EXECUTE_HANDLER) : EXCEPTION_CONTINUE_SEARCH) { 
    } 

           SE_ZERO_ELEM. 
 GetExceptionCode    ,   
  EXCEPTION_CONTINUE_SEARCH.      
SE_ZERO_ELEM,     EXCEPTION_EXECUTE_HANDLER  
     except.    except    
,    GetExceptionInformation.  
EXCEPTION_EXECUTE_HANDLER  ,    
EXCEPTION_RECORD,     SavedExceptRec. 
    ,      except,  SavedExceptRec  
  ,  .    
   memset. 
    ,   ,    . 
        CommitMemory. 

    if (IfAttemptedWrite) { 
    //        
    // .     
    //      . 
    RaiseException(SE_ZERO_ELEM, 0, 1, (LPDWORD) &lpAttemptedAddr); 
    } 

          RaiseException  
    SE_ZERO_ELEM     
.  , 

    570 _____________________________Windows   

          RaiseException,  
     EXCEPTION_MAXIMUM_PARAMETERS (15) 
.            
  .     1     
    .     SEHSoft   : 

    Clicking Execute reserves an array of 50 4-KB structures and          | 
randomly reads and writes to elements in the array                  j 
     of reads/Writes to perform:      Ffoo|f "Execute I 
     Execution log; 
    Execution started^| 
    :,. Writing index; 41                                          J 
    : > Committing memory (write attempted) 
    Reading index: 34                                            ^ 
    > Committing memory (read attempted)                       :;:!: 
    > Zeroed array element                                     dis: 
    Reading Index: 19                                         M 
    > Committing memory (read attempted)                      j;' 
    > Zeroed array element                                    : "f 
    , Reading index. 2B                                          , :; 
    ' > Committing memory (read attempted)                      g 
    ;> Zeroed array element                                   ||1 
    Reading index'12                                            '"!>. 
    > Committing memory (read attempted) 
    > Zeroed array element                                 J^J 

     ,    ,    
 Execution Log   ,     . 

    SEHSOFT.C 
    : SEHSoft. 
    : Copyright  1995-1997,   (Jeffrey Richter) 
    ...,....,.,*.*.*****.*.*...*,.**.....,,*********,.*.,***.*,.******.*****..**/ 
    ((include "..\CmnHdr.H"              /* .   */ 
    ((include <windows.h> 
    include <windowsx.h> 
    ((include <tchar.h> 
    ((include <stdio.h>                  //  sprintf 
    #include <stdlib.h>                 // rand 
    ((include "Resource.H" 
    /////////////////////////////////////7///////////////////////////////////////// 
    ((define NUMELEMENTS (50) 
    //      4  
    typedef struct { 
    BYTE bReserved[4 * 1024]; 
    } ELEMENT, *LPELEMENT; 

    . . . 

    . 16-6.   SEHSoft 

    ______________ 16.    571 


    . 16-6  () 

    II         
    define MAKESOFTWAREEXCEPTION(Severity, Facility, Exception) \ 
    ((DWORD) ( \ 
    /*   "" */         (Severity      ) ] \ 
    /* MS(0)  (1)*/      (1         29) ; \ 
    /* ) */            (0        28) \ \ 
    I*   */                (Facility 16) ; \ 
    /*   */                (Exception  0))) 
    
    //    .  , 
    //       . 
    ftdefine SE_2ERO_ELEM \ 
    MAKESOFTWAREEXCEPTION(ERROR_SEVERITY_ERROR, \ 
    FACILITY_NULL, 1) 
    lilll ttllllll llllllllll ll/llll/ll lllllinilll/ll lltlHIIIIIIIII IIIIIIIIIIIIIIII 
    
    void CoiiimitMeffiory(HWNO hwndLog, LPEXCEPTION_POINTERS IpEP, 
    LPBYTE IpbAttemptedAddr) { 
    BOOL fAttemptedWrite; 
    TCHAR sz8uf[100]; 
    
    // ,         
    fAttemptedWrite = (BOOL) lpEP->ExceptionRecord->ExceptionInformation[0]; 
    
    //     Execution Log 
    _stprintf(szBuf, __TEXT("--> Committing memory (%s attempted)"), 
    fAttemptedWrite ? __TEXT("write") : __TEXT("read")); 
    LlstBox_AddString(hwndLog, szBuf); 
    //     ,    
    //    .     
    //   . 
    VirtualAlloc(lpbAttemptedAddr, sizeof(ELEMENT), MEM_COMMIT, PAGE_READWRITE); 
    if (!fAttemptedWrite) { 
    //        
    // .    , 
    //      . 
    RaiseExceptlon(SE_ZERO_ELEM, 0. 1. (LPDWORD) SIpbAttemptedAddr); 
    / 
    llllllllll/llllll/llllllllllllillllllllllllllllllllllllllllllllllillllHHIIIII 
    int ExpFilter (LPEXCEPTION_POINTERS IpEP, LPBYTE IpbArray, 
    LONG INumBytesInArray, HWND hwndLog) { 
    LPBYTE IpbAttemptedAddr = NULL: 

    . . . 

    572 _____________________________Windows   


    . 16-6  () 

    //   ,     
    DWORD dwExceptionCode = lpEP->ExceptionRecord->ExceptionCode; 
    
    // ,       
    //        
    int nFllterResult = EXCEPTION_CONTINUE_SEARCH; 
    try { 
    
    //   EXCEPTION_RECORD,    
    //  __try.   ,   except. 
    EXCEPTION_RECORD SavedExceptRec; 
    
    //   ,     
    // -      .  
    //        . 
    if (dwExceptionCode != EXGEPTION_AGCESS_VIOLATION) { 
    //         
    // , ,    -   
    //   .     
    //   . 
    nFilterResult = EXCEPTION_CONTINUE_SEARCH; 
    leave; 
    } 
    if (IpbArray == NULL) { 
    //       
    // ,      
    nFilterResult = EXCEPTION_CONTINUE_SEARCH: 
    _leave; 
    } 
    //  ,       
    IpbAttemptedAddr = (LPBYTE) 
    lpEP->ExceptionRecord->ExceptionInfonnation[1]; 
    if ((IpbAttemptedAddr < IpbArray) ',', 
    ((IpbArray + INumBytesInArray) < IpbAttemptedAddr)) { 
    //       
    //    ,   
    // .     . 
    nFllterResult = EXCEPTION_CONTINUE_SEARCH: 
    leave; 
    } 
    // ***      
    try { 
    //  ,     
    // .      
    //  .      
    //   .   . 
    ComnutMemory(hwndLog, IpEP, IpbAttemptedAddr); 

    . . . 

    ________________ 16.    573 

    . 16-6 () 

    I /       
    // ,      
    // .       
    //  ,   
    //  SE_ZERO_ELEM,   , 
    //      . 
    except ((GetExceptionCodeO == SE_ZERO_ELEM) ? (SavedExceptRec = 
    *((Get Exceptioninfrmation())->ExceptionRecord), 
    EXCEPTION_EXECUTE_HANDLER) : EXCEPTION_CONTINUE_SEARCH) { 
    //     
    
    LPELEMENT IpArrayElementToZero = (LPELEMENT) 
    SavedExceptRec.Exceptioninfrmation[0]: 
    
    //   ,     
    chINITSTRUCT(*lpArrayElernentToZero. FALSE); 
    ListBox_AddString(hwndLog, __("--> Zeroed array element")); 
    } 
    
    //   .    , 
    //  ,      , 
    //     . 
    nFilterResult = EXCEPTION_CONTINUE_EXECUTION; 
    } 
    finally { 
    } 
    //  ,      
    //  ,   
    return(nFilterResult); 
    } 
    1111111111111111111111111111111111111111111111111111111111111111111111111111111 
    void Dlg_ReserveArrayAndAccessIt (HWND hwndLog, int nNumAccesses) { 
    LPELEMENT IpArray = NULL: 
    ELEMENT Element; 
    TCHAR szBuf[100]; 
    int nElernentNum = 0; 
    const LONG INumBytesInArray = sizeof(ELEMENT) * NUMELEMENTS; 
    
    //    Execution Log 
    ListBox_ResetContent(hwndLog): 
    ListBox_AddString(hwndLog, __TEXT("Execution started")); 
    __try { 
    
    //   ,  
    //     NUMELEMENTS  ELEMENT 

    . . . 

    574 _____________________________Windows   

    . 16~6  () 
    
    IpArray = VirtualAlloc(NULL, INumBytesInArray, 
    MEM_RESERVE, PAGE_NOACCESS); 
    while (nNumAccesses) { 
    
    //     
    nElementNum = rand() % NUMELEMENTS: 
    
    //  / - 50  50 
    if ((randO % 2) == 0) { 
    //   
    _stprintf(szBuf, __TEXT("Reading index: %d"), nElementNum); 
    ListBox_AddString(hwndLog, szBuf); 
    
    //      
    Element = lpArray[nElenientNuni]; 
    } else { 
    
    //   
    _stprintf(szBuf, __TEXT( "Writing index: %d"), nElementNum); 
    ListBox_AddString(hwndLog, szBuf): 
    
    //      
    lpArray[nElementNum] = Element: 
    } 
    } // while 
    
    //   
    ListBox_AddString(hwndLog, __TEXT("Execution ended")); 
    
    //      ELEMENT 
    VirtualFree(lpArray, , MEM_RELEASE); 
    } // try 
    except ( 
    
    ExpFilter(GetExceptionInformation(), (LPBYTE) IpArray. 
    INumBytesInArray, hwndLog)) { 
    
    //      
    // EXCEPTION_EXECUTE_HANDLER,   
    //   
    } // except 
    } 
    ////////////////////////////////////////////////////////////////////////////// 
    BOOL Dlg_OnInitDialog (HWND hwnd, HWND hwndFocus, LPARAM IParam) { 

    . . . 

    ________________ 16.    575 


    . 16-6  () 
    
    II      
    chSETDLGICONS(hwnd, IDI_SEHSOFT, IDI_SEHSOFT); 
    
    //        - 100 
    SetDlgItemInt(hwnd, IDC_NUMACCESSES, 100, FALSE); 
    return(TRUE); 
    i 
    f 
    1111/llllltlll/llll/ll/ll/l/llllllllllllllllllillllll/lllillil/iillillllllllill 
    void Dlg_OnCommand (HWND hwnd, int id, HWND hwndCtI, UINT codeNotify) { 
    int nNumAccesses; 
    BOOL ^Translated; 
    switch (id) { 
    case IDOK: 
    nNumAccesses = GetDlgItemInt(hwnd, IDC_NUMACCESSES, ^Translated, FALSE); 
    If (fTranslated) { 
    Dlg_ReserveArrayAndAccessIt( 
    Get01gltem(hwnd. IDC_LOG), nNumAccesses); 
    } else { 
    chMB(__TEXT("Invalid number of accesses.")); 
    } 
    break: 
    case IDCANCEL: 
    EndDialog(hwnd, id); 
    break; 
    111111111111111/lllllllllllil/llll/ll/llll/l/llllillillllll/lllllll/lllllll/lll 
    
    BOOL CALLBACK Dlg_Proc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM 
IParam) { 
    switch (uMsg) { 
    chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog); 
    chHANOLE_DLGMSG(hwnd. WM_COMMAND, Dlg_OnCommand); 
    } 
    return(FALSE); 
    } 
    1111111111111111111111111111111111111111111111111111111111111111111111111111111 
    int WINAPI _tWinMain (HINSTANCE hinstExe, 
    HINSTANCE hinstPrev, LPTSTR pszCmdLine, int nCmdShow) { 
    chWARNIFUNICODEUNDERWIN95(): 
    D.i.alogBox(hinstExe, MAKEINTRESOURCE(IDD_SEHSOFT), NULL, Dlg_Proc); 
    return(O); 
    ) 
    //////////////////////////////////   I I I I I / I / I I I 1  / 

    576 _____________________________Windows   


      

       ,       
  ,   .  ,     
  ,     .   , 
      .     
.          
 EXCEPTION_DEBUG_INFO: 

    typedef struct _EXCEPTION_DEBUG_INFO { 
    EXCEPTION_RECORD ExceptionRecord; 
    DWORD dwFirstChance; 
    } EXCEPTION_DEBUG_INFO: 

        .  ExceptionRecord  
  ,       GetExceptionInformation.  
    ,    . 
 dwFirstChance   -  . 
         
       . 
             
,    .    
         
.      ,   
     ,      
EXCEPTION_EXECUTE_HANDLER  EXCEPTION_CONTINUE_EXECUTION.   
    ,   ,    
   . 
     ,   ,   ,  
  ,     .   
  dwFirstChance  EXCEPTION_DEBUG_INFO   0.  
 ,         
, ,    ,    . 

         

          EXCEPTION_CONTINUE_SEARCH   
  ?          
,    ,   
SEH-,     StartOfThread (.  4), 
    UnhandledExceptionFilter. 

    LONG UnhandledExceptionFilter 
    LPEXCEPTION_POINTERS IpexpExceptionInfo): 

    ,    UnhandledExceptionFilter,  , 
  , ,  ,  EXCEPTION_CONTINUE_SEARCH, 
        .    
 ,      , 
    .  Windows 95    
 : 

    _________________ 16.    577 


     This program has performed an illegal operation      n --_.__-,[ 
    ' and will be shut down.                            ^........."^-,,....! 
    If the problem persists, contact the program 
    vendor                                           ii 
    3EHTERM caused an invalid page fault in           ^ 
    module SEHTERM.EXB at; 0137:00401774. 
    Registers; 
    EAX=00000000 CS=0137 BIP=004Q1774 =010206 
    BBX=00540000 33=013f Eap=0064fd94 EBP=0064fda8 
    հ815744 D3=013f ESI=ei574d64 Fa=2iSb7 
    EDX=ei576278 63=013f EDI=81575e34 83=0000 
    Bytes at C3:EIP:                                         ',"; 
    8a 00 BB 15 ?8 6a 00 68 14 10 40 00 6 00 6a 01   | : -".':. 
      Windows NT  : 
    0 The inaruction at "000401774" referenced memory' at "000000000" The memory 
    could not be "read". 
    Click an OK to terminate the application 
    Click on CANCEL to debug the application 
    [i"OK'l| Cancel | 
    11-----1 J 

         Windows NT      
      .    
 -    ,     , 
  ,     . UnhandledExceptionFilter 
     Exceptionlnformation  
EXCEPTION_RECORD,    . 
           . -,  
 ,   UnhandledExceptionFilter   
EXCEPTION_EXECUTE_HANDLER.       
 ,    : 

    ExitProcess(GetExceptionCodeO): 

    -,   Cancel (    
 ).    UnhandledExceptionFilter  
      .     
 ,   ,    
  ,     . 
      ,          
.         
  .     ,  
    ,    ,    
    . , ,  ,   
  ,      .   , 
    ,     ?  
     .   
           Win32. 

    578 ____________________________Windows   

        UnhandkdExceptionFilter   
 , ,   ,  
UnhandledExceptionFilter  : 

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger 

      Visual C++ 4.       : 

    F:\MSDEV\BIN\MSDEV.EXE -p %ld -e %ld 

       ,    (MSDEV.EXE)   
  (      F:\MSDEV\BIN). UnhandledExceptionFilter 
 MSDEV.EXE     :    
 ,  ,    
    ,      
   UnhandledExceptionFilter. MSDEV   -p 
 -e      . 
           , 
UnhandledExceptionFilter    CreateProcess   
 .     ,  
DebugActiveProcess      : 

    BOOL DebugActlveProcess(DWORD idPr-ocess); 

         ,    
  (,        
  ,     ). 
      ,    
,   .      
,   SetEvent,    .   
   ,      
      .    
    ,   CreateProcess,     
,   UnhandledExceptionFilter   . 
    ,         , 
  ,  UnhandledExceptionFilter  
EXCEPTION_CONTINUE_SEARCH,       
.      ,    
   . 

         

     ,          
,  ,    .     
,         . 
     Cancel,        
    .    , 
      . -,   SetErrorMode: 

    UINT SetErrorMode(UINT fuErrorMode); 

       SEMJMOGPFAULTERRORBOX.  
UnhandledExceptionFilter    .   
 ,   . 
    -,      WinMain   
try-except. ,      
EXCEPTION_EXECUTE_HANDLER      ;  
  UnhandledExceptionFilter.     
WinMain        -  
.    

    _________________ 16.    579 

              
,        .  
    ,     
,   . 
         ,       
,     .     
   ,     
UnhandledExceptionFilter.     ,  
  try-except   WinMain,        . 
          , Microsoft   
 Win32 API  SetUnhandledExceptionFilter. 

    LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter( 
    LPTOP_LEVEL_EXCEPTION_FILTER IpTopLevelExceptionFllter); 

        ,      
,      .    
     SetUnhandledExceptionFilter. 
  -   : 

    LONG UnhandledExceptionFilter(LPEXCEPTION_POINTERS IpexpExceptionInfo); 

          UnhandledExceptionFilter.  
    ,      
    EXCEPTION_*.       
  : 

                           

    EXCEPTION_EXECUTE_HANDLER        ,    
       . 
    EXCEPTION_CONTINUE_EXECUTION    , 
 .    ,   
   LPEXCEPTION_POINTERS. 
    EXCEPTION_CONTINUE_SEARCH        \32- 
UnhandledExceptionFilter. 

      UnhandledExceptionFilter     , 
 SetUnhandledExceptionFilter   NULL.  ,  
 ,       , 
SetUnhandledExceptionFilter    .   
  UnhandledExceptionFilter,  NULL. 
         ,   
UnhandledExceptionFilter,    ,    
 .   ,   UnhandledExceptionFilter   
  : 

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Auto 

      Auto    0,  1.    
UnhandledExceptionFilter   ,     .   
      ,    
 . 

    580 _____________________________Windows   

       UnhandfedExcepf'ionFUter 

    UnhandledExceptionFilter   \32-,    
   .    : 

    void Funcadelic (void) { 
    try { 
    } 
    except (ExpFltr(GetExceptlonInformation())) { 
    } 
    LONG ExpFltr (LPEXCEPTION_POINTERS IpEP) { 
    DWORD dwExceptionCode = lpEP->ExceptionRecord.ExceptionCode; 
    if (dwExceptionCode == EXCEPTION_ACCESS_VIOLATION) { 
    //  - ... 
    return(EXCEPTION_CONTINUE_EXECUTION): 
    } 
    return(UnhandledException Filter(IpEP)): 
    } 

       try  Funcadelic    ExpFltr.  
 ,  GetExceptionInformation.   
      EXCEPTION_ACCESS_VIOLATION.  
  ,      
EXCEPTION_CONTINUE_EXECUTION.      
   ,  . 
      -  , ExpFltr  
UnhandledExceptionFilter,     EXCEPTION_POINTERS. 
UnhandledExceptionFilter  ,     
 .  ExpFltr       
UnhandledExceptionFilter. 

     Windows NT:      

         ,  ,  
  User,            
  ,     User.     
     ,  ,   
    ,    .  
  ,   .      
,      ,    
.   ! 
             
  , Windows NT   UnhandledExceptionFilter. 
      ,  - 
 ,   .    
      Microsoft,      
   .    ,  
 ;      . 
