// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. #include "precomp.h" static const HRESULT E_SUSPECTED_TAMPERING = MAKE_HRESULT(SEVERITY_ERROR, 500/*FACILITY_WIX*/, 2001); static void AvoidLocalDllRedirection(LPCWSTR wzPath); int WINAPI wWinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE /* hPrevInstance */, __in_z_opt LPWSTR lpCmdLine, __in int nCmdShow ) { HRESULT hr = S_OK; DWORD dwExitCode = 0; LPWSTR sczPath = NULL; HANDLE hEngineFile = INVALID_HANDLE_VALUE; LPCWSTR rgsczSafelyLoadSystemDlls[] = { L"cabinet.dll", // required by Burn. L"msi.dll", // required by Burn. L"version.dll", // required by Burn. L"wininet.dll", // required by Burn. L"comres.dll", // required by CLSIDFromProgID() when loading clbcatq.dll. L"clbcatq.dll", // required by CLSIDFromProgID() when loading msxml?.dll. L"msasn1.dll", // required by DecryptFile() when loading crypt32.dll. L"crypt32.dll", // required by DecryptFile() when loading feclient.dll. L"feclient.dll", // unsafely loaded by DecryptFile(). }; // Best effort attempt to get our file handle as soon as possible. hr = PathForCurrentProcess(&sczPath, NULL); if (SUCCEEDED(hr)) { hEngineFile = ::CreateFileW(sczPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } AppInitialize(rgsczSafelyLoadSystemDlls, countof(rgsczSafelyLoadSystemDlls)); AvoidLocalDllRedirection(sczPath); // call run hr = EngineRun(hInstance, hEngineFile, lpCmdLine, nCmdShow, &dwExitCode); ExitOnFailure(hr, "Failed to run application."); LExit: ReleaseFileHandle(hEngineFile); ReleaseStr(sczPath); return FAILED(hr) ? (int)hr : (int)dwExitCode; } static void AvoidLocalDllRedirection(LPCWSTR wzPath) { LPWSTR sczLocalPath = NULL; HMODULE hmodComCtl = NULL; // Bail if there's a .exe.local directory, as it's a feature of // DLL redirection that has no real use for a bundle and is a hole for // DLL hijacking attacks. if (FAILED(StrAllocFormatted(&sczLocalPath, L"%ls.local", wzPath)) || DirExists(sczLocalPath, NULL) || FileExistsEx(sczLocalPath, NULL) || FAILED(LoadSystemLibrary(L"Comctl32.dll", &hmodComCtl))) { ::ExitProcess((UINT)E_SUSPECTED_TAMPERING); } ReleaseStr(sczLocalPath); }