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
210 lines
5.1 KiB
// 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;
|
|
}
|
|
|
|
|