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.
1465 lines
45 KiB
1465 lines
45 KiB
#include "utility.h" |
|
#include <Wininet.h> |
|
#pragma comment(lib, "Wininet.lib") |
|
|
|
#pragma region "Weird stuff" |
|
INT64 STDMETHODCALLTYPE nimpl4_1(INT64 a1, DWORD* a2) |
|
{ |
|
*a2 = 1; |
|
return 0; |
|
} |
|
INT64 STDMETHODCALLTYPE nimpl4_0(INT64 a1, DWORD* a2) |
|
{ |
|
*a2 = 0; |
|
return 0; |
|
} |
|
__int64 STDMETHODCALLTYPE nimpl2(__int64 a1, uintptr_t* a2) |
|
{ |
|
__int64 v2; // rax |
|
|
|
v2 = a1 + 8; |
|
if (!a1) |
|
v2 = 0i64; |
|
|
|
*a2 = v2; |
|
return 0i64; |
|
} |
|
ULONG STDMETHODCALLTYPE nimpl3() |
|
{ |
|
return 1; |
|
} |
|
HRESULT STDMETHODCALLTYPE nimpl() |
|
{ |
|
return E_NOTIMPL; |
|
} |
|
HRESULT STDMETHODCALLTYPE nimpl1(__int64 a1, uintptr_t* a2, uintptr_t* a3) |
|
{ |
|
__int64 v4 = a1; // rcx |
|
|
|
if (*a2 != 0x5FADCA5C34A95314i64 || a2[1] != 0xC1661118901A7CAEui64) |
|
return E_NOTIMPL; |
|
|
|
*a3 = v4; |
|
return S_OK; |
|
} |
|
HRESULT STDMETHODCALLTYPE nimpl1_2(__int64 a1, uintptr_t* a2, uintptr_t* a3) |
|
{ |
|
__int64 v4 = a1 - sizeof(__int64); // rcx |
|
|
|
if (*a2 != 0x5FADCA5C34A95314i64 || a2[1] != 0xC1661118901A7CAEui64) |
|
return E_NOTIMPL; |
|
|
|
*a3 = v4; |
|
return S_OK; |
|
} |
|
HRESULT STDMETHODCALLTYPE nimpl1_3(__int64 a1, uintptr_t* a2, uintptr_t* a3) |
|
{ |
|
__int64 v4 = a1 - 2 * sizeof(__int64); // rcx |
|
|
|
if (*a2 != 0x5FADCA5C34A95314i64 || a2[1] != 0xC1661118901A7CAEui64) |
|
return E_NOTIMPL; |
|
|
|
*a3 = v4; |
|
return S_OK; |
|
} |
|
__int64 STDMETHODCALLTYPE nimpl4(__int64 a1, __int64 a2, __int64 a3, BYTE* a4) |
|
{ |
|
*a4 = 0; |
|
return 0i64; |
|
} |
|
const IActivationFactoryVtbl _IActivationFactoryVtbl = { |
|
.QueryInterface = nimpl1, |
|
.AddRef = nimpl3, |
|
.Release = nimpl3, |
|
.GetIids = nimpl, |
|
.GetRuntimeClassName = nimpl, |
|
.GetTrustLevel = nimpl, |
|
.ActivateInstance = nimpl2 |
|
}; |
|
const IActivationFactoryVtbl _IActivationFactoryVtbl2 = { |
|
.QueryInterface = nimpl1_2, |
|
.AddRef = nimpl3, |
|
.Release = nimpl3, |
|
.GetIids = nimpl, |
|
.GetRuntimeClassName = nimpl, |
|
.GetTrustLevel = nimpl, |
|
.ActivateInstance = nimpl |
|
}; |
|
const IActivationFactoryVtbl _IActivationFactoryVtbl3 = { |
|
.QueryInterface = nimpl1_3, |
|
.AddRef = nimpl3, |
|
.Release = nimpl3, |
|
.GetIids = nimpl, |
|
.GetRuntimeClassName = nimpl, |
|
.GetTrustLevel = nimpl, |
|
.ActivateInstance = nimpl4 |
|
}; |
|
const IActivationFactoryAA XamlExtensionsFactory = { |
|
.lpVtbl = &_IActivationFactoryVtbl, |
|
.lpVtbl2 = &_IActivationFactoryVtbl2, |
|
.lpVtbl3 = &_IActivationFactoryVtbl3 |
|
}; |
|
#pragma endregion |
|
|
|
void printf_guid(GUID guid) |
|
{ |
|
printf("Guid = {%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}\n", |
|
guid.Data1, guid.Data2, guid.Data3, |
|
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], |
|
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); |
|
} |
|
|
|
LRESULT CALLBACK BalloonWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
|
{ |
|
if (msg == WM_CREATE) |
|
{ |
|
LPCREATESTRUCT lpCs = lParam; |
|
|
|
NOTIFYICONDATA ni = { 0 }; |
|
ni.cbSize = sizeof(ni); |
|
ni.hWnd = hWnd; |
|
ni.uID = 1; |
|
ni.uFlags = NIF_INFO; |
|
ni.dwInfoFlags = NIIF_INFO; |
|
ni.uTimeout = 2000; |
|
_tcscpy_s(ni.szInfo, _countof(ni.szInfo), lpCs->lpCreateParams); |
|
_tcscpy_s(ni.szInfoTitle, _countof(ni.szInfoTitle), _T("ExplorerPatcher")); |
|
|
|
Shell_NotifyIcon(NIM_ADD, &ni); |
|
|
|
free(lpCs->lpCreateParams); |
|
|
|
exit(0); |
|
} |
|
else |
|
{ |
|
return DefWindowProc(hWnd, msg, wParam, lParam); |
|
} |
|
return 0; |
|
} |
|
|
|
__declspec(dllexport) CALLBACK ZZTestBalloon(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) |
|
{ |
|
TCHAR* lpwszCmdLine = calloc((strlen(lpszCmdLine) + 1), sizeof(TCHAR)); |
|
if (!lpwszCmdLine) exit(0); |
|
size_t numChConv = 0; |
|
mbstowcs_s(&numChConv, lpwszCmdLine, strlen(lpszCmdLine) + 1, lpszCmdLine, strlen(lpszCmdLine) + 1); |
|
|
|
WNDCLASSEX wc; |
|
HWND hwnd; |
|
MSG msg; |
|
|
|
wc.cbSize = sizeof(WNDCLASSEX); |
|
wc.style = 0; |
|
wc.lpfnWndProc = BalloonWndProc; |
|
wc.cbClsExtra = 0; |
|
wc.cbWndExtra = 0; |
|
wc.hInstance = hInstance; |
|
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); |
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW); |
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); |
|
wc.lpszMenuName = NULL; |
|
wc.lpszClassName = L"ExplorerPatcherBalloon"; |
|
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); |
|
|
|
if (!RegisterClassEx(&wc)) { |
|
return 0; |
|
} |
|
|
|
hwnd = CreateWindowEx(0, L"ExplorerPatcherBalloon", L"", |
|
0, 0, 0, 0, 0, |
|
HWND_MESSAGE, NULL, hInstance, lpwszCmdLine); |
|
|
|
while (GetMessage(&msg, NULL, 0, 0) > 0) { |
|
TranslateMessage(&msg); |
|
DispatchMessage(&msg); |
|
} |
|
} |
|
|
|
const wchar_t TestToastXML[] = |
|
L"<toast scenario=\"reminder\" " |
|
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher\" duration=\"%s\">\r\n" |
|
L" <visual>\r\n" |
|
L" <binding template=\"ToastGeneric\">\r\n" |
|
L" <text><![CDATA[%s]]></text>\r\n" |
|
L" <text placement=\"attribution\"><![CDATA[ExplorerPatcher]]></text>\r\n" |
|
L" </binding>\r\n" |
|
L" </visual>\r\n" |
|
L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n" |
|
L"</toast>\r\n"; |
|
__declspec(dllexport) CALLBACK ZZTestToast(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) |
|
{ |
|
TCHAR* lpwszCmdLine = calloc((strlen(lpszCmdLine) + 1), sizeof(TCHAR)); |
|
if (!lpwszCmdLine) exit(0); |
|
size_t numChConv = 0; |
|
mbstowcs_s(&numChConv, lpwszCmdLine, strlen(lpszCmdLine) + 1, lpszCmdLine, strlen(lpszCmdLine) + 1); |
|
TCHAR* buffer = calloc((sizeof(TestToastXML) / sizeof(wchar_t) + strlen(lpszCmdLine) + 10), sizeof(TCHAR)); |
|
if (buffer) |
|
{ |
|
wsprintf( |
|
buffer, |
|
TestToastXML, |
|
L"short", |
|
lpwszCmdLine |
|
); |
|
HRESULT hr = S_OK; |
|
__x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL; |
|
hr = String2IXMLDocument( |
|
buffer, |
|
wcslen(buffer), |
|
&inputXml, |
|
#ifdef DEBUG |
|
stdout |
|
#else |
|
NULL |
|
#endif |
|
); |
|
hr = ShowToastMessage( |
|
inputXml, |
|
APPID, |
|
sizeof(APPID) / sizeof(TCHAR) - 1, |
|
#ifdef DEBUG |
|
stdout |
|
#else |
|
NULL |
|
#endif |
|
); |
|
free(buffer); |
|
} |
|
free(lpwszCmdLine); |
|
} |
|
|
|
__declspec(dllexport) CALLBACK ZZLaunchExplorer(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) |
|
{ |
|
Sleep(100); |
|
TCHAR wszExplorerPath[MAX_PATH + 1]; |
|
GetWindowsDirectory(wszExplorerPath, MAX_PATH + 1); |
|
wcscat_s(wszExplorerPath, MAX_PATH + 1, L"\\explorer.exe"); |
|
STARTUPINFO si = { sizeof(si) }; |
|
PROCESS_INFORMATION pi; |
|
BOOL b = CreateProcess( |
|
NULL, |
|
wszExplorerPath, |
|
NULL, |
|
NULL, |
|
TRUE, |
|
CREATE_UNICODE_ENVIRONMENT, |
|
NULL, |
|
NULL, |
|
&si, |
|
&pi |
|
); |
|
FreeConsole(); |
|
TerminateProcess( |
|
OpenProcess( |
|
PROCESS_TERMINATE, |
|
FALSE, |
|
GetCurrentProcessId() |
|
), |
|
0 |
|
); |
|
} |
|
|
|
__declspec(dllexport) CALLBACK ZZLaunchExplorerDelayed(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) |
|
{ |
|
Sleep(2000); |
|
ZZLaunchExplorer(hWnd, hInstance, lpszCmdLine, nCmdShow); |
|
} |
|
|
|
__declspec(dllexport) CALLBACK ZZRestartExplorer(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int nCmdShow) |
|
{ |
|
BeginExplorerRestart(); |
|
FinishExplorerRestart(); |
|
} |
|
|
|
void* ReadFromFile(wchar_t* wszFileName, DWORD* dwSize) |
|
{ |
|
void* ok = NULL; |
|
HANDLE hImage = CreateFileW(wszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
|
if (hImage) |
|
{ |
|
LARGE_INTEGER dwFileSize; |
|
GetFileSizeEx(hImage, &dwFileSize); |
|
if (dwFileSize.LowPart) |
|
{ |
|
void* pImage = malloc(dwFileSize.LowPart); |
|
if (pImage) |
|
{ |
|
DWORD dwNumberOfBytesRead = 0; |
|
ReadFile(hImage, pImage, dwFileSize.LowPart, &dwNumberOfBytesRead, NULL); |
|
if (dwFileSize.LowPart == dwNumberOfBytesRead) |
|
{ |
|
ok = pImage; |
|
*dwSize = dwNumberOfBytesRead; |
|
} |
|
} |
|
} |
|
CloseHandle(hImage); |
|
} |
|
return ok; |
|
} |
|
|
|
int ComputeFileHash(LPCWSTR filename, LPSTR hash, DWORD dwHash) |
|
{ |
|
DWORD dwStatus = 0; |
|
BOOL bResult = FALSE; |
|
HCRYPTPROV hProv = 0; |
|
HCRYPTHASH hHash = 0; |
|
HANDLE hFile = NULL; |
|
BYTE* rgbFile; |
|
DWORD cbRead = 0; |
|
BYTE rgbHash[16]; |
|
DWORD cbHash = 0; |
|
WCHAR rgbDigits[] = L"0123456789abcdef"; |
|
// Logic to check usage goes here. |
|
|
|
hFile = CreateFile(filename, |
|
GENERIC_READ, |
|
FILE_SHARE_READ, |
|
NULL, |
|
OPEN_EXISTING, |
|
FILE_FLAG_SEQUENTIAL_SCAN, |
|
NULL); |
|
|
|
if (INVALID_HANDLE_VALUE == hFile) |
|
{ |
|
dwStatus = GetLastError(); |
|
return dwStatus; |
|
} |
|
|
|
LARGE_INTEGER dwFileSize; |
|
GetFileSizeEx(hFile, &dwFileSize); |
|
if (!dwFileSize.LowPart) |
|
{ |
|
dwStatus = GetLastError(); |
|
CloseHandle(hFile); |
|
return dwStatus; |
|
} |
|
|
|
rgbFile = malloc(dwFileSize.LowPart); |
|
if (!rgbFile) |
|
{ |
|
dwStatus = E_OUTOFMEMORY; |
|
CloseHandle(hFile); |
|
return dwStatus; |
|
} |
|
|
|
// Get handle to the crypto provider |
|
if (!CryptAcquireContext(&hProv, |
|
NULL, |
|
NULL, |
|
PROV_RSA_FULL, |
|
CRYPT_VERIFYCONTEXT)) |
|
{ |
|
dwStatus = GetLastError(); |
|
CloseHandle(hFile); |
|
return dwStatus; |
|
} |
|
|
|
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) |
|
{ |
|
dwStatus = GetLastError(); |
|
CloseHandle(hFile); |
|
CryptReleaseContext(hProv, 0); |
|
return dwStatus; |
|
} |
|
|
|
while (bResult = ReadFile(hFile, rgbFile, dwFileSize.LowPart, &cbRead, NULL)) |
|
{ |
|
if (0 == cbRead) |
|
{ |
|
break; |
|
} |
|
|
|
if (!CryptHashData(hHash, rgbFile, cbRead, 0)) |
|
{ |
|
dwStatus = GetLastError(); |
|
CryptReleaseContext(hProv, 0); |
|
CryptDestroyHash(hHash); |
|
CloseHandle(hFile); |
|
return dwStatus; |
|
} |
|
} |
|
|
|
if (!bResult) |
|
{ |
|
dwStatus = GetLastError(); |
|
CryptReleaseContext(hProv, 0); |
|
CryptDestroyHash(hHash); |
|
CloseHandle(hFile); |
|
return dwStatus; |
|
} |
|
|
|
cbHash = 16; |
|
if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) |
|
{ |
|
for (DWORD i = 0; i < cbHash; i++) |
|
{ |
|
sprintf_s(hash + (i * 2), 3, "%c%c", rgbDigits[rgbHash[i] >> 4], rgbDigits[rgbHash[i] & 0xf]); |
|
} |
|
} |
|
else |
|
{ |
|
dwStatus = GetLastError(); |
|
} |
|
|
|
CryptDestroyHash(hHash); |
|
CryptReleaseContext(hProv, 0); |
|
CloseHandle(hFile); |
|
free(rgbFile); |
|
|
|
return dwStatus; |
|
} |
|
|
|
int ComputeFileHash2(HMODULE hModule, LPCWSTR filename, LPSTR hash, DWORD dwHash) |
|
{ |
|
if (dwHash < 33) |
|
{ |
|
return ERROR_BUFFER_OVERFLOW; |
|
} |
|
if (!hModule) |
|
{ |
|
return ERROR_INVALID_ADDRESS; |
|
} |
|
|
|
DWORD dwLeftMost = 0; |
|
DWORD dwSecondLeft = 0; |
|
DWORD dwSecondRight = 0; |
|
DWORD dwRightMost = 0; |
|
QueryVersionInfo(hModule, VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost); |
|
|
|
sprintf_s(hash, 33, "%d.%d.%d.%d.", dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost); |
|
|
|
char real_hash[33]; |
|
ComputeFileHash(filename, real_hash, 33); |
|
strncpy_s(hash + strlen(hash), dwHash - strlen(hash), real_hash, 32 - strlen(hash)); |
|
hash[33] = 0; |
|
|
|
return ERROR_SUCCESS; |
|
} |
|
|
|
void LaunchPropertiesGUI(HMODULE hModule) |
|
{ |
|
//CreateThread(0, 0, ZZGUI, 0, 0, 0); |
|
wchar_t wszPath[MAX_PATH * 2]; |
|
ZeroMemory( |
|
wszPath, |
|
(MAX_PATH * 2) * sizeof(wchar_t) |
|
); |
|
wszPath[0] = '\"'; |
|
GetSystemDirectoryW( |
|
wszPath + 1, |
|
MAX_PATH |
|
); |
|
wcscat_s( |
|
wszPath, |
|
MAX_PATH * 2, |
|
L"\\rundll32.exe\" \"" |
|
); |
|
GetModuleFileNameW( |
|
hModule, |
|
wszPath + wcslen(wszPath), |
|
MAX_PATH |
|
); |
|
wcscat_s( |
|
wszPath, |
|
MAX_PATH * 2, |
|
L"\",ZZGUI" |
|
); |
|
wprintf(L"Launching : %s\n", wszPath); |
|
STARTUPINFO si; |
|
ZeroMemory(&si, sizeof(STARTUPINFO)); |
|
si.cb = sizeof(si); |
|
PROCESS_INFORMATION pi; |
|
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); |
|
if (CreateProcessW( |
|
NULL, |
|
wszPath, |
|
NULL, |
|
NULL, |
|
FALSE, |
|
CREATE_UNICODE_ENVIRONMENT, |
|
NULL, |
|
NULL, |
|
&si, |
|
&pi |
|
)) |
|
{ |
|
CloseHandle(pi.hThread); |
|
CloseHandle(pi.hProcess); |
|
} |
|
} |
|
|
|
|
|
BOOL SystemShutdown(BOOL reboot) |
|
{ |
|
HANDLE hToken; |
|
TOKEN_PRIVILEGES tkp; |
|
|
|
// Get a token for this process. |
|
|
|
if (!OpenProcessToken(GetCurrentProcess(), |
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) |
|
return(FALSE); |
|
|
|
// Get the LUID for the shutdown privilege. |
|
|
|
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, |
|
&tkp.Privileges[0].Luid); |
|
|
|
tkp.PrivilegeCount = 1; // one privilege to set |
|
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; |
|
|
|
// Get the shutdown privilege for this process. |
|
|
|
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, |
|
(PTOKEN_PRIVILEGES)NULL, 0); |
|
|
|
if (GetLastError() != ERROR_SUCCESS) |
|
return FALSE; |
|
|
|
// Shut down the system and force all applications to close. |
|
|
|
if (!ExitWindowsEx((reboot ? EWX_REBOOT : EWX_SHUTDOWN) | EWX_FORCE, |
|
SHTDN_REASON_MAJOR_OPERATINGSYSTEM | |
|
SHTDN_REASON_MINOR_UPGRADE | |
|
SHTDN_REASON_FLAG_PLANNED)) |
|
return FALSE; |
|
|
|
//shutdown was successful |
|
return TRUE; |
|
} |
|
|
|
HRESULT FindDesktopFolderView(REFIID riid, void** ppv) |
|
{ |
|
HRESULT hr = E_FAIL; |
|
IShellWindows* spShellWindows = NULL; |
|
hr = CoCreateInstance( |
|
&CLSID_ShellWindows, |
|
NULL, |
|
CLSCTX_ALL, |
|
&IID_IShellWindows, |
|
&spShellWindows |
|
); |
|
if (spShellWindows) |
|
{ |
|
VARIANT vtEmpty; |
|
ZeroMemory(&vtEmpty, sizeof(VARIANT)); |
|
VARIANT vtLoc; |
|
ZeroMemory(&vtLoc, sizeof(VARIANT)); |
|
vtLoc.vt = VT_INT; |
|
vtLoc.intVal = CSIDL_DESKTOP; |
|
long lhwnd = 0; |
|
IDispatch* spdisp = NULL; |
|
hr = spShellWindows->lpVtbl->FindWindowSW( |
|
spShellWindows, |
|
&vtLoc, |
|
&vtEmpty, |
|
SWC_DESKTOP, |
|
&lhwnd, |
|
SWFO_NEEDDISPATCH, |
|
&spdisp |
|
); |
|
if (spdisp) |
|
{ |
|
IServiceProvider* spdisp2 = NULL; |
|
hr = spdisp->lpVtbl->QueryInterface(spdisp, &IID_IServiceProvider, &spdisp2); |
|
if (spdisp2) |
|
{ |
|
IShellBrowser* spBrowser = NULL; |
|
hr = spdisp2->lpVtbl->QueryService(spdisp2, &SID_STopLevelBrowser, &IID_IShellBrowser, &spBrowser); |
|
if (spBrowser) |
|
{ |
|
IShellView* spView = NULL; |
|
hr = spBrowser->lpVtbl->QueryActiveShellView(spBrowser, &spView); |
|
if (spView) |
|
{ |
|
hr = spView->lpVtbl->QueryInterface(spView, riid, ppv); |
|
spView->lpVtbl->Release(spView); |
|
} |
|
spBrowser->lpVtbl->Release(spBrowser); |
|
} |
|
spdisp2->lpVtbl->Release(spdisp2); |
|
} |
|
spdisp->lpVtbl->Release(spdisp); |
|
} |
|
spShellWindows->lpVtbl->Release(spShellWindows); |
|
} |
|
return hr; |
|
} |
|
|
|
HRESULT GetDesktopAutomationObject(REFIID riid, void** ppv) |
|
{ |
|
HRESULT hr = E_FAIL; |
|
IShellView* spsv = NULL; |
|
hr = FindDesktopFolderView(&IID_IShellView, &spsv); |
|
if (spsv) |
|
{ |
|
IDispatch* spdispView = NULL; |
|
hr = spsv->lpVtbl->GetItemObject(spsv, SVGIO_BACKGROUND, &IID_IDispatch, &spdispView); |
|
if (spdispView) |
|
{ |
|
hr = spdispView->lpVtbl->QueryInterface(spdispView, riid, ppv); |
|
spdispView->lpVtbl->Release(spdispView); |
|
} |
|
spsv->lpVtbl->Release(spsv); |
|
} |
|
return hr; |
|
} |
|
|
|
HRESULT ShellExecuteFromExplorer( |
|
PCWSTR pszFile, |
|
PCWSTR pszParameters, |
|
PCWSTR pszDirectory, |
|
PCWSTR pszOperation, |
|
int nShowCmd |
|
) |
|
{ |
|
HRESULT hr = E_FAIL; |
|
IShellFolderViewDual* spFolderView = NULL; |
|
GetDesktopAutomationObject(&IID_IShellFolderViewDual, &spFolderView); |
|
if (spFolderView) |
|
{ |
|
IDispatch* spdispShell = NULL; |
|
spFolderView->lpVtbl->get_Application(spFolderView, &spdispShell); |
|
if (spdispShell) |
|
{ |
|
IShellDispatch2* spdispShell2 = NULL; |
|
spdispShell->lpVtbl->QueryInterface(spdispShell, &IID_IShellDispatch2, &spdispShell2); |
|
if (spdispShell2) |
|
{ |
|
BSTR a_pszFile = pszFile ? SysAllocString(pszFile): SysAllocString(L""); |
|
VARIANT a_pszParameters, a_pszDirectory, a_pszOperation, a_nShowCmd; |
|
ZeroMemory(&a_pszParameters, sizeof(VARIANT)); |
|
ZeroMemory(&a_pszDirectory, sizeof(VARIANT)); |
|
ZeroMemory(&a_pszOperation, sizeof(VARIANT)); |
|
ZeroMemory(&a_nShowCmd, sizeof(VARIANT)); |
|
a_pszParameters.vt = VT_BSTR; |
|
a_pszParameters.bstrVal = pszParameters ? SysAllocString(pszParameters) : SysAllocString(L""); |
|
a_pszDirectory.vt = VT_BSTR; |
|
a_pszDirectory.bstrVal = pszDirectory ? SysAllocString(pszDirectory) : SysAllocString(L""); |
|
a_pszOperation.vt = VT_BSTR; |
|
a_pszOperation.bstrVal = pszOperation ? SysAllocString(pszOperation) : SysAllocString(L""); |
|
a_nShowCmd.vt = VT_INT; |
|
a_nShowCmd.intVal = nShowCmd; |
|
hr = spdispShell2->lpVtbl->ShellExecuteW(spdispShell2, a_pszFile, a_pszParameters, a_pszDirectory, a_pszOperation, a_nShowCmd); |
|
if (a_pszOperation.bstrVal) |
|
{ |
|
SysFreeString(a_pszOperation.bstrVal); |
|
} |
|
if (a_pszDirectory.bstrVal) |
|
{ |
|
SysFreeString(a_pszDirectory.bstrVal); |
|
} |
|
if (a_pszParameters.bstrVal) |
|
{ |
|
SysFreeString(a_pszParameters.bstrVal); |
|
} |
|
if (a_pszFile) |
|
{ |
|
SysFreeString(a_pszFile); |
|
} |
|
spdispShell2->lpVtbl->Release(spdispShell2); |
|
} |
|
spdispShell->lpVtbl->Release(spdispShell); |
|
} |
|
spFolderView->lpVtbl->Release(spFolderView); |
|
} |
|
return hr; |
|
} |
|
|
|
void ToggleTaskbarAutohide() |
|
{ |
|
APPBARDATA abd; |
|
abd.cbSize = sizeof(APPBARDATA); |
|
if (SHAppBarMessage(ABM_GETSTATE, &abd) == ABS_AUTOHIDE) |
|
{ |
|
abd.lParam = 0; |
|
SHAppBarMessage(ABM_SETSTATE, &abd); |
|
} |
|
else |
|
{ |
|
abd.lParam = ABS_AUTOHIDE; |
|
SHAppBarMessage(ABM_SETSTATE, &abd); |
|
} |
|
} |
|
|
|
LSTATUS RegisterDWMService(DWORD dwDesiredState, DWORD dwOverride) |
|
{ |
|
WCHAR wszPath[MAX_PATH]; |
|
GetSystemDirectoryW(wszPath, MAX_PATH); |
|
wcscat_s(wszPath, MAX_PATH, L"\\cmd.exe"); |
|
|
|
WCHAR wszSCPath[MAX_PATH]; |
|
GetSystemDirectoryW(wszSCPath, MAX_PATH); |
|
wcscat_s(wszSCPath, MAX_PATH, L"\\sc.exe"); |
|
|
|
WCHAR wszRundll32[MAX_PATH]; |
|
SHGetFolderPathW(NULL, SPECIAL_FOLDER, NULL, SHGFP_TYPE_CURRENT, wszRundll32); |
|
wcscat_s(wszRundll32, MAX_PATH, _T(APP_RELATIVE_PATH)); |
|
wcscat_s(wszRundll32, MAX_PATH, L"\\ep_dwm.exe"); |
|
|
|
WCHAR wszEP[MAX_PATH]; |
|
GetWindowsDirectoryW(wszEP, MAX_PATH); |
|
wcscat_s(wszEP, MAX_PATH, L"\\dxgi.dll"); |
|
|
|
WCHAR wszTaskkill[MAX_PATH]; |
|
GetSystemDirectoryW(wszTaskkill, MAX_PATH); |
|
wcscat_s(wszTaskkill, MAX_PATH, L"\\taskkill.exe"); |
|
|
|
WCHAR wszArgumentsRegister[MAX_PATH * 10]; |
|
swprintf_s( |
|
wszArgumentsRegister, |
|
MAX_PATH * 10, |
|
L"/c \"" |
|
L"\"%s\" create " _T(EP_DWM_SERVICENAME) L" binPath= \"\\\"%s\\\" %s\" DisplayName= \"ExplorerPatcher Desktop Window Manager Service\" start= auto & " |
|
L"\"%s\" description " _T(EP_DWM_SERVICENAME) L" \"Service for managing aspects related to the Desktop Window Manager.\" & " |
|
L"\"%s\" %s " _T(EP_DWM_SERVICENAME) |
|
L"\"", |
|
wszSCPath, |
|
wszRundll32, |
|
_T(EP_DWM_SERVICENAME) L" " _T(EP_DWM_EVENTNAME), |
|
wszSCPath, |
|
wszSCPath, |
|
(!dwOverride || dwOverride == 3) ? L"start" : L"query" |
|
); |
|
WCHAR wszArgumentsUnRegister[MAX_PATH * 10]; |
|
swprintf_s( |
|
wszArgumentsUnRegister, |
|
MAX_PATH * 10, |
|
L"/c \"" |
|
L"\"%s\" stop " _T(EP_DWM_SERVICENAME) L" & " |
|
L"\"%s\" delete " _T(EP_DWM_SERVICENAME) L" & " |
|
L"\"", |
|
wszSCPath, |
|
wszSCPath |
|
); |
|
wprintf(L"%s\n", wszArgumentsRegister); |
|
|
|
BOOL bAreRoundedCornersDisabled = FALSE; |
|
if (dwOverride) |
|
{ |
|
bAreRoundedCornersDisabled = !(dwOverride - 1); |
|
} |
|
else |
|
{ |
|
HANDLE h_exists = CreateEventW(NULL, FALSE, FALSE, _T(EP_DWM_EVENTNAME)); |
|
if (h_exists) |
|
{ |
|
if (GetLastError() == ERROR_ALREADY_EXISTS) |
|
{ |
|
bAreRoundedCornersDisabled = TRUE; |
|
} |
|
else |
|
{ |
|
bAreRoundedCornersDisabled = FALSE; |
|
} |
|
CloseHandle(h_exists); |
|
} |
|
else |
|
{ |
|
if (GetLastError() == ERROR_ACCESS_DENIED) |
|
{ |
|
bAreRoundedCornersDisabled = TRUE; |
|
} |
|
else |
|
{ |
|
bAreRoundedCornersDisabled = FALSE; |
|
} |
|
} |
|
if ((bAreRoundedCornersDisabled && dwDesiredState) || (!bAreRoundedCornersDisabled && !dwDesiredState)) |
|
{ |
|
return FALSE; |
|
} |
|
} |
|
SHELLEXECUTEINFO ShExecInfo = { 0 }; |
|
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); |
|
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; |
|
ShExecInfo.hwnd = NULL; |
|
ShExecInfo.lpVerb = L"runas"; |
|
ShExecInfo.lpFile = wszPath; |
|
ShExecInfo.lpParameters = !bAreRoundedCornersDisabled ? wszArgumentsRegister : wszArgumentsUnRegister; |
|
ShExecInfo.lpDirectory = NULL; |
|
ShExecInfo.nShow = SW_HIDE; |
|
ShExecInfo.hInstApp = NULL; |
|
if (ShellExecuteExW(&ShExecInfo) && ShExecInfo.hProcess) |
|
{ |
|
WaitForSingleObject(ShExecInfo.hProcess, INFINITE); |
|
DWORD dwExitCode = 0; |
|
GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode); |
|
CloseHandle(ShExecInfo.hProcess); |
|
} |
|
return TRUE; |
|
} |
|
|
|
char* StrReplaceAllA(const char* s, const char* oldW, const char* newW, int* dwNewSize) |
|
{ |
|
char* result; |
|
int i, cnt = 0; |
|
int newWlen = strlen(newW); |
|
int oldWlen = strlen(oldW); |
|
|
|
for (i = 0; s[i] != '\0'; i++) { |
|
if (strstr(&s[i], oldW) == &s[i]) { |
|
cnt++; |
|
i += oldWlen - 1; |
|
} |
|
} |
|
result = (char*)malloc(i + cnt * (newWlen - oldWlen) + 1); |
|
i = 0; |
|
while (*s) { |
|
if (strstr(s, oldW) == s) { |
|
strcpy_s(&result[i], strlen(newW) + 1, newW); |
|
i += newWlen; |
|
s += oldWlen; |
|
} |
|
else |
|
result[i++] = *s++; |
|
} |
|
|
|
result[i] = '\0'; |
|
if (dwNewSize) *dwNewSize = i; |
|
return result; |
|
} |
|
|
|
WCHAR* StrReplaceAllW(const WCHAR* s, const WCHAR* oldW, const WCHAR* newW, int* dwNewSize) |
|
{ |
|
WCHAR* result; |
|
int i, cnt = 0; |
|
int newWlen = wcslen(newW); |
|
int oldWlen = wcslen(oldW); |
|
|
|
for (i = 0; s[i] != L'\0'; i++) { |
|
if (wcsstr(&s[i], oldW) == &s[i]) { |
|
cnt++; |
|
i += oldWlen - 1; |
|
} |
|
} |
|
result = (WCHAR*)malloc((i + cnt * (newWlen - oldWlen) + 1) * sizeof(WCHAR)); |
|
i = 0; |
|
while (*s) { |
|
if (wcsstr(s, oldW) == s) { |
|
wcscpy_s(&result[i], newWlen + 1, newW); |
|
i += newWlen; |
|
s += oldWlen; |
|
} |
|
else |
|
result[i++] = *s++; |
|
} |
|
result[i] = L'\0'; |
|
if (dwNewSize) *dwNewSize = i; |
|
return result; |
|
} |
|
|
|
HWND InputBox_HWND; |
|
|
|
HRESULT getEngineGuid(LPCTSTR extension, GUID* guidBuffer) |
|
{ |
|
wchar_t buffer[100]; |
|
HKEY hk; |
|
DWORD size; |
|
HKEY subKey; |
|
DWORD type; |
|
|
|
// See if this file extension is associated |
|
// with an ActiveX script engine |
|
if (!RegOpenKeyEx(HKEY_CLASSES_ROOT, extension, 0, |
|
KEY_QUERY_VALUE | KEY_READ, &hk)) |
|
{ |
|
type = REG_SZ; |
|
size = sizeof(buffer); |
|
size = RegQueryValueEx(hk, 0, 0, &type, |
|
(LPBYTE)&buffer[0], &size); |
|
RegCloseKey(hk); |
|
if (!size) |
|
{ |
|
// The engine set an association. |
|
// We got the Language string in buffer[]. Now |
|
// we can use it to look up the engine's GUID |
|
|
|
// Open HKEY_CLASSES_ROOT\{LanguageName} |
|
again: size = sizeof(buffer); |
|
if (!RegOpenKeyEx(HKEY_CLASSES_ROOT, (LPCTSTR)&buffer[0], 0, |
|
KEY_QUERY_VALUE | KEY_READ, &hk)) |
|
{ |
|
// Read the GUID (in string format) |
|
// into buffer[] by querying the value of CLSID |
|
if (!RegOpenKeyEx(hk, L"CLSID", 0, |
|
KEY_QUERY_VALUE | KEY_READ, &subKey)) |
|
{ |
|
size = RegQueryValueExW(subKey, 0, 0, &type, |
|
(LPBYTE)&buffer[0], &size); |
|
RegCloseKey(subKey); |
|
} |
|
else if (extension) |
|
{ |
|
// If an error, see if we have a "ScriptEngine" |
|
// key under here that contains |
|
// the real language name |
|
if (!RegOpenKeyEx(hk, L"ScriptEngine", 0, |
|
KEY_QUERY_VALUE | KEY_READ, &subKey)) |
|
{ |
|
size = RegQueryValueEx(subKey, 0, 0, &type, |
|
(LPBYTE)&buffer[0], &size); |
|
RegCloseKey(subKey); |
|
if (!size) |
|
{ |
|
RegCloseKey(hk); |
|
extension = 0; |
|
goto again; |
|
} |
|
} |
|
} |
|
} |
|
|
|
RegCloseKey(hk); |
|
|
|
if (!size) |
|
{ |
|
// Convert the GUID string to a GUID |
|
// and put it in caller's guidBuffer |
|
if ((size = CLSIDFromString(&buffer[0], guidBuffer))) |
|
{ |
|
return(E_FAIL); |
|
} |
|
return(size); |
|
} |
|
} |
|
} |
|
|
|
return(E_FAIL); |
|
} |
|
|
|
ULONG STDMETHODCALLTYPE ep_static_AddRefRelease(void* _this) |
|
{ |
|
return 1; |
|
} |
|
|
|
HRESULT STDMETHODCALLTYPE IActiveScriptSite_QueryInterface(void* _this, REFIID riid, void** ppv) |
|
{ |
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IActiveScriptSite)) |
|
*ppv = _this; |
|
else if (IsEqualIID(riid, &IID_IActiveScriptSiteWindow)) |
|
*ppv = ((unsigned char*)_this + 8); |
|
else |
|
{ |
|
*ppv = 0; |
|
return(E_NOINTERFACE); |
|
} |
|
return S_OK; |
|
} |
|
|
|
HRESULT STDMETHODCALLTYPE IActiveScriptSiteWindow_QueryInterface(void* _this, REFIID riid, void** ppv) |
|
{ |
|
return IActiveScriptSite_QueryInterface((char*)_this - 8, riid, ppv); |
|
} |
|
|
|
HRESULT STDMETHODCALLTYPE IActiveScriptSite_GetLCID(void* _this, LCID* plcid) |
|
{ |
|
*plcid = LOCALE_USER_DEFAULT; |
|
return S_OK; |
|
} |
|
|
|
HRESULT STDMETHODCALLTYPE IActiveScriptSite_GetItemInfo(void* _this, LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown** ppiunkItem, ITypeInfo** ppti) |
|
{ |
|
return TYPE_E_ELEMENTNOTFOUND; |
|
} |
|
|
|
HRESULT STDMETHODCALLTYPE IActiveScriptSite_GetDocVersionString(void* _this, BSTR* pbstrVersion) |
|
{ |
|
*pbstrVersion = 0; |
|
return S_OK; |
|
} |
|
|
|
HRESULT STDMETHODCALLTYPE IActiveScriptSite_OnScriptTerminate(void* _this, const void* pvarResult, const EXCEPINFO* pexcepinfo) |
|
{ |
|
return S_OK; |
|
} |
|
|
|
HRESULT STDMETHODCALLTYPE IActiveScriptSite_OnStateChange(void* _this, SCRIPTSTATE ssScriptState) |
|
{ |
|
return S_OK; |
|
} |
|
|
|
HRESULT STDMETHODCALLTYPE IActiveScriptSite_OnScriptError(void* _this, IActiveScriptError* scriptError) |
|
{ |
|
ULONG lineNumber; |
|
BSTR desc; |
|
EXCEPINFO ei; |
|
OLECHAR wszOutput[1024]; |
|
|
|
// Call GetSourcePosition() to retrieve the line # where |
|
// the error occurred in the script |
|
scriptError->lpVtbl->GetSourcePosition(scriptError, 0, &lineNumber, 0); |
|
|
|
// Call GetSourceLineText() to retrieve the line in the script that |
|
// has an error. |
|
desc = 0; |
|
scriptError->lpVtbl->GetSourceLineText(scriptError, &desc); |
|
|
|
// Call GetExceptionInfo() to fill in our EXCEPINFO struct with more |
|
// information. |
|
ZeroMemory(&ei, sizeof(EXCEPINFO)); |
|
scriptError->lpVtbl->GetExceptionInfo(scriptError, &ei); |
|
|
|
// Format the message we'll display to the user |
|
wsprintfW(&wszOutput[0], L"%s\nLine %u: %s\n%s", ei.bstrSource, |
|
lineNumber + 1, ei.bstrDescription, desc ? desc : ""); |
|
|
|
// Free what we got from the IActiveScriptError functions |
|
SysFreeString(desc); |
|
SysFreeString(ei.bstrSource); |
|
SysFreeString(ei.bstrDescription); |
|
SysFreeString(ei.bstrHelpFile); |
|
|
|
// Display the message |
|
MessageBoxW(0, &wszOutput[0], L"Error", |
|
MB_SETFOREGROUND | MB_OK | MB_ICONEXCLAMATION); |
|
|
|
return(S_OK); |
|
} |
|
|
|
HRESULT STDMETHODCALLTYPE IActiveScriptSite_OnEnterScript(void* _this) |
|
{ |
|
return S_OK; |
|
} |
|
|
|
HRESULT STDMETHODCALLTYPE IActiveScriptSite_OnLeaveScript(void* _this) |
|
{ |
|
return S_OK; |
|
} |
|
|
|
HRESULT STDMETHODCALLTYPE IActiveScriptSiteWindow_GetWindow(void* _this, HWND* phWnd) |
|
{ |
|
*phWnd = InputBox_HWND; |
|
return S_OK; |
|
} |
|
|
|
HRESULT STDMETHODCALLTYPE IActiveScriptSiteWindow_EnableModeless(void* _this, BOOL fEnable) |
|
{ |
|
return S_OK; |
|
} |
|
|
|
static const IActiveScriptSiteVtbl IActiveScriptSite_Vtbl = { |
|
.QueryInterface = IActiveScriptSite_QueryInterface, |
|
.AddRef = ep_static_AddRefRelease, |
|
.Release = ep_static_AddRefRelease, |
|
.GetLCID = IActiveScriptSite_GetLCID, |
|
.GetItemInfo = IActiveScriptSite_GetItemInfo, |
|
.GetDocVersionString = IActiveScriptSite_GetDocVersionString, |
|
.OnScriptTerminate = IActiveScriptSite_OnScriptTerminate, |
|
.OnStateChange = IActiveScriptSite_OnStateChange, |
|
.OnScriptError = IActiveScriptSite_OnScriptError, |
|
.OnEnterScript = IActiveScriptSite_OnEnterScript, |
|
.OnLeaveScript = IActiveScriptSite_OnLeaveScript, |
|
}; |
|
|
|
static const IActiveScriptSiteWindowVtbl IActiveScriptSiteWindow_Vtbl = { |
|
.QueryInterface = IActiveScriptSiteWindow_QueryInterface, |
|
.AddRef = ep_static_AddRefRelease, |
|
.Release = ep_static_AddRefRelease, |
|
.GetWindow = IActiveScriptSiteWindow_GetWindow, |
|
.EnableModeless = IActiveScriptSiteWindow_EnableModeless, |
|
}; |
|
|
|
typedef struct _CSimpleScriptSite |
|
{ |
|
IActiveScriptSiteVtbl* lpVtbl; |
|
IActiveScriptSiteWindowVtbl* lpVtbl1; |
|
} CSimpleScriptSite; |
|
|
|
static const CSimpleScriptSite CSimpleScriptSite_Instance = { |
|
.lpVtbl = &IActiveScriptSite_Vtbl, |
|
.lpVtbl1 = &IActiveScriptSiteWindow_Vtbl |
|
}; |
|
|
|
static BOOL HideInput = FALSE; |
|
static LRESULT CALLBACK InputBoxProc(int nCode, WPARAM wParam, LPARAM lParam) { |
|
if (nCode < HC_ACTION) |
|
return CallNextHookEx(0, nCode, wParam, lParam); |
|
if (nCode = HCBT_ACTIVATE) { |
|
if (HideInput == TRUE) { |
|
HWND TextBox = FindWindowExA((HWND)wParam, NULL, "Edit", NULL); |
|
SendDlgItemMessageW((HWND)wParam, GetDlgCtrlID(TextBox), EM_SETPASSWORDCHAR, L'\x25cf', 0); |
|
} |
|
} |
|
if (nCode = HCBT_CREATEWND) { |
|
if (!(GetWindowLongPtr((HWND)wParam, GWL_STYLE) & WS_CHILD)) |
|
SetWindowLongPtr((HWND)wParam, GWL_EXSTYLE, GetWindowLongPtr((HWND)wParam, GWL_EXSTYLE) | WS_EX_DLGMODALFRAME); |
|
} |
|
return CallNextHookEx(0, nCode, wParam, lParam); |
|
} |
|
|
|
HRESULT InputBox(BOOL bPassword, HWND hWnd, LPCWSTR wszPrompt, LPCWSTR wszTitle, LPCWSTR wszDefault, LPWSTR wszAnswer, DWORD cbAnswer, BOOL* bCancelled) |
|
{ |
|
HRESULT hr = S_OK; |
|
|
|
if (!wszPrompt || !wszTitle || !wszDefault || !wszAnswer || !cbAnswer || !bCancelled) |
|
{ |
|
return E_FAIL; |
|
} |
|
|
|
GUID guidBuffer; |
|
hr = getEngineGuid(L".vbs", &guidBuffer); |
|
|
|
DWORD cchPromptSafe = 0, cchTitleSafe = 0, cchDefaultSafe = 0; |
|
LPWSTR wszPromptSafe = StrReplaceAllW(wszPrompt, L"\"", L"\"\"", &cchPromptSafe); |
|
LPWSTR wszTitleSafe = StrReplaceAllW(wszTitle, L"\"", L"\"\"", &cchTitleSafe); |
|
LPWSTR wszDefaultSafe = StrReplaceAllW(wszDefault, L"\"", L"\"\"", &cchDefaultSafe); |
|
if (!wszPromptSafe || !wszTitleSafe || !wszDefaultSafe) |
|
{ |
|
if (wszPromptSafe) |
|
{ |
|
free(wszPromptSafe); |
|
} |
|
if (wszTitleSafe) |
|
{ |
|
free(wszTitleSafe); |
|
} |
|
if (wszDefaultSafe) |
|
{ |
|
free(wszDefaultSafe); |
|
} |
|
return E_OUTOFMEMORY; |
|
} |
|
|
|
IActiveScript* pActiveScript = NULL; |
|
hr = CoCreateInstance(FAILED(hr) ? &CLSID_VBScript : &guidBuffer, 0, CLSCTX_ALL, |
|
&IID_IActiveScript, |
|
(void**)&pActiveScript); |
|
if (SUCCEEDED(hr) && pActiveScript) |
|
{ |
|
hr = pActiveScript->lpVtbl->SetScriptSite(pActiveScript, &CSimpleScriptSite_Instance); |
|
if (SUCCEEDED(hr)) |
|
{ |
|
IActiveScriptParse* pActiveScriptParse = NULL; |
|
hr = pActiveScript->lpVtbl->QueryInterface(pActiveScript, &IID_IActiveScriptParse, &pActiveScriptParse); |
|
if (SUCCEEDED(hr) && pActiveScriptParse) |
|
{ |
|
hr = pActiveScriptParse->lpVtbl->InitNew(pActiveScriptParse); |
|
if (SUCCEEDED(hr)) |
|
{ |
|
LPWSTR wszEvaluation = malloc(sizeof(WCHAR) * (cchPromptSafe + cchTitleSafe + cchDefaultSafe + 100)); |
|
if (wszEvaluation) |
|
{ |
|
swprintf_s(wszEvaluation, cchPromptSafe + cchTitleSafe + cchDefaultSafe + 100, L"InputBox(\"%s\", \"%s\", \"%s\")", wszPromptSafe, wszTitleSafe, wszDefaultSafe); |
|
DWORD cchEvaluation2 = 0; |
|
LPWSTR wszEvaluation2 = StrReplaceAllW(wszEvaluation, L"\n", L"\" + vbNewLine + \"", &cchEvaluation2); |
|
if (wszEvaluation2) |
|
{ |
|
EXCEPINFO ei; |
|
ZeroMemory(&ei, sizeof(EXCEPINFO)); |
|
DWORD dwThreadId = GetCurrentThreadId(); |
|
HINSTANCE hInstance = GetModuleHandle(NULL); |
|
|
|
if (!hWnd) |
|
{ |
|
InputBox_HWND = GetAncestor(GetActiveWindow(), GA_ROOTOWNER); |
|
} |
|
else |
|
{ |
|
InputBox_HWND = hWnd; |
|
} |
|
|
|
HHOOK hHook = SetWindowsHookExW(WH_CBT, &InputBoxProc, hInstance, dwThreadId); |
|
|
|
VARIANT result; |
|
VariantInit(&result); |
|
|
|
HideInput = bPassword; |
|
hr = pActiveScriptParse->lpVtbl->ParseScriptText(pActiveScriptParse, wszEvaluation2, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &result, &ei); |
|
|
|
*bCancelled = (result.vt == VT_EMPTY); |
|
|
|
UnhookWindowsHookEx(hHook); |
|
|
|
free(wszEvaluation2); |
|
|
|
if (result.bstrVal) |
|
{ |
|
memcpy(wszAnswer, result.bstrVal, cbAnswer * sizeof(WCHAR)); |
|
} |
|
else |
|
{ |
|
if (result.vt != VT_EMPTY) |
|
{ |
|
wszAnswer[0] = 0; |
|
} |
|
} |
|
|
|
VariantClear(&result); |
|
} |
|
free(wszEvaluation); |
|
} |
|
} |
|
pActiveScriptParse->lpVtbl->Release(pActiveScriptParse); |
|
} |
|
pActiveScript->lpVtbl->Release(pActiveScript); |
|
} |
|
} |
|
|
|
if (wszPromptSafe) |
|
{ |
|
free(wszPromptSafe); |
|
} |
|
if (wszTitleSafe) |
|
{ |
|
free(wszTitleSafe); |
|
} |
|
if (wszDefaultSafe) |
|
{ |
|
free(wszDefaultSafe); |
|
} |
|
|
|
return hr; |
|
} |
|
|
|
UINT PleaseWaitTimeout = 0; |
|
HHOOK PleaseWaitHook = NULL; |
|
HWND PleaseWaitHWND = NULL; |
|
void* PleaseWaitCallbackData = NULL; |
|
BOOL (*PleaseWaitCallbackFunc)(void* data) = NULL; |
|
BOOL PleaseWait_UpdateTimeout(int timeout) |
|
{ |
|
if (PleaseWaitHWND) |
|
{ |
|
KillTimer(PleaseWaitHWND, 'EPPW'); |
|
PleaseWaitTimeout = timeout; |
|
return SetTimer(PleaseWaitHWND, 'EPPW', PleaseWaitTimeout, PleaseWait_TimerProc); |
|
} |
|
return FALSE; |
|
} |
|
|
|
VOID CALLBACK PleaseWait_TimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime) |
|
{ |
|
if (idEvent == 'EPPW') |
|
{ |
|
if (PleaseWaitCallbackFunc) |
|
{ |
|
if (PleaseWaitCallbackFunc(PleaseWaitCallbackData)) |
|
{ |
|
return; |
|
} |
|
PleaseWaitCallbackData = NULL; |
|
PleaseWaitCallbackFunc = NULL; |
|
} |
|
KillTimer(hWnd, 'EPPW'); |
|
SetTimer(hWnd, 'EPPW', 0, NULL); // <- this closes the message box |
|
PleaseWaitHWND = NULL; |
|
PleaseWaitTimeout = 0; |
|
} |
|
} |
|
|
|
LRESULT CALLBACK PleaseWait_HookProc(int code, WPARAM wParam, LPARAM lParam) |
|
{ |
|
if (code < 0) |
|
{ |
|
return CallNextHookEx(NULL, code, wParam, lParam); |
|
} |
|
|
|
CWPSTRUCT* msg = (CWPSTRUCT*)lParam; |
|
/*if (msg->message == WM_CREATE) |
|
{ |
|
CREATESTRUCT* pCS = (CREATESTRUCT*)msg->lParam; |
|
if (pCS->lpszClass == RegisterWindowMessageW(L"Button")) |
|
{ |
|
} |
|
}*/ |
|
LRESULT result = CallNextHookEx(NULL, code, wParam, lParam); |
|
|
|
if (msg->message == WM_INITDIALOG) |
|
{ |
|
PleaseWaitHWND = msg->hwnd; |
|
EnableWindow(PleaseWaitHWND, FALSE); |
|
LONG_PTR style = GetWindowLongPtrW(PleaseWaitHWND, GWL_STYLE); |
|
SetWindowLongPtrW(PleaseWaitHWND, GWL_STYLE, style & ~WS_SYSMENU); |
|
RECT rc; |
|
GetWindowRect(PleaseWaitHWND, &rc); |
|
SetWindowPos(PleaseWaitHWND, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top - MulDiv(50, GetDpiForWindow(PleaseWaitHWND), 96), SWP_NOMOVE | SWP_FRAMECHANGED); |
|
SetTimer(PleaseWaitHWND, 'EPPW', PleaseWaitTimeout, PleaseWait_TimerProc); |
|
UnhookWindowsHookEx(PleaseWaitHook); |
|
PleaseWaitHook = NULL; |
|
} |
|
return result; |
|
} |
|
|
|
BOOL DownloadAndInstallWebView2Runtime() |
|
{ |
|
BOOL bOK = FALSE; |
|
HINTERNET hInternet = NULL; |
|
if (hInternet = InternetOpenA( |
|
"ExplorerPatcher", |
|
INTERNET_OPEN_TYPE_PRECONFIG, |
|
NULL, |
|
NULL, |
|
0 |
|
)) |
|
{ |
|
HINTERNET hConnect = InternetOpenUrlA( |
|
hInternet, |
|
"https://go.microsoft.com/fwlink/p/?LinkId=2124703", |
|
NULL, |
|
0, |
|
INTERNET_FLAG_RAW_DATA | |
|
INTERNET_FLAG_RELOAD | |
|
INTERNET_FLAG_RESYNCHRONIZE | |
|
INTERNET_FLAG_NO_COOKIES | |
|
INTERNET_FLAG_NO_UI | |
|
INTERNET_FLAG_NO_CACHE_WRITE | |
|
INTERNET_FLAG_DONT_CACHE, |
|
NULL |
|
); |
|
if (hConnect) |
|
{ |
|
char* exe_buffer = NULL; |
|
DWORD dwSize = 2 * 1024 * 1024; |
|
DWORD dwRead = dwSize; |
|
exe_buffer = calloc(dwSize, sizeof(char)); |
|
if (exe_buffer) |
|
{ |
|
BOOL bRet = FALSE; |
|
if (bRet = InternetReadFile( |
|
hConnect, |
|
exe_buffer, |
|
dwSize - 1, |
|
&dwRead |
|
)) |
|
{ |
|
WCHAR wszPath[MAX_PATH]; |
|
ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR)); |
|
SHGetFolderPathW(NULL, SPECIAL_FOLDER_LEGACY, NULL, SHGFP_TYPE_CURRENT, wszPath); |
|
wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH)); |
|
BOOL bRet = CreateDirectoryW(wszPath, NULL); |
|
if (bRet || (!bRet && GetLastError() == ERROR_ALREADY_EXISTS)) |
|
{ |
|
wcscat_s(wszPath, MAX_PATH, L"\\MicrosoftEdgeWebview2Setup.exe"); |
|
FILE* f = NULL; |
|
_wfopen_s(&f, wszPath, L"wb"); |
|
if (f) |
|
{ |
|
fwrite(exe_buffer, 1, dwRead, f); |
|
fclose(f); |
|
SHELLEXECUTEINFOW sei; |
|
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFOW)); |
|
sei.cbSize = sizeof(sei); |
|
sei.fMask = SEE_MASK_NOCLOSEPROCESS; |
|
sei.hwnd = NULL; |
|
sei.hInstApp = NULL; |
|
sei.lpVerb = NULL; |
|
sei.lpFile = wszPath; |
|
sei.lpParameters = L""; |
|
sei.hwnd = NULL; |
|
sei.nShow = SW_SHOWMINIMIZED; |
|
if (ShellExecuteExW(&sei) && sei.hProcess) |
|
{ |
|
WaitForSingleObject(sei.hProcess, INFINITE); |
|
CloseHandle(sei.hProcess); |
|
Sleep(100); |
|
DeleteFileW(wszPath); |
|
bOK = TRUE; |
|
} |
|
} |
|
} |
|
} |
|
free(exe_buffer); |
|
} |
|
InternetCloseHandle(hConnect); |
|
} |
|
InternetCloseHandle(hInternet); |
|
} |
|
return bOK; |
|
} |
|
|
|
BOOL DownloadFile(LPCWSTR wszURL, DWORD dwSize, LPCWSTR wszPath) |
|
{ |
|
BOOL bOK = FALSE; |
|
HINTERNET hInternet = NULL; |
|
if (hInternet = InternetOpenW( |
|
L"ExplorerPatcher", |
|
INTERNET_OPEN_TYPE_PRECONFIG, |
|
NULL, |
|
NULL, |
|
0 |
|
)) |
|
{ |
|
HINTERNET hConnect = InternetOpenUrlW( |
|
hInternet, |
|
wszURL, |
|
NULL, |
|
0, |
|
INTERNET_FLAG_RAW_DATA | |
|
INTERNET_FLAG_RELOAD | |
|
INTERNET_FLAG_RESYNCHRONIZE | |
|
INTERNET_FLAG_NO_COOKIES | |
|
INTERNET_FLAG_NO_UI | |
|
INTERNET_FLAG_NO_CACHE_WRITE | |
|
INTERNET_FLAG_DONT_CACHE, |
|
NULL |
|
); |
|
if (hConnect) |
|
{ |
|
char* exe_buffer = NULL; |
|
DWORD dwRead = dwSize; |
|
exe_buffer = calloc(dwSize, sizeof(char)); |
|
if (exe_buffer) |
|
{ |
|
BOOL bRet = FALSE; |
|
if (bRet = InternetReadFile( |
|
hConnect, |
|
exe_buffer, |
|
dwSize - 1, |
|
&dwRead |
|
)) |
|
{ |
|
FILE* f = NULL; |
|
_wfopen_s(&f, wszPath, L"wb"); |
|
if (f) |
|
{ |
|
fwrite(exe_buffer, 1, dwRead, f); |
|
fclose(f); |
|
} |
|
} |
|
free(exe_buffer); |
|
} |
|
InternetCloseHandle(hConnect); |
|
} |
|
InternetCloseHandle(hInternet); |
|
} |
|
return bOK; |
|
} |
|
|
|
BOOL IsConnectedToInternet() |
|
{ |
|
BOOL connectedStatus = FALSE; |
|
HRESULT hr = S_FALSE; |
|
|
|
hr = CoInitialize(NULL); |
|
if (SUCCEEDED(hr)) |
|
{ |
|
INetworkListManager* pNetworkListManager; |
|
hr = CoCreateInstance(&CLSID_NetworkListManager, NULL, CLSCTX_ALL, &IID_NetworkListManager, (LPVOID*)&pNetworkListManager); |
|
if (SUCCEEDED(hr)) |
|
{ |
|
NLM_CONNECTIVITY nlmConnectivity = NLM_CONNECTIVITY_DISCONNECTED; |
|
VARIANT_BOOL isConnected = VARIANT_FALSE; |
|
hr = pNetworkListManager->lpVtbl->get_IsConnectedToInternet(pNetworkListManager, &isConnected); |
|
if (SUCCEEDED(hr)) |
|
{ |
|
if (isConnected == VARIANT_TRUE) |
|
connectedStatus = TRUE; |
|
else |
|
connectedStatus = FALSE; |
|
} |
|
if (isConnected == VARIANT_FALSE && SUCCEEDED(pNetworkListManager->lpVtbl->GetConnectivity(pNetworkListManager, &nlmConnectivity))) |
|
{ |
|
if (nlmConnectivity & (NLM_CONNECTIVITY_IPV4_LOCALNETWORK | NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_LOCALNETWORK | NLM_CONNECTIVITY_IPV6_SUBNET)) |
|
{ |
|
connectedStatus = 2; |
|
} |
|
} |
|
pNetworkListManager->lpVtbl->Release(pNetworkListManager); |
|
} |
|
CoUninitialize(); |
|
} |
|
return connectedStatus; |
|
}
|
|
|