This commit is contained in:
DavidXanatos 2023-08-24 20:34:12 +02:00
parent e7aeab5821
commit 0f74c5a4db
8 changed files with 3861 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
#define IMDISK_RC_VERSION_STR "2.0.10"
#define IMDISK_MAJOR_VERSION 2
#define IMDISK_MINOR_VERSION 0
#define IMDISK_MINOR_LOW_VERSION 10
#define IMDISK_RC_VERSION_FLD IMDISK_MAJOR_VERSION,IMDISK_MINOR_VERSION,IMDISK_MINOR_LOW_VERSION

View File

@ -0,0 +1,192 @@
/*
ImDisk Proxy Services.
Copyright (C) 2005-2007 Olof Lagerkvist.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _INC_IMDPROXY_
#define _INC_IMDPROXY_
#if !defined(_WIN32) && !defined(_NTDDK_)
typedef int32_t LONG;
typedef uint32_t ULONG;
typedef int64_t LONGLONG;
typedef uint64_t ULONGLONG;
typedef u_short WCHAR;
#endif
#define IMDPROXY_SVC L"ImDskSvc"
#define IMDPROXY_SVC_PIPE_DOSDEV_NAME L"\\\\.\\PIPE\\" IMDPROXY_SVC
#define IMDPROXY_SVC_PIPE_NATIVE_NAME L"\\Device\\NamedPipe\\" IMDPROXY_SVC
#define IMDPROXY_FLAG_RO 0x01 // Read-only
#define IMDPROXY_FLAG_SUPPORTS_UNMAP 0x02 // Unmap/TRIM ranges
#define IMDPROXY_FLAG_SUPPORTS_ZERO 0x04 // Zero-fill ranges
#define IMDPROXY_FLAG_SUPPORTS_SCSI 0x08 // SCSI SRB operations
#define IMDPROXY_FLAG_SUPPORTS_SHARED 0x10 // Shared image access with reservations
typedef enum _IMDPROXY_REQ
{
IMDPROXY_REQ_NULL,
IMDPROXY_REQ_INFO,
IMDPROXY_REQ_READ,
IMDPROXY_REQ_WRITE,
IMDPROXY_REQ_CONNECT,
IMDPROXY_REQ_CLOSE,
IMDPROXY_REQ_UNMAP,
IMDPROXY_REQ_ZERO,
IMDPROXY_REQ_SCSI,
IMDPROXY_REQ_SHARED
} IMDPROXY_REQ, *PIMDPROXY_REQ;
typedef struct _IMDPROXY_CONNECT_REQ
{
ULONGLONG request_code;
ULONGLONG flags;
ULONGLONG length;
} IMDPROXY_CONNECT_REQ, *PIMDPROXY_CONNECT_REQ;
typedef struct _IMDPROXY_CONNECT_RESP
{
ULONGLONG error_code;
ULONGLONG object_ptr;
} IMDPROXY_CONNECT_RESP, *PIMDPROXY_CONNECT_RESP;
typedef struct _IMDPROXY_INFO_RESP
{
ULONGLONG file_size;
ULONGLONG req_alignment;
ULONGLONG flags;
} IMDPROXY_INFO_RESP, *PIMDPROXY_INFO_RESP;
typedef struct _IMDPROXY_READ_REQ
{
ULONGLONG request_code;
ULONGLONG offset;
ULONGLONG length;
} IMDPROXY_READ_REQ, *PIMDPROXY_READ_REQ;
typedef struct _IMDPROXY_READ_RESP
{
ULONGLONG errorno;
ULONGLONG length;
} IMDPROXY_READ_RESP, *PIMDPROXY_READ_RESP;
typedef struct _IMDPROXY_WRITE_REQ
{
ULONGLONG request_code;
ULONGLONG offset;
ULONGLONG length;
} IMDPROXY_WRITE_REQ, *PIMDPROXY_WRITE_REQ;
typedef struct _IMDPROXY_WRITE_RESP
{
ULONGLONG errorno;
ULONGLONG length;
} IMDPROXY_WRITE_RESP, *PIMDPROXY_WRITE_RESP;
typedef struct _IMDPROXY_UNMAP_REQ
{
ULONGLONG request_code;
ULONGLONG length;
} IMDPROXY_UNMAP_REQ, *PIMDPROXY_UNMAP_REQ;
typedef struct _IMDPROXY_UNMAP_RESP
{
ULONGLONG errorno;
} IMDPROXY_UNMAP_RESP, *PIMDPROXY_UNMAP_RESP;
typedef struct _IMDPROXY_ZERO_REQ
{
ULONGLONG request_code;
ULONGLONG length;
} IMDPROXY_ZERO_REQ, *PIMDPROXY_ZERO_REQ;
typedef struct _IMDPROXY_ZERO_RESP
{
ULONGLONG errorno;
} IMDPROXY_ZERO_RESP, *PIMDPROXY_ZERO_RESP;
typedef struct _IMDPROXY_SCSI_REQ
{
ULONGLONG request_code;
UCHAR cdb[16];
ULONGLONG request_length;
ULONGLONG max_response_length;
} IMDPROXY_SCSI_REQ, *PIMDPROXY_SCSI_REQ;
typedef struct _IMDPROXY_SCSI_RESP
{
ULONGLONG errorno;
ULONGLONG length;
} IMDPROXY_SCSI_RESP, *PIMDPROXY_SCSI_RESP;
typedef struct _IMDPROXY_SHARED_REQ
{
ULONGLONG request_code;
ULONGLONG operation_code;
ULONGLONG reserve_scope;
ULONGLONG reserve_type;
ULONGLONG existing_reservation_key;
ULONGLONG current_channel_key;
ULONGLONG operation_channel_key;
} IMDPROXY_SHARED_REQ, *PIMDPROXY_SHARED_REQ;
typedef struct _IMDPROXY_SHARED_RESP
{
ULONGLONG errorno;
UCHAR unique_id[16];
ULONGLONG channel_key;
ULONGLONG reservation_key;
ULONGLONG reservation_scope;
ULONGLONG reservation_type;
ULONGLONG length;
} IMDPROXY_SHARED_RESP, *PIMDPROXY_SHARED_RESP;
#define IMDPROXY_RESERVATION_KEY_ANY MAXULONGLONG
typedef enum _IMDPROXY_SHARED_OP_CODE
{
GetUniqueId,
ReadKeys,
Register,
ClearKeys,
Reserve,
Release,
Preempt
} IMDPROXY_SHARED_OP_CODE, *PIMDPROXY_SHARED_OP_CODE;
typedef enum _IMDPROXY_SHARED_RESP_CODE
{
NoError,
ReservationCollision,
InvalidParameter,
IOError
} IMDPROXY_SHARED_RESP_CODE, *PIMDPROXY_SHARED_RESP_CODE;
// For shared memory proxy communication only. Offset to data area in
// shared memory.
#define IMDPROXY_HEADER_SIZE 4096
#endif // _INC_IMDPROXY_

View File

@ -0,0 +1,427 @@
#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 {
LONGLONG StartingOffset; //in bytes, must allign to sector
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
ULONG ParameterBlockOffset; // must be alligned to corresponding structure allignment
ULONG ParameterBlockLength; // 0 means Parameter Block does not exist.
ULONG DataSetRangesOffset; // must be alligned to DEVICE_DATA_SET_RANGE structure allignment.
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 ===========================
//
// Structure defintions for supporint file level trim
//
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

View File

@ -0,0 +1,680 @@
///
/// Some additional native user-mode API functions we use
///
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
#define UNICODE_NULL ((WCHAR)0)
typedef LONG NTSTATUS;
typedef NTSTATUS *PNTSTATUS;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define SYMLINK_FLAG_RELATIVE 1
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
USHORT ReparseDataLength;
USHORT Reserved;
union {
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
ULONG Flags;
WCHAR PathBuffer[1];
} SymbolicLinkReparseBuffer;
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
WCHAR PathBuffer[1];
} MountPointReparseBuffer;
struct {
UCHAR DataBuffer[1];
} GenericReparseBuffer;
} DUMMYUNIONNAME;
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
#define REPARSE_GUID_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer)
//
// Maximum allowed size of the reparse data.
//
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
//
// Predefined reparse tags.
// These tags need to avoid conflicting with IO_REMOUNT defined in ntos\inc\io.h
//
#define IO_REPARSE_TAG_RESERVED_ZERO (0)
#define IO_REPARSE_TAG_RESERVED_ONE (1)
//
// The value of the following constant needs to satisfy the following conditions:
// (1) Be at least as large as the largest of the reserved tags.
// (2) Be strictly smaller than all the tags in use.
//
#define IO_REPARSE_TAG_RESERVED_RANGE IO_REPARSE_TAG_RESERVED_ONE
//
// The reparse tags are a ULONG. The 32 bits are laid out as follows:
//
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +-+-+-+-+-----------------------+-------------------------------+
// |M|R|N|R| Reserved bits | Reparse Tag Value |
// +-+-+-+-+-----------------------+-------------------------------+
//
// M is the Microsoft bit. When set to 1, it denotes a tag owned by Microsoft.
// All ISVs must use a tag with a 0 in this position.
// Note: If a Microsoft tag is used by non-Microsoft software, the
// behavior is not defined.
//
// R is reserved. Must be zero for non-Microsoft tags.
//
// N is name surrogate. When set to 1, the file represents another named
// entity in the system.
//
// The M and N bits are OR-able.
// The following macros check for the M and N bit values:
//
//
// Macro to determine whether a reparse point tag corresponds to a tag
// owned by Microsoft.
//
#define IsReparseTagMicrosoft(_tag) ( \
((_tag) & 0x80000000) \
)
//
// Macro to determine whether a reparse point tag is a name surrogate
//
#define IsReparseTagNameSurrogate(_tag) ( \
((_tag) & 0x20000000) \
)
// end_winnt
//
// The following constant represents the bits that are valid to use in
// reparse tags.
//
#define IO_REPARSE_TAG_VALID_VALUES (0xF000FFFF)
//
// Macro to determine whether a reparse tag is a valid tag.
//
#define IsReparseTagValid(_tag) ( \
!((_tag) & ~IO_REPARSE_TAG_VALID_VALUES) && \
((_tag) > IO_REPARSE_TAG_RESERVED_RANGE) \
)
///////////////////////////////////////////////////////////////////////////////
//
// Microsoft tags for reparse points.
//
///////////////////////////////////////////////////////////////////////////////
#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) // winnt
#define IO_REPARSE_TAG_HSM (0xC0000004L) // winnt
#define IO_REPARSE_TAG_DRIVE_EXTENDER (0x80000005L)
#define IO_REPARSE_TAG_HSM2 (0x80000006L) // winnt
#define IO_REPARSE_TAG_SIS (0x80000007L) // winnt
#define IO_REPARSE_TAG_WIM (0x80000008L) // winnt
#define IO_REPARSE_TAG_CSV (0x80000009L) // winnt
#define IO_REPARSE_TAG_DFS (0x8000000AL) // winnt
#define IO_REPARSE_TAG_FILTER_MANAGER (0x8000000BL)
#define IO_REPARSE_TAG_SYMLINK (0xA000000CL) // winnt
#define IO_REPARSE_TAG_IIS_CACHE (0xA0000010L)
#define IO_REPARSE_TAG_DFSR (0x80000012L) // winnt
#define IO_REPARSE_TAG_DEDUP (0x80000013L) // winnt
#define IO_REPARSE_TAG_APPXSTRM (0xC0000014L)
#define IO_REPARSE_TAG_NFS (0x80000014L) // winnt
#define IO_REPARSE_TAG_FILE_PLACEHOLDER (0x80000015L) // winnt
#define IO_REPARSE_TAG_DFM (0x80000016L)
///////////////////////////////////////////////////////////////////////////////
//
// Non-Microsoft tags for reparse points
//
///////////////////////////////////////////////////////////////////////////////
//
// Tag allocated to CONGRUENT, May 2000. Used by IFSTEST
//
#define IO_REPARSE_TAG_IFSTEST_CONGRUENT (0x00000009L)
//
// Tag allocated to Moonwalk Univeral for HSM
// GUID: 257ABE42-5A28-4C8C-AC46-8FEA5619F18F
//
#define IO_REPARSE_TAG_MOONWALK_HSM (0x0000000AL)
//
// Tag allocated to Tsinghua Univeristy for Research purposes
// No released products should use this tag
// GUID: b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2
//
#define IO_REPARSE_TAG_TSINGHUA_UNIVERSITY_RESEARCH (0x0000000BL)
//
// Tag allocated to ARKIVIO for HSM
//
#define IO_REPARSE_TAG_ARKIVIO (0x0000000CL)
//
// Tag allocated to SOLUTIONSOFT for name surrogate
//
#define IO_REPARSE_TAG_SOLUTIONSOFT (0x2000000DL)
//
// Tag allocated to COMMVAULT for HSM
//
#define IO_REPARSE_TAG_COMMVAULT (0x0000000EL)
//
// Tag allocated to Overtone Software for HSM
//
#define IO_REPARSE_TAG_OVERTONE (0x0000000FL)
//
// Tag allocated to Symantec (formerly to KVS Inc) for HSM
// GUID: A49F7BF6-77CA-493c-A0AA-18DBB28D1098
//
#define IO_REPARSE_TAG_SYMANTEC_HSM2 (0x00000010L)
//
// Tag allocated to Enigma Data for HSM
//
#define IO_REPARSE_TAG_ENIGMA_HSM (0x00000011L)
//
// Tag allocated to Symantec for HSM
// GUID: B99F4235-CF1C-48dd-9E6C-459FA289F8C7
//
#define IO_REPARSE_TAG_SYMANTEC_HSM (0x00000012L)
//
// Tag allocated to INTERCOPE for HSM
// GUID: F204BE2D-AEEB-4728-A31C-C7F4E9BEA758}
//
#define IO_REPARSE_TAG_INTERCOPE_HSM (0x00000013L)
//
// Tag allocated to KOM Networks for HSM
//
#define IO_REPARSE_TAG_KOM_NETWORKS_HSM (0x00000014L)
//
// Tag allocated to MEMORY_TECH for HSM
// GUID: E51BA456-046C-43ea-AEC7-DC1A87E1FD49
//
#define IO_REPARSE_TAG_MEMORY_TECH_HSM (0x00000015L)
//
// Tag allocated to BridgeHead Software for HSM
// GUID: EBAFF6E3-F21D-4496-8342-58144B3D2BD0
//
#define IO_REPARSE_TAG_BRIDGEHEAD_HSM (0x00000016L)
//
// Tag allocated to OSR for samples reparse point filter
// GUID: 3740c860-b19b-11d9-9669-0800200c9a66
//
#define IO_REPARSE_TAG_OSR_SAMPLE (0x20000017L)
//
// Tag allocated to Global 360 for HSM
// GUID: C4B51F66-7F00-4c55-9441-8A1B159F209B
//
#define IO_REPARSE_TAG_GLOBAL360_HSM (0x00000018L)
//
// Tag allocated to Altiris for HSM
// GUID: fc1047eb-fb2d-45f2-a2f4-a71c1032fa2dB
//
#define IO_REPARSE_TAG_ALTIRIS_HSM (0x00000019L)
//
// Tag allocated to Hermes for HSM
// GUID: 437E0FD5-FCB4-42fe-877A-C785DA662AC2
//
#define IO_REPARSE_TAG_HERMES_HSM (0x0000001AL)
//
// Tag allocated to PointSoft for HSM
// GUID: 547BC7FD-9604-4deb-AE07-B6514DF5FBC6
//
#define IO_REPARSE_TAG_POINTSOFT_HSM (0x0000001BL)
//
// Tag allocated to GRAU Data Storage for HSM
// GUID: 6662D310-5653-4D10-8C31-F8E166D1A1BD
//
#define IO_REPARSE_TAG_GRAU_DATASTORAGE_HSM (0x0000001CL)
//
// Tag allocated to CommVault for HSM
// GUID: cc38adf3-c583-4efa-b183-72c1671941de
//
#define IO_REPARSE_TAG_COMMVAULT_HSM (0x0000001DL)
//
// Tag allocated to Data Storage Group for single instance storage
// GUID: C1182673-0562-447a-8E40-4F0549FDF817
//
#define IO_REPARSE_TAG_DATASTOR_SIS (0x0000001EL)
//
// Tag allocated to Enterprise Data Solutions, Inc. for HSM
// GUID: EB63DF9D-8874-41cd-999A-A197542CDAFC
//
#define IO_REPARSE_TAG_EDSI_HSM (0x0000001FL)
//
// Tag allocated to HP StorageWorks Reference Information Manager for Files (HSM)
// GUID: 3B0F6B23-0C2E-4281-9C19-C6AEEBC88CD8
//
#define IO_REPARSE_TAG_HP_HSM (0x00000020L)
//
// Tag allocated to SER Beteiligung Solutions Deutschland GmbH (HSM)
// GUID: 55B673F0-978E-41c5-9ADB-AF99640BE90E
//
#define IO_REPARSE_TAG_SER_HSM (0x00000021L)
//
// Tag allocated to Double-Take Software (formerly NSI Software, Inc.) for HSM
// GUID: f7cb0ce8-453a-4ae1-9c56-db41b55f6ed4
//
#define IO_REPARSE_TAG_DOUBLE_TAKE_HSM (0x00000022L)
//
// Tag allocated to Beijing Wisdata Systems CO, LTD for HSM
// GUID: d546500a-2aeb-45f6-9482-f4b1799c3177
//
#define IO_REPARSE_TAG_WISDATA_HSM (0x00000023L)
//
// Tag allocated to Mimosa Systems Inc for HSM
// GUID: 8ddd4144-1a22-404b-8a5a-fcd91c6ee9f3
//
#define IO_REPARSE_TAG_MIMOSA_HSM (0x00000024L)
//
// Tag allocated to H&S Heilig und Schubert Software AG for HSM
// GUID: 77CA30C0-E5EC-43df-9E44-A4910378E284
//
#define IO_REPARSE_TAG_HSAG_HSM (0x00000025L)
//
// Tag allocated to Atempo Inc. (Atempo Digital Archive) for HSM
// GUID: 9B64518A-D6A4-495f-8D01-392F38862F0C
//
#define IO_REPARSE_TAG_ADA_HSM (0x00000026L)
//
// Tag allocated to Autonomy Corporation for HSM
// GUID: EB112A57-10FC-4b42-B590-A61897FDC432
//
#define IO_REPARSE_TAG_AUTN_HSM (0x00000027L)
//
// Tag allocated to Nexsan for HSM
// GUID: d35eba9a-e722-445d-865f-dde1120acf16
//
#define IO_REPARSE_TAG_NEXSAN_HSM (0x00000028L)
//
// Tag allocated to Double-Take for SIS
// GUID: BDA506C2-F74D-4495-9A8D-44FD8D5B4F42
//
#define IO_REPARSE_TAG_DOUBLE_TAKE_SIS (0x00000029L)
//
// Tag allocated to Sony for HSM
// GUID: E95032E4-FD81-4e15-A8E2-A1F078061C4E
//
#define IO_REPARSE_TAG_SONY_HSM (0x0000002AL)
//
// Tag allocated to Eltan Comm for HSM
// GUID: E1596D9F-44D8-43f4-A2D6-E9FE8D3E28FB
//
#define IO_REPARSE_TAG_ELTAN_HSM (0x0000002BL)
//
// Tag allocated to Utixo LLC for HSM
// GUID: 5401F960-2F95-46D0-BBA6-052929FE2C32
//
#define IO_REPARSE_TAG_UTIXO_HSM (0x0000002CL)
//
// Tag allocated to Quest Software for HSM
// GUID: D546500A-2AEB-45F6-9482-F4B1799C3177
//
#define IO_REPARSE_TAG_QUEST_HSM (0x0000002DL)
//
// Tag allocated to DataGlobal GmbH for HSM
// GUID: 7A09CA83-B7B1-4614-ADFD-0BD5F4F989C9
//
#define IO_REPARSE_TAG_DATAGLOBAL_HSM (0x0000002EL)
//
// Tag allocated to Qi Tech LLC for HSM
// GUID: C8110B39-A4CE-432E-B58A-FBEAD296DF03
//
#define IO_REPARSE_TAG_QI_TECH_HSM (0x2000002FL)
//
// Tag allocated to DataFirst Corporation for HSM
// GUID: E0E40591-6434-479f-94AC-DECF6DAEFB5C
//
#define IO_REPARSE_TAG_DATAFIRST_HSM (0x00000030L)
//
// Tag allocated to C2C Systems for HSM
// GUID: 6F2F829C-36AE-4E88-A3B6-E2C24377EA1C
//
#define IO_REPARSE_TAG_C2CSYSTEMS_HSM (0x00000031L)
//
// Tag allocated to Waterford Technologies for deduplication
// GUID: 0AF8B999-B8E8-408b-805F-5448E68F9274
//
#define IO_REPARSE_TAG_WATERFORD (0x00000032L)
//
// Tag allocated to Riverbed Technology for HSM
// GUID: 3336274-255B-4038-9D39-14B0EC3F8256
//
#define IO_REPARSE_TAG_RIVERBED_HSM (0x00000033L)
//
// Tag allocated to Caringo, Inc. for HSM
// GUID: B92426FA-D35F-48DB-A452-8FD557A23353
//
#define IO_REPARSE_TAG_CARINGO_HSM (0x00000034L)
//
// Tag allocated to MaxiScale, Inc. for HSM
// GUID: 643B4714-BA13-427b-B771-C5BFDE787BB7
//
#define IO_REPARSE_TAG_MAXISCALE_HSM (0x20000035L)
//
// Tag allocated to Citrix Systems for profile management
// GUID: B9150EDE-5845-4818-841B-5BCBB3B848E3
//
#define IO_REPARSE_TAG_CITRIX_PM (0x00000036L)
//
// Tag allocated to OpenAFS for DFS
// GUID: EF21A155-5C92-4470-AB3B-370403D96369
//
#define IO_REPARSE_TAG_OPENAFS_DFS (0x00000037L)
//
// Tag allocated to ZL Technologies Inc for HSM
// GUID: A521FE7A-EB10-4148-BAC7-264359827B7E
//
#define IO_REPARSE_TAG_ZLTI_HSM (0x00000038L)
//
// Tag allocated to EMC Corporation for HSM
// GUID: 119EA2B9-8979-48b9-B4CE-5082AF2D81E5
//
#define IO_REPARSE_TAG_EMC_HSM (0x00000039L)
//
// Tag allocated to VMware for profile management
// GUID: 6D020A57-C9BB-4DA4-A43F-49686D8D5E77
//
#define IO_REPARSE_TAG_VMWARE_PM (0x0000003AL)
//
// Tag allocated to Arco Computer Products for backup
// GUID: C933F72B-A64D-44d9-8CD9-F339D12390CC
//
#define IO_REPARSE_TAG_ARCO_BACKUP (0x0000003BL)
//
// Tag allocated to Carroll-Net for HSM
// GUID: 805EB191-564B-415a-A78C-9ED0AF8E02FF
//
#define IO_REPARSE_TAG_CARROLL_HSM (0x0000003CL)
//
// Tag allocated to ComTrade for HSM
// GUID: D546500A-2AEB-45F6-9482-F4B1799C3177
//
#define IO_REPARSE_TAG_COMTRADE_HSM (0x0000003DL)
//
// Tag allocated to EaseVault for HSM
// GUID: BBA65D6F-F8A0-48CC-B748-DBD5FFFCCFB1
//
#define IO_REPARSE_TAG_EASEVAULT_HSM (0x0000003EL)
//
// Tag allocated to Hitachi Data Systems for HSM
// GUID: DC095FD2-AC3C-46BA-9E58-DD182BE86AF4
//
#define IO_REPARSE_TAG_HDS_HSM (0x0000003FL)
//
// Reparse point index keys.
//
// The index with all the reparse points that exist in a volume at a
// given time contains entries with keys of the form
// <reparse tag, file record id>.
// The data part of these records is empty.
//
#pragma pack(4)
typedef struct _REPARSE_INDEX_KEY {
//
// The tag of the reparse point.
//
ULONG FileReparseTag;
//
// The file record Id where the reparse point is set.
//
LARGE_INTEGER FileId;
} REPARSE_INDEX_KEY, *PREPARSE_INDEX_KEY;
#pragma pack()
NTSYSAPI
BOOLEAN
NTAPI
RtlDosPathNameToNtPathName_U(IN PCWSTR DosName,
OUT PUNICODE_STRING NtName,
OUT PCWSTR *DosFilePath OPTIONAL,
OUT PUNICODE_STRING NtFilePath OPTIONAL);
NTSYSAPI
BOOLEAN
NTAPI
RtlCreateUnicodeString(OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString);
NTSYSAPI
VOID
NTAPI
RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString);
NTSYSAPI
VOID
NTAPI
RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString);
NTSYSAPI
NTSTATUS
NTAPI
NtOpenFile(OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions);
NTSYSAPI
BOOLEAN
NTAPI
NtClose(IN HANDLE hObject);
NTSYSAPI
ULONG
NTAPI
RtlNtStatusToDosError(NTSTATUS Status);
NTSYSAPI
NTSTATUS
WINAPI
RtlGetVersion(
__inout __deref
POSVERSIONINFOW lpVersionInformation);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,274 @@
/*
Win32 overlapped I/O API functions encapsulated in C++ classes.
Copyright (C) 2005-2007 Olof Lagerkvist.
*/
#ifndef _WIO_HPP
#define _WIO_HPP
__inline LPSTR
WideToByteAlloc(LPCWSTR lpSrc)
{
LPSTR lpDst;
int iReqSize =
WideCharToMultiByte(CP_ACP, 0, lpSrc, -1, NULL, 0, NULL, NULL);
if (iReqSize == 0)
return NULL;
lpDst = (LPSTR) malloc(iReqSize);
if (lpDst == NULL)
return NULL;
if (WideCharToMultiByte(CP_ACP, 0, lpSrc, -1, lpDst, iReqSize, NULL, NULL)
!= iReqSize)
{
free(lpDst);
return NULL;
}
return lpDst;
}
__inline SOCKET
ConnectTCP(u_long ulAddress, u_short usPort)
{
// Open socket
SOCKET sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sd == INVALID_SOCKET)
return INVALID_SOCKET;
sockaddr_in addr = { 0 };
addr.sin_family = AF_INET;
addr.sin_port = usPort;
addr.sin_addr.s_addr = ulAddress;
if (connect(sd, (sockaddr*)&addr, sizeof addr) == SOCKET_ERROR)
{
int __h_errno = WSAGetLastError();
closesocket(sd);
WSASetLastError(__h_errno);
return INVALID_SOCKET;
}
return sd;
}
__inline SOCKET
ConnectTCP(LPCWSTR wszServer, u_short usPort)
{
if (wszServer == NULL)
return INVALID_SOCKET;
if (usPort == 0)
return INVALID_SOCKET;
LPSTR szServer = WideToByteAlloc(wszServer);
// Get server address
u_long haddr = inet_addr(szServer);
// Wasn't IP? Lookup host.
if (haddr == INADDR_NONE)
{
hostent *hent = gethostbyname(szServer);
if (hent == NULL)
{
free(szServer);
return INVALID_SOCKET;
}
haddr = *(u_long*)hent->h_addr;
}
free(szServer);
return ConnectTCP(haddr, usPort);
}
__inline SOCKET
ConnectTCP(LPCWSTR wszServer, LPCWSTR wszService)
{
if (wszServer == NULL)
return INVALID_SOCKET;
if (wszService == NULL)
return INVALID_SOCKET;
u_short usPort = htons((u_short)wcstoul(wszService, NULL, 0));
if (usPort == 0)
{
// Get port name for service
LPSTR szService = WideToByteAlloc(wszService);
servent *service = getservbyname(szService, "tcp");
free(szService);
if (service == NULL)
return INVALID_SOCKET;
usPort = service->s_port;
}
return ConnectTCP(wszServer, usPort);
}
/// Enhanced OVERLAPPED stucture with encapsulated API functions.
struct WOverlapped : public OVERLAPPED
{
BOOL Read(HANDLE hFile, LPVOID lpBuf, DWORD dwLength, DWORDLONG dwStart = 0)
{
if (!ResetEvent())
return FALSE;
Offset = (DWORD) dwStart;
OffsetHigh = (DWORD) (dwStart >> 32);
DWORD dw;
return ReadFile(hFile, lpBuf, dwLength, &dw, this);
}
BOOL Write(HANDLE hFile, LPCVOID lpBuf, DWORD dwLength,
DWORDLONG dwStart = 0)
{
if (!ResetEvent())
return FALSE;
Offset = (DWORD) dwStart;
OffsetHigh = (DWORD) (dwStart >> 32);
DWORD dw;
return WriteFile(hFile, lpBuf, dwLength, &dw, this);
}
DWORD BufRecv(HANDLE hFile, PVOID pBuf, DWORD dwBufSize)
{
DWORD dwDone = 0;
bool bGood = true;
for (PVOID ptr = pBuf; dwDone < dwBufSize; )
{
if (!Read(hFile, ptr, dwBufSize-dwDone))
if (GetLastError() != ERROR_IO_PENDING)
{
bGood = false;
break;
}
DWORD dwReadLen;
if (!GetResult(hFile, &dwReadLen))
{
bGood = false;
break;
}
if (dwReadLen == 0)
break;
dwDone += dwReadLen;
(*(LPBYTE*) &ptr) += dwReadLen;
}
if (bGood & (dwDone != dwBufSize))
SetLastError(ERROR_HANDLE_EOF);
return dwDone;
}
BOOL BufSend(HANDLE hFile, const void *pBuf, DWORD dwBufSize)
{
DWORD dwDone = 0;
for (const void *ptr = pBuf; dwDone < dwBufSize; )
{
if (!Write(hFile, ptr, dwBufSize-dwDone))
if (GetLastError() != ERROR_IO_PENDING)
break;
DWORD dwWriteLen;
if (!GetResult(hFile, &dwWriteLen))
break;
if (dwWriteLen == 0)
break;
dwDone += dwWriteLen;
*(CONST BYTE**) &ptr += dwWriteLen;
}
return dwDone == dwBufSize;
}
BOOL ConnectNamedPipe(HANDLE hNamedPipe)
{
return ::ConnectNamedPipe(hNamedPipe, this);
}
BOOL WaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask)
{
return ::WaitCommEvent(hFile, lpEvtMask, this);
}
BOOL GetResult(HANDLE hFile, LPDWORD lpNumberOfBytesTransferred,
BOOL bWait = TRUE)
{
return GetOverlappedResult(hFile, this, lpNumberOfBytesTransferred, bWait);
}
bool Wait(DWORD dwTimeout = INFINITE)
{
return WaitForSingleObject(hEvent, dwTimeout) == WAIT_OBJECT_0;
}
bool IsComplete()
{
return WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0;
}
BOOL SetEvent()
{
return ::SetEvent(hEvent);
}
BOOL ResetEvent()
{
return ::ResetEvent(hEvent);
}
BOOL PulseEvent()
{
return ::PulseEvent(hEvent);
}
operator bool() const
{
return hEvent != NULL;
}
bool operator!() const
{
return hEvent == NULL;
}
explicit WOverlapped(OVERLAPPED &ol)
{
*(OVERLAPPED*)this = ol;
}
explicit WOverlapped(BOOL bManualReset = true, BOOL bSignalled = false)
{
ZeroMemory(this, sizeof *this);
hEvent = CreateEvent(NULL, bManualReset, bSignalled, NULL);
}
explicit WOverlapped(LPCTSTR lpName)
{
ZeroMemory(this, sizeof *this);
hEvent = OpenEvent(EVENT_ALL_ACCESS, false, lpName);
}
~WOverlapped()
{
if (hEvent != NULL)
CloseHandle(hEvent);
}
};
#else // __cplusplus
#endif // _WIO_HPP

