mirror of
https://github.com/valinet/ExplorerPatcher.git
synced 2024-11-23 23:21:08 +01:00
Setup: explorer
will restart using the token it was running under before starting application maintenance
The patch has been adapted to employ the old behavior when setup is elevated using the same credentials, while using the updated code with `CreateProcessWithTokenW` when otherwise. Original description (via email): "I have two accounts on my Windows machine: A normal one that is a standard user (not admin) which I use as my main account where I have ExplorerPatcher installed and configured, and an Admin account which is a Windows administrator account. During installation and update the installer restarts itself and requests admin privileges. For this I have to provide the password to the Admin account. The installer then runs as that Admin user, stops the explorer process, installs ExplorerPatcher and then tries to start the explorer again. But the explorer never starts, which leaves me with an empty screen and a session without an explorer. I can then start a Taskmanager via Ctrl + Shift + Esc and manually start the explorer, but this is annoying and maybe even frightening for a nontechnical user. The reason why the explorer is not started again is that it is started as the wrong user. It is started as the Admin user, which isn't logged in so the explorer quits immediately. The fix is to remember the user that the explorer was running under and then start the new explorer for that user. I have tested these changes in a Windows 11 virtual machine, by installing and uninstalling for a standard user, as well as installing and uninstalling for an administrator user." Original patch: https://github.com/Abestanis/ExplorerPatcher/tree/fix_explorer_restart Credit @Abestanis
This commit is contained in:
parent
d7e5b7d3c9
commit
1738b45866
@ -410,13 +410,45 @@ inline BOOL ExitExplorer()
|
||||
return PostMessageW(hWndTray, 0x5B4, 0, 0);
|
||||
}
|
||||
|
||||
inline void StartExplorerWithDelay(int delay)
|
||||
inline void StartExplorerWithDelay(int delay, HANDLE userToken)
|
||||
{
|
||||
WCHAR wszPath[MAX_PATH];
|
||||
ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR));
|
||||
GetWindowsDirectoryW(wszPath, MAX_PATH);
|
||||
wcscat_s(wszPath, MAX_PATH, L"\\explorer.exe");
|
||||
Sleep(delay);
|
||||
if (userToken != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
HANDLE primaryUserToken = INVALID_HANDLE_VALUE;
|
||||
if (ImpersonateLoggedOnUser(userToken))
|
||||
{
|
||||
DuplicateTokenEx(userToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &primaryUserToken);
|
||||
RevertToSelf();
|
||||
}
|
||||
if (primaryUserToken != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
PROCESS_INFORMATION processInfo;
|
||||
ZeroMemory(&processInfo, sizeof(processInfo));
|
||||
STARTUPINFOW startupInfo;
|
||||
ZeroMemory(&startupInfo, sizeof(startupInfo));
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
BOOL processCreated = CreateProcessWithTokenW(
|
||||
primaryUserToken, LOGON_WITH_PROFILE, wszPath, NULL, 0, NULL, NULL, &startupInfo, &processInfo) != 0;
|
||||
CloseHandle(primaryUserToken);
|
||||
if (processInfo.hProcess != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(processInfo.hProcess);
|
||||
}
|
||||
if (processInfo.hThread != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(processInfo.hThread);
|
||||
}
|
||||
if (processCreated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ShellExecuteW(
|
||||
NULL,
|
||||
L"open",
|
||||
|
@ -605,10 +605,62 @@ int WINAPI wWinMain(
|
||||
if (bOk || (!bOk && GetLastError() == ERROR_ALREADY_EXISTS))
|
||||
{
|
||||
bOk = TRUE;
|
||||
HANDLE userToken = INVALID_HANDLE_VALUE;
|
||||
|
||||
HWND hShellTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
|
||||
if (hShellTrayWnd)
|
||||
{
|
||||
DWORD explorerProcessId = 0;
|
||||
GetWindowThreadProcessId(hShellTrayWnd, &explorerProcessId);
|
||||
if (explorerProcessId != 0)
|
||||
{
|
||||
HANDLE explorerProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, explorerProcessId);
|
||||
if (explorerProcess != NULL)
|
||||
{
|
||||
OpenProcessToken(explorerProcess, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, &userToken);
|
||||
CloseHandle(explorerProcess);
|
||||
}
|
||||
if (userToken)
|
||||
{
|
||||
HANDLE myToken = INVALID_HANDLE_VALUE;
|
||||
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, &myToken);
|
||||
if (myToken != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD cbSizeNeeded = 0;
|
||||
SetLastError(0);
|
||||
if (!GetTokenInformation(userToken, TokenUser, NULL, 0, &cbSizeNeeded) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
TOKEN_USER* userTokenInfo = malloc(cbSizeNeeded);
|
||||
if (userTokenInfo)
|
||||
{
|
||||
if (GetTokenInformation(userToken, TokenUser, userTokenInfo, cbSizeNeeded, &cbSizeNeeded))
|
||||
{
|
||||
cbSizeNeeded = 0;
|
||||
SetLastError(0);
|
||||
if (!GetTokenInformation(myToken, TokenUser, NULL, 0, &cbSizeNeeded) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
TOKEN_USER* myTokenInfo = malloc(cbSizeNeeded);
|
||||
if (myTokenInfo)
|
||||
{
|
||||
if (GetTokenInformation(myToken, TokenUser, myTokenInfo, cbSizeNeeded, &cbSizeNeeded))
|
||||
{
|
||||
if (EqualSid(userTokenInfo->User.Sid, myTokenInfo->User.Sid))
|
||||
{
|
||||
CloseHandle(userToken);
|
||||
userToken = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
free(myTokenInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(userTokenInfo);
|
||||
}
|
||||
}
|
||||
CloseHandle(myToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
PDWORD_PTR res = -1;
|
||||
if (!SendMessageTimeoutW(hShellTrayWnd, 1460, 0, 0, SMTO_ABORTIFHUNG, 2000, &res) && res)
|
||||
{
|
||||
@ -1187,7 +1239,8 @@ int WINAPI wWinMain(
|
||||
exit(0);
|
||||
}
|
||||
|
||||
StartExplorerWithDelay(1000);
|
||||
StartExplorerWithDelay(1000, userToken);
|
||||
if (userToken != INVALID_HANDLE_VALUE) CloseHandle(userToken);
|
||||
}
|
||||
|
||||
return GetLastError();
|
||||
|
Loading…
Reference in New Issue
Block a user