From 0f74c5a4dbbb0226914533e71fc03d7c3935c618 Mon Sep 17 00:00:00 2001 From: DavidXanatos <3890945+DavidXanatos@users.noreply.github.com> Date: Thu, 24 Aug 2023 20:34:12 +0200 Subject: [PATCH] 1.11.0 --- SandboxieTools/ImDisk/inc/imdisk.h | 1590 +++++++++++++++++++++++++ SandboxieTools/ImDisk/inc/imdiskver.h | 6 + SandboxieTools/ImDisk/inc/imdproxy.h | 192 +++ SandboxieTools/ImDisk/inc/ntkmapi.h | 427 +++++++ SandboxieTools/ImDisk/inc/ntumapi.h | 680 +++++++++++ SandboxieTools/ImDisk/inc/wio.hpp | 274 +++++ SandboxieTools/ImDisk/inc/wkmem.hpp | 330 +++++ SandboxieTools/ImDisk/inc/wmem.hpp | 362 ++++++ 8 files changed, 3861 insertions(+) create mode 100644 SandboxieTools/ImDisk/inc/imdisk.h create mode 100644 SandboxieTools/ImDisk/inc/imdiskver.h create mode 100644 SandboxieTools/ImDisk/inc/imdproxy.h create mode 100644 SandboxieTools/ImDisk/inc/ntkmapi.h create mode 100644 SandboxieTools/ImDisk/inc/ntumapi.h create mode 100644 SandboxieTools/ImDisk/inc/wio.hpp create mode 100644 SandboxieTools/ImDisk/inc/wkmem.hpp create mode 100644 SandboxieTools/ImDisk/inc/wmem.hpp diff --git a/SandboxieTools/ImDisk/inc/imdisk.h b/SandboxieTools/ImDisk/inc/imdisk.h new file mode 100644 index 00000000..6b364a67 --- /dev/null +++ b/SandboxieTools/ImDisk/inc/imdisk.h @@ -0,0 +1,1590 @@ +/* +ImDisk Virtual Disk Driver for Windows NT/2000/XP. + +Copyright (C) 2005-2018 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_IMDISK_ +#define _INC_IMDISK_ + +#ifndef __T +#if defined(_NTDDK_) || defined(UNICODE) || defined(_UNICODE) +#define __T(x) L ## x +#else +#define __T(x) x +#endif +#endif + +#ifndef _T +#define _T(x) __T(x) +#endif + +#include "imdiskver.h" +#define IMDISK_VERSION ((IMDISK_MAJOR_VERSION << 8) | (IMDISK_MINOR_VERSION << 4) | (IMDISK_MINOR_LOW_VERSION)) +#define IMDISK_DRIVER_VERSION 0x0103 + +#ifndef ZERO_STRUCT +#define ZERO_STRUCT { 0 } +#endif + +/// +/// Base names for device objects created in \Device +/// +#define IMDISK_DEVICE_DIR_NAME _T("\\Device") +#define IMDISK_DEVICE_BASE_NAME IMDISK_DEVICE_DIR_NAME _T("\\ImDisk") +#define IMDISK_CTL_DEVICE_NAME IMDISK_DEVICE_BASE_NAME _T("Ctl") + +/// +/// Symlinks created in \DosDevices to device objects +/// +#define IMDISK_SYMLNK_NATIVE_DIR_NAME _T("\\DosDevices") +#define IMDISK_SYMLNK_WIN32_DIR_NAME _T("\\\\?") +#define IMDISK_SYMLNK_NATIVE_BASE_NAME IMDISK_SYMLNK_NATIVE_DIR_NAME _T("\\ImDisk") +#define IMDISK_SYMLNK_WIN32_BASE_NAME IMDISK_SYMLNK_WIN32_DIR_NAME _T("\\ImDisk") +#define IMDISK_CTL_SYMLINK_NAME IMDISK_SYMLNK_NATIVE_BASE_NAME _T("Ctl") +#define IMDISK_CTL_DOSDEV_NAME IMDISK_SYMLNK_WIN32_BASE_NAME _T("Ctl") + +/// +/// The driver name and image path +/// +#define IMDISK_DRIVER_NAME _T("ImDisk") +#define IMDISK_DRIVER_PATH _T("system32\\drivers\\imdisk.sys") + +#ifndef AWEALLOC_DRIVER_NAME +#define AWEALLOC_DRIVER_NAME _T("AWEAlloc") +#endif +#ifndef AWEALLOC_DEVICE_NAME +#define AWEALLOC_DEVICE_NAME _T("\\Device\\") AWEALLOC_DRIVER_NAME +#endif + +/// +/// Global refresh event name +/// +#define IMDISK_REFRESH_EVENT_NAME _T("ImDiskRefresh") + +/// +/// Registry settings. It is possible to specify devices to be mounted +/// automatically when the driver loads. +/// +#define IMDISK_CFG_PARAMETER_KEY _T("\\Parameters") +#define IMDISK_CFG_MAX_DEVICES_VALUE _T("MaxDevices") +#define IMDISK_CFG_LOAD_DEVICES_VALUE _T("LoadDevices") +#define IMDISK_CFG_DISALLOWED_DRIVE_LETTERS_VALUE _T("DisallowedDriveLetters") +#define IMDISK_CFG_IMAGE_FILE_PREFIX _T("FileName") +#define IMDISK_CFG_SIZE_PREFIX _T("Size") +#define IMDISK_CFG_FLAGS_PREFIX _T("Flags") +#define IMDISK_CFG_DRIVE_LETTER_PREFIX _T("DriveLetter") +#define IMDISK_CFG_OFFSET_PREFIX _T("ImageOffset") + +#define KEY_NAME_HKEY_MOUNTPOINTS \ + _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MountPoints") +#define KEY_NAME_HKEY_MOUNTPOINTS2 \ + _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MountPoints2") + +#define IMDISK_WINVER_MAJOR() (GetVersion() & 0xFF) +#define IMDISK_WINVER_MINOR() ((GetVersion() & 0xFF00) >> 8) + +#define IMDISK_WINVER() ((IMDISK_WINVER_MAJOR() << 8) | \ + IMDISK_WINVER_MINOR()) + +#if defined(NT4_COMPATIBLE) && !defined(_WIN64) +#define IMDISK_GTE_WIN2K() (IMDISK_WINVER_MAJOR() >= 0x05) +#else +#define IMDISK_GTE_WIN2K() TRUE +#endif + +#ifdef _WIN64 +#define IMDISK_GTE_WINXP() TRUE +#else +#define IMDISK_GTE_WINXP() (IMDISK_WINVER() >= 0x0501) +#endif + +#define IMDISK_GTE_SRV2003() (IMDISK_WINVER() >= 0x0502) + +#define IMDISK_GTE_VISTA() (IMDISK_WINVER_MAJOR() >= 0x06) + +#ifndef IMDISK_API +#ifdef IMDISK_CPL_EXPORTS +#define IMDISK_API __declspec(dllexport) +#else +#define IMDISK_API __declspec(dllimport) +#endif +#endif + +/// +/// Base value for the IOCTL's. +/// +#define FILE_DEVICE_IMDISK 0x8372 + +#define IOCTL_IMDISK_QUERY_VERSION ((ULONG) CTL_CODE(FILE_DEVICE_IMDISK, 0x800, METHOD_BUFFERED, 0)) +#define IOCTL_IMDISK_CREATE_DEVICE ((ULONG) CTL_CODE(FILE_DEVICE_IMDISK, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)) +#define IOCTL_IMDISK_QUERY_DEVICE ((ULONG) CTL_CODE(FILE_DEVICE_IMDISK, 0x802, METHOD_BUFFERED, 0)) +#define IOCTL_IMDISK_QUERY_DRIVER ((ULONG) CTL_CODE(FILE_DEVICE_IMDISK, 0x803, METHOD_BUFFERED, 0)) +#define IOCTL_IMDISK_REFERENCE_HANDLE ((ULONG) CTL_CODE(FILE_DEVICE_IMDISK, 0x804, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)) +#define IOCTL_IMDISK_SET_DEVICE_FLAGS ((ULONG) CTL_CODE(FILE_DEVICE_IMDISK, 0x805, METHOD_BUFFERED, 0)) +#define IOCTL_IMDISK_REMOVE_DEVICE ((ULONG) CTL_CODE(FILE_DEVICE_IMDISK, 0x806, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)) +#define IOCTL_IMDISK_IOCTL_PASS_THROUGH ((ULONG) CTL_CODE(FILE_DEVICE_IMDISK, 0x807, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)) +#define IOCTL_IMDISK_FSCTL_PASS_THROUGH ((ULONG) CTL_CODE(FILE_DEVICE_IMDISK, 0x808, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)) +#define IOCTL_IMDISK_GET_REFERENCED_HANDLE ((ULONG) CTL_CODE(FILE_DEVICE_IMDISK, 0x809, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)) + +/// +/// Bit constants for the Flags field in IMDISK_CREATE_DATA +/// + +/// Read-only device +#define IMDISK_OPTION_RO 0x00000001 + +/// Check if flags specifies read-only +#define IMDISK_READONLY(x) ((ULONG)(x) & 0x00000001) + +/// Removable, hot-plug, device +#define IMDISK_OPTION_REMOVABLE 0x00000002 + +/// Check if flags specifies removable +#define IMDISK_REMOVABLE(x) ((ULONG)(x) & 0x00000002) + +/// Specifies that image file is created with sparse attribute. +#define IMDISK_OPTION_SPARSE_FILE 0x00000004 + +/// Check if flags specifies sparse +#define IMDISK_SPARSE_FILE(x) ((ULONG)(x) & 0x00000004) + +/// Swaps each byte pair in image file. +#define IMDISK_OPTION_BYTE_SWAP 0x00000008 + +/// Check if flags specifies byte swapping +#define IMDISK_BYTE_SWAP(x) ((ULONG)(x) & 0x00000008) + +/// Device type is virtual harddisk partition +#define IMDISK_DEVICE_TYPE_HD 0x00000010 +/// Device type is virtual floppy drive +#define IMDISK_DEVICE_TYPE_FD 0x00000020 +/// Device type is virtual CD/DVD-ROM drive +#define IMDISK_DEVICE_TYPE_CD 0x00000030 +/// Device type is unknown "raw" (for use with third-party client drivers) +#define IMDISK_DEVICE_TYPE_RAW 0x00000040 + +/// Extracts the IMDISK_DEVICE_TYPE_xxx from flags +#define IMDISK_DEVICE_TYPE(x) ((ULONG)(x) & 0x000000F0) + +/// Virtual disk is backed by image file +#define IMDISK_TYPE_FILE 0x00000100 +/// Virtual disk is backed by virtual memory +#define IMDISK_TYPE_VM 0x00000200 +/// Virtual disk is backed by proxy connection +#define IMDISK_TYPE_PROXY 0x00000300 + +/// Extracts the IMDISK_TYPE_xxx from flags +#define IMDISK_TYPE(x) ((ULONG)(x) & 0x00000F00) + +// Types with proxy mode + +/// Proxy connection is direct-type +#define IMDISK_PROXY_TYPE_DIRECT 0x00000000 +/// Proxy connection is over serial line +#define IMDISK_PROXY_TYPE_COMM 0x00001000 +/// Proxy connection is over TCP/IP +#define IMDISK_PROXY_TYPE_TCP 0x00002000 +/// Proxy connection uses shared memory +#define IMDISK_PROXY_TYPE_SHM 0x00003000 + +/// Extracts the IMDISK_PROXY_TYPE_xxx from flags +#define IMDISK_PROXY_TYPE(x) ((ULONG)(x) & 0x0000F000) + +// Types with file mode + +/// Serialized I/O to an image file, done in a worker thread +#define IMDISK_FILE_TYPE_QUEUED_IO 0x00000000 +/// Direct parallel I/O to AWEAlloc driver (physical RAM), done in request +/// thread +#define IMDISK_FILE_TYPE_AWEALLOC 0x00001000 +/// Direct parallel I/O to an image file, done in request thread +#define IMDISK_FILE_TYPE_PARALLEL_IO 0x00002000 + +/// Extracts the IMDISK_FILE_TYPE_xxx from flags +#define IMDISK_FILE_TYPE(x) ((ULONG)(x) & 0x0000F000) + +/// Flag set by write request dispatchers to indicated that virtual disk has +/// been since mounted +#define IMDISK_IMAGE_MODIFIED 0x00010000 + +// 0x00020000 is reserved. Corresponds to IMSCSI_FAKE_DISK_SIG in +// Arsenal Image Mounter. + +/// This flag causes the driver to open image files in shared write mode even +/// if the image is opened for writing. This could be useful in some cases, +/// but could easily corrupt filesystems on image files if used incorrectly. +#define IMDISK_OPTION_SHARED_IMAGE 0x00040000 +/// Check if flags indicate shared write mode +#define IMDISK_SHARED_IMAGE(x) ((ULONG)(x) & 0x00040000) + +/// Macro to determine if flags specify either virtual memory (type vm) or +/// physical memory (type file with awealloc) virtual disk drive +#define IMDISK_IS_MEMORY_DRIVE(x) \ + ((IMDISK_TYPE(x) == IMDISK_TYPE_VM) || \ + ((IMDISK_TYPE(x) == IMDISK_TYPE_FILE) && \ + (IMDISK_FILE_TYPE(x) == IMDISK_FILE_TYPE_AWEALLOC))) + +/// Specify as device number to automatically select first free. +#define IMDISK_AUTO_DEVICE_NUMBER ((ULONG)-1) + +/** +Structure used by the IOCTL_IMDISK_CREATE_DEVICE and +IOCTL_IMDISK_QUERY_DEVICE calls and by the ImDiskQueryDevice function. +*/ +typedef struct _IMDISK_CREATE_DATA +{ + /// On create this can be set to IMDISK_AUTO_DEVICE_NUMBER + ULONG DeviceNumber; + /// Total size in bytes (in the Cylinders field) and virtual geometry. + DISK_GEOMETRY DiskGeometry; + /// The byte offset in the image file where the virtual disk begins. + LARGE_INTEGER ImageOffset; + /// Creation flags. Type of device and type of connection. + ULONG Flags; + /// Drive letter (if used, otherwise zero). + WCHAR DriveLetter; + /// Length in bytes of the FileName member. + USHORT FileNameLength; + /// Dynamically-sized member that specifies the image file name. + WCHAR FileName[1]; +} IMDISK_CREATE_DATA, *PIMDISK_CREATE_DATA; + +typedef struct _IMDISK_SET_DEVICE_FLAGS +{ + ULONG FlagsToChange; + ULONG FlagValues; +} IMDISK_SET_DEVICE_FLAGS, *PIMDISK_SET_DEVICE_FLAGS; + +#define IMDISK_API_NO_BROADCAST_NOTIFY 0x00000001 +#define IMDISK_API_FORCE_DISMOUNT 0x00000002 + +#pragma pack(push) +#pragma pack(1) +typedef struct _FAT_BPB +{ + USHORT BytesPerSector; + UCHAR SectorsPerCluster; + USHORT ReservedSectors; + UCHAR NumberOfFileAllocationTables; + USHORT NumberOfRootEntries; + USHORT NumberOfSectors; + UCHAR MediaDescriptor; + USHORT SectorsPerFileAllocationTable; + USHORT SectorsPerTrack; + USHORT NumberOfHeads; + union + { + struct + { + USHORT NumberOfHiddenSectors; + USHORT TotalNumberOfSectors; + } DOS_320; + struct + { + ULONG NumberOfHiddenSectors; + ULONG TotalNumberOfSectors; + } DOS_331; + }; +} FAT_BPB, *PFAT_BPB; + +typedef struct _FAT_VBR +{ + UCHAR JumpInstruction[3]; + CHAR OEMName[8]; + FAT_BPB BPB; + UCHAR FillData[512 - 3 - 8 - sizeof(FAT_BPB) - 1 - 2]; + UCHAR PhysicalDriveNumber; + UCHAR Signature[2]; +} FAT_VBR, *PFAT_VBR; + +#pragma warning(push) +#pragma warning(disable: 4214) +typedef struct _MBR_PARTITION_TABLE_ENTRY +{ + UCHAR Zero : 7; + UCHAR BootIndicator : 1; + UCHAR StartCHS[3]; + UCHAR PartitionType; + UCHAR EndCHS[3]; + ULONG StartingSector; + ULONG NumberOfSectors; +} MBR_PARTITION_TABLE_ENTRY, *PMBR_PARTITION_TABLE_ENTRY; +#pragma warning(pop) + +typedef struct _MBR_PARTITION_TABLE +{ + MBR_PARTITION_TABLE_ENTRY PartitionEntry[4]; + USHORT Signature; // == 0xAA55 +} MBR_PARTITION_TABLE, *PMBR_PARTITION_TABLE; + +#pragma pack(pop) + +#ifdef WINAPI + +#ifdef __cplusplus +extern "C" { +#endif + + /** + Get behaviour flags for API. + */ + IMDISK_API ULONGLONG + WINAPI + ImDiskGetAPIFlags(); + + /** + Set behaviour flags for API. Returns previously defined flag field. + + Flags New flags value to set. + */ + IMDISK_API ULONGLONG + WINAPI + ImDiskSetAPIFlags(ULONGLONG Flags); + + /** + An interactive rundll32.exe-compatible function to show the Add New Virtual + Disk dialog box with a file name already filled in. It is used by the + Windows Explorer context menus. + + hWnd Specifies a window that will be the owner window of any + MessageBox:es or similar. + + hInst Ignored. + + lpszCmdLine An ANSI string specifying the image file to mount. + + nCmdShow Ignored. + */ + IMDISK_API void + WINAPI + RunDLL_MountFile(HWND hWnd, + HINSTANCE hInst, + LPSTR lpszCmdLine, + int nCmdShow); + + /** + An interactive rundll32.exe-compatible function to remove an existing ImDisk + virtual disk. If the filesystem on the device cannot be locked and + dismounted a MessageBox is displayed that asks the user if dismount should + be forced. + + hWnd Specifies a window that will be the owner window of any + MessageBox:es or similar. + + hInst Ignored. + + lpszCmdLine An ANSI string specifying the virtual disk to remove. This + can be on the form "F:" or "F:\" (without the quotes). + + nCmdShow Ignored. + */ + IMDISK_API void + WINAPI + RunDLL_RemoveDevice(HWND hWnd, + HINSTANCE hInst, + LPSTR lpszCmdLine, + int nCmdShow); + + /** + An interactive rundll32.exe-compatible function to save a virtual or + physical drive as an image file. If the filesystem on the device cannot be + locked and dismounted a MessageBox is displayed that asks the user if the + image saving should continue anyway. + + hWnd Specifies a window that will be the owner window of any + MessageBox:es or similar. + + hInst Ignored. + + lpszCmdLine An ANSI string specifying the disk to save. This can be on + the form "F:" or "F:\" (without the quotes). + + nCmdShow Ignored. + */ + IMDISK_API void + WINAPI + RunDLL_SaveImageFile(HWND hWnd, + HINSTANCE hInst, + LPSTR lpszCmdLine, + int nCmdShow); + + /** + This function displays a MessageBox dialog with a + FormatMessage-formatted message. + + hWndParent Parent window for the MessageBox call. + + uStyle Style for the MessageBox call. + + lpTitle Window title for the MessageBox call. + + lpMessage Format string to be used in call to FormatMessage followed + by field parameters. + */ + IMDISK_API BOOL + CDECL + ImDiskMsgBoxPrintF(IN HWND hWndParent OPTIONAL, + IN UINT uStyle, + IN LPCWSTR lpTitle, + IN LPCWSTR lpMessage, ...); + + /** + Synchronously flush Windows message queue to make GUI components responsive. + */ + IMDISK_API VOID + WINAPI + ImDiskFlushWindowMessages(HWND hWnd); + + /** + Used to get a string describing a partition type. + + PartitionType Partition type from partition table. + + Name Pointer to memory that receives a string describing the + partition type. + + NameSize Size of memory area pointed to by the Name parameter. + */ + IMDISK_API VOID + WINAPI + ImDiskGetPartitionTypeName(IN BYTE PartitionType, + IN OUT LPWSTR Name, + IN DWORD NameSize); + + /** + Returns the offset in bytes to actual disk image data for some known + "non-raw" image file formats with headers. Returns TRUE if file extension + is recognized and the known offset has been stored in the variable pointed + to by the Offset parameter. Otherwise the function returns FALSE and the + value pointed to by the Offset parameter is not changed. + + ImageFile Name of raw disk image file. This does not need to be a valid + path or filename, just the extension is used by this function. + + Offset Returned offset in bytes if function returns TRUE. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetOffsetByFileExt(IN LPCWSTR ImageFile, + IN OUT PLARGE_INTEGER Offset); + + /** + Prototype for raw disk reader function used with ImDisk***Indirect + functions. + + Handle Value that was passed as first parameter to + ImDiskGetPartitionInfoIndirect. + + Buffer Buffer where read data is to be stored. + + Offset Disk offset where read operation starts. + + NumberOfBytesToRead Number of bytes to read from disk. + + NumberOfBytesRead Pointer to DWORD size variable where function stores + number of bytes actually read into Buffer. This value + can be equal to or less than NumberOfBytesToRead + parameter. + */ + typedef BOOL(WINAPI *ImDiskReadFileProc)(IN HANDLE Handle, + IN OUT LPVOID Buffer, + IN LARGE_INTEGER Offset, + IN DWORD NumberOfBytesToRead, + IN OUT LPDWORD NumberOfBytesRead); + + /** + Prototype for caller supplied function that receives a + PARTITION_INFORMATION structure called one time for each partition + that ImDiskGetPartitionInfoIndirectEx finds. The function should return + TRUE to indicate that search for further partition entries should be + done, or FALSE to stop the search. The ImDisk***Get*** function will then + return FALSE to the caller with GetLastError value set to ERROR_CANCELLED. + + UserData Value that was passed as last parameter to + ImDiskGetPartitionInfoIndirectEx. + + PartitionInformation Pointer to PARTITION_INFORMATION structure. + */ + typedef BOOL(WINAPI *ImDiskGetPartitionInfoProc)(LPVOID UserData, + PPARTITION_INFORMATION PartitionInformation); + + /** + Attempts to find partition information from a partition table for a raw + disk image file. If no master boot record is found this function returns + FALSE. Returns TRUE if a master boot record with a partition table is found + and values stored in the structures pointed to by the PartitionInformation + parameter. Otherwise the function returns FALSE. + + ImageFile Name of raw disk image file to examine. + + SectorSize Optional sector size used on disk if different from default + 512 bytes. + + Offset Optional offset in bytes to master boot record within file for + use with "non-raw" image files with headers before the actual + disk image data. + + PartitionInformation + Pointer to an array of eight PARTITION_INFORMATION structures + which will receive information from four recognized primary + partition entries followed by four recognized extended entries. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetPartitionInformation(IN LPCWSTR ImageFile, + IN DWORD SectorSize OPTIONAL, + IN PLARGE_INTEGER Offset OPTIONAL, + IN OUT PPARTITION_INFORMATION PartitionInformation); + + + /** + Attempts to find partition information from a partition table for a raw + disk image file. If no master boot record is found this function returns + FALSE. Returns TRUE if a master boot record with a partition table is found + and a value stored in the structure pointed to by the PartitionInformation + parameter. Otherwise the function returns FALSE. + + ImageFile Name of raw disk image file to examine. + + SectorSize Optional sector size used on disk if different from default + 512 bytes. + + Offset Optional offset in bytes to master boot record within file for + use with "non-raw" image files with headers before the actual + disk image data. + + PartitionInformation + Pointer to a PARTITION_INFORMATION structure that will receive information + from a recognized partition entry. + + PartitionNumber + Number of partition to receive information for. If there was no partition + found with this number, the function returns FALSE and GetLastError will + return ERROR_NOT_FOUND. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetSinglePartitionInformation(IN LPCWSTR ImageFile, + IN DWORD SectorSize OPTIONAL, + IN PLARGE_INTEGER Offset OPTIONAL, + IN OUT PPARTITION_INFORMATION PartitionInformation, + IN INT PartitionNumber); + + + /** + Attempts to find partition information from a partition table for a raw + disk image file. + + If no master boot record is found this function returns FALSE. Returns TRUE + if a master boot record with a partition table is found and values where + returned to callback function. If the callback function cancels search by + returning FALSE, this function returns FALSE with GetLastError value set + to ERROR_CANCELLED. + + ImageFile Name of raw disk image file to examine. + + SectorSize Optional sector size used on disk if different from default + 512 bytes. + + Offset Optional offset in bytes to master boot record within file for + use with "non-raw" image files with headers before the actual + disk image data. + + CallBack + Caller supplied function that is called with a PARTITION_INFORMATION + structure for each recognized partition entry. + + UserData Optional data to send as first parameter to callback + function. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetPartitionInformationEx(IN LPCWSTR ImageFile, + IN DWORD SectorSize OPTIONAL, + IN PLARGE_INTEGER Offset OPTIONAL, + IN ImDiskGetPartitionInfoProc GetPartitionInfoProc, + IN LPVOID UserData OPTIONAL); + + + /** + A device read function with ImDiskReadFileProc, which means that it can be + used when calling ImDiskGetPartitionInfoIndirect function. + + Handle Operating system file handle representing a file or device + opened for reading. + + Buffer Buffer where read data is to be stored. + + Offset Disk offset where read operation starts. + + NumberOfBytesToRead + Number of bytes to read from disk. + + NumberOfBytesRead + Pointer to DWORD size variable where function stores number of + bytes actually read into Buffer. This value can be equal to or + less than NumberOfBytesToRead parameter. + */ + IMDISK_API BOOL + WINAPI + ImDiskReadFileHandle(IN HANDLE Handle, + IN OUT LPVOID Buffer, + IN LARGE_INTEGER Offset, + IN DWORD NumberOfBytesToRead, + IN OUT LPDWORD NumberOfBytesRead); + + /** + Attempts to find partition information from a partition table for a disk + image through a supplied device reader function. + + If no master boot record is found this function returns FALSE. Returns TRUE + if a master boot record with a partition table is found and values where + returned to callback function. If the callback function cancels search by + returning FALSE, this function returns FALSE with GetLastError value set + to ERROR_CANCELLED. + + Handle Value that is passed as first parameter to ReadFileProc. + + ReadFileProc Procedure of type ImDiskReadFileProc that is called to read raw + disk image. + + SectorSize Optional sector size used on disk if different from default + 512 bytes. + + Offset Optional offset in bytes to master boot record within file for + use with "non-raw" image files with headers before the actual + disk image data. + + CallBack + Caller supplied function that is called with a PARTITION_INFORMATION + structure for each recognized partition entry. + + UserData Optional data to send as first parameter to callback + function. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetPartitionInfoIndirectEx(IN HANDLE Handle, + IN ImDiskReadFileProc ReadFileProc, + IN DWORD SectorSize OPTIONAL, + IN PLARGE_INTEGER Offset OPTIONAL, + IN ImDiskGetPartitionInfoProc GetPartitionInfoProc, + IN LPVOID UserData OPTIONAL); + + /** + Attempts to find partition information from a partition table for a disk + image through a supplied device reader function. + + If no master boot record is found this function returns FALSE. Returns TRUE + if a master boot record with a partition table is found and values stored in + the structures pointed to by the PartitionInformation parameter. Otherwise + the function returns FALSE. + + Handle Value that is passed as first parameter to ReadFileProc. + + ReadFileProc Procedure of type ImDiskReadFileProc that is called to read raw + disk image. + + SectorSize Optional sector size used on disk if different from default + 512 bytes. + + Offset Optional offset in bytes to master boot record within file for + use with "non-raw" image files with headers before the actual + disk image data. + + PartitionInformation + Pointer to an array of eight PARTITION_INFORMATION structures + which will receive information from four recognized primary + partition entries followed by four recognized extended entries. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetPartitionInfoIndirect(IN HANDLE Handle, + IN ImDiskReadFileProc ReadFileProc, + IN DWORD SectorSize OPTIONAL, + IN PLARGE_INTEGER Offset OPTIONAL, + IN OUT PPARTITION_INFORMATION PartitionInfo); + + /** + Attempts to find partition information from a partition table for a disk + image through a supplied device reader function. + + If no master boot record is found this function returns FALSE. Returns + TRUE if a master boot record with a partition table is found and a value + stored in the structure pointed to by the PartitionInformation parameter. + Otherwise the function returns FALSE. + + ImageFile Name of raw disk image file to examine. + + SectorSize Optional sector size used on disk if different from default + 512 bytes. + + Offset Optional offset in bytes to master boot record within file for + use with "non-raw" image files with headers before the actual + disk image data. + + PartitionInformation + Pointer to a PARTITION_INFORMATION structure that will receive information + from a recognized partition entry. + + PartitionNumber + Number of partition to receive information for. If there was no partition + found with this number, the function returns FALSE and GetLastError will + return ERROR_NOT_FOUND. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetSinglePartitionInfoIndirect(IN HANDLE Handle, + IN ImDiskReadFileProc ReadFileProc, + IN DWORD SectorSize OPTIONAL, + IN PLARGE_INTEGER Offset OPTIONAL, + IN OUT PPARTITION_INFORMATION PartitionInformation, + IN INT PartitionNumber); + + + /** + Finds out if image file contains an ISO9660 filesystem. + + ImageFile Name of disk image file to examine. + + Offset Optional offset in bytes to where raw disk data begins, for use + with "non-raw" image files with headers before the actual disk + image data. + */ + IMDISK_API BOOL + WINAPI + ImDiskImageContainsISOFS(IN LPCWSTR ImageFile, + IN PLARGE_INTEGER Offset OPTIONAL); + + /** + Finds out if image file contains an ISO9660 filesystem, through a supplied + device reader function. + + Handle Value that is passed as first parameter to ReadFileProc. + + ReadFileProc Procedure of type ImDiskReadFileProc that is called to read raw + disk image. + + Offset Optional offset in bytes to where raw disk data begins, for use + with "non-raw" image files with headers before the actual disk + image data. + */ + IMDISK_API BOOL + WINAPI + ImDiskImageContainsISOFSIndirect(IN HANDLE Handle, + IN ImDiskReadFileProc ReadFileProc, + IN PLARGE_INTEGER Offset OPTIONAL); + + /** + Starts a Win32 service or loads a kernel module or driver. + + ServiceName Key name of the service or driver. + */ + IMDISK_API BOOL + WINAPI + ImDiskStartService(IN LPWSTR ServiceName); + + /** + An easy way to turn an empty NTFS directory to a reparse point that redirects + requests to a mounted device. Acts quite like mount points or symbolic links + in *nix. If MountPoint specifies a character followed by a colon, a drive + letter is instead created to point to Target. + + MountPoint Path to empty directory on an NTFS volume, or a drive letter + followed by a colon. + + Target Target device path on kernel object namespace form, e.g. + \Device\ImDisk2 or similar. + */ + IMDISK_API BOOL + WINAPI + ImDiskCreateMountPoint(IN LPCWSTR MountPoint, + IN LPCWSTR Target); + + /** + Restores a reparse point to be an ordinary empty directory, or removes a + drive letter mount point. When removing a drive letter mount point, this + function notifies shell components that drive letter is gone unless API + flags are set to turn off shell notifications. + + MountPoint Path to a reparse point on an NTFS volume, or a drive letter + followed by a colon to remove a drive letter mount point. + */ + IMDISK_API BOOL + WINAPI + ImDiskRemoveMountPoint(IN LPCWSTR MountPoint); + + /** + Opens a device object in the kernel object namespace. + + FileName Full kernel object namespace path to the object to open, e.g. + \Device\ImDisk2 or similar. + + AccessMode Access mode to request. + */ + IMDISK_API HANDLE + WINAPI + ImDiskOpenDeviceByName(IN PUNICODE_STRING FileName, + IN DWORD AccessMode); + + /** + Opens an ImDisk device by the device number. + + DeviceNumber Number of the ImDisk device to open. + + AccessMode Access mode to request. + */ + IMDISK_API HANDLE + WINAPI + ImDiskOpenDeviceByNumber(IN DWORD DeviceNumber, + IN DWORD AccessMode); + + /** + Opens the device a junction/mount-point type reparse point is pointing to. + + MountPoint Path to the reparse point on an NTFS volume. + + AccessMode Access mode to request to the target device. + */ + IMDISK_API HANDLE + WINAPI + ImDiskOpenDeviceByMountPoint(IN LPCWSTR MountPoint, + IN DWORD AccessMode); + + /** + Check that the user-mode library and kernel-mode driver version matches for + an open ImDisk created device object. + + DeviceHandle Handle to an open ImDisk virtual disk or control device. + */ + IMDISK_API BOOL + WINAPI + ImDiskCheckDriverVersion(IN HANDLE DeviceHandle); + + /** + Retrieves the version numbers of the user-mode API library and the kernel- + mode driver. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetVersion(IN OUT PULONG LibraryVersion OPTIONAL, + IN OUT PULONG DriverVersion OPTIONAL); + + /** + Returns the first free drive letter in the range D-Z. + */ + IMDISK_API WCHAR + WINAPI + ImDiskFindFreeDriveLetter(); + + /** + Returns a bit-field representing ImDisk devices. Bit 0 represents device 0, + bit 1 represents device 1 and so on. A bit is 1 if the device exists or 0 if + the device number is free. + + Compatibility notice: + This function is exported for compatibility with ImDisk versions before + 1.7.0. Since that version, drives can have device numbers above 63. This + function cannot return such device numbers, so in case any drive with device + number above 63 exist when this function is called, it returns a value + filled with all ones ((ULONGLONG)-1). + + Use ImDiskGetDeviceListEx function with newer versions of ImDisk. + */ + IMDISK_API ULONGLONG + WINAPI + ImDiskGetDeviceList(); + + /** + Builds a list of currently existing ImDisk virtual disks. + + ListLength Set this parameter to number of ULONG element that can be + store at the location pointed to by DeviceList parameter. + This parameter must be at least 3 for this function to work + correctly. + + DeviceList Pointer to memory location where one ULONG, containing a + device number, will be stored for each currently existing + ImDisk device. First element in list is used to store number + of devices. + + Upon return, first element in DeviceList will contain number of currently + existing ImDisk virtual disks. If DeviceList is too small to contain all + items as indicated by ListLength parameter, number of existing devices will + be stored at DeviceList location, but no further items will be stored. + + If an error occurs, this function returns FALSE and GetLastError + will return an error code. If successful, the function returns TRUE and + first element at location pointed to by DeviceList will contain number of + devices currently on the system, i.e. number of elements following the first + one in DeviceList. + + If DeviceList buffer is too small, the function returns FALSE and + GetLastError returns ERROR_MORE_DATA. In that case, only number of + existing devices will be stored at location pointed to by DeviceList + parameter. That value, plus one for the first length element, indicates how + large the buffer needs to be to successfully store all items. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetDeviceListEx(IN ULONG ListLength, + OUT PULONG DeviceList); + + /** + This function sends an IOCTL_IMDISK_QUERY_DEVICE control code to an existing + device and returns information about the device in an IMDISK_CREATE_DATA + structure. + + DeviceNumber Number of the ImDisk device to query. + + CreateData Pointer to a sufficiently large IMDISK_CREATE_DATA + structure to receive all data including the image file name + where applicable. + + CreateDataSize The size in bytes of the memory the CreateData parameter + points to. The function call will fail if the memory is not + large enough to hold the entire IMDISK_CREATE_DATA + structure. + */ + IMDISK_API BOOL + WINAPI + ImDiskQueryDevice(IN DWORD DeviceNumber, + IN OUT PIMDISK_CREATE_DATA CreateData, + IN ULONG CreateDataSize); + + /** + This function creates a new ImDisk virtual disk device. + + hWndStatusText A handle to a window that can display status message text. + The function will send WM_SETTEXT messages to this window. + If this parameter is NULL no WM_SETTEXT messages are sent + and the function acts non-interactive. + + DiskGeometry The virtual geometry of the new virtual disk. Note that the + Cylinders member does not specify the number of Cylinders + but the total size in bytes of the new virtual disk. The + actual number of cylinders are then automatically + calculated and rounded down if necessary. + + The Cylinders member can be zero if the device is backed by + an image file or a proxy device, but not if it is virtual + memory only device. + + All or some of the other members of this structure can be + zero in which case they are automatically filled in with + most reasonable values by the driver. + + Flags Bitwise or-ed combination of one of the IMDISK_TYPE_xxx + flags, one of the IMDISK_DEVICE_TYPE_xxx flags and any + number of IMDISK_OPTION_xxx flags. The flags can often be + left zero and left to the driver to automatically select. + For example, if a virtual disk size is specified to 1440 KB + and an image file name is not specified, the driver + automatically selects IMDISK_TYPE_VM|IMDISK_DEVICE_TYPE_FD + for this parameter. + + FileName Name of disk image file. In case IMDISK_TYPE_VM is + specified in the Flags parameter, this file will be loaded + into the virtual memory-backed disk when created. + + NativePath Set to TRUE if the FileName parameter specifies an NT + native path, such as \??\C:\imagefile.img or FALSE if it + specifies a Win32/DOS-style path such as C:\imagefile.img. + + MountPoint Drive letter to assign to the new virtual device. It can be + specified on the form F: or F:\. It can also specify an empty directory + on another NTFS volume. + */ + IMDISK_API BOOL + WINAPI + ImDiskCreateDevice(IN HWND hWndStatusText OPTIONAL, + IN OUT PDISK_GEOMETRY DiskGeometry OPTIONAL, + IN PLARGE_INTEGER ImageOffset OPTIONAL, + IN DWORD Flags OPTIONAL, + IN LPCWSTR FileName OPTIONAL, + IN BOOL NativePath, + IN LPWSTR MountPoint OPTIONAL); + + /** + This function creates a new ImDisk virtual disk device. + + hWndStatusText A handle to a window that can display status message text. + The function will send WM_SETTEXT messages to this window. + If this parameter is NULL no WM_SETTEXT messages are sent + and the function acts non-interactive. + + DeviceNumber In: Device number for device to create. Device number must + not be in use by an existing virtual disk. For automatic + allocation of device number, use IMDISK_AUTO_DEVICE_NUMBER + constant or specify a NULL pointer. + + Out: If DeviceNumber parameter is not NULL, device number + for created device is returned in DWORD variable pointed to. + + DiskGeometry The virtual geometry of the new virtual disk. Note that the + Cylinders member does not specify the number of Cylinders + but the total size in bytes of the new virtual disk. The + actual number of cylinders are then automatically + calculated and rounded down if necessary. + + The Cylinders member can be zero if the device is backed by + an image file or a proxy device, but not if it is virtual + memory only device. + + All or some of the other members of this structure can be + zero in which case they are automatically filled in with + most reasonable values by the driver. + + Flags Bitwise or-ed combination of one of the IMDISK_TYPE_xxx + flags, one of the IMDISK_DEVICE_TYPE_xxx flags and any + number of IMDISK_OPTION_xxx flags. The flags can often be + left zero and left to the driver to automatically select. + For example, if a virtual disk size is specified to 1440 KB + and an image file name is not specified, the driver + automatically selects IMDISK_TYPE_VM|IMDISK_DEVICE_TYPE_FD + for this parameter. + + FileName Name of disk image file. In case IMDISK_TYPE_VM is + specified in the Flags parameter, this file will be loaded + into the virtual memory-backed disk when created. + + NativePath Set to TRUE if the FileName parameter specifies an NT + native path, such as \??\C:\imagefile.img or FALSE if it + specifies a Win32/DOS-style path such as C:\imagefile.img. + + MountPoint Drive letter to assign to the new virtual device. It can + be specified on the form F: or F:\. It can also specify an empty directory + on another NTFS volume. + */ + IMDISK_API BOOL + WINAPI + ImDiskCreateDeviceEx(IN HWND hWndStatusText OPTIONAL, + IN OUT LPDWORD DeviceNumber OPTIONAL, + IN OUT PDISK_GEOMETRY DiskGeometry OPTIONAL, + IN PLARGE_INTEGER ImageOffset OPTIONAL, + IN DWORD Flags OPTIONAL, + IN LPCWSTR FileName OPTIONAL, + IN BOOL NativePath, + IN LPWSTR MountPoint OPTIONAL); + + /** + This function removes (unmounts) an existing ImDisk virtual disk device. + + hWndStatusText A handle to a window that can display status message text. + The function will send WM_SETTEXT messages to this window. + If this parameter is NULL no WM_SETTEXT messages are sent + and the function acts non-interactive. + + DeviceNumber Number of the ImDisk device to remove. This parameter is + only used if MountPoint parameter is null. + + MountPoint Drive letter of the device to remove. It can be specified + on the form F: or F:\. + */ + IMDISK_API BOOL + WINAPI + ImDiskRemoveDevice(IN HWND hWndStatusText OPTIONAL, + IN DWORD DeviceNumber OPTIONAL, + IN LPCWSTR MountPoint OPTIONAL); + + /** + This function forcefully removes (unmounts) an existing ImDisk virtual disk + device. Any unsaved data will be lost. + + Device Handle to open device. If not NULL, it is used to query + device number to find out which device to remove. If this + parameter is NULL the DeviceNumber parameter is used + instead. + + DeviceNumber Number of the ImDisk device to remove. This parameter is + only used if Device parameter is NULL. + */ + IMDISK_API BOOL + WINAPI + ImDiskForceRemoveDevice(IN HANDLE Device OPTIONAL, + IN DWORD DeviceNumber OPTIONAL); + + /** + This function changes the device characteristics of an existing ImDisk + virtual disk device. + + hWndStatusText A handle to a window that can display status message text. + The function will send WM_SETTEXT messages to this window. + If this parameter is NULL no WM_SETTEXT messages are sent + and the function acts non-interactive. + + DeviceNumber Number of the ImDisk device to change. This parameter is + only used if MountPoint parameter is null. + + MountPoint Drive letter of the device to change. It can be specified + on the form F: or F:\. + + FlagsToChange A bit-field specifying which flags to edit. The flags are + the same as the option flags in the Flags parameter used + when a new virtual disk is created. Only flags set in this + parameter are changed to the corresponding flag value in the + Flags parameter. + + Flags New values for the flags specified by the FlagsToChange + parameter. + */ + IMDISK_API BOOL + WINAPI + ImDiskChangeFlags(HWND hWndStatusText OPTIONAL, + DWORD DeviceNumber OPTIONAL, + LPCWSTR MountPoint OPTIONAL, + DWORD FlagsToChange, + DWORD Flags); + + /** + This function extends the size of an existing ImDisk virtual disk device. + + hWndStatusText A handle to a window that can display status message text. + The function will send WM_SETTEXT messages to this window. + If this parameter is NULL no WM_SETTEXT messages are sent + and the function acts non-interactive. + + DeviceNumber Number of the ImDisk device to extend. + + ExtendSize A pointer to a LARGE_INTEGER structure that specifies the + number of bytes to extend the device. + */ + IMDISK_API BOOL + WINAPI + ImDiskExtendDevice(IN HWND hWndStatusText OPTIONAL, + IN DWORD DeviceNumber, + IN CONST PLARGE_INTEGER ExtendSize); + + /** + This function saves the contents of a device to an image file. + + DeviceHandle Handle to a device for which the contents are to be saved to + an image file. + + The handle must be opened for reading, may be + opened for sequential scan and/or without intermediate + buffering but cannot be opened for overlapped operation. + Please note that a call to this function will turn on + FSCTL_ALLOW_EXTENDED_DASD_IO on for this handle. + + FileHandle Handle to an image file opened for writing. The handle + can be opened for operation without intermediate buffering + but performance is usually better if the handle is opened + with intermediate buffering. The handle cannot be opened for + overlapped operation. + + BufferSize I/O buffer size to use when reading source disk. This + parameter is optional, if it is zero the buffer size to use + will automatically chosen. + + CancelFlag Optional pointer to a BOOL value. If this BOOL value is set + to TRUE during the function call the operation is cancelled, + the function returns FALSE and GetLastError will return + ERROR_CANCELLED. If this parameter is non-null the function + will also dispatch window messages for the current thread + between each I/O operation. + */ + IMDISK_API BOOL + WINAPI + ImDiskSaveImageFile(IN HANDLE DeviceHandle, + IN HANDLE FileHandle, + IN DWORD BufferSize OPTIONAL, + IN LPBOOL CancelFlag OPTIONAL); + + /** + This function gets the size of a disk volume. + + Handle Handle to a disk volume device. + + Size Pointer to a 64 bit variable that upon successful completion + receives disk volume size as a signed integer. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetVolumeSize(IN HANDLE Handle, + IN OUT PLONGLONG Size); + + /** + Reads formatted geometry for a volume by parsing BPB, BIOS Parameter Block, + from volume boot record into a DISK_GEOMETRY structure. + + If no boot record signature is found, this function returns FALSE. + + ImageFile Path to a volume image file or a device path to a disk volume, + such as \\.\A: or \\.\C:. + + Offset Optional offset in bytes to volume boot record within file for + use with "non-raw" volume image files. This parameter can be + used to for example skip over headers for specific disk image + formats, or to skip over master boot record in a disk image + file that contains a complete raw disk image and not only a + single volume. + + DiskGeometry Pointer to DISK_GEOMETRY structure that receives information + about formatted geometry. This function zeros the Cylinders + member. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetFormattedGeometry(IN LPCWSTR ImageFile, + IN PLARGE_INTEGER Offset OPTIONAL, + IN OUT PDISK_GEOMETRY DiskGeometry); + + /** + Reads formatted geometry for a volume by parsing BPB, BIOS Parameter Block, + from volume boot record into a DISK_GEOMETRY structure. + + If no boot record signature is found, this function returns FALSE. + + Handle Value that is passed as first parameter to ReadFileProc. + + ReadFileProc Procedure of type ImDiskReadFileProc that is called to read + disk volume. + + Offset Optional offset in bytes to volume boot record within file for + use with "non-raw" volume image files. This parameter can be + used to for example skip over headers for specific disk image + formats, or to skip over master boot record in a disk image + file that contains a complete raw disk image and not only a + single volume. + + DiskGeometry Pointer to DISK_GEOMETRY structure that receives information + about formatted geometry. This function zeros the Cylinders + member. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetFormattedGeometryIndirect(IN HANDLE Handle, + IN ImDiskReadFileProc ReadFileProc, + IN PLARGE_INTEGER Offset OPTIONAL, + IN OUT PDISK_GEOMETRY DiskGeometry); + + /** + This function builds a Master Boot Record, MBR, in memory. The MBR will + contain a default Initial Program Loader, IPL, which could be used to boot + an operating system partition when the MBR is written to a disk. + + DiskGeometry Pointer to a DISK_GEOMETRY or DISK_GEOMETRY_EX structure + that contains information about logical geometry of the + disk. + + This function only uses the BytesPerSector, SectorsPerTrack + and TracksPerCylinder members. + + This parameter can be NULL if NumberOfParts parameter is + zero. + + PartitionInfo Pointer to an array of up to four PARTITION_INFORMATION + structures containing information about partitions to store + in MBR partition table. + + This function only uses the StartingOffset, PartitionLength, + BootIndicator and PartitionType members. + + This parameter can be NULL if NumberOfParts parameter is + zero. + + NumberOfParts Number of PARTITION_INFORMATION structures in array that + PartitionInfo parameter points to. + + If this parameter is zero, DiskGeometry and PartitionInfo + parameters are ignored and can be NULL. In that case MBR + will contain an empty partition table when this function + returns. + + MBR Pointer to memory buffer of at least 512 bytes where MBR + will be built. + + MBRSize Size of buffer pointed to by MBR parameter. This parameter + must be at least 512. + */ + IMDISK_API BOOL + WINAPI + ImDiskBuildMBR(IN PDISK_GEOMETRY DiskGeometry OPTIONAL, + IN PPARTITION_INFORMATION PartitionInfo OPTIONAL, + IN BYTE NumberOfParts OPTIONAL, + IN OUT LPBYTE MBR, + IN DWORD_PTR MBRSize); + + /** + This function converts a CHS disk address to LBA format. + + DiskGeometry Pointer to a DISK_GEOMETRY or DISK_GEOMETRY_EX structure + that contains information about logical geometry of the + disk. This function only uses the SectorsPerTrack and + TracksPerCylinder members. + + CHS Pointer to CHS disk address in three-byte partition table + style format. + */ + IMDISK_API DWORD + WINAPI + ImDiskConvertCHSToLBA(IN PDISK_GEOMETRY DiskGeometry, + IN LPBYTE CHS); + + /** + This function converts an LBA disk address to three-byte partition style CHS + format. The three bytes are returned in the three lower bytes of a DWORD. + + DiskGeometry Pointer to a DISK_GEOMETRY or DISK_GEOMETRY_EX structure + that contains information about logical geometry of the + disk. This function only uses the SectorsPerTrack and + TracksPerCylinder members. + + LBA LBA disk address. + */ + IMDISK_API DWORD + WINAPI + ImDiskConvertLBAToCHS(IN PDISK_GEOMETRY DiskGeometry, + IN DWORD LBA); + + /** + This function adjusts size of a saved image file. If file size is less than + requested disk size, the size will be left unchanged with return value FALSE + and GetLastError will return ERROR_DISK_OPERATION_FAILED. + + FileHandle Handle to file where disk image has been saved. + + FileSize Size of original disk which image file should be adjusted + to. + */ + IMDISK_API BOOL + WINAPI + ImDiskAdjustImageFileSize(IN HANDLE FileHandle, + IN PLARGE_INTEGER FileSize); + + /** + This function converts a native NT-style path to a Win32 DOS-style path. The + path string is converted in-place and the start address is adjusted to skip + over native directories such as \??\. Because of this, the Path parameter is + a pointer to a pointer to a string so that the pointer can be adjusted to + the new start address. + + Path Pointer to pointer to Path string in native NT-style format. + Upon return the pointed address will contain the start + address of the Win32 DOS-style path within the original + buffer. + */ + IMDISK_API VOID + WINAPI + ImDiskNativePathToWin32(IN OUT LPWSTR *Path); + + /** + This function saves the contents of a device to an image file. This is a + user-interactive function that displays dialog boxes where user can select + image file and other options. + + DeviceHandle Handle to a device for which the contents are to be saved to + an image file. + + The handle must be opened for reading, may be + opened for sequential scan and/or without intermediate + buffering but cannot be opened for overlapped operation. + Please note that a call to this function will turn on + FSCTL_ALLOW_EXTENDED_DASD_IO on for this handle. + + WindowHandle Handle to existing window that will be parent to dialog + boxes etc. + + BufferSize I/O buffer size to use when reading source disk. This + parameter is optional, if it is zero the buffer size to use + will automatically chosen. + + IsCdRomType If this parameter is TRUE and the source device type cannot + be automatically determined this function will ask user for + a .iso suffixed image file name. + */ + IMDISK_API VOID + WINAPI + ImDiskSaveImageFileInteractive(IN HANDLE DeviceHandle, + IN HWND WindowHandle OPTIONAL, + IN DWORD BufferSize OPTIONAL, + IN BOOL IsCdRomType OPTIONAL); + + /* + Opens or creates a global synchronization event. This event is shared with + ImDisk driver and will be pulsed when an ImDisk device is created, removed + or have settings changed in some other way. + + This is particularly useful for user interface components that need to be + notified when device lists and similar need to be updated. + + If successful, this function returns a handle to an event that can be used + in call to system wait functions, such as WaitForSingleObject. When the + handle is not needed, it must be closed by calling CloseHandle. + + If the function fails, it returns NULL and GetLastError will return a + system error code that further explains the error. + + InheritHandle Specifies whether or not the returned handle will be + inherited by child processes. + + */ + IMDISK_API HANDLE + WINAPI + ImDiskOpenRefreshEvent(BOOL InheritHandle); + + /* + Adds registry settings for creating a virtual disk at system startup (or + when driver is loaded). + + This function returns TRUE if successful, FALSE otherwise. If FALSE is + returned, GetLastError could be used to get actual error code. + + CreateData Pointer to IMDISK_CREATE_DATA structure that contains + device creation settings to save. + + */ + IMDISK_API BOOL + WINAPI + ImDiskSaveRegistrySettings(PIMDISK_CREATE_DATA CreateData); + + /* + Remove registry settings for creating a virtual disk at system startup (or + when driver is loaded). + + This function returns TRUE if successful, FALSE otherwise. If FALSE is + returned, GetLastError could be used to get actual error code. + + DeviceNumber Device number specified in registry settings. + */ + IMDISK_API BOOL + WINAPI + ImDiskRemoveRegistrySettings(DWORD DeviceNumber); + + /* + Retrieves number of auto-loading devices at system startup, or when driver + is loaded. This is the value of the LoadDevices registry value for + imdisk.sys driver. + + This function returns TRUE if successful, FALSE otherwise. If FALSE is + returned, GetLastError could be used to get actual error code. + + LoadDevicesValue + Pointer to variable that receives the value. + */ + IMDISK_API BOOL + WINAPI + ImDiskGetRegistryAutoLoadDevices(LPDWORD LoadDevicesValue); + + /* + Notify Explorer and other shell components that a new drive letter has + been created. Called automatically by device creation after creating a + drive letter. If no drive letter was created by a device creation routine + or if API flags was set to turn off shell notification during device + creation, this function can be called manually later. + + Note that calling this function has no effect if API flags are set to + turn off shell notifications, or if supplied drive letter path does not + specify an A-Z drive letter. + + This function returns TRUE if successful, FALSE otherwise. If FALSE is + returned, GetLastError could be used to get actual error code. + + hWnd + Window handle to use as parent handle for any message boxes. If this + parameter is NULL, no message boxes are displayed. + + DriveLetterPath + Drive letter path in one of formats A:\ or A:. + */ + IMDISK_API BOOL + WINAPI + ImDiskNotifyShellDriveLetter(HWND hWnd, + LPWSTR DriveLetterPath); + + /* + Notify Explorer and other shell components that a drive is about to be + removed. + + hWnd + Window handle to use as parent handle for any message boxes. If this + parameter is NULL, no message boxes are displayed. + + DriveLetter + Drive letter. + */ + IMDISK_API BOOL + WINAPI + ImDiskNotifyRemovePending(HWND hWnd, + WCHAR DriveLetter); + + IMDISK_API LPWSTR + CDECL + ImDiskAllocPrintF(LPCWSTR lpMessage, ...); + + IMDISK_API int + WINAPI + ImDiskConsoleMessageA( + HWND hWnd, + LPCSTR lpText, + LPCSTR lpCaption, + UINT uType); + + IMDISK_API int + WINAPI + ImDiskConsoleMessageW( + HWND hWnd, + LPCWSTR lpText, + LPCWSTR lpCaption, + UINT uType); + +#ifdef CORE_BUILD + +#ifdef CharToOemA +#undef CharToOemA +#endif + +#define CharToOemA(s,t) + +#ifdef MessageBoxA +#undef MessageBoxA +#endif +#ifdef MessageBoxW +#undef MessageBoxW +#endif +#ifdef SetWindowTextA +#undef SetWindowTextA +#endif +#ifdef SetWindowTextW +#undef SetWindowTextW +#endif + +#define MessageBoxA ImDiskConsoleMessageA +#define MessageBoxW ImDiskConsoleMessageW + +#define SetWindowTextA(h,t) ImDiskConsoleMessageA(h,t,"",0) +#define SetWindowTextW(h,t) ImDiskConsoleMessageW(h,t,L"",0) + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif + +#endif // _INC_IMDISK_ diff --git a/SandboxieTools/ImDisk/inc/imdiskver.h b/SandboxieTools/ImDisk/inc/imdiskver.h new file mode 100644 index 00000000..0c12331f --- /dev/null +++ b/SandboxieTools/ImDisk/inc/imdiskver.h @@ -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 diff --git a/SandboxieTools/ImDisk/inc/imdproxy.h b/SandboxieTools/ImDisk/inc/imdproxy.h new file mode 100644 index 00000000..71211117 --- /dev/null +++ b/SandboxieTools/ImDisk/inc/imdproxy.h @@ -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_ diff --git a/SandboxieTools/ImDisk/inc/ntkmapi.h b/SandboxieTools/ImDisk/inc/ntkmapi.h new file mode 100644 index 00000000..763af249 --- /dev/null +++ b/SandboxieTools/ImDisk/inc/ntkmapi.h @@ -0,0 +1,427 @@ +#ifndef VER_PRODUCTBUILD +#include +#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 diff --git a/SandboxieTools/ImDisk/inc/ntumapi.h b/SandboxieTools/ImDisk/inc/ntumapi.h new file mode 100644 index 00000000..2bc9722f --- /dev/null +++ b/SandboxieTools/ImDisk/inc/ntumapi.h @@ -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 +// . +// 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 diff --git a/SandboxieTools/ImDisk/inc/wio.hpp b/SandboxieTools/ImDisk/inc/wio.hpp new file mode 100644 index 00000000..aeb61572 --- /dev/null +++ b/SandboxieTools/ImDisk/inc/wio.hpp @@ -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 diff --git a/SandboxieTools/ImDisk/inc/wkmem.hpp b/SandboxieTools/ImDisk/inc/wkmem.hpp new file mode 100644 index 00000000..080e3320 --- /dev/null +++ b/SandboxieTools/ImDisk/inc/wkmem.hpp @@ -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 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 TC* GetPtr() + { + return (TC*)(void*)ptr; + } + + template 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 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 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 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(); + } +}; + diff --git a/SandboxieTools/ImDisk/inc/wmem.hpp b/SandboxieTools/ImDisk/inc/wmem.hpp new file mode 100644 index 00000000..86821d9b --- /dev/null +++ b/SandboxieTools/ImDisk/inc/wmem.hpp @@ -0,0 +1,362 @@ +#include + +/* +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 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 +{ +public: + WEnvironmentStrings() + : WMemHolder(GetEnvironmentStrings()) + { + } + + BOOL Free() + { + if (ptr != NULL) + { + return FreeEnvironmentStrings(ptr); + } + else + { + return TRUE; + } + } + + ~WEnvironmentStrings() + { + Free(); + } +}; + +template class WMem : public WMemHolder +{ +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(LocalAlloc(LPTR, dwAllocSize)) + { + } + + explicit WMem(T *pBlk) + : WMemHolder(pBlk) + { + } + + ~WMem() + { + Free(); + } +}; + +#ifdef _INC_MALLOC +template class WCRTMem : public WMemHolder +{ +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*)malloc(dwAllocSize)) { } + + explicit WCRTMem(T *pBlk) + : WMemHolder(pBlk) { } + + ~WCRTMem() + { + Free(); + } +}; +#endif + +template class WHeapMem :public WMemHolder +{ +public: + T* operator =(T *pBlk) + { + Free(); + return ptr = pBlk; + } + + WHeapMem & operator =(WHeapMem &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*)HeapAlloc(GetProcessHeap(), dwFlags, dwAllocSize)) + { + } + + explicit WHeapMem(T *pBlk) + : WMemHolder(pBlk) + { + } + + ~WHeapMem() + { + Free(); + } +}; +