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;
|
||||
// Try to report the process that is locking the drive
|
||||
// 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);
|
||||
}
|
||||
|
@ -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());
|
||||
// See if we can report the processes are accessing the drive
|
||||
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
|
||||
if ((access_mask & 0x07) != 0x01)
|
||||
safe_closehandle(hDrive);
|
||||
|
|
|
@ -175,6 +175,8 @@ const char* WinInetErrorString(void)
|
|||
return "The header could not be added because it already exists.";
|
||||
case ERROR_HTTP_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:
|
||||
return "Client Authentication certificate needed";
|
||||
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_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);
|
||||
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;
|
||||
}
|
||||
|
||||
// Ensure that we get a text file
|
||||
dwSize = sizeof(dwStatus);
|
||||
|
|
|
@ -52,6 +52,9 @@ PF_TYPE_DECL(NTAPI, NTSTATUS, NtClose, (HANDLE));
|
|||
PF_TYPE_DECL(WINAPI, BOOL, QueryFullProcessImageNameW, (HANDLE, DWORD, LPWSTR, PDWORD));
|
||||
|
||||
static PVOID PhHeapHandle = NULL;
|
||||
static char* _HandleName;
|
||||
static BOOL _bPartialMatch, _bIgnoreSelf, _bQuiet;
|
||||
static BYTE access_mask;
|
||||
extern StrArray BlockingProcess;
|
||||
|
||||
/*
|
||||
|
@ -307,18 +310,8 @@ NTSTATUS PhQueryProcessesUsingVolumeOrFile(HANDLE VolumeOrFileHandle,
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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)
|
||||
|
||||
static DWORD WINAPI SearchProcessThread(LPVOID param)
|
||||
{
|
||||
const char *access_rights_str[8] = { "n", "r", "w", "rw", "x", "rx", "wx", "rwx" };
|
||||
char tmp[MAX_PATH];
|
||||
|
@ -333,9 +326,8 @@ BYTE SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL
|
|||
WCHAR *wHandleName = NULL;
|
||||
HANDLE dupHandle = NULL;
|
||||
HANDLE processHandle = NULL;
|
||||
BOOLEAN bFound = FALSE, bGotExePath, verbose = !bQuiet;
|
||||
BOOLEAN bFound = FALSE, bGotExePath, verbose = !_bQuiet;
|
||||
ULONG access_rights = 0;
|
||||
BYTE access_mask = 0;
|
||||
DWORD size;
|
||||
char exe_path[MAX_PATH] = { 0 };
|
||||
wchar_t wexe_path[MAX_PATH];
|
||||
|
@ -361,7 +353,7 @@ BYTE SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL
|
|||
pid[0] = (ULONG_PTR)0;
|
||||
cur_pid = 1;
|
||||
|
||||
wHandleName = utf8_to_wchar(HandleName);
|
||||
wHandleName = utf8_to_wchar(_HandleName);
|
||||
wHandleNameLen = (USHORT)wcslen(wHandleName);
|
||||
|
||||
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
|
||||
if (processHandle == NtCurrentProcess()) {
|
||||
if (bIgnoreSelf)
|
||||
if (_bIgnoreSelf)
|
||||
continue;
|
||||
dupHandle = (HANDLE)handleInfo->HandleValue;
|
||||
} 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
|
||||
if ((!bPartialMatch) && (wHandleNameLen != buffer->Name.Length))
|
||||
if ((!_bPartialMatch) && (wHandleNameLen != buffer->Name.Length))
|
||||
continue;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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 (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
|
||||
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));
|
||||
}
|
||||
|
||||
// Still nothing? Try GetProcessImageFileName (but don't bother about Unicode)
|
||||
// Note that GetProcessImageFileName uses '\Device\Harddisk#\Partition#' instead drive letters
|
||||
if (!bGotExePath)
|
||||
bGotExePath = (GetProcessImageFileNameA(processHandle, exe_path, MAX_PATH) != 0);
|
||||
// Still nothing? Try GetProcessImageFileName. Note that GetProcessImageFileName uses
|
||||
// '\Device\Harddisk#\Partition#\' instead drive letters
|
||||
if (!bGotExePath) {
|
||||
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
|
||||
if (!bGotExePath) {
|
||||
|
@ -524,12 +518,51 @@ out:
|
|||
if (exe_path[0] != 0)
|
||||
vuprintf("You should close these applications before attempting to reformat the drive.");
|
||||
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);
|
||||
PhFree(buffer);
|
||||
PhFree(handles);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -2172,7 +2172,7 @@ static BOOL CheckDriveAccess(void)
|
|||
// Search for any blocking processes against the physical drive
|
||||
PhysicalPath = GetPhysicalName(DeviceNum);
|
||||
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) {
|
||||
bProceed = FALSE;
|
||||
uprintf("Found potentially blocking process(es) against %s:", &PhysicalPath[4]);
|
||||
|
@ -2187,7 +2187,7 @@ static BOOL CheckDriveAccess(void)
|
|||
drive_name[0] = drive_letter[i];
|
||||
if (QueryDosDeviceA(drive_name, DevPath, sizeof(DevPath)) != 0) {
|
||||
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
|
||||
if ((access_mask & 0x06) || (access_mask == 0x80)) {
|
||||
bProceed = FALSE;
|
||||
|
|
|
@ -497,7 +497,7 @@ extern char* GetCurrentMUI(void);
|
|||
extern char* GetMuiString(char* szModuleName, UINT uID);
|
||||
extern BOOL SetFormatPromptHook(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 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
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_ACCEPTFILES
|
||||
CAPTION "Rufus 2.16.1145"
|
||||
CAPTION "Rufus 2.16.1146"
|
||||
FONT 8, "Segoe UI Symbol", 400, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
|
||||
|
@ -366,8 +366,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,16,1145,0
|
||||
PRODUCTVERSION 2,16,1145,0
|
||||
FILEVERSION 2,16,1146,0
|
||||
PRODUCTVERSION 2,16,1146,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -384,13 +384,13 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
||||
VALUE "FileDescription", "Rufus"
|
||||
VALUE "FileVersion", "2.16.1145"
|
||||
VALUE "FileVersion", "2.16.1146"
|
||||
VALUE "InternalName", "Rufus"
|
||||
VALUE "LegalCopyright", "© 2011-2017 Pete Batard (GPL v3)"
|
||||
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
||||
VALUE "OriginalFilename", "rufus.exe"
|
||||
VALUE "ProductName", "Rufus"
|
||||
VALUE "ProductVersion", "2.16.1145"
|
||||
VALUE "ProductVersion", "2.16.1146"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue