Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
5.9 KiB

  1. // File32.cpp: implementation of the File32 class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include <windows.h>
  5. #include <imagehlp.h>
  6. #include <stdio.h>
  7. #include "File32.h"
  8. #include "depend.h"
  9. //////////////////////////////////////////////////////////////////////
  10. // Construction/Destruction
  11. //////////////////////////////////////////////////////////////////////
  12. //pszFileName - file to be loaded, including path
  13. File32::File32(TCHAR *pszFileName) : File(pszFileName)
  14. {
  15. HANDLE hFileMap;
  16. //open the file
  17. if ((hFile = CreateFile(pszFileName,GENERIC_READ,0,0,OPEN_EXISTING,0,0)) == INVALID_HANDLE_VALUE) {
  18. if(bNoisy) {
  19. _putws( GetFormattedMessage( ThisModule,
  20. FALSE,
  21. Message,
  22. sizeof(Message)/sizeof(Message[0]),
  23. MSG_ERROR_FILE_OPEN,
  24. pszFileName) );
  25. }
  26. dwERROR = errFILE_LOCKED;
  27. throw errFILE_LOCKED;
  28. }
  29. //create a memory map
  30. hFileMap = CreateFileMapping(hFile,0,PAGE_READONLY,0,0,0);
  31. pImageBase = MapViewOfFile(hFileMap,FILE_MAP_READ,0,0,0);
  32. //try to create an NTHeader structure to give file information
  33. if (pNthdr = ImageNtHeader(pImageBase)) {
  34. if (pNthdr->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) return;
  35. else { CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE; throw 0; }
  36. } else {
  37. CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE; throw 0; }
  38. }
  39. File32::~File32()
  40. {
  41. delete pImageBase;
  42. pImageBase = 0;
  43. }
  44. //Checks the dependencies of this file, and adds the dependencies to the queue so
  45. //their dependencies can be checked later
  46. //If a file comes up missing add it to the MissingFiles queue. Add the file that was looking for it to the missing files'
  47. //list of broken files.
  48. //This function has logic in it to handle the special case of 'ntoskrnl.exe'. If a file is
  49. //looking for 'ntoskrnl.exe' and it is missing then the function also looks for 'ntkrnlmp.exe'
  50. void File32::CheckDependencies() {
  51. char *pszDllName = new char[256];
  52. TCHAR*pwsDllName = new TCHAR[256],*pszBuf = new TCHAR[256],*pszBufName;
  53. int temp = 0;
  54. File* pTempFile;
  55. DWORD dwOffset;
  56. DWORD dwVA = pNthdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  57. PIMAGE_SECTION_HEADER pSectHdr = IMAGE_FIRST_SECTION( pNthdr ),pImportHdr = 0;
  58. PIMAGE_IMPORT_DESCRIPTOR pImportDir;
  59. //figure out which section the imports table is in
  60. for ( unsigned i = 0; i < pNthdr->FileHeader.NumberOfSections; i++, pSectHdr++ ) {
  61. DWORD cbMaxOnDisk = min( pSectHdr->Misc.VirtualSize, pSectHdr->SizeOfRawData );
  62. DWORD startSectRVA = pSectHdr->VirtualAddress;
  63. DWORD endSectRVA = startSectRVA + cbMaxOnDisk;
  64. if ( (dwVA >= startSectRVA) && (dwVA < endSectRVA) ) {
  65. dwOffset = pSectHdr->PointerToRawData + (dwVA - startSectRVA);
  66. pImportHdr = pSectHdr;
  67. i = pNthdr->FileHeader.NumberOfSections;
  68. }
  69. }
  70. //if we found the imports table, create a pointer to it
  71. if (pImportHdr) {
  72. pImportDir = (PIMAGE_IMPORT_DESCRIPTOR) (((PBYTE)pImageBase) + (DWORD)dwOffset);
  73. //go through each import, try and find it, and add it to the queue
  74. while ((DWORD)(pImportDir->Name)!=0) {
  75. strcpy(pszDllName,(char*)(pImportDir->Name + ((PBYTE)pImageBase) - pImportHdr->VirtualAddress + pImportHdr->PointerToRawData));
  76. _strlwr(pszDllName);
  77. //if the ListDependencies flag is set, add this file to the dependencies list
  78. if (bListDependencies) {
  79. MultiByteToWideChar(CP_ACP,0,pszDllName,-1,pwsDllName,256);
  80. if (!dependencies->Find(pwsDllName)) dependencies->Add(new StringNode(pwsDllName));
  81. }
  82. //if this isn't ntoskrnl.exe
  83. if (strcmp(pszDllName,"ntoskrnl.exe")) {
  84. //if the file is already known to be missing
  85. temp = MultiByteToWideChar(CP_ACP,0,pszDllName,-1,pwsDllName,256);
  86. if (pTempFile = (File*)pMissingFiles->Find(pwsDllName)) {
  87. dwERROR = errMISSING_DEPENDENCY;
  88. //add this file to the list of broken files
  89. pTempFile->AddDependant(new StringNode(fileName));
  90. } else {
  91. //either search the windows path or the path specified in the command line
  92. if ( ((!pSearchPath)&&(!(SearchPath(0,pwsDllName,0,256,pszBuf,&pszBufName))))|| ((pSearchPath)&&(!SearchPath(pwsDllName,pszBuf))) ) {
  93. //if the file is not found, add it to missing files list and throw an error
  94. pMissingFiles->Add(new File(pwsDllName));
  95. ((File*)(pMissingFiles->head))->AddDependant(new StringNode(fileName));
  96. dwERROR = errMISSING_DEPENDENCY;
  97. if (!bNoisy) goto CLEANUP;
  98. }
  99. else {
  100. //if the file is found, add it to the queue
  101. _wcslwr(pszBuf);
  102. if (!(pQueue->Find(pszBuf))) pQueue->Add(new StringNode(pszBuf));
  103. }
  104. }
  105. } else {
  106. //if the file is already known to be missing
  107. if ((pTempFile = (File*)pMissingFiles->Find(L"ntoskrnl.exe"))) {
  108. dwERROR = errMISSING_DEPENDENCY;
  109. pTempFile->AddDependant(new StringNode(fileName));
  110. } else {
  111. //either search the windows path or the path specified in the command line
  112. if ( (((!pSearchPath)&&(!(SearchPath(0,L"ntoskrnl.exe",0,256,pszBuf,&pszBufName))))||((pSearchPath)&&(!SearchPath(L"ntoskrnl.exe",pszBuf))))
  113. &&(((!pSearchPath)&&(!(SearchPath(0,L"ntkrnlmp.exe",0,256,pszBuf,&pszBufName))))||((pSearchPath)&&(!SearchPath(L"ntkrnlmp.exe",pszBuf))))) {
  114. //if the file is not found, add it to missing files list and throw an error
  115. pMissingFiles->Add(new File(L"ntoskrnl.exe"));
  116. ((File*)(pMissingFiles->head))->AddDependant(new StringNode(fileName));
  117. dwERROR = errMISSING_DEPENDENCY;
  118. if (!bNoisy) goto CLEANUP;
  119. }
  120. else {
  121. //if the file is found, add it to the queue
  122. _wcslwr(pszBuf);
  123. if (!(pQueue->Find(pszBuf))) pQueue->Add(new StringNode(pszBuf));
  124. }
  125. }
  126. }
  127. pImportDir++;
  128. }
  129. }
  130. CLEANUP:
  131. delete [] pszDllName;
  132. delete [] pszBuf;
  133. }