home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_03 / Handles / Snapshot.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-11  |  6.8 KB  |  263 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : snapshot.cpp                                                         //
  10. //  Description: Virtual memory snapshot                                             //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define WIN32_LEAN_AND_MEAN
  16.  
  17. #include <windows.h>
  18. #include <assert.h>
  19. #include <stdio.h>
  20.  
  21. #include "listview.h"
  22. #include "dialog.h"
  23. #include "pefile.h"
  24.  
  25. #include "Snapshot.h"
  26. #include "Resource.h"
  27. #include "MemView.h"
  28.  
  29. typedef struct
  30. {
  31.     unsigned id;
  32.     const char * key;
  33. } Word;
  34.  
  35.  
  36. void AddFlags(char * rslt, unsigned value, const Word * dic, int no);
  37.  
  38.  
  39. const Word Protections[] = 
  40. {
  41.     { PAGE_READONLY,          "ro  " },
  42.     { PAGE_READWRITE,         "rw  " }, 
  43.     { PAGE_WRITECOPY,         "wc  " }, 
  44.     { PAGE_EXECUTE,           "e   " }, 
  45.     { PAGE_EXECUTE_READ,      "er  " }, 
  46.     { PAGE_EXECUTE_READWRITE, "erw " },
  47.     { PAGE_EXECUTE_WRITECOPY, "ewc " }, 
  48.     { PAGE_GUARD,             "grd " }, 
  49.     { PAGE_NOACCESS,          "nac " }, 
  50.     { PAGE_NOCACHE,           "ncc " }
  51. };    
  52.  
  53.  
  54. void AddFlags(char * rslt, unsigned value, const Word * dic, int no)
  55. {
  56.     for (int i=0; i<no; i++)
  57.         if ( value & dic[i].id )
  58.             strcat(rslt, dic[i].key);
  59. }
  60.  
  61.  
  62. KRegion * KSnapShot::FindRegion(unsigned char * regionstart, unsigned regionsize)
  63. {
  64.     // search for a region with same start and size
  65.     for (int r=0; r<m_nRegionNo; r++)
  66.         if ( ( m_Regions[r].start == regionstart ) &&
  67.              ( m_Regions[r].size  == regionsize ) )
  68.              return & m_Regions[r];
  69.  
  70.     // add a new region
  71.     if ( m_nRegionNo < nMaxRegionNo )
  72.     {
  73.         m_Regions[m_nRegionNo].start = regionstart;
  74.         m_Regions[m_nRegionNo].size  = regionsize;
  75.         m_Regions[m_nRegionNo].count = 0;
  76.  
  77.         return & m_Regions[m_nRegionNo++];
  78.     }
  79.     else
  80.         return NULL;
  81. }
  82.  
  83.  
  84. void KSnapShot::Shot(KListView * list)
  85. {
  86.     unsigned char * start = NULL;
  87.     MEMORY_BASIC_INFORMATION info;
  88.  
  89.     KPEFile  module;
  90.     void   * lastmodule = NULL;
  91.     
  92.     typedef enum { nMaxHeaps = 10 };
  93.     HANDLE   ProcHeaps[nMaxHeaps];
  94.  
  95.     int heaps = GetProcessHeaps(nMaxHeaps, ProcHeaps);
  96.  
  97.     while ( VirtualQuery(start, & info, sizeof(info)) )
  98.     {
  99.         KRegion * pRegion = NULL;
  100.  
  101.         // compute CRC for committed region
  102.         if (info.State == MEM_COMMIT)
  103.         {
  104.             pRegion = FindRegion(start, info.RegionSize);        
  105.             if (pRegion)
  106.             {
  107.                 pRegion->type    = info.Type;
  108.                 pRegion->lastcrc = pRegion->crc;
  109.                 pRegion->crc     = m_crc.Update(0, start, info.RegionSize);
  110.                 pRegion->count ++;
  111.             }
  112.         }
  113.         
  114.         if (list)
  115.         {
  116.             TCHAR temp[MAX_PATH];
  117.             const TCHAR * p ;
  118.  
  119.             if ( pRegion && pRegion->count>=2 )
  120.             {
  121.                 wsprintf(temp, "%04x", pRegion->lastcrc);
  122.                 list->AddItem(0, temp, ( pRegion->lastcrc != pRegion->crc ) + 1);
  123.             }
  124.             else
  125.                 list->AddItem(0, "     ", 0);
  126.  
  127.             if ( pRegion )
  128.             {
  129.                 wsprintf(temp, "%04x", pRegion->crc);
  130.                 list->AddItem(1, temp);
  131.             }
  132.             
  133.             wsprintf(temp, "%08lx", info.BaseAddress);    list->AddItem(2, temp);
  134.             wsprintf(temp, "%08lx", info.RegionSize);   list->AddItem(3, temp);
  135.  
  136.             switch (info.State)
  137.             {
  138.                 case MEM_FREE:    p = "F "; break;
  139.                 case MEM_RESERVE: p = "R "; break;
  140.                 case MEM_COMMIT:  p = "C "; break;
  141.                 default:          p = "? ";   
  142.             }
  143.             strcpy(temp, p);
  144.  
  145.             if ( info.State != MEM_FREE)
  146.             {
  147.                 switch (info.Type)
  148.                 {
  149.                     case MEM_IMAGE:   p = "I "; break;
  150.                     case MEM_MAPPED:  p = "M "; break;
  151.                     case MEM_PRIVATE: p = "P "; break;
  152.                     default:          p = "? ";
  153.                 }
  154.                 strcat(temp, p);
  155.  
  156.                 AddFlags(temp, info.AllocationProtect, Protections, sizeof(Protections)/sizeof(Protections[0]));
  157.             }
  158.             list->AddItem(4, temp);
  159.  
  160. /*
  161.             char t[MAX_PATH];
  162.             wsprintf(t, "%8lx ", info.AllocationBase);
  163.             strcat(temp, t);
  164.  
  165.             if (info.State != MEM_RESERVE)
  166.                 AddFlags(temp, info.Protect, Protections, sizeof(Protections)/sizeof(Protections[0]));
  167. */
  168.  
  169.             if (info.State != MEM_FREE )
  170.                 if ( GetModuleFileName((HINSTANCE) info.BaseAddress, temp, sizeof(temp)) )
  171.                 {
  172.                     if (lastmodule)
  173.                     {
  174.                         module.Unload();
  175.                         lastmodule = NULL;
  176.                     }
  177.                 
  178.                     if ( module.Load(temp) )
  179.                         lastmodule = info.BaseAddress;
  180.  
  181.                     // remove the directory path, keep only the filename
  182.                     if ( strchr(temp, '\\') )
  183.                     {
  184.                         for (char *p = strchr(temp, '\\') + 1;
  185.                                        strchr(p, '\\');
  186.                                    p = strchr(p, '\\') + 1);
  187.                         list->AddItem(5, p);
  188.                     }
  189.                     else 
  190.                         list->AddItem(5, temp);
  191.                 }
  192.                 else
  193.                 {
  194.                     const char * p = NULL;
  195.  
  196.                     if (lastmodule != NULL)
  197.                         p = module.GetSectionName((unsigned) info.BaseAddress - (unsigned) lastmodule);
  198.  
  199.                     if (p == NULL)
  200.                         for (int h=0; h<heaps; h++)
  201.                             if ( info.BaseAddress == ProcHeaps[h] )
  202.                             {
  203.                                 wsprintf(temp, "Heap %d", h+1);
  204.                                 p = temp;
  205.                                 break;
  206.                             }
  207.  
  208.                     if (p == NULL)
  209.                         if ( ( (unsigned) (& p) >= (unsigned) info.BaseAddress ) &&
  210.                              ( (unsigned) (& p) <  (unsigned) info.BaseAddress + info.RegionSize ) )
  211.                             p = "Stack";
  212.  
  213.                     if ( p )
  214.                         list->AddItem(5, p);
  215.                 }
  216.                             
  217.         }
  218.  
  219.         start += info.RegionSize;
  220.  
  221.         if (start == 0)
  222.             break;
  223.     }
  224.  
  225.     if (lastmodule)
  226.         module.Unload();
  227. }
  228.  
  229.  
  230. void KSnapShot::ShowDetail(HINSTANCE hInst, unsigned start, unsigned size)
  231. {
  232.     KMemViewer memory(start, size);
  233.  
  234.     memory.Dialogbox(hInst, MAKEINTRESOURCE(IDD_MEMORY));
  235. }
  236.  
  237.  
  238. /*
  239. void CSnapShot::Compare(CSnapShot & after)
  240. {
  241.     if (m_nRegionNo != after.m_nRegionNo)
  242.         OutputDebugString("Region No different\n");
  243.  
  244.     for (int i=0; i<min(m_nRegionNo, after.m_nRegionNo); i++)
  245.     {
  246.         CRegion & r1 = m_Regions[i];
  247.         CRegion & r2 = after.m_Regions[i];
  248.  
  249.         if ( ( r1.start != r2.start ) || ( r1.size  != r2.size  ) ||
  250.              ( r1.type  != r2.type  ) || ( r1.crc   != r2.crc   ) )
  251.         {
  252.             TCHAR temp[MAX_PATH];
  253.  
  254.             wsprintf(temp, "%3d { %8x %8x %8x %4x } -> { %8x %8x %8x %4x } \n",
  255.                             i, 
  256.                             r1.start, r1.size, r1.type, r1.crc,
  257.                             r2.start, r2.size, r2.type, r2.crc);
  258.             OutputDebugString(temp);
  259.         }            
  260.     }
  261. }
  262. */
  263.