View File

@ -0,0 +1,330 @@
#pragma once
inline void *operator_new(size_t Size, UCHAR FillByte)
{
void * result = ExAllocatePoolWithTag(NonPagedPool, Size, POOL_TAG);
if (result != NULL)
{
RtlFillMemory(result, Size, FillByte);
}
return result;
}
inline void operator_delete(void *Ptr)
{
if (Ptr != NULL)
{
ExFreePoolWithTag(Ptr, POOL_TAG);
}
}
void * __CRTDECL operator new(size_t Size);
void * __CRTDECL operator new[](size_t Size);
void * __CRTDECL operator new(size_t Size, UCHAR FillByte);
void __CRTDECL operator delete(void * Ptr);
void __CRTDECL operator delete(void * Ptr, size_t);
void __CRTDECL operator delete[](void * Ptr);
template<typename T, POOL_TYPE pool_type> class WPoolMem
{
protected:
T *ptr;
SIZE_T bytecount;
explicit WPoolMem(T *pBlk, SIZE_T AllocationSize)
: ptr(pBlk),
bytecount(pBlk != NULL ? AllocationSize : 0) { }
public:
operator bool()
{
return ptr != NULL;
}
bool operator!()
{
return ptr == NULL;
}
operator T*()
{
return ptr;
}
T* operator ->()
{
return ptr;
}
T* operator+(int i)
{
return ptr + i;
}
T* operator-(int i)
{
return ptr - i;
}
T* operator =(T *pBlk)
{
Free();
return ptr = pBlk;
}
T* GetPtr()
{
return ptr;
}
T* GetPtr(LONG_PTR offset)
{
return ptr + offset;
}
template<typename TC> TC* GetPtr()
{
return (TC*)(void*)ptr;
}
template<typename TC> TC* GetPtr(LONG_PTR offset)
{
return ((TC*)(void*)ptr) + offset;
}
SIZE_T Count() const
{
return GetSize() / sizeof(T);
}
SIZE_T GetSize() const
{
return ptr != NULL ? bytecount : 0;
}
void Free()
{
if (ptr != NULL)
{
ExFreePoolWithTag(ptr, POOL_TAG);
ptr = NULL;
}
}
void Clear()
{
if ((ptr != NULL) && (bytecount > 0))
{
RtlZeroMemory(ptr, bytecount);
}
}
T* Abandon()
{
T* ab_ptr = ptr;
ptr = NULL;
bytecount = 0;
return ab_ptr;
}
~WPoolMem()
{
Free();
}
void Initialize(SIZE_T AllocateSize)
{
ptr = (T*)ExAllocatePoolWithTag(pool_type, AllocateSize, POOL_TAG);
bytecount = AllocateSize;
}
public:
WPoolMem() :
ptr(NULL),
bytecount(0) { }
explicit WPoolMem(SIZE_T AllocateSize)
{
Initialize(AllocateSize);
}
T* Alloc(SIZE_T AllocateSize)
{
Free();
Initialize(AllocateSize);
return ptr;
}
};
template<POOL_TYPE pool_type> struct WUnicodeString : public UNICODE_STRING
{
operator bool()
{
return (Buffer != NULL) && (MaximumLength != 0);
}
operator !()
{
return (Buffer == NULL) || (MaximumLength == 0);
}
WUnicodeString(USHORT max_length)
{
Length = 0;
Buffer = (PWCHAR)ExAllocatePoolWithTag(pool_type, max_length, MP_TAG_GENERAL);
MaximumLength = Buffer != NULL ? max_length : 0;
}
WUnicodeString(PWCHAR buffer, USHORT length)
{
Buffer = buffer;
Length = MaximumLength = length;
}
WUnicodeString(PWCHAR buffer, USHORT length, USHORT max_length)
{
Buffer = buffer;
Length = length;
MaximumLength = max_length;
}
~WUnicodeString()
{
if (Buffer != NULL)
{
ExFreePoolWithTag(Buffer, MP_TAG_GENERAL);
}
}
};
template<POOL_TYPE pool_type> struct WAnsiString : public ANSI_STRING
{
operator bool()
{
return (Buffer != NULL) && (MaximumLength != 0);
}
operator !()
{
return (Buffer == NULL) || (MaximumLength == 0);
}
WAnsiString(USHORT max_length)
{
Length = 0;
Buffer = (PCHAR)ExAllocatePoolWithTag(pool_type, max_length, MP_TAG_GENERAL);
MaximumLength = Buffer != NULL ? max_length : 0;
}
WAnsiString(PCHAR buffer, USHORT length)
{
Buffer = buffer;
Length = MaximumLength = length;
}
WAnsiString(PCHAR buffer, USHORT length, USHORT max_length)
{
Buffer = buffer;
Length = length;
MaximumLength = max_length;
}
~WAnsiString()
{
if (Buffer != NULL)
{
ExFreePoolWithTag(Buffer, MP_TAG_GENERAL);
}
}
};
template<POOL_TYPE pool_type> struct WOemString : public OEM_STRING
{
operator bool()
{
return (Buffer != NULL) && (MaximumLength != 0);
}
operator !()
{
return (Buffer == NULL) || (MaximumLength == 0);
}
WOemString(USHORT max_length)
{
Length = 0;
Buffer = (PCHAR)ExAllocatePoolWithTag(pool_type, max_length, MP_TAG_GENERAL);
MaximumLength = Buffer != NULL ? max_length : 0;
}
WOemString(PCHAR buffer, USHORT length)
{
Buffer = buffer;
Length = MaximumLength = length;
}
WOemString(PCHAR buffer, USHORT length, USHORT max_length)
{
Buffer = buffer;
Length = length;
MaximumLength = max_length;
}
~WOemString()
{
if (Buffer != NULL)
{
ExFreePoolWithTag(Buffer, MP_TAG_GENERAL);
}
}
};
class WHandle
{
private:
HANDLE h;
public:
operator bool()
{
return h != NULL;
}
bool operator !()
{
return h == NULL;
}
operator HANDLE()
{
return h;
}
void Close()
{
if (h != NULL)
{
ZwClose(h);
h = NULL;
}
}
WHandle() :
h(NULL) { }
explicit WHandle(HANDLE h) :
h(h) { }
~WHandle()
{
Close();
}
};

