{
------------------------------------------------------------------
            IOCTL Header Port for Delphi
------------------------------------------------------------------
Based upon Microsoft's IOCTL header file in C &
DEC's Modula (yes, Modula!) interface port.

Copyright (c) 1999 Daniel Polistchuck - QualTech IT
------------------------------------------------------------------
This source code is freeware, feel free to use it as
you wish - either commercially or not. The author shall
not be held responsible for any damage made by the use
or misuse of this software material.

Please, if any changes or corrections are made, send
me a copy at danpol@pobox.com.
------------------------------------------------------------------
Observations:
Most DeviceIOControl Functions on Fixed or Logical drives
work only with Windows NT. Part of the functionality
conatined here is also available to Win95/98 through
the use of the function Win95IOCtl provided in this unit.

At least in Windows 98, the INT 21, Subfunction 440Dh
examples provided by Microsoft's SDK Help file that
comes with Delphi may cause the appearance of
the dreaded "blue screen". Instead of directly coding
in assembly, the developer should use the Win95IOCTL function
provided here.

Good Luck!
P.S. The SDK Examples may be found by creating an index on
the Windows API help files and searching for the 440D Keyword.
------------------------------------------------------------------
Version history:
v1.1 - Corrected error checking in Win95IOCtl
v1.0 - Added Win95IOCtl. (first public release)
v0.9 - Initial port (private)

}

unit WinIOCtl;
interface
uses
  Windows;

const
  VWIN32_DIOC_DOS_IOCTL = 1;

type
  PDEVIOCTL_REGISTERS=^DEVIOCTL_REGISTERS;
  DEVIOCTL_REGISTERS = packed Record
    reg_EBX,
    reg_EDX,
    reg_ECX,
    reg_EAX,
    reg_EDI,
    reg_ESI,
    reg_Flags : DWORD
  end;

//Win95 IOCTL  
function Win95IOCTL(preg : PDEVIOCTL_REGISTERS): Boolean;  

TYPE
  DEVICE_TYPE = DWORD;

CONST
  FILE_DEVICE_BEEP                = $00000001;
  FILE_DEVICE_CD_ROM              = $00000002;
  FILE_DEVICE_CD_ROM_FILE_SYSTEM  = $00000003;
  FILE_DEVICE_CONTROLLER          = $00000004;
  FILE_DEVICE_DATALINK            = $00000005;
  FILE_DEVICE_DFS                 = $00000006;
  FILE_DEVICE_DISK                = $00000007;
  FILE_DEVICE_DISK_FILE_SYSTEM    = $00000008;
  FILE_DEVICE_FILE_SYSTEM         = $00000009;
  FILE_DEVICE_INPORT_PORT         = $0000000A;
  FILE_DEVICE_KEYBOARD            = $0000000B;
  FILE_DEVICE_MAILSLOT            = $0000000C;
  FILE_DEVICE_MIDI_IN             = $0000000D;
  FILE_DEVICE_MIDI_OUT            = $0000000E;
  FILE_DEVICE_MOUSE               = $0000000F;
  FILE_DEVICE_MULTI_UNC_PROVIDER  = $00000010;
  FILE_DEVICE_NAMED_PIPE          = $00000011;
  FILE_DEVICE_NETWORK             = $00000012;
  FILE_DEVICE_NETWORK_BROWSER     = $00000013;
  FILE_DEVICE_NETWORK_FILE_SYSTEM = $00000014;
  FILE_DEVICE_NULL                = $00000015;
  FILE_DEVICE_PARALLEL_PORT       = $00000016;
  FILE_DEVICE_PHYSICAL_NETCARD    = $00000017;
  FILE_DEVICE_PRINTER             = $00000018;
  FILE_DEVICE_SCANNER             = $00000019;
  FILE_DEVICE_SERIAL_MOUSE_PORT   = $0000001A;
  FILE_DEVICE_SERIAL_PORT         = $0000001B;
  FILE_DEVICE_SCREEN              = $0000001C;
  FILE_DEVICE_SOUND               = $0000001D;
  FILE_DEVICE_STREAMS             = $0000001E;
  FILE_DEVICE_TAPE                = $0000001F;
  FILE_DEVICE_TAPE_FILE_SYSTEM    = $00000020;
  FILE_DEVICE_TRANSPORT           = $00000021;
  FILE_DEVICE_UNKNOWN             = $00000022;
  FILE_DEVICE_VIDEO               = $00000023;
  FILE_DEVICE_VIRTUAL_DISK        = $00000024;
  FILE_DEVICE_WAVE_IN             = $00000025;
  FILE_DEVICE_WAVE_OUT            = $00000026;
  FILE_DEVICE_8042_PORT           = $00000027;
  FILE_DEVICE_NETWORK_REDIRECTOR  = $00000028;
  FILE_DEVICE_BATTERY             = $00000029;
  FILE_DEVICE_BUS_EXTENDER        = $0000002A;
{
   Macro definition for defining IOCTL and FSCTL function control
   codes. Note that function codes 0-2047 are reserved for Microsoft
   Corporation, and 2048-4095 are reserved for customers.
}


