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.
502 lines
13 KiB
502 lines
13 KiB
#include "utility.h" |
|
|
|
#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 displayTimestamp=\"2021-08-29T00:00:00.000Z\" 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, LPCSTR 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; |
|
} |
|
|
|
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, |
|
TRUE, |
|
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; |
|
}
|
|
|