mirror of https://github.com/pbatard/rufus.git
Browse Source
[core] list potentially blocking processes on disk access error
[core] list potentially blocking processes on disk access error
* Using functionality from Process Hacker: https://github.com/processhacker2/processhacker2/ * Part of the #773 enhancement * Also fix minor MinGW and WDK warningspull/879/merge

16 changed files with 654 additions and 26 deletions
-
2src/.clang/rufus.vcxproj
-
6src/.clang/rufus.vcxproj.filters
-
2src/.msvc/rufus.vcxproj
-
6src/.msvc/rufus.vcxproj.filters
-
4src/Makefile.am
-
18src/Makefile.in
-
11src/drive.c
-
4src/license.h
-
46src/msapi_utf8.h
-
8src/rufus.c
-
1src/rufus.h
-
10src/rufus.rc
-
358src/search.c
-
186src/search.h
-
16src/stdfn.c
-
2src/stdlg.c
@ -0,0 +1,358 @@ |
|||
/* |
|||
* Rufus: The Reliable USB Formatting Utility |
|||
* Search functionality for handles |
|||
* |
|||
* Modified from Process Hacker: |
|||
* https://github.com/processhacker2/processhacker2/ |
|||
* Copyright © 2009-2016 wj32 |
|||
* Copyright © 2017 dmex |
|||
* Copyright © 2017 Pete Batard <pete@akeo.ie> |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU General Public License as published by |
|||
* the Free Software Foundation, either version 3 of the License, or |
|||
* (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#ifdef _CRTDBG_MAP_ALLOC |
|||
#include <stdlib.h> |
|||
#include <crtdbg.h> |
|||
#endif |
|||
|
|||
#include <windows.h> |
|||
|
|||
#include "rufus.h" |
|||
#include "search.h" |
|||
#include "missing.h" |
|||
#include "msapi_utf8.h" |
|||
|
|||
PF_TYPE_DECL(NTAPI, PVOID, RtlCreateHeap, (ULONG, PVOID, SIZE_T, SIZE_T, PVOID, PRTL_HEAP_PARAMETERS)); |
|||
PF_TYPE_DECL(NTAPI, PVOID, RtlAllocateHeap, (PVOID, ULONG, SIZE_T)); |
|||
PF_TYPE_DECL(NTAPI, BOOLEAN, RtlFreeHeap, (PVOID, ULONG, PVOID)); |
|||
|
|||
PF_TYPE_DECL(NTAPI, NTSTATUS, NtQuerySystemInformation, (SYSTEM_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, NtOpenProcess, (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PCLIENT_ID)); |
|||
PF_TYPE_DECL(NTAPI, NTSTATUS, NtClose, (HANDLE)); |
|||
|
|||
PVOID PhHeapHandle = NULL; |
|||
|
|||
/* |
|||
* Convert an NT Status to an error message |
|||
* |
|||
* \param Status An operattonal status. |
|||
* |
|||
* \return An error message string. |
|||
* |
|||
*/ |
|||
static char* NtStatusError(NTSTATUS Status) { |
|||
static char unknown[32]; |
|||
|
|||
switch (Status) { |
|||
case STATUS_UNSUCCESSFUL: |
|||
return "Operation Failed"; |
|||
case STATUS_NOT_IMPLEMENTED: |
|||
return "Not Implemented"; |
|||
case STATUS_BUFFER_OVERFLOW: |
|||
return "Buffer Overflow"; |
|||
case STATUS_INVALID_HANDLE: |
|||
return "Invalid Handle."; |
|||
case STATUS_INVALID_PARAMETER: |
|||
return "Invalid Parameter"; |
|||
case STATUS_NO_MEMORY: |
|||
return "Not Enough Quota"; |
|||
case STATUS_ACCESS_DENIED: |
|||
return "Access Denied"; |
|||
case STATUS_BUFFER_TOO_SMALL: |
|||
return "Buffer Too Small"; |
|||
case STATUS_OBJECT_TYPE_MISMATCH: |
|||
return "Wrong Type"; |
|||
case STATUS_OBJECT_NAME_INVALID: |
|||
return "Object Name invalid"; |
|||
case STATUS_OBJECT_NAME_NOT_FOUND: |
|||
return "Object Name not found"; |
|||
case STATUS_SHARING_VIOLATION: |
|||
return "Sharing Violation"; |
|||
case STATUS_INSUFFICIENT_RESOURCES: |
|||
return "Insufficient resources"; |
|||
case STATUS_NOT_SUPPORTED: |
|||
return "Operation is not supported"; |
|||
default: |
|||
safe_sprintf(unknown, sizeof(unknown), "Unknown error 0x%08lx", Status); |
|||
return unknown; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Allocates a block of memory. |
|||
* |
|||
* \param Size The number of bytes to allocate. |
|||
* |
|||
* \return A pointer to the allocated block of memory. |
|||
* |
|||
*/ |
|||
static PVOID PhAllocate(SIZE_T Size) |
|||
{ |
|||
PF_INIT_OR_OUT(RtlCreateHeap, Ntdll); |
|||
PF_INIT_OR_OUT(RtlAllocateHeap, Ntdll); |
|||
|
|||
if (PhHeapHandle == NULL) { |
|||
PhHeapHandle = pfRtlCreateHeap(HEAP_GROWABLE, NULL, 2 * MB, 1 * MB, NULL, NULL); |
|||
} |
|||
return pfRtlAllocateHeap(PhHeapHandle, 0, Size); |
|||
out: |
|||
return NULL; |
|||
} |
|||
|
|||
/** |
|||
* Frees a block of memory allocated with PhAllocate(). |
|||
* |
|||
* \param Memory A pointer to a block of memory. |
|||
* |
|||
*/ |
|||
static VOID PhFree(PVOID Memory) |
|||
{ |
|||
PF_INIT(RtlFreeHeap, Ntdll); |
|||
if (pfRtlFreeHeap != NULL) |
|||
pfRtlFreeHeap(PhHeapHandle, 0, Memory); |
|||
} |
|||
|
|||
/** |
|||
* Enumerates all open handles. |
|||
* |
|||
* \param Handles A variable which receives a pointer to a structure containing information about |
|||
* all opened handles. You must free the structure using PhFree() when you no longer need it. |
|||
* |
|||
* \return An NTStatus indicating success or the error code. |
|||
*/ |
|||
NTSTATUS PhEnumHandlesEx(PSYSTEM_HANDLE_INFORMATION_EX *Handles) |
|||
{ |
|||
static ULONG initialBufferSize = 0x10000; |
|||
NTSTATUS status; |
|||
PVOID buffer; |
|||
ULONG bufferSize; |
|||
|
|||
PF_INIT(NtQuerySystemInformation, Ntdll); |
|||
if (pfNtQuerySystemInformation == NULL) |
|||
return STATUS_NOT_IMPLEMENTED; |
|||
|
|||
bufferSize = initialBufferSize; |
|||
buffer = PhAllocate(bufferSize); |
|||
if (buffer == NULL) |
|||
return STATUS_NO_MEMORY; |
|||
|
|||
while ((status = pfNtQuerySystemInformation(SystemExtendedHandleInformation, |
|||
buffer, bufferSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH) { |
|||
PhFree(buffer); |
|||
bufferSize *= 2; |
|||
|
|||
// Fail if we're resizing the buffer to something very large. |
|||
if (bufferSize > PH_LARGE_BUFFER_SIZE) |
|||
return STATUS_INSUFFICIENT_RESOURCES; |
|||
|
|||
buffer = PhAllocate(bufferSize); |
|||
if (buffer == NULL) |
|||
return STATUS_NO_MEMORY; |
|||
} |
|||
|
|||
if (!NT_SUCCESS(status)) { |
|||
PhFree(buffer); |
|||
return status; |
|||
} |
|||
|
|||
if (bufferSize <= 0x200000) |
|||
initialBufferSize = bufferSize; |
|||
*Handles = (PSYSTEM_HANDLE_INFORMATION_EX)buffer; |
|||
|
|||
return status; |
|||
} |
|||
|
|||
/** |
|||
* Opens a process. |
|||
* |
|||
* \param ProcessHandle A variable which receives a handle to the process. |
|||
* \param DesiredAccess The desired access to the process. |
|||
* \param ProcessId The ID of the process. |
|||
* |
|||
* \return An NTStatus indicating success or the error code. |
|||
*/ |
|||
NTSTATUS PhOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, HANDLE ProcessId) |
|||
{ |
|||
NTSTATUS status = STATUS_NOT_IMPLEMENTED; |
|||
OBJECT_ATTRIBUTES objectAttributes; |
|||
CLIENT_ID clientId; |
|||
|
|||
if ((LONG_PTR)ProcessId == (LONG_PTR)GetCurrentProcessId()) { |
|||
*ProcessHandle = NtCurrentProcess(); |
|||
return 0; |
|||
} |
|||
|
|||
PF_INIT_OR_OUT(NtOpenProcess, Ntdll); |
|||
|
|||
clientId.UniqueProcess = ProcessId; |
|||
clientId.UniqueThread = NULL; |
|||
|
|||
InitializeObjectAttributes(&objectAttributes, NULL, 0, NULL, NULL); |
|||
status = pfNtOpenProcess(ProcessHandle, DesiredAccess, &objectAttributes, &clientId); |
|||
|
|||
out: |
|||
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. |
|||
* |
|||
* \return TRUE if matching processes were found, FALSE otherwise. |
|||
*/ |
|||
BOOL SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf) |
|||
{ |
|||
NTSTATUS status; |
|||
PSYSTEM_HANDLE_INFORMATION_EX handles; |
|||
POBJECT_NAME_INFORMATION buffer; |
|||
ULONG_PTR i; |
|||
ULONG bufferSize; |
|||
USHORT wHandleNameLen; |
|||
WCHAR *wHandleName; |
|||
HANDLE dupHandle = NULL; |
|||
HANDLE processHandle = NULL; |
|||
BOOLEAN bFound = FALSE; |
|||
char exe_path[2][MAX_PATH]; |
|||
int cur; |
|||
|
|||
status = STATUS_NOT_IMPLEMENTED; |
|||
PF_INIT(NtQueryObject, Ntdll); |
|||
PF_INIT(NtDuplicateObject, NtDll); |
|||
PF_INIT(NtClose, NtDll); |
|||
if ((pfNtQueryObject != NULL) && (pfNtClose != NULL) && (pfNtDuplicateObject != NULL)) |
|||
status = 0; |
|||
|
|||
if (NT_SUCCESS(status)) |
|||
status = PhEnumHandlesEx(&handles); |
|||
if (!NT_SUCCESS(status)) { |
|||
uprintf("Could not enumerate handles: %s", NtStatusError(status)); |
|||
return FALSE; |
|||
} |
|||
|
|||
|
|||
exe_path[0][0] = 0; |
|||
cur = 1; |
|||
|
|||
wHandleName = utf8_to_wchar(HandleName); |
|||
wHandleNameLen = (USHORT) wcslen(wHandleName); |
|||
|
|||
bufferSize = 0x200; |
|||
buffer = PhAllocate(bufferSize); |
|||
|
|||
for (i = 0; ; i++) { |
|||
ULONG attempts = 8; |
|||
PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo = &handles->Handles[i]; |
|||
|
|||
if ((dupHandle != NULL) && (processHandle != NtCurrentProcess())) { |
|||
pfNtClose(dupHandle); |
|||
dupHandle = NULL; |
|||
} |
|||
if (processHandle != NULL) { |
|||
if (processHandle != NtCurrentProcess()) |
|||
pfNtClose(processHandle); |
|||
processHandle = NULL; |
|||
} |
|||
|
|||
CHECK_FOR_USER_CANCEL; |
|||
|
|||
// Exit loop condition |
|||
if (i >= handles->NumberOfHandles) |
|||
break; |
|||
|
|||
// Get the process that created the handle we are after |
|||
// TODO: We probably should keep a list of the most recent processes and perform a lookup |
|||
// instead of Opening the process every time |
|||
status = PhOpenProcess(&processHandle, PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, |
|||
(HANDLE)handleInfo->UniqueProcessId); |
|||
// There exists some processes we can't access |
|||
if (!NT_SUCCESS(status)) |
|||
continue; |
|||
|
|||
// Must duplicate the handle onto our own process, before we can access its properties |
|||
if (processHandle == NtCurrentProcess()) { |
|||
if (bIgnoreSelf) |
|||
continue; |
|||
dupHandle = (HANDLE)handleInfo->HandleValue; |
|||
} else { |
|||
status = pfNtDuplicateObject(processHandle, (HANDLE)handleInfo->HandleValue, |
|||
NtCurrentProcess(), &dupHandle, 0, 0, 0); |
|||
// Why does it always work for Process Hacker and not me??? |
|||
if (!NT_SUCCESS(status)) |
|||
continue; |
|||
} |
|||
|
|||
// Filter non-storage handles. We're not interested in them and they make NtQueryObject() freeze |
|||
if (GetFileType(dupHandle) != FILE_TYPE_DISK) |
|||
continue; |
|||
|
|||
// A loop is needed because the I/O subsystem likes to give us the wrong return lengths... |
|||
do { |
|||
status = pfNtQueryObject(dupHandle, ObjectBasicInformation + 1, |
|||
buffer, bufferSize, &bufferSize); |
|||
if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_INFO_LENGTH_MISMATCH || |
|||
status == STATUS_BUFFER_TOO_SMALL) { |
|||
PhFree(buffer); |
|||
buffer = PhAllocate(bufferSize); |
|||
} else { |
|||
break; |
|||
} |
|||
} while (--attempts); |
|||
if (!NT_SUCCESS(status)) |
|||
continue; |
|||
|
|||
// Don't bother comparing if we are looking for full match and the length is different |
|||
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)) |
|||
continue; |
|||
|
|||
// Match against our target string |
|||
if (wcsncmp(wHandleName, buffer->Name.Buffer, wHandleNameLen) != 0) |
|||
continue; |
|||
|
|||
if (!bFound) { |
|||
uprintf("\r\nNOTE: The following process(es) are accessing %s:", HandleName); |
|||
bFound = TRUE; |
|||
} |
|||
|
|||
// TODO: only list processes with conflicting access rights (ignore "Read attributes" or "Synchronize") |
|||
if (GetModuleFileNameExU(processHandle, 0, exe_path[cur], MAX_PATH - 1)) { |
|||
// Avoid printing the same path repeatedly |
|||
if (strcmp(exe_path[0], exe_path[1]) != 0) { |
|||
uprintf("o %s", exe_path[cur]); |
|||
cur = (cur + 1) % 2; |
|||
} |
|||
} else { |
|||
uprintf("o Unknown (Process ID %d)", GetProcessId(processHandle)); |
|||
} |
|||
} |
|||
|
|||
out: |
|||
if (bFound) |
|||
uprintf("You should try to close these applications before attempting to reformat the drive."); |
|||
else |
|||
uprintf("NOTE: " APPLICATION_NAME " was not able to identify the process(es) preventing access to %s", HandleName); |
|||
|
|||
free(wHandleName); |
|||
PhFree(buffer); |
|||
return bFound; |
|||
} |
@ -0,0 +1,186 @@ |
|||
/* |
|||
* Rufus: The Reliable USB Formatting Utility |
|||
* Search functionality for handles |
|||
* |
|||
* Modified from Process Hacker: |
|||
* https://github.com/processhacker2/processhacker2/ |
|||
* Copyright © 2009-2016 wj32 |
|||
* Copyright © 2017 dmex |
|||
* Copyright © 2017 Pete Batard <pete@akeo.ie> |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU General Public License as published by |
|||
* the Free Software Foundation, either version 3 of the License, or |
|||
* (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#include <windows.h> |
|||
#include <winnt.h> |
|||
#include <winternl.h> |
|||
|
|||
#pragma once |
|||
|
|||
#define PH_LARGE_BUFFER_SIZE (256 * 1024 * 1024) |
|||
|
|||
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0x80000001L) |
|||
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L) |
|||
#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L) |
|||
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) |
|||
//#define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008L) |
|||
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) |
|||
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) |
|||
#define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS)0xC0000024L) |
|||
#define STATUS_OBJECT_NAME_INVALID ((NTSTATUS)0xC0000033L) |
|||
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L) |
|||
#define STATUS_SHARING_VIOLATION ((NTSTATUS)0xC0000043L) |
|||
#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009AL) |
|||
#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL) |
|||
|
|||
#define SystemExtendedHandleInformation 64 |
|||
|
|||
#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1) |
|||
|
|||
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX |
|||
{ |
|||
PVOID Object; |
|||
ULONG_PTR UniqueProcessId; |
|||
ULONG_PTR HandleValue; |
|||
ULONG GrantedAccess; |
|||
USHORT CreatorBackTraceIndex; |
|||
USHORT ObjectTypeIndex; |
|||
ULONG HandleAttributes; |
|||
ULONG Reserved; |
|||
} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX; |
|||
|
|||
typedef struct _SYSTEM_HANDLE_INFORMATION_EX |
|||
{ |
|||
ULONG_PTR NumberOfHandles; |
|||
ULONG_PTR Reserved; |
|||
SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1]; |
|||
} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX; |
|||
|
|||
#if defined(_MSC_VER) |
|||
typedef struct _OBJECT_NAME_INFORMATION |
|||
{ |
|||
UNICODE_STRING Name; |
|||
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; |
|||
|
|||
typedef struct _CLIENT_ID |
|||
{ |
|||
HANDLE UniqueProcess; |
|||
HANDLE UniqueThread; |
|||
} CLIENT_ID, *PCLIENT_ID; |
|||
#endif |
|||
|
|||
// Heaps |
|||
|
|||
typedef struct _RTL_HEAP_ENTRY |
|||
{ |
|||
SIZE_T Size; |
|||
USHORT Flags; |
|||
USHORT AllocatorBackTraceIndex; |
|||
union |
|||
{ |
|||
struct |
|||
{ |
|||
SIZE_T Settable; |
|||
ULONG Tag; |
|||
} s1; |
|||
struct |
|||
{ |
|||
SIZE_T CommittedSize; |
|||
PVOID FirstBlock; |
|||
} s2; |
|||
} u; |
|||
} RTL_HEAP_ENTRY, *PRTL_HEAP_ENTRY; |
|||
|
|||
#define RTL_HEAP_BUSY (USHORT)0x0001 |
|||
#define RTL_HEAP_SEGMENT (USHORT)0x0002 |
|||
#define RTL_HEAP_SETTABLE_VALUE (USHORT)0x0010 |
|||
#define RTL_HEAP_SETTABLE_FLAG1 (USHORT)0x0020 |
|||
#define RTL_HEAP_SETTABLE_FLAG2 (USHORT)0x0040 |
|||
#define RTL_HEAP_SETTABLE_FLAG3 (USHORT)0x0080 |
|||
#define RTL_HEAP_SETTABLE_FLAGS (USHORT)0x00e0 |
|||
#define RTL_HEAP_UNCOMMITTED_RANGE (USHORT)0x0100 |
|||
#define RTL_HEAP_PROTECTED_ENTRY (USHORT)0x0200 |
|||
|
|||
typedef struct _RTL_HEAP_TAG |
|||
{ |
|||
ULONG NumberOfAllocations; |
|||
ULONG NumberOfFrees; |
|||
SIZE_T BytesAllocated; |
|||
USHORT TagIndex; |
|||
USHORT CreatorBackTraceIndex; |
|||
WCHAR TagName[24]; |
|||
} RTL_HEAP_TAG, *PRTL_HEAP_TAG; |
|||
|
|||
typedef struct _RTL_HEAP_INFORMATION |
|||
{ |
|||
PVOID BaseAddress; |
|||
ULONG Flags; |
|||
USHORT EntryOverhead; |
|||
USHORT CreatorBackTraceIndex; |
|||
SIZE_T BytesAllocated; |
|||
SIZE_T BytesCommitted; |
|||
ULONG NumberOfTags; |
|||
ULONG NumberOfEntries; |
|||
ULONG NumberOfPseudoTags; |
|||
ULONG PseudoTagGranularity; |
|||
ULONG Reserved[5]; |
|||
PRTL_HEAP_TAG Tags; |
|||
PRTL_HEAP_ENTRY Entries; |
|||
} RTL_HEAP_INFORMATION, *PRTL_HEAP_INFORMATION; |
|||
|
|||
typedef struct _RTL_PROCESS_HEAPS |
|||
{ |
|||
ULONG NumberOfHeaps; |
|||
RTL_HEAP_INFORMATION Heaps[1]; |
|||
} RTL_PROCESS_HEAPS, *PRTL_PROCESS_HEAPS; |
|||
|
|||
typedef NTSTATUS(NTAPI *PRTL_HEAP_COMMIT_ROUTINE)( |
|||
_In_ PVOID Base, |
|||
_Inout_ PVOID *CommitAddress, |
|||
_Inout_ PSIZE_T CommitSize |
|||
); |
|||
|
|||
#if defined(_MSC_VER) |
|||
typedef struct _RTL_HEAP_PARAMETERS |
|||
{ |
|||
ULONG Length; |
|||
SIZE_T SegmentReserve; |
|||
SIZE_T SegmentCommit; |
|||
SIZE_T DeCommitFreeBlockThreshold; |
|||
SIZE_T DeCommitTotalFreeThreshold; |
|||
SIZE_T MaximumAllocationSize; |
|||
SIZE_T VirtualMemoryThreshold; |
|||
SIZE_T InitialCommit; |
|||
SIZE_T InitialReserve; |
|||
PRTL_HEAP_COMMIT_ROUTINE CommitRoutine; |
|||
SIZE_T Reserved[2]; |
|||
} RTL_HEAP_PARAMETERS, *PRTL_HEAP_PARAMETERS; |
|||
#endif |
|||
|
|||
#define HEAP_SETTABLE_USER_VALUE 0x00000100 |
|||
#define HEAP_SETTABLE_USER_FLAG1 0x00000200 |
|||
#define HEAP_SETTABLE_USER_FLAG2 0x00000400 |
|||
#define HEAP_SETTABLE_USER_FLAG3 0x00000800 |
|||
#define HEAP_SETTABLE_USER_FLAGS 0x00000e00 |
|||
|
|||
#define HEAP_CLASS_0 0x00000000 // Process heap |
|||
#define HEAP_CLASS_1 0x00001000 // Private heap |
|||
#define HEAP_CLASS_2 0x00002000 // Kernel heap |
|||
#define HEAP_CLASS_3 0x00003000 // GDI heap |
|||
#define HEAP_CLASS_4 0x00004000 // User heap |
|||
#define HEAP_CLASS_5 0x00005000 // Console heap |
|||
#define HEAP_CLASS_6 0x00006000 // User desktop heap |
|||
#define HEAP_CLASS_7 0x00007000 // CSR shared heap |
|||
#define HEAP_CLASS_8 0x00008000 // CSR port heap |
|||
#define HEAP_CLASS_MASK 0x0000f000 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue