mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-17 16:44:27 -04:00
[process] add a timeout for the process search
* The process search appears to be blocking on some platform, and we also don't want users to have to wait too long on format startup * Also update the update check for Windows XP SSL errors
This commit is contained in:
parent
5c3437f6de
commit
4617ba786d
6 changed files with 72 additions and 35 deletions
|
@ -153,7 +153,7 @@ static HANDLE GetHandle(char* Path, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWr
|
||||||
bWriteShare = TRUE;
|
bWriteShare = TRUE;
|
||||||
// Try to report the process that is locking the drive
|
// Try to report the process that is locking the drive
|
||||||
// We also use bit 6 as a flag to indicate that SearchProcess was called.
|
// We also use bit 6 as a flag to indicate that SearchProcess was called.
|
||||||
access_mask = SearchProcess(DevPath, TRUE, TRUE, FALSE) | 0x40;
|
access_mask = SearchProcess(DevPath, 5000, TRUE, TRUE, FALSE) | 0x40;
|
||||||
}
|
}
|
||||||
Sleep(DRIVE_ACCESS_TIMEOUT / DRIVE_ACCESS_RETRIES);
|
Sleep(DRIVE_ACCESS_TIMEOUT / DRIVE_ACCESS_RETRIES);
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@ static HANDLE GetHandle(char* Path, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWr
|
||||||
uprintf("Could not lock access to %s: %s", Path, WindowsErrorString());
|
uprintf("Could not lock access to %s: %s", Path, WindowsErrorString());
|
||||||
// See if we can report the processes are accessing the drive
|
// See if we can report the processes are accessing the drive
|
||||||
if (!IS_ERROR(FormatStatus) && (access_mask == 0))
|
if (!IS_ERROR(FormatStatus) && (access_mask == 0))
|
||||||
access_mask = SearchProcess(DevPath, TRUE, TRUE, FALSE);
|
access_mask = SearchProcess(DevPath, 5000, TRUE, TRUE, FALSE);
|
||||||
// Try to continue if the only access rights we saw were for read-only
|
// Try to continue if the only access rights we saw were for read-only
|
||||||
if ((access_mask & 0x07) != 0x01)
|
if ((access_mask & 0x07) != 0x01)
|
||||||
safe_closehandle(hDrive);
|
safe_closehandle(hDrive);
|
||||||
|
|
|
@ -175,6 +175,8 @@ const char* WinInetErrorString(void)
|
||||||
return "The header could not be added because it already exists.";
|
return "The header could not be added because it already exists.";
|
||||||
case ERROR_HTTP_REDIRECT_FAILED:
|
case ERROR_HTTP_REDIRECT_FAILED:
|
||||||
return "The redirection failed because either the scheme changed or all attempts made to redirect failed.";
|
return "The redirection failed because either the scheme changed or all attempts made to redirect failed.";
|
||||||
|
case ERROR_INTERNET_SECURITY_CHANNEL_ERROR:
|
||||||
|
return "This system's SSL library is too old to be able to access this website.";
|
||||||
case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED:
|
case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED:
|
||||||
return "Client Authentication certificate needed";
|
return "Client Authentication certificate needed";
|
||||||
case ERROR_INTERNET_BAD_AUTO_PROXY_SCRIPT:
|
case ERROR_INTERNET_BAD_AUTO_PROXY_SCRIPT:
|
||||||
|
@ -512,8 +514,10 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
|
||||||
INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS|
|
INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS|
|
||||||
INTERNET_FLAG_NO_COOKIES|INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_HYPERLINK|
|
INTERNET_FLAG_NO_COOKIES|INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_HYPERLINK|
|
||||||
((UrlParts.nScheme == INTERNET_SCHEME_HTTPS)?INTERNET_FLAG_SECURE:0), (DWORD_PTR)NULL);
|
((UrlParts.nScheme == INTERNET_SCHEME_HTTPS)?INTERNET_FLAG_SECURE:0), (DWORD_PTR)NULL);
|
||||||
if ((hRequest == NULL) || (!HttpSendRequestA(hRequest, NULL, 0, NULL, 0)))
|
if ((hRequest == NULL) || (!HttpSendRequestA(hRequest, NULL, 0, NULL, 0))) {
|
||||||
|
uprintf("Unable to send request: %s", WinInetErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure that we get a text file
|
// Ensure that we get a text file
|
||||||
dwSize = sizeof(dwStatus);
|
dwSize = sizeof(dwStatus);
|
||||||
|
|
|
@ -52,6 +52,9 @@ PF_TYPE_DECL(NTAPI, NTSTATUS, NtClose, (HANDLE));
|
||||||
PF_TYPE_DECL(WINAPI, BOOL, QueryFullProcessImageNameW, (HANDLE, DWORD, LPWSTR, PDWORD));
|
PF_TYPE_DECL(WINAPI, BOOL, QueryFullProcessImageNameW, (HANDLE, DWORD, LPWSTR, PDWORD));
|
||||||
|
|
||||||
static PVOID PhHeapHandle = NULL;
|
static PVOID PhHeapHandle = NULL;
|
||||||
|
static char* _HandleName;
|
||||||
|
static BOOL _bPartialMatch, _bIgnoreSelf, _bQuiet;
|
||||||
|
static BYTE access_mask;
|
||||||
extern StrArray BlockingProcess;
|
extern StrArray BlockingProcess;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -307,18 +310,8 @@ NTSTATUS PhQueryProcessesUsingVolumeOrFile(HANDLE VolumeOrFileHandle,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Search all the processes and list the ones that have a specific handle open.
|
static DWORD WINAPI SearchProcessThread(LPVOID param)
|
||||||
*
|
|
||||||
* \param HandleName The name of the handle to look for.
|
|
||||||
* \param bPartialMatch Whether partial matches should be allowed.
|
|
||||||
* \param bIgnoreSelf Whether the current process should be listed.
|
|
||||||
* \param bQuiet Prints minimal output.
|
|
||||||
*
|
|
||||||
* \return a byte containing the cummulated access rights (f----xwr) from all the handles found
|
|
||||||
* with bit 7 ('f') also set if at least one process was found.
|
|
||||||
*/
|
|
||||||
BYTE SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL bQuiet)
|
|
||||||
{
|
{
|
||||||
const char *access_rights_str[8] = { "n", "r", "w", "rw", "x", "rx", "wx", "rwx" };
|
const char *access_rights_str[8] = { "n", "r", "w", "rw", "x", "rx", "wx", "rwx" };
|
||||||
char tmp[MAX_PATH];
|
char tmp[MAX_PATH];
|
||||||
|
@ -333,9 +326,8 @@ BYTE SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL
|
||||||
WCHAR *wHandleName = NULL;
|
WCHAR *wHandleName = NULL;
|
||||||
HANDLE dupHandle = NULL;
|
HANDLE dupHandle = NULL;
|
||||||
HANDLE processHandle = NULL;
|
HANDLE processHandle = NULL;
|
||||||
BOOLEAN bFound = FALSE, bGotExePath, verbose = !bQuiet;
|
BOOLEAN bFound = FALSE, bGotExePath, verbose = !_bQuiet;
|
||||||
ULONG access_rights = 0;
|
ULONG access_rights = 0;
|
||||||
BYTE access_mask = 0;
|
|
||||||
DWORD size;
|
DWORD size;
|
||||||
char exe_path[MAX_PATH] = { 0 };
|
char exe_path[MAX_PATH] = { 0 };
|
||||||
wchar_t wexe_path[MAX_PATH];
|
wchar_t wexe_path[MAX_PATH];
|
||||||
|
@ -361,7 +353,7 @@ BYTE SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL
|
||||||
pid[0] = (ULONG_PTR)0;
|
pid[0] = (ULONG_PTR)0;
|
||||||
cur_pid = 1;
|
cur_pid = 1;
|
||||||
|
|
||||||
wHandleName = utf8_to_wchar(HandleName);
|
wHandleName = utf8_to_wchar(_HandleName);
|
||||||
wHandleNameLen = (USHORT)wcslen(wHandleName);
|
wHandleNameLen = (USHORT)wcslen(wHandleName);
|
||||||
|
|
||||||
bufferSize = 0x200;
|
bufferSize = 0x200;
|
||||||
|
@ -435,7 +427,7 @@ BYTE SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL
|
||||||
|
|
||||||
// Now duplicate this handle onto our own process, so that we can access its properties
|
// Now duplicate this handle onto our own process, so that we can access its properties
|
||||||
if (processHandle == NtCurrentProcess()) {
|
if (processHandle == NtCurrentProcess()) {
|
||||||
if (bIgnoreSelf)
|
if (_bIgnoreSelf)
|
||||||
continue;
|
continue;
|
||||||
dupHandle = (HANDLE)handleInfo->HandleValue;
|
dupHandle = (HANDLE)handleInfo->HandleValue;
|
||||||
} else {
|
} else {
|
||||||
|
@ -471,11 +463,11 @@ BYTE SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't bother comparing if we are looking for full match and the length is different
|
// Don't bother comparing if we are looking for full match and the length is different
|
||||||
if ((!bPartialMatch) && (wHandleNameLen != buffer->Name.Length))
|
if ((!_bPartialMatch) && (wHandleNameLen != buffer->Name.Length))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Likewise, if we are looking for a partial match and the current length is smaller
|
// Likewise, if we are looking for a partial match and the current length is smaller
|
||||||
if ((bPartialMatch) && (wHandleNameLen > buffer->Name.Length))
|
if ((_bPartialMatch) && (wHandleNameLen > buffer->Name.Length))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Match against our target string
|
// Match against our target string
|
||||||
|
@ -494,7 +486,7 @@ BYTE SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL
|
||||||
|
|
||||||
// If this is the very first process we find, print a header
|
// If this is the very first process we find, print a header
|
||||||
if (exe_path[0] == 0)
|
if (exe_path[0] == 0)
|
||||||
vuprintf("WARNING: The following process(es) or service(s) are accessing %s:", HandleName);
|
vuprintf("WARNING: The following process(es) or service(s) are accessing %s:", _HandleName);
|
||||||
|
|
||||||
// First, we try to get the executable path using GetModuleFileNameEx
|
// First, we try to get the executable path using GetModuleFileNameEx
|
||||||
bGotExePath = (GetModuleFileNameExU(processHandle, 0, exe_path, MAX_PATH - 1) != 0);
|
bGotExePath = (GetModuleFileNameExU(processHandle, 0, exe_path, MAX_PATH - 1) != 0);
|
||||||
|
@ -508,10 +500,12 @@ BYTE SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL
|
||||||
wchar_to_utf8_no_alloc(wexe_path, exe_path, sizeof(exe_path));
|
wchar_to_utf8_no_alloc(wexe_path, exe_path, sizeof(exe_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Still nothing? Try GetProcessImageFileName (but don't bother about Unicode)
|
// Still nothing? Try GetProcessImageFileName. Note that GetProcessImageFileName uses
|
||||||
// Note that GetProcessImageFileName uses '\Device\Harddisk#\Partition#' instead drive letters
|
// '\Device\Harddisk#\Partition#\' instead drive letters
|
||||||
if (!bGotExePath)
|
if (!bGotExePath) {
|
||||||
bGotExePath = (GetProcessImageFileNameA(processHandle, exe_path, MAX_PATH) != 0);
|
if (bGotExePath = (GetProcessImageFileNameW(processHandle, wexe_path, MAX_PATH) != 0))
|
||||||
|
wchar_to_utf8_no_alloc(wexe_path, exe_path, sizeof(exe_path));
|
||||||
|
}
|
||||||
|
|
||||||
// Complete failure => Just craft a default process name that includes the PID
|
// Complete failure => Just craft a default process name that includes the PID
|
||||||
if (!bGotExePath) {
|
if (!bGotExePath) {
|
||||||
|
@ -524,12 +518,51 @@ out:
|
||||||
if (exe_path[0] != 0)
|
if (exe_path[0] != 0)
|
||||||
vuprintf("You should close these applications before attempting to reformat the drive.");
|
vuprintf("You should close these applications before attempting to reformat the drive.");
|
||||||
else
|
else
|
||||||
vuprintf("NOTE: Could not identify the process(es) or service(s) accessing %s", HandleName);
|
vuprintf("NOTE: Could not identify the process(es) or service(s) accessing %s", _HandleName);
|
||||||
|
|
||||||
free(wHandleName);
|
free(wHandleName);
|
||||||
PhFree(buffer);
|
PhFree(buffer);
|
||||||
PhFree(handles);
|
PhFree(handles);
|
||||||
PhDestroyHeap();
|
PhDestroyHeap();
|
||||||
|
ExitThread((DWORD)access_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search all the processes and list the ones that have a specific handle open.
|
||||||
|
*
|
||||||
|
* \param HandleName The name of the handle to look for.
|
||||||
|
* \param dwTimeOut The maximum amounf of time (ms) that may be spent searching
|
||||||
|
* \param bPartialMatch Whether partial matches should be allowed.
|
||||||
|
* \param bIgnoreSelf Whether the current process should be listed.
|
||||||
|
* \param bQuiet Prints minimal output.
|
||||||
|
*
|
||||||
|
* \return a byte containing the cummulated access rights (f----xwr) from all the handles found
|
||||||
|
* with bit 7 ('f') also set if at least one process was found.
|
||||||
|
*/
|
||||||
|
BYTE SearchProcess(char* HandleName, DWORD dwTimeOut, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL bQuiet)
|
||||||
|
{
|
||||||
|
HANDLE handle;
|
||||||
|
DWORD dw = 0;
|
||||||
|
|
||||||
|
_HandleName = HandleName;
|
||||||
|
_bPartialMatch = bPartialMatch;
|
||||||
|
_bIgnoreSelf = bIgnoreSelf;
|
||||||
|
_bQuiet = bQuiet;
|
||||||
|
access_mask = 0;
|
||||||
|
|
||||||
|
handle = CreateThread(NULL, 0, SearchProcessThread, NULL, 0, NULL);
|
||||||
|
if (handle == NULL) {
|
||||||
|
uprintf("Unable to create process search thread");
|
||||||
|
return 0x00;
|
||||||
|
}
|
||||||
|
dw = WaitForSingleObject(handle, dwTimeOut);
|
||||||
|
if (dw == WAIT_TIMEOUT) {
|
||||||
|
// Timeout - kill the thread
|
||||||
|
TerminateThread(handle, 0);
|
||||||
|
uprintf("Warning: Killed process search thread");
|
||||||
|
} else if (dw != WAIT_OBJECT_0) {
|
||||||
|
uprintf("Failed to wait for process search thread: %s", WindowsErrorString());
|
||||||
|
}
|
||||||
return access_mask;
|
return access_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2172,7 +2172,7 @@ static BOOL CheckDriveAccess(void)
|
||||||
// Search for any blocking processes against the physical drive
|
// Search for any blocking processes against the physical drive
|
||||||
PhysicalPath = GetPhysicalName(DeviceNum);
|
PhysicalPath = GetPhysicalName(DeviceNum);
|
||||||
QueryDosDeviceA(&PhysicalPath[4], DevPath, sizeof(DevPath));
|
QueryDosDeviceA(&PhysicalPath[4], DevPath, sizeof(DevPath));
|
||||||
access_mask = SearchProcess(DevPath, TRUE, TRUE, TRUE);
|
access_mask = SearchProcess(DevPath, 2000, TRUE, TRUE, TRUE);
|
||||||
if (access_mask != 0) {
|
if (access_mask != 0) {
|
||||||
bProceed = FALSE;
|
bProceed = FALSE;
|
||||||
uprintf("Found potentially blocking process(es) against %s:", &PhysicalPath[4]);
|
uprintf("Found potentially blocking process(es) against %s:", &PhysicalPath[4]);
|
||||||
|
@ -2187,7 +2187,7 @@ static BOOL CheckDriveAccess(void)
|
||||||
drive_name[0] = drive_letter[i];
|
drive_name[0] = drive_letter[i];
|
||||||
if (QueryDosDeviceA(drive_name, DevPath, sizeof(DevPath)) != 0) {
|
if (QueryDosDeviceA(drive_name, DevPath, sizeof(DevPath)) != 0) {
|
||||||
StrArrayClear(&BlockingProcess);
|
StrArrayClear(&BlockingProcess);
|
||||||
access_mask = SearchProcess(DevPath, TRUE, TRUE, TRUE);
|
access_mask = SearchProcess(DevPath, 2000, TRUE, TRUE, TRUE);
|
||||||
// Ignore if all we have is read-only
|
// Ignore if all we have is read-only
|
||||||
if ((access_mask & 0x06) || (access_mask == 0x80)) {
|
if ((access_mask & 0x06) || (access_mask == 0x80)) {
|
||||||
bProceed = FALSE;
|
bProceed = FALSE;
|
||||||
|
|
|
@ -497,7 +497,7 @@ extern char* GetCurrentMUI(void);
|
||||||
extern char* GetMuiString(char* szModuleName, UINT uID);
|
extern char* GetMuiString(char* szModuleName, UINT uID);
|
||||||
extern BOOL SetFormatPromptHook(void);
|
extern BOOL SetFormatPromptHook(void);
|
||||||
extern void ClrFormatPromptHook(void);
|
extern void ClrFormatPromptHook(void);
|
||||||
extern BYTE SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL bQuiet);
|
extern BYTE SearchProcess(char* HandleName, DWORD dwTimeout, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL bQuiet);
|
||||||
extern BOOL EnablePrivileges(void);
|
extern BOOL EnablePrivileges(void);
|
||||||
extern void FlashTaskbar(HANDLE handle);
|
extern void FlashTaskbar(HANDLE handle);
|
||||||
|
|
||||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 242, 376
|
IDD_DIALOG DIALOGEX 12, 12, 242, 376
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_ACCEPTFILES
|
EXSTYLE WS_EX_ACCEPTFILES
|
||||||
CAPTION "Rufus 2.16.1145"
|
CAPTION "Rufus 2.16.1146"
|
||||||
FONT 8, "Segoe UI Symbol", 400, 0, 0x0
|
FONT 8, "Segoe UI Symbol", 400, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
|
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
|
||||||
|
@ -366,8 +366,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,16,1145,0
|
FILEVERSION 2,16,1146,0
|
||||||
PRODUCTVERSION 2,16,1145,0
|
PRODUCTVERSION 2,16,1146,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -384,13 +384,13 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "2.16.1145"
|
VALUE "FileVersion", "2.16.1146"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2017 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2017 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
||||||
VALUE "OriginalFilename", "rufus.exe"
|
VALUE "OriginalFilename", "rufus.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "2.16.1145"
|
VALUE "ProductVersion", "2.16.1146"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue