Windows2003-3790/inetcore/urlmon/download/peldr.cxx
2020-09-30 16:53:55 +02:00

211 lines
5.1 KiB
C++

// PELDR.CXX kernel32
//
// (C) Copyright Microsoft Corp., 1988-1994
//
// Swiped without thanks from the Win32 loader
//
#include <cdlpch.h>
extern int g_CPUType;
HRESULT
GetMachineTypeOfFile(const char *szName, LPDWORD pdwMachine)
{
DEBUG_ENTER((DBG_DOWNLOAD,
Hresult,
"GetMachineTypeOfFile",
"%.80q, %#x",
szName, pdwMachine
));
IMAGE_DOS_HEADER idh;
IMAGE_NT_HEADERS nth;
DWORD cbT;
DWORD size;
DWORD dwBytesRead = 0;
HANDLE dfhFile = INVALID_HANDLE_VALUE;
HRESULT hr = S_OK;
*pdwMachine = IMAGE_FILE_MACHINE_UNKNOWN;
if ( (dfhFile = CreateFile(szName, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto Exit;
}
// Read DOS header
if ((!ReadFile(dfhFile, &idh, sizeof(idh), &dwBytesRead, NULL)) ||
(idh.e_magic != 0x5a4d)) {
// not PE file!
hr = HRESULT_FROM_WIN32(GetLastError());
if (SUCCEEDED(hr)) {
// not enough bytes read
hr = HRESULT_FROM_WIN32(ERROR_INVALID_EXE_SIGNATURE);
}
goto Exit;
}
// Read PE header
SetFilePointer (dfhFile, idh.e_lfanew, NULL, FILE_BEGIN);
if ((!ReadFile(dfhFile, &nth, sizeof(IMAGE_NT_HEADERS), &dwBytesRead, NULL))) {
hr = HRESULT_FROM_WIN32(GetLastError());
if (SUCCEEDED(hr)) {
// not enough bytes read
hr = HRESULT_FROM_WIN32(ERROR_INVALID_EXE_SIGNATURE);
}
goto Exit;
}
cbT = dwBytesRead;
// Valid PE header?
if ((cbT != sizeof(IMAGE_NT_HEADERS)) || (nth.Signature != 0x00004550)) {
// not PE file!
hr = HRESULT_FROM_WIN32(ERROR_INVALID_EXE_SIGNATURE);
goto Exit;
}
*pdwMachine = nth.FileHeader.Machine;
Exit:
if (dfhFile != INVALID_HANDLE_VALUE)
CloseHandle(dfhFile);
DEBUG_LEAVE(hr);
return hr ;
}
HRESULT
IsCompatibleType(DWORD dwBinaryType)
{
DEBUG_ENTER((DBG_DOWNLOAD,
Hresult,
"IsCompatibleType",
"%#x",
dwBinaryType
));
int CPUType = PROCESSOR_ARCHITECTURE_UNKNOWN;
switch (dwBinaryType) {
case IMAGE_FILE_MACHINE_AMD64:
CPUType = PROCESSOR_ARCHITECTURE_AMD64;
break;
case IMAGE_FILE_MACHINE_I386:
#ifdef WX86
if (g_fWx86Present) {
// Wx86 is installed - I386 images are OK.
DEBUG_LEAVE(S_OK);
return S_OK;
}
#endif
CPUType = PROCESSOR_ARCHITECTURE_INTEL;
break;
case IMAGE_FILE_MACHINE_IA64:
CPUType = PROCESSOR_ARCHITECTURE_IA64;
break;
}
DEBUG_ENTER((DBG_DOWNLOAD,
Hresult,
"IsCompatibleType:comparing",
"%#x Vs %#x (PROCESSOR_ARCHITECTURE_UNKNOWN)=%#x, (PROCESSOR_ARCHITECTURE_INTEL)=%#x, (IMAGE_FILE_MACHINE_I386)=%#x ",
g_CPUType, CPUType, PROCESSOR_ARCHITECTURE_UNKNOWN, PROCESSOR_ARCHITECTURE_INTEL, IMAGE_FILE_MACHINE_I386
));
HRESULT hr = (g_CPUType == CPUType)?S_OK:HRESULT_FROM_WIN32(ERROR_EXE_MACHINE_TYPE_MISMATCH);
DEBUG_LEAVE(hr);
DEBUG_LEAVE(hr);
return hr;
}
// IsCompatibleFile(const char *szFileName, LPDWORD lpdwMachineType=NULL);
// returns:
// S_OK: file is compatible install it and LoadLibrary it
// S_FALSE: file is not a PE
// ERROR_EXE_MACHINE_TYPE_MISMATCH: not compatible
HRESULT
IsCompatibleFile(const char *szFileName, LPDWORD lpdwMachineType)
{
DEBUG_ENTER((DBG_DOWNLOAD,
Hresult,
"IsCompatibleFile",
"%.80q, %#x",
szFileName, lpdwMachineType
));
DWORD dwMachine = 0;
HRESULT hr = GetMachineTypeOfFile(szFileName, &dwMachine);
if (SUCCEEDED(hr)) {
hr = IsCompatibleType(dwMachine);
} else {
hr = S_FALSE;
}
if (lpdwMachineType)
*lpdwMachineType = dwMachine;
DEBUG_LEAVE(hr);
return hr;
}
// IsRegisterableDLL(const char *szFileName)
// returns:
// S_OK: file is registerable, LoadLibrary and call GetProcAddress
// S_FALSE: file is not registerable
HRESULT
IsRegisterableDLL(const char *szFileName)
{
DEBUG_ENTER((DBG_DOWNLOAD,
Hresult,
"IsRegisterableDLL",
"%.80q",
szFileName
));
HRESULT hr = S_FALSE;
HINSTANCE hinst = LoadLibraryEx (szFileName, NULL,
DONT_RESOLVE_DLL_REFERENCES | LOAD_WITH_ALTERED_SEARCH_PATH);
if (hinst)
{
FARPROC pfn = GetProcAddress (hinst, "DllRegisterServer");
if (pfn)
hr = S_OK;
FreeLibrary (hinst);
}
DEBUG_LEAVE(hr);
return hr;
}