CONST
  IOCTL_USER_CODES = $0800;
{ Define the method codes for how buffers are passed for I/O and FS
   controls}
CONST
  METHOD_BUFFERED    = 0;
  METHOD_IN_DIRECT   = 1;
  METHOD_OUT_DIRECT  = 2;
  METHOD_NEITHER     = 3;

{Define the access check value for any access}

CONST
  FILE_ANY_ACCESS   = 0;
  FILE_READ_ACCESS  = 1;    (* file & pipe *)
  FILE_WRITE_ACCESS = 2;    (* file & pipe *)

  FILE_READ_DATA    = FILE_READ_ACCESS;
  FILE_WRITE_DATA   = FILE_WRITE_ACCESS;

{IoControlCodevalues for disk devices.}
CONST
  IOCTL_DISK_BASE                = FILE_DEVICE_DISK;
function IOCTL_DISK_GET_DRIVE_GEOMETRY  : DWORD;

function IOCTL_DISK_GET_PARTITION_INFO  : DWORD;

function IOCTL_DISK_SET_PARTITION_INFO  : DWORD;

function IOCTL_DISK_GET_DRIVE_LAYOUT    : DWORD;

function IOCTL_DISK_SET_DRIVE_LAYOUT    : DWORD;

function IOCTL_DISK_VERIFY              : DWORD;

function IOCTL_DISK_FORMAT_TRACKS       : DWORD;

function IOCTL_DISK_REASSIGN_BLOCKS     : DWORD;

function IOCTL_DISK_PERFORMANCE         : DWORD;

function IOCTL_DISK_IS_WRITABLE         : DWORD;

function IOCTL_DISK_LOGGING             : DWORD;

function IOCTL_DISK_FORMAT_TRACKS_EX    : DWORD;

function IOCTL_DISK_HISTOGRAM_STRUCTURE : DWORD;

function IOCTL_DISK_HISTOGRAM_DATA      : DWORD;

function IOCTL_DISK_HISTOGRAM_RESET     : DWORD;

function IOCTL_DISK_REQUEST_STRUCTURE   : DWORD;

function IOCTL_DISK_REQUEST_DATA        : DWORD;

{ The following device control codes are common for all class
   drivers. The functions codes defined here must match all of the
   other class drivers.}

function IOCTL_DISK_CHECK_VERIFY     : DWORD;

function IOCTL_DISK_MEDIA_REMOVAL    : DWORD;

function IOCTL_DISK_EJECT_MEDIA      : DWORD;

function IOCTL_DISK_LOAD_MEDIA       : DWORD;

function IOCTL_DISK_RESERVE          : DWORD;

function IOCTL_DISK_RELEASE          : DWORD;

function IOCTL_DISK_FIND_NEW_DEVICES : DWORD;

function IOCTL_DISK_REMOVE_DEVICE    : DWORD;

function IOCTL_DISK_GET_MEDIA_TYPES  : DWORD;

{Define the partition types returnable by known disk drivers.}

