mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[process] add a more efficient method to search for processes
* As suggested in #773 * Don't switch to using this method though, as it requires a handle to the disk or volume to be obtained, and we use the process search in case there is an issue doing so.
This commit is contained in:
parent
867177c5cd
commit
302f108d79
3 changed files with 107 additions and 6 deletions
|
@ -48,6 +48,7 @@ PF_TYPE_DECL(NTAPI, BOOLEAN, RtlEqualUnicodeString, (PCUNICODE_STRING, PCUNICODE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PF_TYPE_DECL(NTAPI, NTSTATUS, NtQuerySystemInformation, (SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG));
|
PF_TYPE_DECL(NTAPI, NTSTATUS, NtQuerySystemInformation, (SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG));
|
||||||
|
PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryInformationFile, (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS));
|
||||||
PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryObject, (HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG));
|
PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryObject, (HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG));
|
||||||
PF_TYPE_DECL(NTAPI, NTSTATUS, NtDuplicateObject, (HANDLE, HANDLE, HANDLE, PHANDLE, ACCESS_MASK, ULONG, ULONG));
|
PF_TYPE_DECL(NTAPI, NTSTATUS, NtDuplicateObject, (HANDLE, HANDLE, HANDLE, PHANDLE, ACCESS_MASK, ULONG, ULONG));
|
||||||
PF_TYPE_DECL(NTAPI, NTSTATUS, NtOpenProcess, (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PCLIENT_ID));
|
PF_TYPE_DECL(NTAPI, NTSTATUS, NtOpenProcess, (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PCLIENT_ID));
|
||||||
|
@ -338,6 +339,54 @@ ULONG PhGetObjectTypeNumber(PUNICODE_STRING TypeName)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query processes with open handles to a file, volume or disk.
|
||||||
|
*
|
||||||
|
* \param VolumeOrFileHandle The handle to the target.
|
||||||
|
* \param Information The returned list of processes.
|
||||||
|
*
|
||||||
|
* \return An NTStatus indicating success or the error code.
|
||||||
|
*/
|
||||||
|
NTSTATUS PhQueryProcessesUsingVolumeOrFile(HANDLE VolumeOrFileHandle,
|
||||||
|
PFILE_PROCESS_IDS_USING_FILE_INFORMATION *Information)
|
||||||
|
{
|
||||||
|
static ULONG initialBufferSize = 16 * KB;
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
PVOID buffer;
|
||||||
|
ULONG bufferSize;
|
||||||
|
IO_STATUS_BLOCK isb;
|
||||||
|
|
||||||
|
PF_INIT_OR_SET_STATUS(NtQueryInformationFile, NtDll);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
bufferSize = initialBufferSize;
|
||||||
|
buffer = PhAllocate(bufferSize);
|
||||||
|
if (buffer == NULL)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
while ((status = pfNtQueryInformationFile(VolumeOrFileHandle, &isb, buffer, bufferSize,
|
||||||
|
FileProcessIdsUsingFileInformation)) == STATUS_INFO_LENGTH_MISMATCH) {
|
||||||
|
PhFree(buffer);
|
||||||
|
bufferSize *= 2;
|
||||||
|
// Fail if we're resizing the buffer to something very large.
|
||||||
|
if (bufferSize > 64 * MB)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
buffer = PhAllocate(bufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
PhFree(buffer);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufferSize <= 64 * MB)
|
||||||
|
initialBufferSize = bufferSize;
|
||||||
|
*Information = (PFILE_PROCESS_IDS_USING_FILE_INFORMATION)buffer;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search all the processes and list the ones that have a specific handle open.
|
* Search all the processes and list the ones that have a specific handle open.
|
||||||
*
|
*
|
||||||
|
@ -553,6 +602,51 @@ out:
|
||||||
return bFound;
|
return bFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alternative search for processes keeping a handle on a specific disk or volume
|
||||||
|
* Note that this search requires opening the disk or volume, which may not always
|
||||||
|
* be convenient for our usage (since we might be looking for processes preventing
|
||||||
|
* us to open said target in exclusive mode).
|
||||||
|
*
|
||||||
|
* \param HandleName The name of the handle to look for.
|
||||||
|
*
|
||||||
|
* \return TRUE if processes were found, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
BOOL SearchProcessAlt(char* HandleName)
|
||||||
|
{
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
ULONG i;
|
||||||
|
HANDLE searchHandle = NULL;
|
||||||
|
BOOLEAN bFound = FALSE;
|
||||||
|
PFILE_PROCESS_IDS_USING_FILE_INFORMATION info = NULL;
|
||||||
|
|
||||||
|
status = PhCreateHeap();
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
// Note that the access rights being used with CreateFile() might matter...
|
||||||
|
searchHandle = CreateFileA(HandleName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
|
status = PhQueryProcessesUsingVolumeOrFile(searchHandle, &info);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status) && (info->NumberOfProcessIdsInList > 0)) {
|
||||||
|
bFound = TRUE;
|
||||||
|
uprintf("NOTE: The following process(es) or service(s) are accessing %s:", HandleName);
|
||||||
|
for (i = 0; i < info->NumberOfProcessIdsInList; i++) {
|
||||||
|
uprintf("o Process with PID %ld", info->ProcessIdList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
safe_closehandle(searchHandle);
|
||||||
|
PhFree(info);
|
||||||
|
PhDestroyHeap();
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
uprintf("SearchProcessAlt('%s') failed: %s", HandleName, NtStatusError(status));
|
||||||
|
return bFound;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increase the privileges of the current application.
|
* Increase the privileges of the current application.
|
||||||
*
|
*
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL)
|
#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL)
|
||||||
|
|
||||||
#define SystemExtendedHandleInformation 64
|
#define SystemExtendedHandleInformation 64
|
||||||
|
#define FileProcessIdsUsingFileInformation 47
|
||||||
|
|
||||||
#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)
|
#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)
|
||||||
|
|
||||||
|
@ -118,6 +119,12 @@ typedef struct _OBJECT_TYPES_INFORMATION
|
||||||
ULONG NumberOfTypes;
|
ULONG NumberOfTypes;
|
||||||
} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION;
|
} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _FILE_PROCESS_IDS_USING_FILE_INFORMATION {
|
||||||
|
ULONG NumberOfProcessIdsInList;
|
||||||
|
ULONG_PTR ProcessIdList[1];
|
||||||
|
} FILE_PROCESS_IDS_USING_FILE_INFORMATION, *PFILE_PROCESS_IDS_USING_FILE_INFORMATION;
|
||||||
|
|
||||||
#define ALIGN_UP_BY(Address, Align) (((ULONG_PTR)(Address) + (Align) - 1) & ~((Align) - 1))
|
#define ALIGN_UP_BY(Address, Align) (((ULONG_PTR)(Address) + (Align) - 1) & ~((Align) - 1))
|
||||||
#define ALIGN_UP(Address, Type) ALIGN_UP_BY(Address, sizeof(Type))
|
#define ALIGN_UP(Address, Type) ALIGN_UP_BY(Address, sizeof(Type))
|
||||||
|
|
||||||
|
|
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.15.1106"
|
CAPTION "Rufus 2.15.1107"
|
||||||
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
|
||||||
|
@ -334,8 +334,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,15,1106,0
|
FILEVERSION 2,15,1107,0
|
||||||
PRODUCTVERSION 2,15,1106,0
|
PRODUCTVERSION 2,15,1107,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -352,13 +352,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.15.1106"
|
VALUE "FileVersion", "2.15.1107"
|
||||||
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.15.1106"
|
VALUE "ProductVersion", "2.15.1107"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
Loading…
Reference in a new issue