home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / samples1.exe / MetaInfo / mdobj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  9.1 KB  |  275 lines

  1. //*****************************************************************************
  2. // File: mdobj.cpp
  3. //
  4. // Copyright (c) 1997-1998 Microsoft Corporation.  All Rights Reserved.
  5. // Microsoft Confidential.
  6. //*****************************************************************************
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include <crtdbg.h>
  10. #include "mdinfo.h"
  11.  
  12. #ifndef STRING_BUFFER_LEN
  13. #define STRING_BUFFER_LEN 255
  14. #endif
  15.  
  16. #define OBJ_EXT         ".obj"
  17. #define OBJ_EXT_LEN     4
  18. #define LIB_EXT         ".lib"
  19. #define LIB_EXT_LEN     4
  20.  
  21. extern IMetaDataDispenserEx *g_pDisp;
  22.  
  23. // This function is copied from peparse.c file.  Making this static, so we won't end up with
  24. // duplicate definitions causing confusion.
  25. static const char g_szCORMETA[] = ".cormeta";
  26. static HRESULT FindObjMetaData(PVOID pImage, PVOID *ppMetaData, long *pcbMetaData)
  27. {
  28.     IMAGE_FILE_HEADER *pImageHdr;       // Header for the .obj file.
  29.     IMAGE_SECTION_HEADER *pSectionHdr;  // Section header.
  30.     WORD        i;                      // Loop control.
  31.  
  32.     // Get a pointer to the header and the first section.
  33.     pImageHdr = (IMAGE_FILE_HEADER *) pImage;
  34.     pSectionHdr = (IMAGE_SECTION_HEADER *)(pImageHdr + 1);
  35.  
  36.     // Avoid confusion.
  37.     *ppMetaData = NULL;
  38.     *pcbMetaData = 0;
  39.  
  40.     // Walk each section looking for .cormeta.
  41.     for (i=0;  i<pImageHdr->NumberOfSections;  i++, pSectionHdr++)
  42.     {
  43.         // Simple comparison to section name.
  44.         if (strcmp((const char *) pSectionHdr->Name, g_szCORMETA) == 0)
  45.         {
  46.             *pcbMetaData = pSectionHdr->SizeOfRawData;
  47.             *ppMetaData = (void *) ((long) pImage + pSectionHdr->PointerToRawData);
  48.             break;
  49.         }
  50.     }
  51.  
  52.     // Check for errors.
  53.     if (*ppMetaData == NULL || *pcbMetaData == 0)
  54.         return (E_FAIL);
  55.     return (S_OK);
  56. }
  57.  
  58.  
  59. // This function returns the address to the MapView of file and file size.
  60. void GetMapViewOfFile(char *szFile, PBYTE *ppbMap, DWORD *pdwFileSize)
  61. {
  62.     HANDLE      hMapFile;
  63.     DWORD       dwHighSize;
  64.  
  65.     HANDLE hFile = CreateFileA(szFile,
  66.                                GENERIC_READ,
  67.                                FILE_SHARE_READ,
  68.                                NULL,
  69.                                OPEN_EXISTING,
  70.                                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
  71.                                NULL); 
  72.     if (hFile == INVALID_HANDLE_VALUE) 
  73.         MDInfo::Error("CreateFileA failed!");
  74.  
  75.     *pdwFileSize = GetFileSize(hFile, &dwHighSize);
  76.  
  77.     if ((*pdwFileSize == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
  78.         MDInfo::Error("GetFileSize failed!");
  79.     _ASSERTE(dwHighSize == 0);
  80.  
  81.     hMapFile = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  82.     CloseHandle(hFile);
  83.     if (!hMapFile)
  84.         MDInfo::Error("CreateFileMappingA failed!");
  85.  
  86.     *ppbMap = (PBYTE) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
  87.     CloseHandle(hMapFile);
  88.     
  89.     if (!*ppbMap)
  90.         MDInfo::Error("MapViewOfFile failed!");
  91. } // void GetMapViewOfFile()
  92.  
  93. // This function skips a member given the pointer to the member header
  94. // and returns a pointer to the next header.
  95. PBYTE SkipMember(PBYTE pbMapAddress)
  96. {
  97.     PIMAGE_ARCHIVE_MEMBER_HEADER pMemHdr;
  98.     ULONG       ulMemSize;
  99.     int         j;
  100.  
  101.     pMemHdr = (PIMAGE_ARCHIVE_MEMBER_HEADER)pbMapAddress;
  102.  
  103.     // Get size of the member.
  104.     ulMemSize = 0;
  105.     for (j = 0; j < 10; j++)
  106.     {
  107.         if (pMemHdr->Size[j] < '0' || pMemHdr->Size[j] > '9')
  108.             break;
  109.         else
  110.             ulMemSize = ulMemSize * 10 + pMemHdr->Size[j] - '0';
  111.     }
  112.  
  113.     // Skip past the header.
  114.     pbMapAddress += IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR + ulMemSize;
  115.     // Find the next even address if the current one is not even.
  116.     if ((ULONG)pbMapAddress % 2)
  117.         pbMapAddress++;
  118.  
  119.     return pbMapAddress;
  120. } // void SkipMember()
  121.  
  122. // This function returns the name of the given Obj.  If the name fits in the header,
  123. // szBuf will be filled in and returned from the function.  Else an offset into the long
  124. // names section will be returned.
  125. char *GetNameOfObj(PBYTE pbLongNames, PIMAGE_ARCHIVE_MEMBER_HEADER pMemHdr, char szBuf[17])
  126. {
  127.     if (pMemHdr->Name[0] == '/')
  128.     {
  129.         ULONG   ulOffset = 0;
  130.  
  131.         // Long Names section must exist if the .obj file name starts with '/'.
  132.         _ASSERTE(pbLongNames &&
  133.             "Corrupt archive file - .obj file name in the header starts with "
  134.             "'/' but no long names section present in the archive file.");
  135.  
  136.         // Calculate the offset into the long names section.
  137.         for (int j = 1; j < 16; j++)
  138.         {
  139.             if (pMemHdr->Name[j] < '0' || pMemHdr->Name[j] > '9')
  140.                 break;
  141.             else
  142.                 ulOffset = ulOffset * 10 + pMemHdr->Name[j] - '0';
  143.         }
  144.         return (char *)(pbLongNames + ulOffset);
  145.     }
  146.     else
  147.     {
  148.         for (int j = 0; j < 16; j++)
  149.             if ((szBuf[j] = pMemHdr->Name[j]) == '/')
  150.                 break;
  151.         szBuf[j] = '\0';
  152.         return szBuf;
  153.     }
  154. } // char *GetNameOfObj()
  155.  
  156. // DisplayArchive() function
  157. //
  158. // Opens the .LIB file, and displays the metadata in the specified object files.
  159.  
  160. void DisplayArchive(char* szFile, ULONG DumpFilter, char* szObjName, strPassBackFn pDisplayString)
  161. {
  162.     PBYTE       pbMapAddress;
  163.     PBYTE       pbStartAddress;
  164.     PBYTE       pbLongNameAddress;
  165.     PIMAGE_ARCHIVE_MEMBER_HEADER pMemHdr;
  166.     DWORD       dwFileSize;
  167.     PVOID       pvMetaData;
  168.     char        *szName;
  169.     char        szBuf[17];
  170.     long        cbMetaData;
  171.     int         i;
  172.     HRESULT     hr;
  173.     char        szString[1024];
  174.  
  175.     GetMapViewOfFile(szFile, &pbMapAddress, &dwFileSize);
  176.     pbStartAddress = pbMapAddress;
  177.  
  178.     // Verify and skip archive signature.
  179.     if (dwFileSize < IMAGE_ARCHIVE_START_SIZE ||
  180.         strncmp((char *)pbMapAddress, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
  181.     {
  182.         MDInfo::Error("Bad file format - archive signature mis-match!");
  183.     }
  184.     pbMapAddress += IMAGE_ARCHIVE_START_SIZE;
  185.  
  186.     // Skip linker member 1, linker member 2.
  187.     for (i = 0; i < 2; i++)
  188.         pbMapAddress = SkipMember(pbMapAddress);
  189.  
  190.     // Save address of the long name member and skip it if there exists one.
  191.     pMemHdr = (PIMAGE_ARCHIVE_MEMBER_HEADER)pbMapAddress;
  192.     if (pMemHdr->Name[0] == '/' && pMemHdr->Name[1] == '/')
  193.     {
  194.         pbLongNameAddress = pbMapAddress + IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR;
  195.         pbMapAddress = SkipMember(pbMapAddress);
  196.     }
  197.     else
  198.         pbLongNameAddress = 0;
  199.  
  200.     pDisplayString ("\n");
  201.     // Get the MetaData for each object file and display it.
  202.     while (DWORD(pbMapAddress - pbStartAddress) < dwFileSize)
  203.     {
  204.         szName = GetNameOfObj(pbLongNameAddress, (PIMAGE_ARCHIVE_MEMBER_HEADER)pbMapAddress, szBuf);
  205.  
  206.         // Display metadata only for object files.
  207.         // If szObjName is specified, display metadata only for that one object file.
  208.         if (!strcmp(&szName[strlen(szName) - OBJ_EXT_LEN], OBJ_EXT) && 
  209.             (!szObjName || !strcmp(szObjName, szName)))
  210.         {
  211.             // Try to find the MetaData section in the current object file.
  212.             hr = FindObjMetaData(pbMapAddress+IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR, &pvMetaData, &cbMetaData);
  213.             if (SUCCEEDED(hr))
  214.             {
  215.                 sprintf (szString,"MetaData for object file %s:\n", szName);
  216.                 pDisplayString(szString);
  217.                 MDInfo archiveInfo(g_pDisp,
  218.                                 (PBYTE)pvMetaData,
  219.                                 cbMetaData,
  220.                                 pDisplayString,
  221.                                 DumpFilter);
  222.                 archiveInfo.DisplayMD();
  223.             }
  224.             else
  225.             {
  226.                 sprintf(szString,"MetaData not found for object file %s!\n\n", szName);
  227.                 pDisplayString(szString);
  228.             }
  229.         }
  230.  
  231.         // Skip past the object file.
  232.         pbMapAddress = SkipMember(pbMapAddress);
  233.     }
  234.  
  235.     UnmapViewOfFile(pbStartAddress);
  236. } // void DisplayArchive()
  237.  
  238. // DisplayFile() function
  239. //
  240. // Opens the meta data content of a .EXE, .CLB, .CLASS, .TLB, .DLL or .LIB file, and
  241. // calls RawDisplay()
  242.  
  243. void DisplayFile(char* szFile, BOOL isFile, ULONG DumpFilter, char* szObjName, strPassBackFn pDisplayString)
  244. {
  245.     HRESULT hr=S_OK;
  246.  
  247.     // Open the emit scope
  248.     WCHAR szScope[STRING_BUFFER_LEN];
  249.     WCHAR *pFile;
  250.     char szString[1024];
  251.  
  252.     if (isFile)
  253.         pFile = wcscpy(szScope, L"file:") + 5;
  254.     else
  255.         pFile = szScope;
  256.     mbstowcs(pFile, szFile, sizeof(szScope)-1-(pFile-szScope));
  257.  
  258.     // print bar that separates different files
  259.     pDisplayString("////////////////////////////////////////////////////////////////\n");
  260.     char rcFname[_MAX_FNAME], rcExt[_MAX_EXT];
  261.  
  262.     _splitpath(szFile, 0, 0, rcFname, rcExt);
  263.     sprintf(szString,"\nFile %s%s: \n",rcFname, rcExt);
  264.     pDisplayString(szString);
  265.  
  266.     if (!lstrcmpi(rcExt, LIB_EXT))
  267.         DisplayArchive(szFile, DumpFilter, szObjName, pDisplayString);
  268.     else
  269.     {
  270.         MDInfo metaDataInfo(g_pDisp, szScope, pDisplayString, DumpFilter);
  271.         metaDataInfo.DisplayMD();
  272.     }
  273. } // void DisplayFile()
  274.  
  275.