2023-08-24 19:34:12 +01:00
|
|
|
#ifndef VER_PRODUCTBUILD
|
|
|
|
#include <ntverp.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
///
|
|
|
|
/// Some additional native kernel-mode API functions we use
|
|
|
|
///
|
|
|
|
|
|
|
|
//
|
|
|
|
// Ensures that we build a pre Win 2000 compatible x86 sys file
|
|
|
|
// (without ExFreePoolWithTag()). // Olof Lagerkvist
|
|
|
|
//
|
|
|
|
#ifndef _WIN64
|
|
|
|
#ifdef ExFreePool
|
|
|
|
#undef ExFreePool
|
|
|
|
#endif
|
|
|
|
#ifdef ExFreePoolWithTag
|
|
|
|
#undef ExFreePoolWithTag
|
|
|
|
#endif
|
|
|
|
#define ExFreePoolWithTag(b, t) ExFreePool(b)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#pragma warning(disable: 4996)
|
|
|
|
|
|
|
|
//
|
|
|
|
// We include some stuff from newer DDK:s here so that one
|
|
|
|
// version of the driver for all versions of Windows can
|
|
|
|
// be compiled with the Windows 2000 DDK.
|
|
|
|
//
|
|
|
|
#if (VER_PRODUCTBUILD < 2195)
|
|
|
|
|
|
|
|
#define IOCTL_DISK_GET_PARTITION_INFO_EX CTL_CODE(IOCTL_DISK_BASE, 0x0012, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
|
|
|
#define IOCTL_DISK_GET_LENGTH_INFO CTL_CODE(IOCTL_DISK_BASE, 0x0017, METHOD_BUFFERED, FILE_READ_ACCESS)
|
|
|
|
#define IOCTL_DISK_GET_PARTITION_INFO_EX CTL_CODE(IOCTL_DISK_BASE, 0x0012, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
|
|
|
#define IOCTL_DISK_SET_PARTITION_INFO_EX CTL_CODE(IOCTL_DISK_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
|
|
|
|
|
|
|
typedef enum _PARTITION_STYLE
|
|
|
|
{
|
|
|
|
PARTITION_STYLE_MBR,
|
|
|
|
PARTITION_STYLE_GPT
|
|
|
|
} PARTITION_STYLE;
|
|
|
|
|
|
|
|
typedef unsigned __int64 ULONG64, *PULONG64;
|
|
|
|
|
|
|
|
typedef struct _PARTITION_INFORMATION_MBR
|
|
|
|
{
|
|
|
|
UCHAR PartitionType;
|
|
|
|
BOOLEAN BootIndicator;
|
|
|
|
BOOLEAN RecognizedPartition;
|
|
|
|
ULONG HiddenSectors;
|
|
|
|
} PARTITION_INFORMATION_MBR, *PPARTITION_INFORMATION_MBR;
|
|
|
|
|
|
|
|
typedef struct _PARTITION_INFORMATION_GPT
|
|
|
|
{
|
|
|
|
GUID PartitionType;
|
|
|
|
GUID PartitionId;
|
|
|
|
ULONG64 Attributes;
|
|
|
|
WCHAR Name[36];
|
|
|
|
} PARTITION_INFORMATION_GPT, *PPARTITION_INFORMATION_GPT;
|
|
|
|
|
|
|
|
typedef struct _PARTITION_INFORMATION_EX
|
|
|
|
{
|
|
|
|
PARTITION_STYLE PartitionStyle;
|
|
|
|
LARGE_INTEGER StartingOffset;
|
|
|
|
LARGE_INTEGER PartitionLength;
|
|
|
|
ULONG PartitionNumber;
|
|
|
|
BOOLEAN RewritePartition;
|
|
|
|
union
|
|
|
|
{
|
|
|
|
PARTITION_INFORMATION_MBR Mbr;
|
|
|
|
PARTITION_INFORMATION_GPT Gpt;
|
|
|
|
};
|
|
|
|
} PARTITION_INFORMATION_EX, *PPARTITION_INFORMATION_EX;
|
|
|
|
|
|
|
|
typedef struct _GET_LENGTH_INFORMATION
|
|
|
|
{
|
|
|
|
LARGE_INTEGER Length;
|
|
|
|
} GET_LENGTH_INFORMATION, *PGET_LENGTH_INFORMATION;
|
|
|
|
|
|
|
|
typedef SET_PARTITION_INFORMATION SET_PARTITION_INFORMATION_MBR;
|
|
|
|
typedef PARTITION_INFORMATION_GPT SET_PARTITION_INFORMATION_GPT;
|
|
|
|
|
|
|
|
typedef struct _SET_PARTITION_INFORMATION_EX {
|
|
|
|
PARTITION_STYLE PartitionStyle;
|
|
|
|
union {
|
|
|
|
SET_PARTITION_INFORMATION_MBR Mbr;
|
|
|
|
SET_PARTITION_INFORMATION_GPT Gpt;
|
|
|
|
};
|
|
|
|
} SET_PARTITION_INFORMATION_EX, *PSET_PARTITION_INFORMATION_EX;
|
|
|
|
|
|
|
|
#endif // (VER_PRODUCTBUILD < 2600)
|
|
|
|
|
|
|
|
#if (VER_PRODUCTBUILD < 3790)
|
|
|
|
|
|
|
|
#define IOCTL_STORAGE_GET_HOTPLUG_INFO CTL_CODE(IOCTL_STORAGE_BASE, 0x0305, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
|
|
|
|
|
|
|
//
|
|
|
|
// IOCTL_STORAGE_GET_HOTPLUG_INFO
|
|
|
|
//
|
|
|
|
|
|
|
|
typedef struct _STORAGE_HOTPLUG_INFO {
|
|
|
|
ULONG Size;
|
|
|
|
BOOLEAN MediaRemovable;
|
|
|
|
BOOLEAN MediaHotplug;
|
|
|
|
BOOLEAN DeviceHotplug;
|
|
|
|
BOOLEAN WriteCacheEnableOverride;
|
|
|
|
} STORAGE_HOTPLUG_INFO, *PSTORAGE_HOTPLUG_INFO;
|
|
|
|
|
|
|
|
#endif // (VER_PRODUCTBUILD < 3790)
|
|
|
|
|
|
|
|
NTSYSAPI
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
ZwPulseEvent(IN HANDLE EventHandle,
|
|
|
|
OUT PLONG PreviousState OPTIONAL);
|
|
|
|
|
|
|
|
//
|
|
|
|
// We include some stuff from ntifs.h here so that
|
|
|
|
// the driver can be compiled with only the Win2K DDK.
|
|
|
|
//
|
|
|
|
#ifndef _NTIFS_INCLUDED_
|
|
|
|
|
|
|
|
NTSYSAPI
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
ZwSetEvent(IN HANDLE EventHandle,
|
|
|
|
OUT PLONG PreviousState OPTIONAL);
|
|
|
|
|
|
|
|
NTSYSAPI
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
ZwWaitForSingleObject(IN HANDLE Handle,
|
|
|
|
IN BOOLEAN Alertable,
|
|
|
|
IN PLARGE_INTEGER Timeout OPTIONAL);
|
|
|
|
|
|
|
|
NTSYSAPI
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
ZwAllocateVirtualMemory(IN HANDLE ProcessHandle,
|
|
|
|
IN OUT PVOID *BaseAddress,
|
|
|
|
IN ULONG_PTR ZeroBits,
|
|
|
|
IN OUT PSIZE_T RegionSize,
|
|
|
|
IN ULONG AllocationType,
|
|
|
|
IN ULONG Protect);
|
|
|
|
|
|
|
|
NTSYSAPI
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
ZwFreeVirtualMemory(IN HANDLE ProcessHandle,
|
|
|
|
IN PVOID *BaseAddress,
|
|
|
|
IN OUT PSIZE_T RegionSize,
|
|
|
|
IN ULONG FreeType);
|
|
|
|
|
|
|
|
NTSYSAPI
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
ZwFsControlFile(
|
|
|
|
__in HANDLE FileHandle,
|
|
|
|
__in_opt HANDLE Event,
|
|
|
|
__in_opt PIO_APC_ROUTINE ApcRoutine,
|
|
|
|
__in_opt PVOID ApcContext,
|
|
|
|
__out PIO_STATUS_BLOCK IoStatusBlock,
|
|
|
|
__in ULONG FsControlCode,
|
|
|
|
__in_bcount_opt(InputBufferLength) PVOID InputBuffer,
|
|
|
|
__in ULONG InputBufferLength,
|
|
|
|
__out_bcount_opt(OutputBufferLength) PVOID OutputBuffer,
|
|
|
|
__in ULONG OutputBufferLength
|
|
|
|
);
|
|
|
|
|
|
|
|
#define FSCTL_SET_SPARSE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
|
|
|
|
|
|
|
|
typedef enum _TOKEN_TYPE {
|
|
|
|
TokenPrimary = 1,
|
|
|
|
TokenImpersonation
|
|
|
|
} TOKEN_TYPE;
|
|
|
|
typedef TOKEN_TYPE *PTOKEN_TYPE;
|
|
|
|
|
|
|
|
#define TOKEN_SOURCE_LENGTH 8
|
|
|
|
|
|
|
|
typedef struct _TOKEN_SOURCE {
|
|
|
|
CHAR SourceName[TOKEN_SOURCE_LENGTH];
|
|
|
|
LUID SourceIdentifier;
|
|
|
|
} TOKEN_SOURCE, *PTOKEN_SOURCE;
|
|
|
|
|
|
|
|
typedef struct _TOKEN_CONTROL
|
|
|
|
{
|
|
|
|
LUID TokenId;
|
|
|
|
LUID AuthenticationId;
|
|
|
|
LUID ModifiedId;
|
|
|
|
TOKEN_SOURCE TokenSource;
|
|
|
|
} TOKEN_CONTROL, *PTOKEN_CONTROL;
|
|
|
|
|
|
|
|
typedef struct _SECURITY_CLIENT_CONTEXT
|
|
|
|
{
|
|
|
|
SECURITY_QUALITY_OF_SERVICE SecurityQos;
|
|
|
|
PACCESS_TOKEN ClientToken;
|
|
|
|
BOOLEAN DirectlyAccessClientToken;
|
|
|
|
BOOLEAN DirectAccessEffectiveOnly;
|
|
|
|
BOOLEAN ServerIsRemote;
|
|
|
|
TOKEN_CONTROL ClientTokenControl;
|
|
|
|
} SECURITY_CLIENT_CONTEXT, *PSECURITY_CLIENT_CONTEXT;
|
|
|
|
|
|
|
|
NTKERNELAPI
|
|
|
|
NTSTATUS
|
|
|
|
SeCreateClientSecurity(IN PETHREAD Thread,
|
|
|
|
IN PSECURITY_QUALITY_OF_SERVICE QualityOfService,
|
|
|
|
IN BOOLEAN RemoteClient,
|
|
|
|
OUT PSECURITY_CLIENT_CONTEXT ClientContext);
|
|
|
|
|
|
|
|
NTKERNELAPI
|
|
|
|
VOID
|
|
|
|
SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext,
|
|
|
|
IN PETHREAD ServerThread OPTIONAL);
|
|
|
|
|
|
|
|
NTKERNELAPI
|
|
|
|
TOKEN_TYPE
|
|
|
|
SeTokenType(IN PACCESS_TOKEN Token);
|
|
|
|
|
|
|
|
// PsRevertToSelf() removed for Windows NT 3.51 compatibility, Olof Lagerkvist.
|
|
|
|
|
|
|
|
#define SeDeleteClientSecurity(C) \
|
|
|
|
((SeTokenType((C)->ClientToken) == TokenPrimary) ? \
|
|
|
|
(PsDereferencePrimaryToken( (C)->ClientToken )) : \
|
|
|
|
(PsDereferenceImpersonationToken( (C)->ClientToken )))
|
|
|
|
|
|
|
|
#endif // _NTIFS_INCLUDED_
|
|
|
|
|
|
|
|
#define PsDereferenceImpersonationToken(T) \
|
|
|
|
((ARGUMENT_PRESENT((T))) ? \
|
|
|
|
(ObDereferenceObject((T))) : 0)
|
|
|
|
|
|
|
|
#define PsDereferencePrimaryToken(T) (ObDereferenceObject((T)))
|
|
|
|
|
|
|
|
//
|
|
|
|
// For backward compatibility with <= Windows NT 4.0 by Bruce Engle.
|
|
|
|
//
|
|
|
|
#ifndef _WIN64
|
|
|
|
#ifdef MmGetSystemAddressForMdlSafe
|
|
|
|
#undef MmGetSystemAddressForMdlSafe
|
|
|
|
#endif
|
|
|
|
#define MmGetSystemAddressForMdlSafe(MDL, PRIORITY) \
|
|
|
|
MmGetSystemAddressForMdlPrettySafe(MDL)
|
|
|
|
|
|
|
|
__forceinline PVOID
|
|
|
|
MmGetSystemAddressForMdlPrettySafe(PMDL Mdl)
|
|
|
|
{
|
|
|
|
CSHORT MdlMappingCanFail;
|
|
|
|
PVOID MappedSystemVa;
|
|
|
|
|
|
|
|
if (Mdl == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
#pragma warning(suppress: 28145)
|
|
|
|
if (Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL))
|
|
|
|
return Mdl->MappedSystemVa;
|
|
|
|
|
|
|
|
#pragma warning(suppress: 28145)
|
|
|
|
MdlMappingCanFail = Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL;
|
|
|
|
|
|
|
|
#pragma warning(suppress: 28145)
|
|
|
|
Mdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;
|
|
|
|
|
|
|
|
#pragma warning(suppress: 28159)
|
|
|
|
MappedSystemVa = MmMapLockedPages(Mdl, KernelMode);
|
|
|
|
|
|
|
|
if (MdlMappingCanFail == 0)
|
|
|
|
{
|
|
|
|
#pragma warning(suppress: 28145)
|
|
|
|
Mdl->MdlFlags &= ~MDL_MAPPING_CAN_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MappedSystemVa;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES
|
|
|
|
|
|
|
|
#define IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES CTL_CODE(IOCTL_STORAGE_BASE, 0x0501, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
|
|
|
|
|
|
|
//
|
|
|
|
// Defines the various actions
|
|
|
|
//
|
|
|
|
|
|
|
|
typedef ULONG DEVICE_DATA_MANAGEMENT_SET_ACTION;
|
|
|
|
|
|
|
|
#define DeviceDsmAction_None 0
|
|
|
|
#define DeviceDsmAction_Trim 1
|
|
|
|
|
|
|
|
//
|
|
|
|
// Structure used to describe the list of ranges to process
|
|
|
|
//
|
|
|
|
|
|
|
|
typedef struct _DEVICE_DATA_SET_RANGE {
|
2023-10-21 13:10:45 +01:00
|
|
|
LONGLONG StartingOffset; //in bytes, must align to sector
|
2023-08-24 19:34:12 +01:00
|
|
|
ULONGLONG LengthInBytes; // multiple of sector size.
|
|
|
|
} DEVICE_DATA_SET_RANGE, *PDEVICE_DATA_SET_RANGE;
|
|
|
|
|
|
|
|
//
|
|
|
|
// input structure for IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES
|
|
|
|
// 1. Value ofParameterBlockOffset or ParameterBlockLength is 0 indicates that Parameter Block does not exist.
|
|
|
|
// 2. Value of DataSetRangesOffset or DataSetRangesLength is 0 indicates that DataSetRanges Block does not exist.
|
|
|
|
// If DataSetRanges Block exists, it contains contiguous DEVICE_DATA_SET_RANGE structures.
|
|
|
|
// 3. The total size of buffer should be at least:
|
|
|
|
// sizeof (DEVICE_MANAGE_DATA_SET_ATTRIBUTES) + ParameterBlockLength + DataSetRangesLength
|
|
|
|
//
|
|
|
|
typedef struct _DEVICE_MANAGE_DATA_SET_ATTRIBUTES {
|
|
|
|
ULONG Size; // Size of structure DEVICE_MANAGE_DATA_SET_ATTRIBUTES
|
|
|
|
DEVICE_DATA_MANAGEMENT_SET_ACTION Action;
|
|
|
|
|
|
|
|
ULONG Flags; // Global flags across all actions
|
|
|
|
|
2023-10-21 13:10:45 +01:00
|
|
|
ULONG ParameterBlockOffset; // must be aligned to corresponding structure alignment
|
2023-08-24 19:34:12 +01:00
|
|
|
ULONG ParameterBlockLength; // 0 means Parameter Block does not exist.
|
|
|
|
|
2023-10-21 13:10:45 +01:00
|
|
|
ULONG DataSetRangesOffset; // must be aligned to DEVICE_DATA_SET_RANGE structure alignment.
|
2023-08-24 19:34:12 +01:00
|
|
|
ULONG DataSetRangesLength; // 0 means DataSetRanges Block does not exist.
|
|
|
|
|
|
|
|
} DEVICE_MANAGE_DATA_SET_ATTRIBUTES, *PDEVICE_MANAGE_DATA_SET_ATTRIBUTES;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef FSCTL_FILE_LEVEL_TRIM
|
|
|
|
|
|
|
|
#define FSCTL_FILE_LEVEL_TRIM CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 130, METHOD_BUFFERED, FILE_WRITE_DATA)
|
|
|
|
|
|
|
|
//
|
|
|
|
//======================== FSCTL_FILE_LEVEL_TRIM ===========================
|
|
|
|
//
|
2023-10-21 13:10:45 +01:00
|
|
|
// Structure definitions for supporint file level trim
|
2023-08-24 19:34:12 +01:00
|
|
|
//
|
|
|
|
|
|
|
|
typedef struct _FILE_LEVEL_TRIM_RANGE {
|
|
|
|
|
|
|
|
//
|
|
|
|
// Bytes offset from the front of the given file to trim at
|
|
|
|
//
|
|
|
|
|
|
|
|
ULONGLONG Offset;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Length in bytes to trim from the given offset
|
|
|
|
//
|
|
|
|
|
|
|
|
ULONGLONG Length;
|
|
|
|
} FILE_LEVEL_TRIM_RANGE, *PFILE_LEVEL_TRIM_RANGE;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Input buffer defining what ranges to trim
|
|
|
|
//
|
|
|
|
|
|
|
|
typedef struct _FILE_LEVEL_TRIM {
|
|
|
|
|
|
|
|
//
|
|
|
|
// Used when interacting with byte range locks. Set to zero if not SMB or
|
|
|
|
// similar.
|
|
|
|
//
|
|
|
|
|
|
|
|
ULONG Key;
|
|
|
|
|
|
|
|
//
|
|
|
|
// A count of how many Offset:Length pairs are given
|
|
|
|
//
|
|
|
|
|
|
|
|
ULONG NumRanges;
|
|
|
|
|
|
|
|
//
|
|
|
|
// All the pairs.
|
|
|
|
//
|
|
|
|
|
|
|
|
FILE_LEVEL_TRIM_RANGE Ranges[1];
|
|
|
|
|
|
|
|
} FILE_LEVEL_TRIM, *PFILE_LEVEL_TRIM;
|
|
|
|
|
|
|
|
//
|
|
|
|
// This is an optional output buffer
|
|
|
|
//
|
|
|
|
|
|
|
|
typedef struct _FILE_LEVEL_TRIM_OUTPUT {
|
|
|
|
|
|
|
|
//
|
|
|
|
// Receives the number of input ranges
|
|
|
|
// that were processed
|
|
|
|
//
|
|
|
|
|
|
|
|
ULONG NumRangesProcessed;
|
|
|
|
|
|
|
|
} FILE_LEVEL_TRIM_OUTPUT, *PFILE_LEVEL_TRIM_OUTPUT;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if (VER_PRODUCTBUILD < 7600)
|
|
|
|
|
|
|
|
typedef VOID
|
|
|
|
KSTART_ROUTINE(IN PVOID StartContext);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef __drv_maxIRQL
|
|
|
|
#define __drv_maxIRQL(i)
|
|
|
|
#endif
|
|
|
|
#ifndef __drv_when
|
|
|
|
#define __drv_when(c,a)
|
|
|
|
#endif
|
|
|
|
#ifndef __drv_savesIRQLGlobal
|
|
|
|
#define __drv_savesIRQLGlobal(t,o)
|
|
|
|
#endif
|
|
|
|
#ifndef __drv_setsIRQL
|
|
|
|
#define __drv_setsIRQL(i)
|
|
|
|
#endif
|
|
|
|
#ifndef __drv_acquiresExclusiveResource
|
|
|
|
#define __drv_acquiresExclusiveResource(t)
|
|
|
|
#endif
|
|
|
|
#ifndef __drv_releasesExclusiveResource
|
|
|
|
#define __drv_releasesExclusiveResource(t)
|
|
|
|
#endif
|
|
|
|
#ifndef __drv_requiresIRQL
|
|
|
|
#define __drv_requiresIRQL(i)
|
|
|
|
#endif
|
|
|
|
#ifndef __drv_dispatchType
|
|
|
|
#define __drv_dispatchType(f)
|
|
|
|
#endif
|
|
|
|
#ifndef _Dispatch_type_
|
|
|
|
#define _Dispatch_type_ __drv_dispatchType
|
|
|
|
#endif
|
|
|
|
#ifndef _Inout_
|
|
|
|
#define _Inout_
|
|
|
|
#endif
|