Leaked source code of windows server 2003
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.

210 lines
5.1 KiB

  1. // PELDR.CXX kernel32
  2. //
  3. // (C) Copyright Microsoft Corp., 1988-1994
  4. //
  5. // Swiped without thanks from the Win32 loader
  6. //
  7. #include <cdlpch.h>
  8. extern int g_CPUType;
  9. HRESULT
  10. GetMachineTypeOfFile(const char *szName, LPDWORD pdwMachine)
  11. {
  12. DEBUG_ENTER((DBG_DOWNLOAD,
  13. Hresult,
  14. "GetMachineTypeOfFile",
  15. "%.80q, %#x",
  16. szName, pdwMachine
  17. ));
  18. IMAGE_DOS_HEADER idh;
  19. IMAGE_NT_HEADERS nth;
  20. DWORD cbT;
  21. DWORD size;
  22. DWORD dwBytesRead = 0;
  23. HANDLE dfhFile = INVALID_HANDLE_VALUE;
  24. HRESULT hr = S_OK;
  25. *pdwMachine = IMAGE_FILE_MACHINE_UNKNOWN;
  26. if ( (dfhFile = CreateFile(szName, GENERIC_READ, FILE_SHARE_READ,
  27. NULL, OPEN_EXISTING,
  28. FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE) {
  29. hr = HRESULT_FROM_WIN32(GetLastError());
  30. goto Exit;
  31. }
  32. // Read DOS header
  33. if ((!ReadFile(dfhFile, &idh, sizeof(idh), &dwBytesRead, NULL)) ||
  34. (idh.e_magic != 0x5a4d)) {
  35. // not PE file!
  36. hr = HRESULT_FROM_WIN32(GetLastError());
  37. if (SUCCEEDED(hr)) {
  38. // not enough bytes read
  39. hr = HRESULT_FROM_WIN32(ERROR_INVALID_EXE_SIGNATURE);
  40. }
  41. goto Exit;
  42. }
  43. // Read PE header
  44. SetFilePointer (dfhFile, idh.e_lfanew, NULL, FILE_BEGIN);
  45. if ((!ReadFile(dfhFile, &nth, sizeof(IMAGE_NT_HEADERS), &dwBytesRead, NULL))) {
  46. hr = HRESULT_FROM_WIN32(GetLastError());
  47. if (SUCCEEDED(hr)) {
  48. // not enough bytes read
  49. hr = HRESULT_FROM_WIN32(ERROR_INVALID_EXE_SIGNATURE);
  50. }
  51. goto Exit;
  52. }
  53. cbT = dwBytesRead;
  54. // Valid PE header?
  55. if ((cbT != sizeof(IMAGE_NT_HEADERS)) || (nth.Signature != 0x00004550)) {
  56. // not PE file!
  57. hr = HRESULT_FROM_WIN32(ERROR_INVALID_EXE_SIGNATURE);
  58. goto Exit;
  59. }
  60. *pdwMachine = nth.FileHeader.Machine;
  61. Exit:
  62. if (dfhFile != INVALID_HANDLE_VALUE)
  63. CloseHandle(dfhFile);
  64. DEBUG_LEAVE(hr);
  65. return hr ;
  66. }
  67. HRESULT
  68. IsCompatibleType(DWORD dwBinaryType)
  69. {
  70. DEBUG_ENTER((DBG_DOWNLOAD,
  71. Hresult,
  72. "IsCompatibleType",
  73. "%#x",
  74. dwBinaryType
  75. ));
  76. int CPUType = PROCESSOR_ARCHITECTURE_UNKNOWN;
  77. switch (dwBinaryType) {
  78. case IMAGE_FILE_MACHINE_AMD64:
  79. CPUType = PROCESSOR_ARCHITECTURE_AMD64;
  80. break;
  81. case IMAGE_FILE_MACHINE_I386:
  82. #ifdef WX86
  83. if (g_fWx86Present) {
  84. // Wx86 is installed - I386 images are OK.
  85. DEBUG_LEAVE(S_OK);
  86. return S_OK;
  87. }
  88. #endif
  89. CPUType = PROCESSOR_ARCHITECTURE_INTEL;
  90. break;
  91. case IMAGE_FILE_MACHINE_IA64:
  92. CPUType = PROCESSOR_ARCHITECTURE_IA64;
  93. break;
  94. }
  95. DEBUG_ENTER((DBG_DOWNLOAD,
  96. Hresult,
  97. "IsCompatibleType:comparing",
  98. "%#x Vs %#x (PROCESSOR_ARCHITECTURE_UNKNOWN)=%#x, (PROCESSOR_ARCHITECTURE_INTEL)=%#x, (IMAGE_FILE_MACHINE_I386)=%#x ",
  99. g_CPUType, CPUType, PROCESSOR_ARCHITECTURE_UNKNOWN, PROCESSOR_ARCHITECTURE_INTEL, IMAGE_FILE_MACHINE_I386
  100. ));
  101. HRESULT hr = (g_CPUType == CPUType)?S_OK:HRESULT_FROM_WIN32(ERROR_EXE_MACHINE_TYPE_MISMATCH);
  102. DEBUG_LEAVE(hr);
  103. DEBUG_LEAVE(hr);
  104. return hr;
  105. }
  106. // IsCompatibleFile(const char *szFileName, LPDWORD lpdwMachineType=NULL);
  107. // returns:
  108. // S_OK: file is compatible install it and LoadLibrary it
  109. // S_FALSE: file is not a PE
  110. // ERROR_EXE_MACHINE_TYPE_MISMATCH: not compatible
  111. HRESULT
  112. IsCompatibleFile(const char *szFileName, LPDWORD lpdwMachineType)
  113. {
  114. DEBUG_ENTER((DBG_DOWNLOAD,
  115. Hresult,
  116. "IsCompatibleFile",
  117. "%.80q, %#x",
  118. szFileName, lpdwMachineType
  119. ));
  120. DWORD dwMachine = 0;
  121. HRESULT hr = GetMachineTypeOfFile(szFileName, &dwMachine);
  122. if (SUCCEEDED(hr)) {
  123. hr = IsCompatibleType(dwMachine);
  124. } else {
  125. hr = S_FALSE;
  126. }
  127. if (lpdwMachineType)
  128. *lpdwMachineType = dwMachine;
  129. DEBUG_LEAVE(hr);
  130. return hr;
  131. }
  132. // IsRegisterableDLL(const char *szFileName)
  133. // returns:
  134. // S_OK: file is registerable, LoadLibrary and call GetProcAddress
  135. // S_FALSE: file is not registerable
  136. HRESULT
  137. IsRegisterableDLL(const char *szFileName)
  138. {
  139. DEBUG_ENTER((DBG_DOWNLOAD,
  140. Hresult,
  141. "IsRegisterableDLL",
  142. "%.80q",
  143. szFileName
  144. ));
  145. HRESULT hr = S_FALSE;
  146. HINSTANCE hinst = LoadLibraryEx (szFileName, NULL,
  147. DONT_RESOLVE_DLL_REFERENCES | LOAD_WITH_ALTERED_SEARCH_PATH);
  148. if (hinst)
  149. {
  150. FARPROC pfn = GetProcAddress (hinst, "DllRegisterServer");
  151. if (pfn)
  152. hr = S_OK;
  153. FreeLibrary (hinst);
  154. }
  155. DEBUG_LEAVE(hr);
  156. return hr;
  157. }