View File

@ -0,0 +1,362 @@
#include <WINDOWS.H>
/*
WPreserveLastError
An object of this class preserves value of Win32 GetLastError(). Constructor
calls GetLastError() and saves returned value. Destructor calls SetLastError()
with saved value.
*/
class WPreserveLastError
{
public:
DWORD Value;
WPreserveLastError()
{
Value = GetLastError();
}
~WPreserveLastError()
{
SetLastError(Value);
}
};
struct WSystemInfo : public SYSTEM_INFO
{
WSystemInfo()
{
GetSystemInfo(this);
}
};
#if _WIN32_WINNT >= 0x0501
struct WNativeSystemInfo : public SYSTEM_INFO
{
WNativeSystemInfo()
{
GetNativeSystemInfo(this);
}
};
#endif
struct WOSVersionInfo : public OSVERSIONINFO
{
WOSVersionInfo()
{
dwOSVersionInfoSize = sizeof(*this);
#if _MSC_VER >= 1500
#pragma warning(suppress: 4996)
#endif
GetVersionEx(this);
}
};
struct WOSVersionInfoEx : public OSVERSIONINFOEX
{
WOSVersionInfoEx()
{
dwOSVersionInfoSize = sizeof(*this);
#if _MSC_VER >= 1500
#pragma warning(suppress: 4996)
#endif
GetVersionEx((LPOSVERSIONINFO)this);
}
};
template<typename T> class WMemHolder
{
protected:
T *ptr;
public:
operator bool() const
{
return ptr != NULL;
}
bool operator!() const
{
return ptr == NULL;
}
operator T*() const
{
return ptr;
}
T* operator ->() const
{
return ptr;
}
T* operator+(int i) const
{
return ptr + i;
}
T* operator-(int i) const
{
return ptr - i;
}
T* operator =(T *pBlk)
{
Free();
return ptr = pBlk;
}
T* Abandon()
{
T* ab_ptr = ptr;
ptr = NULL;
return ab_ptr;
}
WMemHolder()
: ptr(NULL) { }
explicit WMemHolder(T *pBlk)
: ptr(pBlk)
{
}
};
class WEnvironmentStrings : public WMemHolder<TCHAR>
{
public:
WEnvironmentStrings()
: WMemHolder<TCHAR>(GetEnvironmentStrings())
{
}
BOOL Free()
{
if (ptr != NULL)
{
return FreeEnvironmentStrings(ptr);
}
else
{
return TRUE;
}
}
~WEnvironmentStrings()
{
Free();
}
};
template<typename T> class WMem : public WMemHolder<T>
{
public:
T* operator =(T *pBlk)
{
Free();
return ptr = pBlk;
}
DWORD_PTR Count() const
{
return GetSize() / sizeof(T);
}
DWORD_PTR GetSize() const
{
if (ptr == NULL)
return 0;
else
return LocalSize(ptr);
}
/* WMem::ReAlloc()
*
* Note that this function uses LocalReAlloc() which makes it lose the
* data if the block must be moved to increase.
*/
T* ReAlloc(DWORD dwAllocSize)
{
T *newblock = (T*)LocalReAlloc(ptr, dwAllocSize, LMEM_ZEROINIT);
if (newblock != NULL)
return ptr = newblock;
else
return NULL;
}
T* Free()
{
if (ptr == NULL)
return NULL;
else
return ptr = (T*)LocalFree(ptr);
}
WMem()
{
}
explicit WMem(DWORD dwAllocSize)
: WMemHolder<T>(LocalAlloc(LPTR, dwAllocSize))
{
}
explicit WMem(T *pBlk)
: WMemHolder<T>(pBlk)
{
}
~WMem()
{
Free();
}
};
#ifdef _INC_MALLOC
template<typename T> class WCRTMem : public WMemHolder<T>
{
public:
T* operator =(T *pBlk)
{
Free();
return ptr = pBlk;
}
size_t Count() const
{
return GetSize() / sizeof(T);
}
size_t GetSize() const
{
if (ptr == NULL)
return 0;
else
return _msize(ptr);
}
/* WHeapMem::ReAlloc()
*
* This function uses realloc() which makes it preserve the data if the
* block must be moved to increase.
*/
T* ReAlloc(size_t dwAllocSize)
{
T *newblock = (T*)realloc(ptr, dwAllocSize);
if (newblock != NULL)
return ptr = newblock;
else
return NULL;
}
void Free()
{
if (ptr != NULL)
{
free(ptr);
ptr = NULL;
}
}
WCRTMem()
{
}
explicit WCRTMem(size_t dwAllocSize)
: WMemHolder<T>((T*)malloc(dwAllocSize)) { }
explicit WCRTMem(T *pBlk)
: WMemHolder<T>(pBlk) { }
~WCRTMem()
{
Free();
}
};
#endif
template<typename T> class WHeapMem :public WMemHolder<T>
{
public:
T* operator =(T *pBlk)
{
Free();
return ptr = pBlk;
}
WHeapMem<T> & operator =(WHeapMem<T> &o)
{
Free();
ptr = o.ptr;
o.ptr = NULL;
return *this;
}
SIZE_T Count() const
{
return GetSize() / sizeof(T);
}
SIZE_T GetSize(DWORD dwFlags = 0) const
{
if (ptr == NULL)
return 0;
else
return HeapSize(GetProcessHeap(), dwFlags, ptr);
}
/* WHeapMem::ReAlloc()
*
* This function uses HeapReAlloc() which makes it preserve the data if the
* block must be moved to increase.
*/
T* ReAlloc(SIZE_T AllocSize, DWORD dwFlags = 0)
{
if (ptr == NULL)
{
return ptr =
(T*)HeapAlloc(GetProcessHeap(), dwFlags, AllocSize);
}
T *newblock = (T*)HeapReAlloc(GetProcessHeap(), dwFlags, ptr, AllocSize);
if (newblock != NULL)
return ptr = newblock;
else
return NULL;
}
T *Free(DWORD dwFlags = 0)
{
if ((this == NULL) || (ptr == NULL))
return NULL;
else if (HeapFree(GetProcessHeap(), dwFlags, ptr))
return ptr = NULL;
else
#pragma warning(suppress: 6001)
return ptr;
}
WHeapMem()
{
}
explicit WHeapMem(SIZE_T dwAllocSize, DWORD dwFlags = 0)
: WMemHolder<T>((T*)HeapAlloc(GetProcessHeap(), dwFlags, dwAllocSize))
{
}
explicit WHeapMem(T *pBlk)
: WMemHolder<T>(pBlk)
{
}
~WHeapMem()
{
Free();
}
};