CONST
  PARTITION_ENTRY_UNUSED = $00; (* Entry unused *)
  PARTITION_FAT_12       = $01; (* 12-bit FAT entries *)
  PARTITION_XENIX_1      = $02; (* Xenix *)
  PARTITION_XENIX_2      = $03; (* Xenix *)
  PARTITION_FAT_16       = $04; (* 16-bit FAT entries *)
  PARTITION_EXTENDED     = $05; (* Extended partition entry *)
  PARTITION_HUGE         = $06; (* Huge partition MS-DOS V4 *)
  PARTITION_IFS          = $07; (* IFS Partition *)
  PARTITION_PREP         = $41; (* PowerPC Ref. Platform Boot Partition *)
  PARTITION_UNIX         = $63; (* Unix *)
  VALID_NTFT             = $C0; (* NTFT uses high order bits *)
{The high bit of the partition type code indicates that a partition
   is part of an NTFT mirror or striped array.}

CONST PARTITION_NTFT     = $80; (* NTFT partition *)
{Define the media types supported by the driver.}

TYPE
  PMEDIA_TYPE = ^MEDIA_TYPE;
  MEDIA_TYPE = (
    Unknown,                (* Format is unknown *)
    F5_1Pt2_512,            (* 5.25&quot;, 1.2MB,  512 bytes/sector *)
    F3_1Pt44_512,           (* 3.5&quot;,  1.44MB, 512 bytes/sector *)
    F3_2Pt88_512,           (* 3.5&quot;,  2.88MB, 512 bytes/sector *)
    F3_20Pt8_512,           (* 3.5&quot;,  20.8MB, 512 bytes/sector *)
    F3_720_512,             (* 3.5&quot;,  720KB,  512 bytes/sector *)
    F5_360_512,             (* 5.25&quot;, 360KB,  512 bytes/sector *)
    F5_320_512,             (* 5.25&quot;, 320KB,  512 bytes/sector *)
    F5_320_1024,            (* 5.25&quot;, 320KB,  1024 bytes/sector *)
    F5_180_512,             (* 5.25&quot;, 180KB,  512 bytes/sector *)
    F5_160_512,             (* 5.25&quot;, 160KB,  512 bytes/sector *)
    RemovableMedia,         (* Removable media other than floppy *)
    FixedMedia              (* Fixed hard disk media *)
  );
{ Define the input buffer structure for the driver, when
   it is called with IOCTL_DISK_FORMAT_TRACKS.}

