mirror of
https://github.com/valinet/ExplorerPatcher.git
synced 2025-02-17 11:08:41 +01:00
Implement restoration of Logon, Logoff, and Shutdown sounds based on code in Windows 7 explorer.exe (disabled in public builds for now).
- Also properly fixed the logon delay on 22000. - Removed the logon delay option.
This commit is contained in:
parent
47cc16552b
commit
24e019d484
@ -117,6 +117,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)libs\funchook\build\Release\;$(SolutionDir)libs\Detours\lib.X64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>Winmm.dll</DelayLoadDLLs>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
@ -147,6 +148,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)libs\funchook\build\Release\;$(SolutionDir)libs\Detours\lib.X64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>Winmm.dll</DelayLoadDLLs>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
@ -174,6 +176,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)libs\funchook\build\Release\;$(SolutionDir)libs\Detours\lib.X64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>Winmm.dll</DelayLoadDLLs>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
@ -201,6 +204,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)libs\funchook\build\Release\;$(SolutionDir)libs\Detours\lib.X64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>Winmm.dll</DelayLoadDLLs>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>
|
||||
@ -284,7 +288,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StartupSound.c">
|
||||
<ClCompile Include="StartupSound.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
@ -1,29 +0,0 @@
|
||||
#include "StartupSound.h"
|
||||
|
||||
DWORD PlayStartupSound(PlayStartupSoundParams* unused)
|
||||
{
|
||||
Sleep(2000);
|
||||
printf("Started \"Play startup sound\" thread.\n");
|
||||
|
||||
HRESULT hr = CoInitialize(NULL);
|
||||
|
||||
// this checks Software\\Microsoft\\Windows\\CurrentVersion\\Authentication\\LogonUI\\LogonSoundPlayed
|
||||
// and then plays the startup sound
|
||||
|
||||
AuthUILogonSound* ppv;
|
||||
hr = CoCreateInstance(
|
||||
&__uuidof_AuthUILogonSound,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&__uuidof_IAuthUILogonSound,
|
||||
&ppv
|
||||
);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ppv->lpVtbl->PlayIfNecessary(ppv, 1);
|
||||
ppv->lpVtbl->Release(ppv);
|
||||
}
|
||||
|
||||
printf("Ended \"Play startup sound\" thread.\n");
|
||||
return 0;
|
||||
}
|
390
ExplorerPatcher/StartupSound.cpp
Normal file
390
ExplorerPatcher/StartupSound.cpp
Normal file
@ -0,0 +1,390 @@
|
||||
#include "StartupSound.h"
|
||||
|
||||
#include <Shlwapi.h>
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
#include <stdio.h>
|
||||
#include <strsafe.h>
|
||||
#pragma comment(lib, "Winmm.lib")
|
||||
#include <Wtsapi32.h>
|
||||
#pragma comment(lib, "Wtsapi32.lib")
|
||||
#include <tchar.h>
|
||||
#include <wrl/client.h>
|
||||
#include <wil/result_macros.h>
|
||||
|
||||
#include "def.h"
|
||||
|
||||
BOOL AreLogonLogoffShutdownSoundsEnabled()
|
||||
{
|
||||
#if 0
|
||||
DWORD dwValue = 0;
|
||||
DWORD dwSize = sizeof(dwValue);
|
||||
RegGetValueW(HKEY_CURRENT_USER, _T(REGPATH), L"LogonLogoffShutdownSounds", RRF_RT_DWORD, nullptr, &dwValue, &dwSize);
|
||||
return dwValue != 0;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
DWORD GetLastErrorError()
|
||||
{
|
||||
DWORD result = GetLastError();
|
||||
return result == ERROR_SUCCESS ? 1 : result;
|
||||
}
|
||||
|
||||
HRESULT HRESULTFromLastErrorError()
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
if (error != ERROR_SUCCESS && (int)error <= 0)
|
||||
return (HRESULT)GetLastErrorError();
|
||||
else
|
||||
return (HRESULT)((GetLastErrorError() & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000);
|
||||
}
|
||||
|
||||
DWORD PlaySoundFileThreadProc(LPVOID pvData)
|
||||
{
|
||||
PlaySoundW((LPCWSTR)pvData, nullptr, SND_NODEFAULT | SND_MEMORY | SND_SYSTEM);
|
||||
LocalFree(pvData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT PlaySoundFile(HANDLE* phThread, const WCHAR* pszPath)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
void* pvData = nullptr;
|
||||
HANDLE hFile = CreateFileW(
|
||||
pszPath,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_DELETE,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
|
||||
nullptr
|
||||
);
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD dwSize = GetFileSize(hFile, nullptr);
|
||||
hr = E_OUTOFMEMORY;
|
||||
if (dwSize != (DWORD)-1 && dwSize)
|
||||
{
|
||||
if (dwSize < 0x400000)
|
||||
{
|
||||
pvData = LocalAlloc(0, dwSize);
|
||||
if (pvData)
|
||||
{
|
||||
DWORD dwRead;
|
||||
if (ReadFile(hFile, pvData, dwSize, &dwRead, nullptr))
|
||||
hr = dwSize == dwRead ? S_OK : HRESULT_FROM_WIN32(ERROR_IO_PENDING);
|
||||
else
|
||||
hr = HRESULTFromLastErrorError();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = HRESULTFromLastErrorError();
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = HRESULTFromLastErrorError();
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
HANDLE hThread = CreateThread(nullptr, 0, PlaySoundFileThreadProc, pvData, 0, nullptr);
|
||||
if (hThread)
|
||||
{
|
||||
if (phThread)
|
||||
*phThread = hThread;
|
||||
else
|
||||
CloseHandle(hThread);
|
||||
return hr;
|
||||
}
|
||||
hr = HRESULTFromLastErrorError();
|
||||
}
|
||||
if (pvData)
|
||||
LocalFree(pvData);
|
||||
return hr;
|
||||
}
|
||||
|
||||
typedef enum LOGONOFFSOUNDTYPE
|
||||
{
|
||||
LOGONOFFSOUNDTYPE_LOGON,
|
||||
LOGONOFFSOUNDTYPE_LOGOFF,
|
||||
LOGONOFFSOUNDTYPE_EXIT,
|
||||
} LOGONOFFSOUNDTYPE;
|
||||
|
||||
HRESULT PlayLogonLogoffSound(HANDLE* phThread, LOGONOFFSOUNDTYPE type)
|
||||
{
|
||||
const WCHAR* szEventName;
|
||||
switch (type)
|
||||
{
|
||||
case LOGONOFFSOUNDTYPE_LOGON:
|
||||
szEventName = L"WindowsLogon";
|
||||
break;
|
||||
case LOGONOFFSOUNDTYPE_LOGOFF:
|
||||
szEventName = L"WindowsLogoff";
|
||||
break;
|
||||
default:
|
||||
szEventName = L"SystemExit";
|
||||
break;
|
||||
}
|
||||
|
||||
WCHAR szSubKey[MAX_PATH];
|
||||
HRESULT hr = StringCchPrintfW(szSubKey, ARRAYSIZE(szSubKey), L"AppEvents\\Schemes\\Apps\\.Default\\%ws\\.Current", szEventName);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
WCHAR szPath[MAX_PATH];
|
||||
DWORD cbData = sizeof(szPath);
|
||||
LSTATUS lStat = RegGetValueW(HKEY_CURRENT_USER, szSubKey, nullptr, REG_EXPAND_SZ, nullptr, szPath, &cbData);
|
||||
if (lStat != ERROR_SUCCESS)
|
||||
return HRESULT_FROM_WIN32(lStat);
|
||||
|
||||
return PlaySoundFile(phThread, szPath);
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/59810748
|
||||
bool IsSessionLocked()
|
||||
{
|
||||
WTSINFOEXW* pInfo = NULL;
|
||||
WTS_INFO_CLASS wtsic = WTSSessionInfoEx;
|
||||
LPTSTR ppBuffer = NULL;
|
||||
DWORD dwBytesReturned = 0;
|
||||
LONG sessionFlags = WTS_SESSIONSTATE_UNKNOWN;
|
||||
|
||||
DWORD dwSessionID = WTSGetActiveConsoleSessionId();
|
||||
|
||||
if (WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, dwSessionID, wtsic, &ppBuffer, &dwBytesReturned))
|
||||
{
|
||||
if (dwBytesReturned > 0)
|
||||
{
|
||||
pInfo = (WTSINFOEXW*)ppBuffer;
|
||||
if (pInfo->Level == 1)
|
||||
{
|
||||
sessionFlags = pInfo->Data.WTSInfoExLevel1.SessionFlags;
|
||||
}
|
||||
}
|
||||
WTSFreeMemory(ppBuffer);
|
||||
ppBuffer = NULL;
|
||||
}
|
||||
|
||||
return (sessionFlags == WTS_SESSIONSTATE_LOCK);
|
||||
}
|
||||
|
||||
HRESULT (*CLogonSound_PlayIfNecessaryFunc)(void* _this, LOGON_SOUND_CLIENT client);
|
||||
HRESULT CLogonSound_PlayIfNecessaryHook(void* _this, LOGON_SOUND_CLIENT client)
|
||||
{
|
||||
HRESULT hr = CLogonSound_PlayIfNecessaryFunc(_this, client);
|
||||
if (hr != S_OK && client == LSC_EXPLORER)
|
||||
{
|
||||
if (!IsSessionLocked())
|
||||
PlayLogonLogoffSound(nullptr, LOGONOFFSOUNDTYPE_LOGON);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT HookLogonSound()
|
||||
{
|
||||
RETURN_IF_FAILED(CoInitialize(nullptr));
|
||||
|
||||
Microsoft::WRL::ComPtr<IAuthUILogonSound> logonSound;
|
||||
RETURN_IF_FAILED(CoCreateInstance(__uuidof_AuthUILogonSound, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&logonSound)));
|
||||
|
||||
void** vtable = *(void***)logonSound.Get();
|
||||
DWORD flOldProtect;
|
||||
RETURN_HR_IF(E_FAIL, !VirtualProtect(&vtable[3], sizeof(void*), PAGE_EXECUTE_READWRITE, &flOldProtect));
|
||||
|
||||
CLogonSound_PlayIfNecessaryFunc = (decltype(CLogonSound_PlayIfNecessaryFunc))vtable[3];
|
||||
vtable[3] = (void*)CLogonSound_PlayIfNecessaryHook;
|
||||
VirtualProtect(&vtable[3], sizeof(void*), flOldProtect, &flOldProtect);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LRESULT SHDefWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (IsWindowUnicode(hwnd))
|
||||
{
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
return DefWindowProcA(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
HWND g_hwndSound;
|
||||
|
||||
class CSoundWnd
|
||||
{
|
||||
public:
|
||||
CSoundWnd();
|
||||
|
||||
BOOL Init();
|
||||
DWORD Release();
|
||||
|
||||
protected:
|
||||
static LRESULT CALLBACK s_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT v_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
private:
|
||||
static DWORD s_CreateWindow(void* pvParam);
|
||||
static DWORD s_ThreadProc(void* pvParam);
|
||||
|
||||
LONG m_refCount;
|
||||
HWND m_hwnd;
|
||||
HANDLE m_thread;
|
||||
};
|
||||
|
||||
CSoundWnd::CSoundWnd()
|
||||
: m_refCount(1)
|
||||
, m_hwnd(nullptr)
|
||||
, m_thread(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL CSoundWnd::Init()
|
||||
{
|
||||
SHCreateThread(s_ThreadProc, this, CTF_THREAD_REF | CTF_COINIT_STA | CTF_REF_COUNTED | CTF_NOADDREFLIB, s_CreateWindow);
|
||||
g_hwndSound = m_hwnd;
|
||||
return m_hwnd != nullptr;
|
||||
}
|
||||
|
||||
DWORD CSoundWnd::Release()
|
||||
{
|
||||
LONG refCount = InterlockedDecrement(&m_refCount);
|
||||
if (refCount == 0 && this)
|
||||
operator delete(this);
|
||||
return refCount;
|
||||
}
|
||||
|
||||
LRESULT CSoundWnd::s_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
CSoundWnd* pThis = (CSoundWnd*)GetWindowLongPtrW(hwnd, 0);
|
||||
if (pThis)
|
||||
return pThis->v_WndProc(hwnd, uMsg, wParam, lParam);
|
||||
else
|
||||
return SHDefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
LRESULT CSoundWnd::v_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_QUERYENDSESSION:
|
||||
{
|
||||
if ((lParam & ENDSESSION_CRITICAL) == 0)
|
||||
{
|
||||
WCHAR sz[256];
|
||||
LoadStringW(GetModuleHandleW(nullptr), 731, sz, ARRAYSIZE(sz)); // Playing logoff sound...
|
||||
ShutdownBlockReasonCreate(m_hwnd, sz);
|
||||
PlayLogonLogoffSound(&m_thread, (lParam & ENDSESSION_LOGOFF) != 0 ? LOGONOFFSOUNDTYPE_LOGOFF : LOGONOFFSOUNDTYPE_EXIT);
|
||||
if (m_thread)
|
||||
{
|
||||
WaitForSingleObject(m_thread, INFINITE); // @MOD
|
||||
CloseHandle(m_thread); // @MOD
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case WM_ENDSESSION:
|
||||
{
|
||||
/*if (wParam && (lParam & ENDSESSION_CRITICAL) == 0 && m_thread) // @MOD This doesn't work
|
||||
{
|
||||
WaitForSingleObject(m_thread, INFINITE);
|
||||
CloseHandle(m_thread);
|
||||
}*/
|
||||
DestroyWindow(m_hwnd);
|
||||
break;
|
||||
}
|
||||
case WM_NCDESTROY:
|
||||
{
|
||||
SetWindowLongW(hwnd, 0, 0);
|
||||
g_hwndSound = nullptr;
|
||||
m_hwnd = nullptr;
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return SHDefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
extern "C" HWND (__stdcall *explorerframe_SHCreateWorkerWindowFunc)(
|
||||
WNDPROC wndProc,
|
||||
HWND hWndParent,
|
||||
DWORD dwExStyle,
|
||||
DWORD dwStyle,
|
||||
HMENU hMenu,
|
||||
LONG_PTR wnd_extra
|
||||
);
|
||||
|
||||
DWORD CSoundWnd::s_CreateWindow(void* pvParam)
|
||||
{
|
||||
CSoundWnd* pThis = (CSoundWnd*)pvParam;
|
||||
InterlockedIncrement(&pThis->m_refCount);
|
||||
pThis->m_hwnd = explorerframe_SHCreateWorkerWindowFunc(s_WndProc, nullptr, 0, 0, nullptr, (LONG_PTR)pThis);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD CSoundWnd::s_ThreadProc(void* pvParam)
|
||||
{
|
||||
CSoundWnd* pThis = (CSoundWnd*)pvParam;
|
||||
if (pThis->m_hwnd)
|
||||
{
|
||||
MSG Msg;
|
||||
while (GetMessageW(&Msg, nullptr, 0, 0))
|
||||
{
|
||||
TranslateMessage(&Msg);
|
||||
DispatchMessageW(&Msg);
|
||||
}
|
||||
}
|
||||
pThis->Release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL InitSoundWindow()
|
||||
{
|
||||
BOOL bSuccess = FALSE;
|
||||
CSoundWnd* soundWnd = new CSoundWnd();
|
||||
if (soundWnd)
|
||||
{
|
||||
bSuccess = soundWnd->Init();
|
||||
soundWnd->Release();
|
||||
}
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
void TermSoundWindow()
|
||||
{
|
||||
if (g_hwndSound)
|
||||
{
|
||||
PostMessageW(g_hwndSound, WM_CLOSE, 0, 0);
|
||||
g_hwndSound = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT SHPlaySound(LPCWSTR pszSound, DWORD dwFlags)
|
||||
{
|
||||
HRESULT hr;
|
||||
BOOL bDefault = (dwFlags & 1) != 0;
|
||||
BOOL bSecondAttempt = FALSE;
|
||||
while (true)
|
||||
{
|
||||
WCHAR szKey[MAX_PATH];
|
||||
hr = StringCchPrintfW(szKey, MAX_PATH, L"AppEvents\\Schemes\\Apps\\%s\\%s\\.current", bDefault ? L".Default" : L"Explorer", pszSound);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
WCHAR pvData[MAX_PATH];
|
||||
DWORD cbData = sizeof(pvData);
|
||||
if (SHGetValueW(HKEY_CURRENT_USER, szKey, nullptr, nullptr, pvData, &cbData) == ERROR_SUCCESS && cbData && pvData[0])
|
||||
hr = PlaySoundW(pszSound, nullptr, (!bDefault ? 0x400000 : 0) | (SND_ASYNC | SND_NODEFAULT | SND_NOSTOP | SND_NOWAIT | SND_ALIAS | SND_SENTRY | SND_SYSTEM)) ? S_OK : S_FALSE;
|
||||
}
|
||||
if (hr == S_OK || (dwFlags & 2) == 0 || bSecondAttempt)
|
||||
break;
|
||||
bDefault = !bDefault;
|
||||
bSecondAttempt = TRUE;
|
||||
}
|
||||
return hr;
|
||||
}
|
@ -8,43 +8,33 @@ DEFINE_GUID(__uuidof_AuthUILogonSound,
|
||||
0x1100, 0x4389, 0xAB, 0x44,
|
||||
0x46, 0x4F, 0xAF, 0x00, 0x12, 0x88
|
||||
);
|
||||
DEFINE_GUID(__uuidof_IAuthUILogonSound,
|
||||
0xc35243ea,
|
||||
0x4cfc, 0x435a, 0x91, 0xc2,
|
||||
0x9d, 0xbd, 0xec, 0xbf, 0xfc, 0x95
|
||||
);
|
||||
|
||||
typedef interface AuthUILogonSound AuthUILogonSound;
|
||||
|
||||
typedef struct AuthUILogonSoundVtbl
|
||||
#ifdef __cplusplus
|
||||
enum LOGON_SOUND_CLIENT
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT(STDMETHODCALLTYPE* QueryInterface)(
|
||||
AuthUILogonSound* This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
_COM_Outptr_ void** ppvObject);
|
||||
|
||||
ULONG(STDMETHODCALLTYPE* AddRef)(
|
||||
AuthUILogonSound* This);
|
||||
|
||||
ULONG(STDMETHODCALLTYPE* Release)(
|
||||
AuthUILogonSound* This);
|
||||
|
||||
HRESULT(STDMETHODCALLTYPE* PlayIfNecessary)(
|
||||
AuthUILogonSound* This,
|
||||
/* [in] */ INT64 a1);
|
||||
|
||||
END_INTERFACE
|
||||
} AuthUILogonSoundVtbl;
|
||||
|
||||
interface AuthUILogonSound
|
||||
{
|
||||
CONST_VTBL struct AuthUILogonSoundVtbl* lpVtbl;
|
||||
LSC_LOGONUI,
|
||||
LSC_EXPLORER,
|
||||
};
|
||||
|
||||
typedef DWORD PlayStartupSoundParams;
|
||||
MIDL_INTERFACE("c35243ea-4cfc-435a-91c2-9dbdecbffc95")
|
||||
IAuthUILogonSound : IUnknown
|
||||
{
|
||||
virtual HRESULT STDMETHODCALLTYPE PlayIfNecessary(LOGON_SOUND_CLIENT client) = 0;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
BOOL AreLogonLogoffShutdownSoundsEnabled();
|
||||
HRESULT HookLogonSound();
|
||||
BOOL InitSoundWindow();
|
||||
void TermSoundWindow();
|
||||
HRESULT SHPlaySound(LPCWSTR pszSound, DWORD dwFlags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
DWORD PlayStartupSound(PlayStartupSoundParams* unused);
|
||||
#endif
|
@ -39,6 +39,16 @@ public:
|
||||
STDMETHODIMP InitializeWithTray(ITrayUIHost* host, ITrayUI** result) override
|
||||
{
|
||||
RETURN_IF_FAILED(explorer_TrayUI_CreateInstanceFunc(host, IID_ITrayUI, (void**)result));
|
||||
|
||||
// Fix delayed logon when using the Windows 10 taskbar on Windows 11 21H2.
|
||||
// Not present in 51, present in 120 onwards. 65, 71, and 100 are not checked yet.
|
||||
if (global_rovi.dwBuildNumber == 22000 && global_ubr >= 120)
|
||||
{
|
||||
void** vtable = *(void***)host;
|
||||
void (*FireDesktopSwitchIfReady)(ITrayUIHost*, int) = (decltype(FireDesktopSwitchIfReady))vtable[78];
|
||||
FireDesktopSwitchIfReady(host, 8);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
|
@ -85,7 +85,6 @@ DWORD bCenterMenus = TRUE;
|
||||
DWORD bSkinMenus = TRUE;
|
||||
DWORD bSkinIcons = TRUE;
|
||||
DWORD bReplaceNetwork = FALSE;
|
||||
DWORD dwExplorerReadyDelay = 0;
|
||||
DWORD bEnableArchivePlugin = FALSE;
|
||||
DWORD bMonitorOverride = TRUE;
|
||||
DWORD bOpenAtLogon = FALSE;
|
||||
@ -2623,6 +2622,39 @@ INT64 Shell_TrayWndSubclassProc(
|
||||
g_bIsDesktopRaised = (lParam & 1) == 0;
|
||||
break;
|
||||
}
|
||||
case WM_QUIT:
|
||||
{
|
||||
if (AreLogonLogoffShutdownSoundsEnabled())
|
||||
{
|
||||
TermSoundWindow();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x581:
|
||||
{
|
||||
if (AreLogonLogoffShutdownSoundsEnabled())
|
||||
{
|
||||
BOOL bLogoff = wParam != 0;
|
||||
SHPlaySound(bLogoff ? L"WindowsLogoff" : L"WindowsLogon", 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x590:
|
||||
{
|
||||
if (AreLogonLogoffShutdownSoundsEnabled())
|
||||
{
|
||||
InitSoundWindow();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x5B4:
|
||||
{
|
||||
if (AreLogonLogoffShutdownSoundsEnabled())
|
||||
{
|
||||
TermSoundWindow();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uMsg >= 0xC000 && uMsg <= 0xFFFF && uMsg == RegisterWindowMessageW(L"Windows11ContextMenu_" _T(EP_CLSID)))
|
||||
@ -4033,7 +4065,7 @@ HRESULT uxtheme_DwmExtendFrameIntoClientAreaHook(HWND hWnd, MARGINS* m)
|
||||
return DwmExtendFrameIntoClientArea(hWnd, m);
|
||||
}
|
||||
|
||||
static HWND(__stdcall *explorerframe_SHCreateWorkerWindowFunc)(
|
||||
HWND(__stdcall *explorerframe_SHCreateWorkerWindowFunc)(
|
||||
WNDPROC wndProc,
|
||||
HWND hWndParent,
|
||||
DWORD dwExStyle,
|
||||
@ -4270,7 +4302,7 @@ HRESULT pnidui_CoCreateInstanceHook(
|
||||
);
|
||||
if (dwVal)
|
||||
{
|
||||
if (dwVal == 5 || dwVal == 6)
|
||||
if ((dwVal == 5 || dwVal == 6) && IsWindows11() && !IsWindows11Version22H2Build1413OrHigher())
|
||||
{
|
||||
if (hCheckForegroundThread)
|
||||
{
|
||||
@ -5726,7 +5758,7 @@ INT64 ShowDesktopSubclassProc(
|
||||
#pragma endregion
|
||||
|
||||
|
||||
#pragma region "Notify shell ready (fixes delay at logon)"
|
||||
#pragma region "Notify shell ready"
|
||||
#ifdef _WIN64
|
||||
DWORD SignalShellReady(DWORD wait)
|
||||
{
|
||||
@ -5761,21 +5793,8 @@ DWORD SignalShellReady(DWORD wait)
|
||||
Sleep(100);
|
||||
}
|
||||
|
||||
if (!wait)
|
||||
{
|
||||
Sleep(600);
|
||||
}
|
||||
else
|
||||
{
|
||||
Sleep(wait);
|
||||
}
|
||||
Sleep(600);
|
||||
|
||||
HANDLE hEvent = CreateEventW(0, 0, 0, L"ShellDesktopSwitchEvent");
|
||||
if (hEvent)
|
||||
{
|
||||
printf(">>> Signal shell ready.\n");
|
||||
SetEvent(hEvent);
|
||||
}
|
||||
SetEvent(hCanStartSws);
|
||||
if (bOldTaskbar && (global_rovi.dwBuildNumber >= 22567))
|
||||
{
|
||||
@ -6584,15 +6603,6 @@ void WINAPI LoadSettings(LPARAM lParam)
|
||||
&dwSize
|
||||
);
|
||||
dwSize = sizeof(DWORD);
|
||||
RegQueryValueExW(
|
||||
hKey,
|
||||
TEXT("ExplorerReadyDelay"),
|
||||
0,
|
||||
NULL,
|
||||
&dwExplorerReadyDelay,
|
||||
&dwSize
|
||||
);
|
||||
dwSize = sizeof(DWORD);
|
||||
RegQueryValueExW(
|
||||
hKey,
|
||||
TEXT("ArchiveMenu"),
|
||||
@ -12828,39 +12838,29 @@ DWORD Inject(BOOL bIsExplorer)
|
||||
|
||||
|
||||
|
||||
if (AreLogonLogoffShutdownSoundsEnabled())
|
||||
{
|
||||
HookLogonSound();
|
||||
}
|
||||
|
||||
rv = funchook_install(funchook, 0);
|
||||
if (rv != 0)
|
||||
{
|
||||
FreeLibraryAndExitThread(hModule, rv);
|
||||
return rv;
|
||||
}
|
||||
funchook_destroy(funchook);
|
||||
funchook = NULL;
|
||||
// funchook_destroy(funchook);
|
||||
// funchook = NULL;
|
||||
printf("Installed hooks.\n");
|
||||
|
||||
|
||||
|
||||
|
||||
/*HANDLE hEvent = CreateEventEx(
|
||||
0,
|
||||
L"ShellDesktopSwitchEvent",
|
||||
CREATE_EVENT_MANUAL_RESET,
|
||||
EVENT_ALL_ACCESS
|
||||
);
|
||||
if (GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
printf("Created ShellDesktopSwitchEvent event.\n");
|
||||
ResetEvent(hEvent);
|
||||
}*/
|
||||
|
||||
if (IsWindows11())
|
||||
{
|
||||
if (bOldTaskbar)
|
||||
{
|
||||
CreateThread(0, 0, PlayStartupSound, 0, 0, 0);
|
||||
printf("Play startup sound thread...\n");
|
||||
CreateThread(0, 0, SignalShellReady, dwExplorerReadyDelay, 0, 0);
|
||||
printf("Signal shell ready...\n");
|
||||
CreateThread(0, 0, SignalShellReady, 0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
28
ep_gui/GUI.c
28
ep_gui/GUI.c
@ -207,6 +207,34 @@ LSTATUS GUI_Internal_RegSetValueExW(
|
||||
{
|
||||
if (!lpValueName || wcsncmp(lpValueName, L"Virtualized_" _T(EP_CLSID), 50))
|
||||
{
|
||||
if (lpValueName && !wcscmp(lpValueName, L"LogonLogoffShutdownSounds"))
|
||||
{
|
||||
DWORD bExcluded = !*(const DWORD*)lpData;
|
||||
|
||||
HKEY localHKey = NULL;
|
||||
RegOpenKeyExW(HKEY_CURRENT_USER, L"AppEvents\\EventLabels\\SystemExit", REG_OPTION_NON_VOLATILE, KEY_WRITE, &localHKey);
|
||||
if (localHKey && localHKey != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
RegSetValueExW(localHKey, L"ExcludeFromCPL", 0, REG_DWORD, &bExcluded, sizeof(DWORD));
|
||||
RegCloseKey(localHKey);
|
||||
}
|
||||
|
||||
localHKey = NULL;
|
||||
RegOpenKeyExW(HKEY_CURRENT_USER, L"AppEvents\\EventLabels\\WindowsLogoff", REG_OPTION_NON_VOLATILE, KEY_WRITE, &localHKey);
|
||||
if (localHKey && localHKey != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
RegSetValueExW(localHKey, L"ExcludeFromCPL", 0, REG_DWORD, &bExcluded, sizeof(DWORD));
|
||||
RegCloseKey(localHKey);
|
||||
}
|
||||
|
||||
localHKey = NULL;
|
||||
RegOpenKeyExW(HKEY_CURRENT_USER, L"AppEvents\\EventLabels\\WindowsLogon", REG_OPTION_NON_VOLATILE, KEY_WRITE, &localHKey);
|
||||
if (localHKey && localHKey != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
RegSetValueExW(localHKey, L"ExcludeFromCPL", 0, REG_DWORD, &bExcluded, sizeof(DWORD));
|
||||
RegCloseKey(localHKey);
|
||||
}
|
||||
}
|
||||
return RegSetValueExW(hKey, lpValueName, 0, dwType, lpData, cbData);
|
||||
}
|
||||
if (!wcscmp(lpValueName, L"Virtualized_" _T(EP_CLSID) L"_TaskbarPosition"))
|
||||
|
@ -330,6 +330,7 @@
|
||||
#define IDS_OTHER_NOREDIRECT_PROGRAMS 1724
|
||||
#define IDS_OTHER_NOREDIRECT_DATETIME 1725
|
||||
#define IDS_OTHER_NOREDIRECT_TRAYICONS 1726
|
||||
#define IDS_OTHER_LOGONLOGOFFSHUTDOWNSOUNDS 1727
|
||||
|
||||
#define IDS_UPDATES 1801
|
||||
#define IDS_UPDATES_POLICY 1802
|
||||
@ -361,19 +362,6 @@
|
||||
#define IDS_ADV_SYMBOLS 1911
|
||||
#define IDS_ADV_PINNEDITEMS 1912
|
||||
#define IDS_ADV_REMOVEEXTRAGAP 1913
|
||||
#define IDS_ADV_DELAY 1914
|
||||
#define IDS_ADV_DELAY_0 1915
|
||||
#define IDS_ADV_DELAY_300 1916
|
||||
#define IDS_ADV_DELAY_600 1917
|
||||
#define IDS_ADV_DELAY_1000 1918
|
||||
#define IDS_ADV_DELAY_1500 1919
|
||||
#define IDS_ADV_DELAY_2000 1920
|
||||
#define IDS_ADV_DELAY_3000 1921
|
||||
#define IDS_ADV_DELAY_4000 1922
|
||||
#define IDS_ADV_DELAY_5000 1923
|
||||
#define IDS_ADV_DELAY_6000 1924
|
||||
#define IDS_ADV_DELAY_8000 1925
|
||||
#define IDS_ADV_DELAY_10000 1926
|
||||
#define IDS_ADV_XAMLSOUNDS 1927
|
||||
|
||||
#define IDS_ABOUT 2001
|
||||
|
@ -366,6 +366,7 @@ BEGIN
|
||||
IDS_OTHER_PWRBTNACTION_64 "Hibernate"
|
||||
IDS_OTHER_PWRBTNACTION_2 "Shut down (default)"
|
||||
IDS_OTHER_PWRBTNACTION_4 "Restart"
|
||||
IDS_OTHER_LOGONLOGOFFSHUTDOWNSOUNDS "Enable logon, logoff, and shutdown sounds"
|
||||
IDS_OTHER_NOREDIRECT "Prevent the following Control Panel links from being redirected to the Settings app:"
|
||||
IDS_OTHER_NOREDIRECT_SYSTEM "System / About page"
|
||||
IDS_OTHER_NOREDIRECT_PROGRAMS "Programs and Features"
|
||||
@ -404,19 +405,6 @@ BEGIN
|
||||
IDS_ADV_SYMBOLS "Enable symbols download"
|
||||
IDS_ADV_PINNEDITEMS "Pinned items act as quick launch (don't group with active apps)"
|
||||
IDS_ADV_REMOVEEXTRAGAP "When the taskbar shows button labels, remove the extra gap around pinned items"
|
||||
IDS_ADV_DELAY "Supplementary delay at logon"
|
||||
IDS_ADV_DELAY_0 "None (default)"
|
||||
IDS_ADV_DELAY_300 "300 ms"
|
||||
IDS_ADV_DELAY_600 "600 ms"
|
||||
IDS_ADV_DELAY_1000 "1 second"
|
||||
IDS_ADV_DELAY_1500 "1.5 seconds"
|
||||
IDS_ADV_DELAY_2000 "2 seconds"
|
||||
IDS_ADV_DELAY_3000 "3 seconds"
|
||||
IDS_ADV_DELAY_4000 "4 seconds"
|
||||
IDS_ADV_DELAY_5000 "5 seconds"
|
||||
IDS_ADV_DELAY_6000 "6 seconds"
|
||||
IDS_ADV_DELAY_8000 "8 seconds"
|
||||
IDS_ADV_DELAY_10000 "10 seconds"
|
||||
IDS_ADV_XAMLSOUNDS "Enable UI sounds in Explorer's XAML views"
|
||||
|
||||
IDS_ABOUT "About"
|
||||
|
@ -682,6 +682,11 @@
|
||||
;x 2 %R:1720%
|
||||
;x 4 %R:1721%
|
||||
"Start_PowerButtonAction"=dword:00000002
|
||||
;s LogonLogoffShutdownSounds LogonLogoffShutdownSoundsAvailable
|
||||
[HKEY_CURRENT_USER\Software\ExplorerPatcher]
|
||||
;b %R:1727% *
|
||||
"LogonLogoffShutdownSounds"=dword:00000000
|
||||
;g LogonLogoffShutdownSounds
|
||||
;t %R:1722%
|
||||
[HKEY_CURRENT_USER\Software\ExplorerPatcher]
|
||||
;b %R:1723%
|
||||
@ -756,20 +761,6 @@
|
||||
;b %R:1913% *
|
||||
"RemoveExtraGapAroundPinnedItems"=dword:00000000
|
||||
;g Advanced_Windows10
|
||||
;c 12 %R:1914% *
|
||||
;x 0 %R:1915%
|
||||
;x 300 %R:1916%
|
||||
;x 600 %R:1917%
|
||||
;x 1000 %R:1918%
|
||||
;x 1500 %R:1919%
|
||||
;x 2000 %R:1920%
|
||||
;x 3000 %R:1921%
|
||||
;x 4000 %R:1922%
|
||||
;x 5000 %R:1923%
|
||||
;x 6000 %R:1924%
|
||||
;x 8000 %R:1925%
|
||||
;x 10000 %R:1926%
|
||||
"ExplorerReadyDelay"=dword:00000000
|
||||
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher]
|
||||
;b %R:1927% *
|
||||
"XamlSounds"=dword:00000000
|
||||
|
@ -496,6 +496,11 @@
|
||||
;x 2 %R:1720%
|
||||
;x 4 %R:1721%
|
||||
"Start_PowerButtonAction"=dword:00000002
|
||||
;s LogonLogoffShutdownSounds LogonLogoffShutdownSoundsAvailable
|
||||
[HKEY_CURRENT_USER\Software\ExplorerPatcher]
|
||||
;b %R:1727% *
|
||||
"LogonLogoffShutdownSounds"=dword:00000000
|
||||
;g LogonLogoffShutdownSounds
|
||||
;t %R:1722%
|
||||
[HKEY_CURRENT_USER\Software\ExplorerPatcher]
|
||||
;b %R:1723%
|
||||
|
Loading…
x
Reference in New Issue
Block a user