mirror of
https://github.com/veracrypt/VeraCrypt
synced 2024-11-28 05:53:29 +01:00
Windows: Implement support for processor groups in the driver and fix build issues caused by previous implementation
This commit is contained in:
parent
c1d670fd75
commit
94d3a1919c
@ -10,11 +10,6 @@
|
|||||||
code distribution packages.
|
code distribution packages.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined (WIN64)
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <Versionhelpers.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "EncryptionThreadPool.h"
|
#include "EncryptionThreadPool.h"
|
||||||
#include "Pkcs5.h"
|
#include "Pkcs5.h"
|
||||||
#ifdef DEVICE_DRIVER
|
#ifdef DEVICE_DRIVER
|
||||||
@ -49,6 +44,18 @@
|
|||||||
#define TC_ACQUIRE_MUTEX(MUTEX) WaitForSingleObject (*(MUTEX), INFINITE)
|
#define TC_ACQUIRE_MUTEX(MUTEX) WaitForSingleObject (*(MUTEX), INFINITE)
|
||||||
#define TC_RELEASE_MUTEX(MUTEX) ReleaseMutex (*(MUTEX))
|
#define TC_RELEASE_MUTEX(MUTEX) ReleaseMutex (*(MUTEX))
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *SetThreadGroupAffinityFn)(
|
||||||
|
HANDLE hThread,
|
||||||
|
const GROUP_AFFINITY *GroupAffinity,
|
||||||
|
PGROUP_AFFINITY PreviousGroupAffinity
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef WORD (WINAPI* GetActiveProcessorGroupCountFn)();
|
||||||
|
|
||||||
|
typedef DWORD (WINAPI *GetActiveProcessorCountFn)(
|
||||||
|
WORD GroupNumber
|
||||||
|
);
|
||||||
|
|
||||||
#endif // !DEVICE_DRIVER
|
#endif // !DEVICE_DRIVER
|
||||||
|
|
||||||
|
|
||||||
@ -105,6 +112,7 @@ static volatile BOOL StopPending = FALSE;
|
|||||||
|
|
||||||
static uint32 ThreadCount;
|
static uint32 ThreadCount;
|
||||||
static TC_THREAD_HANDLE ThreadHandles[TC_ENC_THREAD_POOL_MAX_THREAD_COUNT];
|
static TC_THREAD_HANDLE ThreadHandles[TC_ENC_THREAD_POOL_MAX_THREAD_COUNT];
|
||||||
|
static WORD ThreadProcessorGroups[TC_ENC_THREAD_POOL_MAX_THREAD_COUNT];
|
||||||
|
|
||||||
static EncryptionThreadPoolWorkItem WorkItemQueue[TC_ENC_THREAD_POOL_QUEUE_SIZE];
|
static EncryptionThreadPoolWorkItem WorkItemQueue[TC_ENC_THREAD_POOL_QUEUE_SIZE];
|
||||||
|
|
||||||
@ -117,10 +125,6 @@ static TC_MUTEX DequeueMutex;
|
|||||||
static TC_EVENT WorkItemReadyEvent;
|
static TC_EVENT WorkItemReadyEvent;
|
||||||
static TC_EVENT WorkItemCompletedEvent;
|
static TC_EVENT WorkItemCompletedEvent;
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined (WIN64)
|
|
||||||
static uint32 totalProcessors;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
void EncryptDataUnitsCurrentThreadEx (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
|
void EncryptDataUnitsCurrentThreadEx (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
|
||||||
{
|
{
|
||||||
@ -173,13 +177,21 @@ static void SetWorkItemState (EncryptionThreadPoolWorkItem *workItem, WorkItemSt
|
|||||||
|
|
||||||
static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
|
static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
|
||||||
{
|
{
|
||||||
|
EncryptionThreadPoolWorkItem *workItem;
|
||||||
#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
|
#ifdef DEVICE_DRIVER
|
||||||
GROUP_AFFINITY groupAffinity = { ~0ULL, *(int*)(threadArg), { 0, 0, 0 } };
|
SetThreadCpuGroupAffinity ((USHORT) *(WORD*)(threadArg));
|
||||||
BOOL value = SetThreadGroupAffinity(GetCurrentThread(), &groupAffinity, NULL);
|
#else
|
||||||
|
SetThreadGroupAffinityFn SetThreadGroupAffinityPtr = (SetThreadGroupAffinityFn) GetProcAddress (GetModuleHandle (L"kernel32.dll"), "SetThreadGroupAffinity");
|
||||||
|
if (SetThreadGroupAffinityPtr && threadArg)
|
||||||
|
{
|
||||||
|
GROUP_AFFINITY groupAffinity = {0};
|
||||||
|
groupAffinity.Mask = ~0ULL;
|
||||||
|
groupAffinity.Group = *(WORD*)(threadArg);
|
||||||
|
SetThreadGroupAffinityPtr(GetCurrentThread(), &groupAffinity, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EncryptionThreadPoolWorkItem *workItem;
|
|
||||||
|
|
||||||
while (!StopPending)
|
while (!StopPending)
|
||||||
{
|
{
|
||||||
@ -279,36 +291,33 @@ static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
|
|||||||
|
|
||||||
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount)
|
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount)
|
||||||
{
|
{
|
||||||
size_t cpuCount = 0, i = 0, processors = 0, totalProcessors = 0;
|
size_t cpuCount = 0, i = 0;
|
||||||
int threadProcessorGroups[128];
|
#ifdef DEVICE_DRIVER
|
||||||
#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined (WIN64)
|
cpuCount = GetCpuCount();
|
||||||
for (i = 0; i < GetActiveProcessorGroupCount(); ++i)
|
#else
|
||||||
|
SYSTEM_INFO sysInfo;
|
||||||
|
GetActiveProcessorGroupCountFn GetActiveProcessorGroupCountPtr = (GetActiveProcessorGroupCountFn) GetProcAddress (GetModuleHandle (L"Kernel32.dll"), "GetActiveProcessorGroupCount");
|
||||||
|
GetActiveProcessorCountFn GetActiveProcessorCountPtr = (GetActiveProcessorCountFn) GetProcAddress (GetModuleHandle (L"Kernel32.dll"), "GetActiveProcessorCount");
|
||||||
|
if (GetActiveProcessorGroupCountPtr && GetActiveProcessorCountPtr)
|
||||||
{
|
{
|
||||||
processors = GetActiveProcessorCount(i);
|
WORD j, groupCount = GetActiveProcessorGroupCountPtr();
|
||||||
totalProcessors += processors;
|
size_t totalProcessors = 0;
|
||||||
}
|
for (j = 0; j < groupCount; ++j)
|
||||||
|
{
|
||||||
|
totalProcessors += (size_t) GetActiveProcessorCountPtr(j);
|
||||||
|
}
|
||||||
|
cpuCount = totalProcessors;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetSystemInfo(&sysInfo);
|
||||||
|
cpuCount = sysInfo.dwNumberOfProcessors;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ThreadPoolRunning)
|
if (ThreadPoolRunning)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
|
|
||||||
SYSTEM_INFO sysInfo;
|
|
||||||
GetSystemInfo(&sysInfo);
|
|
||||||
cpuCount = (IsWindows7OrGreater) ? totalProcessors : sysInfo.dwNumberOfProcessors;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
#ifdef DEVICE_DRIVER
|
|
||||||
cpuCount = GetCpuCount();
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
SYSTEM_INFO sysInfo;
|
|
||||||
GetSystemInfo (&sysInfo);
|
|
||||||
cpuCount = sysInfo.dwNumberOfProcessors;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
if (cpuCount > encryptionFreeCpuCount)
|
if (cpuCount > encryptionFreeCpuCount)
|
||||||
cpuCount -= encryptionFreeCpuCount;
|
cpuCount -= encryptionFreeCpuCount;
|
||||||
|
|
||||||
@ -368,34 +377,34 @@ BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount)
|
|||||||
|
|
||||||
for (ThreadCount = 0; ThreadCount < cpuCount; ++ThreadCount)
|
for (ThreadCount = 0; ThreadCount < cpuCount; ++ThreadCount)
|
||||||
{
|
{
|
||||||
|
#ifdef DEVICE_DRIVER
|
||||||
#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
|
ThreadProcessorGroups[ThreadCount] = GetCpuGroup ((size_t) ThreadCount);
|
||||||
|
#else
|
||||||
// Determine which processor group to bind the thread to.
|
// Determine which processor group to bind the thread to.
|
||||||
totalProcessors = 0U;
|
if (GetActiveProcessorGroupCountPtr && GetActiveProcessorCountPtr)
|
||||||
for (i = 0U; i < GetActiveProcessorGroupCount(); ++i)
|
|
||||||
{
|
{
|
||||||
totalProcessors += GetActiveProcessorCount(i);
|
WORD j, groupCount = GetActiveProcessorGroupCountPtr();
|
||||||
if (totalProcessors >= ThreadCount)
|
uint32 totalProcessors = 0U;
|
||||||
|
for (j = 0U; j < groupCount; j++)
|
||||||
{
|
{
|
||||||
threadProcessorGroups[ThreadCount] = i;
|
totalProcessors += (uint32) GetActiveProcessorCountPtr(j);
|
||||||
break;
|
if (totalProcessors >= ThreadCount)
|
||||||
|
{
|
||||||
|
ThreadProcessorGroups[ThreadCount] = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
ThreadProcessorGroups[ThreadCount] = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEVICE_DRIVER
|
#ifdef DEVICE_DRIVER
|
||||||
if (!NT_SUCCESS(TCStartThread(EncryptionThreadProc, (void*)(&threadProcessorGroups[ThreadCount]), &ThreadHandles[ThreadCount])))
|
if (!NT_SUCCESS(TCStartThread(EncryptionThreadProc, (void*)(&ThreadProcessorGroups[ThreadCount]), &ThreadHandles[ThreadCount])))
|
||||||
#else
|
#else
|
||||||
if (!(ThreadHandles[ThreadCount] = (HANDLE)_beginthreadex(NULL, 0, EncryptionThreadProc, (void*)(&threadProcessorGroups[ThreadCount]), 0, NULL)))
|
if (!(ThreadHandles[ThreadCount] = (HANDLE)_beginthreadex(NULL, 0, EncryptionThreadProc, (void*)(&ThreadProcessorGroups[ThreadCount]), 0, NULL)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
#ifdef DEVICE_DRIVER
|
|
||||||
if (!NT_SUCCESS (TCStartThread (EncryptionThreadProc, NULL, &ThreadHandles[ThreadCount])))
|
|
||||||
#else
|
|
||||||
if (!(ThreadHandles[ThreadCount] = (HANDLE) _beginthreadex (NULL, 0, EncryptionThreadProc, NULL, 0, NULL)))
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
EncryptionThreadPoolStop();
|
EncryptionThreadPoolStop();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -263,6 +263,10 @@ extern ULONG AllocTag;
|
|||||||
typedef int BOOL;
|
typedef int BOOL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef WORD
|
||||||
|
typedef USHORT WORD;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef BOOLEAN
|
#ifndef BOOLEAN
|
||||||
typedef unsigned char BOOLEAN;
|
typedef unsigned char BOOLEAN;
|
||||||
#endif
|
#endif
|
||||||
@ -295,6 +299,17 @@ typedef NTSTATUS (NTAPI *ExGetFirmwareEnvironmentVariableFn) (
|
|||||||
|
|
||||||
typedef BOOLEAN (NTAPI *KeAreAllApcsDisabledFn) ();
|
typedef BOOLEAN (NTAPI *KeAreAllApcsDisabledFn) ();
|
||||||
|
|
||||||
|
typedef void (NTAPI *KeSetSystemGroupAffinityThreadFn)(
|
||||||
|
PGROUP_AFFINITY Affinity,
|
||||||
|
PGROUP_AFFINITY PreviousAffinity
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef USHORT (NTAPI *KeQueryActiveGroupCountFn)();
|
||||||
|
|
||||||
|
typedef ULONG (NTAPI *KeQueryActiveProcessorCountExFn)(
|
||||||
|
USHORT GroupNumber
|
||||||
|
);
|
||||||
|
|
||||||
extern NTSTATUS NTAPI KeSaveExtendedProcessorState (
|
extern NTSTATUS NTAPI KeSaveExtendedProcessorState (
|
||||||
__in ULONG64 Mask,
|
__in ULONG64 Mask,
|
||||||
PXSTATE_SAVE XStateSave
|
PXSTATE_SAVE XStateSave
|
||||||
|
@ -143,6 +143,9 @@ static KeSaveExtendedProcessorStateFn KeSaveExtendedProcessorStatePtr = NULL;
|
|||||||
static KeRestoreExtendedProcessorStateFn KeRestoreExtendedProcessorStatePtr = NULL;
|
static KeRestoreExtendedProcessorStateFn KeRestoreExtendedProcessorStatePtr = NULL;
|
||||||
static ExGetFirmwareEnvironmentVariableFn ExGetFirmwareEnvironmentVariablePtr = NULL;
|
static ExGetFirmwareEnvironmentVariableFn ExGetFirmwareEnvironmentVariablePtr = NULL;
|
||||||
static KeAreAllApcsDisabledFn KeAreAllApcsDisabledPtr = NULL;
|
static KeAreAllApcsDisabledFn KeAreAllApcsDisabledPtr = NULL;
|
||||||
|
static KeSetSystemGroupAffinityThreadFn KeSetSystemGroupAffinityThreadPtr = NULL;
|
||||||
|
static KeQueryActiveGroupCountFn KeQueryActiveGroupCountPtr = NULL;
|
||||||
|
static KeQueryActiveProcessorCountExFn KeQueryActiveProcessorCountExPtr = NULL;
|
||||||
|
|
||||||
POOL_TYPE ExDefaultNonPagedPoolType = NonPagedPool;
|
POOL_TYPE ExDefaultNonPagedPoolType = NonPagedPool;
|
||||||
ULONG ExDefaultMdlProtection = 0;
|
ULONG ExDefaultMdlProtection = 0;
|
||||||
@ -283,13 +286,20 @@ NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// KeSaveExtendedProcessorState/KeRestoreExtendedProcessorState are available starting from Windows 7
|
// KeSaveExtendedProcessorState/KeRestoreExtendedProcessorState are available starting from Windows 7
|
||||||
|
// KeQueryActiveGroupCount/KeQueryActiveProcessorCountEx/KeSetSystemGroupAffinityThread are available starting from Windows 7
|
||||||
if ((OsMajorVersion > 6) || (OsMajorVersion == 6 && OsMinorVersion >= 1))
|
if ((OsMajorVersion > 6) || (OsMajorVersion == 6 && OsMinorVersion >= 1))
|
||||||
{
|
{
|
||||||
UNICODE_STRING saveFuncName, restoreFuncName;
|
UNICODE_STRING saveFuncName, restoreFuncName, groupCountFuncName, procCountFuncName, setAffinityFuncName;
|
||||||
RtlInitUnicodeString(&saveFuncName, L"KeSaveExtendedProcessorState");
|
RtlInitUnicodeString(&saveFuncName, L"KeSaveExtendedProcessorState");
|
||||||
RtlInitUnicodeString(&restoreFuncName, L"KeRestoreExtendedProcessorState");
|
RtlInitUnicodeString(&restoreFuncName, L"KeRestoreExtendedProcessorState");
|
||||||
|
RtlInitUnicodeString(&groupCountFuncName, L"KeQueryActiveGroupCount");
|
||||||
|
RtlInitUnicodeString(&procCountFuncName, L"KeQueryActiveProcessorCountEx");
|
||||||
|
RtlInitUnicodeString(&setAffinityFuncName, L"KeSetSystemGroupAffinityThread");
|
||||||
KeSaveExtendedProcessorStatePtr = (KeSaveExtendedProcessorStateFn) MmGetSystemRoutineAddress(&saveFuncName);
|
KeSaveExtendedProcessorStatePtr = (KeSaveExtendedProcessorStateFn) MmGetSystemRoutineAddress(&saveFuncName);
|
||||||
KeRestoreExtendedProcessorStatePtr = (KeRestoreExtendedProcessorStateFn) MmGetSystemRoutineAddress(&restoreFuncName);
|
KeRestoreExtendedProcessorStatePtr = (KeRestoreExtendedProcessorStateFn) MmGetSystemRoutineAddress(&restoreFuncName);
|
||||||
|
KeSetSystemGroupAffinityThreadPtr = (KeSetSystemGroupAffinityThreadFn) MmGetSystemRoutineAddress(&setAffinityFuncName);
|
||||||
|
KeQueryActiveGroupCountPtr = (KeQueryActiveGroupCountFn) MmGetSystemRoutineAddress(&groupCountFuncName);
|
||||||
|
KeQueryActiveProcessorCountExPtr = (KeQueryActiveProcessorCountExFn) MmGetSystemRoutineAddress(&procCountFuncName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExGetFirmwareEnvironmentVariable is available starting from Windows 8
|
// ExGetFirmwareEnvironmentVariable is available starting from Windows 8
|
||||||
@ -4488,16 +4498,27 @@ NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information)
|
|||||||
|
|
||||||
size_t GetCpuCount ()
|
size_t GetCpuCount ()
|
||||||
{
|
{
|
||||||
KAFFINITY activeCpuMap = KeQueryActiveProcessors();
|
|
||||||
size_t mapSize = sizeof (activeCpuMap) * 8;
|
|
||||||
size_t cpuCount = 0;
|
size_t cpuCount = 0;
|
||||||
|
if (KeQueryActiveGroupCountPtr && KeQueryActiveProcessorCountExPtr)
|
||||||
while (mapSize--)
|
|
||||||
{
|
{
|
||||||
if (activeCpuMap & 1)
|
USHORT i, groupCount = KeQueryActiveGroupCountPtr ();
|
||||||
++cpuCount;
|
for (i = 0; i < groupCount; i++)
|
||||||
|
{
|
||||||
|
cpuCount += (size_t) KeQueryActiveProcessorCountExPtr (i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KAFFINITY activeCpuMap = KeQueryActiveProcessors();
|
||||||
|
size_t mapSize = sizeof (activeCpuMap) * 8;
|
||||||
|
|
||||||
activeCpuMap >>= 1;
|
while (mapSize--)
|
||||||
|
{
|
||||||
|
if (activeCpuMap & 1)
|
||||||
|
++cpuCount;
|
||||||
|
|
||||||
|
activeCpuMap >>= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpuCount == 0)
|
if (cpuCount == 0)
|
||||||
@ -4506,6 +4527,35 @@ size_t GetCpuCount ()
|
|||||||
return cpuCount;
|
return cpuCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
USHORT GetCpuGroup (size_t index)
|
||||||
|
{
|
||||||
|
if (KeQueryActiveGroupCountPtr && KeQueryActiveProcessorCountExPtr)
|
||||||
|
{
|
||||||
|
USHORT i, groupCount = KeQueryActiveGroupCountPtr ();
|
||||||
|
size_t cpuCount = 0;
|
||||||
|
for (i = 0; i < groupCount; i++)
|
||||||
|
{
|
||||||
|
cpuCount += (size_t) KeQueryActiveProcessorCountExPtr (i);
|
||||||
|
if (cpuCount >= index)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetThreadCpuGroupAffinity (USHORT index)
|
||||||
|
{
|
||||||
|
if (KeSetSystemGroupAffinityThreadPtr)
|
||||||
|
{
|
||||||
|
GROUP_AFFINITY groupAffinity = {0};
|
||||||
|
groupAffinity.Mask = ~0ULL;
|
||||||
|
groupAffinity.Group = index;
|
||||||
|
KeSetSystemGroupAffinityThreadPtr (&groupAffinity, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes)
|
void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes)
|
||||||
{
|
{
|
||||||
|
@ -174,6 +174,8 @@ NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information);
|
|||||||
NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *driveSize);
|
NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *driveSize);
|
||||||
BOOL UserCanAccessDriveDevice ();
|
BOOL UserCanAccessDriveDevice ();
|
||||||
size_t GetCpuCount ();
|
size_t GetCpuCount ();
|
||||||
|
USHORT GetCpuGroup (size_t index);
|
||||||
|
void SetThreadCpuGroupAffinity (USHORT index);
|
||||||
void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes);
|
void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes);
|
||||||
void *AllocateMemoryWithTimeout (size_t size, int retryDelay, int timeout);
|
void *AllocateMemoryWithTimeout (size_t size, int retryDelay, int timeout);
|
||||||
BOOL IsDriveLetterAvailable (int nDosDriveNo, DeviceNamespaceType namespaceType);
|
BOOL IsDriveLetterAvailable (int nDosDriveNo, DeviceNamespaceType namespaceType);
|
||||||
|
Loading…
Reference in New Issue
Block a user