TYPE
  PFORMAT_PARAMETERS = ^FORMAT_PARAMETERS;
  FORMAT_PARAMETERS = RECORD
    MediaType: MEDIA_TYPE;
    StartCylinderNumber: DWORD;
    EndCylinderNumber: DWORD;
    StartHeadNumber: DWORD;
    EndHeadNumber: DWORD;
  END;
{ Define the BAD_TRACK_NUMBER type. An array of elements of this type is
   returned by the driver on IOCTL_DISK_FORMAT_TRACKS requests, to indicate
   what tracks were bad during formatting. The length of that array is
   reported in the `Information' field of the I/O Status Block.}

TYPE
  BAD_TRACK_NUMBER = WORD;
  PBAD_TRACK_NUMBER = ^BAD_TRACK_NUMBER;
{ Define the input buffer structure for the driver, when
   it is called with IOCTL_DISK_FORMAT_TRACKS_EX<.}

TYPE
  PFORMAT_EX_PARAMETERS = ^FORMAT_EX_PARAMETERS;
  FORMAT_EX_PARAMETERS = RECORD
    MediaType : MEDIA_TYPE;
    StartCylinderNumber: DWORD;
    EndCylinderNumber: DWORD;
    StartHeadNumber: DWORD;
    EndHeadNumber: DWORD;
    FormatGapLength: WORD;
    SectorsPerTrack: WORD;
    SectorNumber: ARRAY [0..0] OF WORD;
  END;
{ The following structure is returned on an <CODE>IOCTL_DISK_GET_DRIVE_GEOMETRY</CODE>
   request and an array of them is returned on an <CODE>IOCTL_DISK_GET_MEDIA_TYPES</CODE>
   request.}

TYPE
  PDISK_GEOMETRY = ^DISK_GEOMETRY;
  DISK_GEOMETRY = RECORD
    Cylinders: TLARGEINTEGER;
    MediaType: MEDIA_TYPE;
    TracksPerCylinder: DWORD;
    SectorsPerTrack  : DWORD;
    BytesPerSector   : DWORD;
  END;
{ The following structure is returned on an <CODE>IOCTL_DISK_GET_PARTITION_INFO</CODE>
   and an <CODE>IOCTL_DISK_GET_DRIVE_LAYOUT</CODE> request.  It is also used in a request
   to change the drive layout, <CODE>IOCTL_DISK_SET_DRIVE_LAYOUT</CODE>.}

TYPE
  PPARTITION_INFORMATION = ^PARTITION_INFORMATION;
  PARTITION_INFORMATION = RECORD
    StartingOffset: TLargeInteger;
    PartitionLength: TLargeInteger;
    HiddenSectors: DWORD;
    PartitionNumber: DWORD;
    PartitionType: BYTE;
    BootIndicator: WordBool;
    RecognizedPartition: WordBool;
    RewritePartition: WordBool;
  END;
{ The following structure is used to change the partition type of a
   specified disk partition using an <CODE>IOCTL_DISK_SET_PARTITION_INFO</CODE>
   request.}

TYPE
  PSET_PARTITION_INFORMATION = ^SET_PARTITION_INFORMATION;
  SET_PARTITION_INFORMATION = RECORD
    PartitionType: BYTE;
  END;
{ The following structures is returned on an <CODE>IOCTL_DISK_GET_DRIVE_LAYOUT</CODE>
   request and given as input to an <CODE>IOCTL_DISK_SET_DRIVE_LAYOUT</CODE> request.}

TYPE
  PDRIVE_LAYOUT_INFORMATION = ^DRIVE_LAYOUT_INFORMATION;
  DRIVE_LAYOUT_INFORMATION = RECORD
    PartitionCount: DWORD;
    Signature: DWORD;
    PartitionEntry: ARRAY [0..0] OF PARTITION_INFORMATION;
  END;
{ The following structure is passed in on an <CODE>IOCTL_DISK_VERIFY</CODE> request.
   The offset and length parameters are both given in bytes.}

TYPE
  PVERIFY_INFORMATION = ^VERIFY_INFORMATION;
  VERIFY_INFORMATION = RECORD
    StartingOffset: TLargeInteger;
    Length: DWORD;
  END;
{ The following structure is passed in on an <CODE>IOCTL_DISK_REASSIGN_BLOCKS</CODE>
   request.}

TYPE
  PREASSIGN_BLOCKS = ^REASSIGN_BLOCKS;
  REASSIGN_BLOCKS = RECORD
    Reserved: WORD;
    Count: WORD;
    BlockNumber: ARRAY [0..0] OF DWORD;
  END;
{ <CODE>IOCTL_DISK_MEDIA_REMOVAL</CODE> disables the mechanism on a SCSI device
   that ejects media. This function may or may not be supported on
   SCSI devices that support removable media. <CODE>PreventMediaRemove</CODE>
   is <CODE>TRUE</CODE> if and only if media should be prevented from being
   removed.}

TYPE
  PPREVENT_MEDIA_REMOVAL = ^PREVENT_MEDIA_REMOVAL;
  PREVENT_MEDIA_REMOVAL = RECORD
    PreventMediaRemoval: WordBool;
  END;
{ The following structures define disk performance statistics:
   specifically the locations of all the reads and writes which have
   occured on the disk.

   To use these structures, you must issue an <CODE>IOCTL_DISK_HIST_STRUCTURE</CODE>
   (with a <CODE>DISK_HISTOGRAM</CODE>) to obtain the basic histogram information.
   The number of buckets which must allocated is part of this structure.
   Allocate the required number of buckets and call an <CODE>IOCTL_DISK_HIST_DATA</CODE>
   to fill in the data.}

CONST HIST_NO_OF_BUCKETS  = 24;

TYPE
  PHISTOGRAM_BUCKET = ^HISTOGRAM_BUCKET;
  HISTOGRAM_BUCKET = RECORD
    Reads : DWORD;
    Writes: DWORD;
  END;

CONST HISTOGRAM_BUCKET_SIZE = Sizeof(HISTOGRAM_BUCKET);

TYPE
  PDISK_HISTOGRAM = ^DISK_HISTOGRAM;
  DISK_HISTOGRAM = RECORD
    DiskSize: TLargeInteger;
    Start: TLargeInteger;
    _End: TLargeInteger;
    Average: TLargeInteger;
    AverageRead: TLargeInteger;
    AverageWrite: TLargeInteger;
    Granularity: DWORD;
    Size: DWORD;
    ReadCount: DWORD;
    WriteCount: DWORD;
    Histogram: PHISTOGRAM_BUCKET;
  END;

CONST DISK_HISTOGRAM_SIZE = Sizeof(DISK_HISTOGRAM);
{ The following structures define disk debugging capabilities. The
   IOCTLs are directed to one of the two disk filter drivers.
<P>
   <CODE>DISKPERF</CODE> is a utilty for collecting disk request statistics.
<P>
   <CODE>SIMBAD</CODE> is a utility for injecting faults in IO requests to disks.

<P> The following structure is exchanged on an <CODE>IOCTL_DISK_GET_PERFORMANCE</CODE>
   request. This ioctl collects summary disk request statistics used in
   measuring performance.}

TYPE
  PDISK_PERFORMANCE = ^DISK_PERFORMANCE;
  DISK_PERFORMANCE = RECORD
    BytesRead: TLargeInteger;
    BytesWritten: TLargeInteger;
    ReadTime: TLargeInteger;
    WriteTime: TLargeInteger;
    ReadCount: DWORD;
    WriteCount: DWORD;
    QueueDepth: DWORD;
  END;
{ This structure defines the disk logging record. When disk logging
   is enabled, one of these is written to an internal buffer for each
   disk request.}

TYPE
  PDISK_RECORD = ^DISK_RECORD;
  DISK_RECORD = RECORD
   ByteOffset: TLargeInteger;
   StartTime: TLargeInteger;
   EndTime: TLargeInteger;
   VirtualAddress: Pointer;
   NumberOfBytes: DWORD;
   DeviceNumber: BYTE;
   ReadRequest: WordBool;
  END;
{ The following structure is exchanged on an <CODE>IOCTL_DISK_LOG</CODE> request.
   Not all fields are valid with each function type.}

TYPE
  PDISK_LOGGING = ^DISK_LOGGING;
  DISK_LOGGING = RECORD
    _Function: BYTE;
    BufferAddress: Pointer;
    BufferSize: DWORD;
  END;
{ Disk logging functions

<P> Start disk logging. Only the <CODE>Function</CODE> and <CODE>BufferSize</CODE> fields are
valid.}
CONST DISK_LOGGING_START   = 0;
// Stop disk logging. Only the <CODE>Function</CODE> field is valid.
CONST DISK_LOGGING_STOP    = 1;
{ Return disk log. All fields are valid. Data will be copied from
   internal buffer to buffer specified for the number of bytes requested.}
CONST DISK_LOGGING_DUMP    = 2;
{ DISK BINNING
<P>
   <CODE>DISKPERF</CODE> will keep counters for IO that falls in each of these ranges.
   The application determines the number and size of the ranges. Joe Lin
   wanted me to keep it flexible as possible, for instance, IO sizes are
   interesting in ranges like 0-4096, 4097-16384, 16385-65536, 65537+.}

CONST DISK_BINNING        = 3;
// Bin types
TYPE BIN_TYPES = ( RequestSize, RequestLocation );
// Bin ranges
TYPE
  PBIN_RANGE = ^BIN_RANGE;
  BIN_RANGE = RECORD
    StartValue: TLargeInteger;
    Length: TLargeInteger;
  END;
// Bin definition
TYPE
  PPERF_BIN = ^PERF_BIN;
  PERF_BIN = RECORD
    NumberOfBins: DWORD;
    TypeOfBin: DWORD;
    BinsRanges: ARRAY [0..0] OF BIN_RANGE;
  END;
// Bin count
TYPE
  PBIN_COUNT = ^BIN_COUNT;
  BIN_COUNT = RECORD
    BinRange: BIN_RANGE;
    BinCount: DWORD;
  END;
// Bin results
TYPE
  PBIN_RESULTS = ^BIN_RESULTS;
  BIN_RESULTS = RECORD
    NumberOfBins: DWORD;
    BinCounts: ARRAY[0..0] OF BIN_COUNT;
  END;


function IOCTL_SERIAL_LSRMST_INSERT  : DWORD;

{ The following values follow the escape designator in the
   data stream if the <CODE>LSRMST_INSERT</CODE> mode has been turned on.}

CONST SERIAL_LSRMST_ESCAPE     : BYTE = 0;
{ Following this value is the contents of the line status
   register, and then the character in the RX hardware when
   the line status register was encountered.}

CONST SERIAL_LSRMST_LSR_DATA   : BYTE = 1;
{ Following this value is the contents of the line status
   register.  No error character follows.}

CONST SERIAL_LSRMST_LSR_NODATA : BYTE = 2;
{ Following this value is the contents of the modem status
   register.}

CONST
  SERIAL_LSRMST_MST : BYTE = 3;

function FSCTL_LOCK_VOLUME       : DWORD;

function FSCTL_UNLOCK_VOLUME     : DWORD;

function FSCTL_DISMOUNT_VOLUME   : DWORD;

function FSCTL_MOUNT_DBLS_VOLUME : DWORD;

function FSCTL_GET_COMPRESSION   : DWORD;

function FSCTL_SET_COMPRESSION   : DWORD;

function FSCTL_READ_COMPRESSION  : DWORD;

function FSCTL_WRITE_COMPRESSION : DWORD;


function CTL_CODE (DeviceType, Func, Method, Access : DWORD ) : DWORD;

implementation

function Win95IOCTL(preg : PDEVIOCTL_REGISTERS): Boolean;
var
  hDevice : THandle;
  fResult : Boolean;
  cb : DWORD;
begin
    preg^.reg_Flags := $8000; //* assume error (carry flag set) */

    hDevice := CreateFile('\\.\vwin32',
        GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
        nil, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL, 0);

    if (hDevice =INVALID_HANDLE_VALUE) then
    begin
        Result := FALSE;
        Exit;
    end
    else
    begin
        fResult := DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL,
            preg, sizeof(preg^), preg, sizeof(preg^), cb, nil);

        if (not fResult) then
        begin
            result := FALSE;
            Exit;
        end;
    end;

    CloseHandle(hDevice);

    Result :=  TRUE;
end;

function CTL_CODE (DeviceType, Func, Method, Access : DWORD ) : DWORD;
begin
 Result := (((DeviceType) shl 16) or ((Access) shl 14) or ((Func) shl 2) or
         (Method));
end;

  function IOCTL_DISK_GET_DRIVE_GEOMETRY  : DWORD;
  begin
    Result := CTL_CODE(
    IOCTL_DISK_BASE, $0000,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function IOCTL_DISK_GET_PARTITION_INFO  : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0001,
    METHOD_BUFFERED, FILE_READ_ACCESS );
  end;

  function IOCTL_DISK_SET_PARTITION_INFO  : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0002,
    METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS );
  end;

  function IOCTL_DISK_GET_DRIVE_LAYOUT    : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0003,
    METHOD_BUFFERED, FILE_READ_ACCESS );
  end;

  function IOCTL_DISK_SET_DRIVE_LAYOUT    : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0004,
    METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS );
  end;

  function IOCTL_DISK_VERIFY              : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0005,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function IOCTL_DISK_FORMAT_TRACKS       : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0006,
    METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS );
  end;

  function IOCTL_DISK_REASSIGN_BLOCKS     : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0007,
    METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS );
  end;

  function IOCTL_DISK_PERFORMANCE         : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0008,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function IOCTL_DISK_IS_WRITABLE         : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0009,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function IOCTL_DISK_LOGGING             : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $000A,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function IOCTL_DISK_FORMAT_TRACKS_EX    : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $000B,
    METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS );
  end;

  function IOCTL_DISK_HISTOGRAM_STRUCTURE : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $000C,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function IOCTL_DISK_HISTOGRAM_DATA      : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $000D,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function IOCTL_DISK_HISTOGRAM_RESET     : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $000E,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function IOCTL_DISK_REQUEST_STRUCTURE   : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $000F,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function IOCTL_DISK_REQUEST_DATA        : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0010,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

{ The following device control codes are common for all class
   drivers. The functions codes defined here must match all of the
   other class drivers.}

  function IOCTL_DISK_CHECK_VERIFY     : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0200,
    METHOD_BUFFERED, FILE_READ_ACCESS );
  end;

  function IOCTL_DISK_MEDIA_REMOVAL    : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0201,
    METHOD_BUFFERED, FILE_READ_ACCESS );
  end;

  function IOCTL_DISK_EJECT_MEDIA      : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0202,
    METHOD_BUFFERED, FILE_READ_ACCESS );
  end;

  function IOCTL_DISK_LOAD_MEDIA       : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0203,
    METHOD_BUFFERED, FILE_READ_ACCESS );
  end;

  function IOCTL_DISK_RESERVE          : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0204,
    METHOD_BUFFERED, FILE_READ_ACCESS );
  end;

  function IOCTL_DISK_RELEASE          : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0205,
    METHOD_BUFFERED, FILE_READ_ACCESS );
  end;

  function IOCTL_DISK_FIND_NEW_DEVICES : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0206,
    METHOD_BUFFERED, FILE_READ_ACCESS );
  end;

  function IOCTL_DISK_REMOVE_DEVICE    : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0207,
    METHOD_BUFFERED, FILE_READ_ACCESS );
  end;

  function IOCTL_DISK_GET_MEDIA_TYPES  : DWORD;
  begin
    Result :=  CTL_CODE(
    IOCTL_DISK_BASE, $0300,
    METHOD_BUFFERED, FILE_ANY_ACCESS  );
  end;




function IOCTL_SERIAL_LSRMST_INSERT  : DWORD;
begin
  Result := CTL_CODE(
    FILE_DEVICE_SERIAL_PORT, 31,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
end;

  function FSCTL_LOCK_VOLUME: DWORD;
  begin
    Result :=  CTL_CODE(
    FILE_DEVICE_FILE_SYSTEM, 6,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;
  
  function FSCTL_UNLOCK_VOLUME     : DWORD;
  begin
    Result :=  CTL_CODE(
    FILE_DEVICE_FILE_SYSTEM,  7,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function FSCTL_DISMOUNT_VOLUME   : DWORD;
  begin
    Result :=  CTL_CODE(
    FILE_DEVICE_FILE_SYSTEM,  8,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function FSCTL_MOUNT_DBLS_VOLUME : DWORD;
  begin
    Result :=  CTL_CODE(
    FILE_DEVICE_FILE_SYSTEM, 13,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function FSCTL_GET_COMPRESSION   : DWORD;
  begin
    Result :=  CTL_CODE(
    FILE_DEVICE_FILE_SYSTEM, 15,
    METHOD_BUFFERED, FILE_ANY_ACCESS );
  end;

  function FSCTL_SET_COMPRESSION   : DWORD;
  begin
    Result :=  CTL_CODE(
    FILE_DEVICE_FILE_SYSTEM, 16,
    METHOD_BUFFERED, FILE_READ_DATA + FILE_WRITE_DATA );
  end;

  function FSCTL_READ_COMPRESSION  : DWORD;
  begin
    Result :=  CTL_CODE(
    FILE_DEVICE_FILE_SYSTEM, 17,
    METHOD_NEITHER,  FILE_READ_DATA  );
  end;

  function FSCTL_WRITE_COMPRESSION : DWORD;
  begin
    Result :=  CTL_CODE(
    FILE_DEVICE_FILE_SYSTEM, 18,
    METHOD_NEITHER,  FILE_WRITE_DATA );
  end;


END.


