Programmierung > Delphi > I/O Control Codes

I/O Control Code

  • Beschreibung
  • Definition der I/O Control Codes
  • Macro
  • DeviceType
  • Function
  • Method (Transfer Type)
  • Access
  • Links
  • Beschreibung

    Mit der Funktion DeviceIoControl kann man seit Windows XP auf Windowssystemfunktionen zugreifen. Dafür wird ein I/O Control Code (dwIoControlCode) benötigt, welcher mit einem Makro aus verschiedenen Konstanten erstellt wird. Die Konstanten sind in verschiedenen Headerdateien definiert.

    BOOL WINAPI DeviceIoControl(
      _In_        HANDLE       hDevice,
      _In_        DWORD        dwIoControlCode,
      _In_opt_    LPVOID       lpInBuffer,
      _In_        DWORD        nInBufferSize,
      _Out_opt_   LPVOID       lpOutBuffer,
      _In_        DWORD        nOutBufferSize,
      _Out_opt_   LPDWORD      lpBytesReturned,
      _Inout_opt_ LPOVERLAPPED lpOverlapped
    );
    

    Definition der I/O Control Codes

    Der Control Code ist vom Typ DWord und vier Byte beziehungsweise 32 Bit lang. Die Bestandteile sind:

    Als Liste:

    • 16 Bit: Common-Bit und Device Type
    • 2 Bit: Required Access
    • 12 Bit: Custom-Bit und Function Code
    • 2 Bit: Transfer Type

    Als Schema:

     76543210
    0CommonDevice Type
    1noch Device Type
    2Required AccessCustomFunction Code
    3noch Function CodeTransfer Type

    Macro

    In C bzw. C++ werden die entsprechenden I/O Control Codes so definiert:

    #define IOCTL_Device_Function CTL_CODE(DeviceType, Function, Method, Access)
    

    Das Macro ist in verschiedenen Headerdateien definiert. Zum Beispiel windev.h, ntddk.h oder wdm.h.

    #define CTL_CODE(DeviceType, Function, Method, Access) \
      (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
    

    In Delphi gibt es diese Makros nicht, deshalb werden die Werte ermittelt und die Konstanten damit definert oder die Kontanten als Formel definiert. Das sieht dann so aus:

    const
      IOCTL_Device_Function =
        ((DeviceType shl 16) or (Access shl 14) or (Function shl 2) or Method);
    

    Die Werte für die Konstanten muss man sich aus den Headerdateien, zum Beispiel windev.h, ntddk.h oder wdm.h heraussuchen. Die Headerdateien muss man sich jedoch auch meist aus dem Internet herausfischen.

    DeviceType

    Dieser Wert bestimmt den Gerätetyp. Der Wertebereich unter $8000 (32767) ist für Microsoft reserviert. Dies ist der Bereich, in welchem das Common-Bit nicht gesetzt ist. Der Wertebereich darüber darf von Erstausrüstern (Original Equipment Manufacturer - OEM) und unabhängigen Hardwareherstellern (Independent Hardware Vendor - IHV) genutzt werden.

    In Hardware Dev Center von Microsoft sind mit Stand vom 2017-6-16 folgende Geräte definiert:

    #define FILE_DEVICE_8042_PORT           0x00000027
    #define FILE_DEVICE_ACPI                0x00000032
    #define FILE_DEVICE_BATTERY             0x00000029
    #define FILE_DEVICE_BEEP                0x00000001
    #define FILE_DEVICE_BUS_EXTENDER        0x0000002a
    #define FILE_DEVICE_CD_ROM              0x00000002
    #define FILE_DEVICE_CD_ROM_FILE_SYSTEM  0x00000003
    #define FILE_DEVICE_CHANGER             0x00000030
    #define FILE_DEVICE_CONTROLLER          0x00000004
    #define FILE_DEVICE_DATALINK            0x00000005
    #define FILE_DEVICE_DFS                 0x00000006
    #define FILE_DEVICE_DFS_FILE_SYSTEM     0x00000035
    #define FILE_DEVICE_DFS_VOLUME          0x00000036
    #define FILE_DEVICE_DISK                0x00000007
    #define FILE_DEVICE_DISK_FILE_SYSTEM    0x00000008
    #define FILE_DEVICE_DVD                 0x00000033
    #define FILE_DEVICE_FILE_SYSTEM         0x00000009
    #define FILE_DEVICE_FIPS                0x0000003a
    #define FILE_DEVICE_FULLSCREEN_VIDEO    0x00000034
    #define FILE_DEVICE_INPORT_PORT         0x0000000a
    #define FILE_DEVICE_KEYBOARD            0x0000000b
    #define FILE_DEVICE_KS                  0x0000002f
    #define FILE_DEVICE_KSEC                0x00000039
    #define FILE_DEVICE_MAILSLOT            0x0000000c
    #define FILE_DEVICE_MASS_STORAGE        0x0000002d
    #define FILE_DEVICE_MIDI_IN             0x0000000d
    #define FILE_DEVICE_MIDI_OUT            0x0000000e
    #define FILE_DEVICE_MODEM               0x0000002b
    #define FILE_DEVICE_MOUSE               0x0000000f
    #define FILE_DEVICE_MULTI_UNC_PROVIDER  0x00000010
    #define FILE_DEVICE_NAMED_PIPE          0x00000011
    #define FILE_DEVICE_NETWORK             0x00000012
    #define FILE_DEVICE_NETWORK_BROWSER     0x00000013
    #define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
    #define FILE_DEVICE_NETWORK_REDIRECTOR  0x00000028
    #define FILE_DEVICE_NULL                0x00000015
    #define FILE_DEVICE_PARALLEL_PORT       0x00000016
    #define FILE_DEVICE_PHYSICAL_NETCARD    0x00000017
    #define FILE_DEVICE_PRINTER             0x00000018
    #define FILE_DEVICE_SCANNER             0x00000019
    #define FILE_DEVICE_SCREEN              0x0000001c
    #define FILE_DEVICE_SERENUM             0x00000037
    #define FILE_DEVICE_SERIAL_MOUSE_PORT   0x0000001a
    #define FILE_DEVICE_SERIAL_PORT         0x0000001b
    #define FILE_DEVICE_SMARTCARD           0x00000031
    #define FILE_DEVICE_SMB                 0x0000002e
    #define FILE_DEVICE_SOUND               0x0000001d
    #define FILE_DEVICE_STREAMS             0x0000001e
    #define FILE_DEVICE_TAPE                0x0000001f
    #define FILE_DEVICE_TAPE_FILE_SYSTEM    0x00000020
    #define FILE_DEVICE_TERMSRV             0x00000038
    #define FILE_DEVICE_TRANSPORT           0x00000021
    #define FILE_DEVICE_UNKNOWN             0x00000022
    #define FILE_DEVICE_VDM                 0x0000002c
    #define FILE_DEVICE_VIDEO               0x00000023
    #define FILE_DEVICE_VIRTUAL_DISK        0x00000024
    #define FILE_DEVICE_WAVE_IN             0x00000025
    #define FILE_DEVICE_WAVE_OUT            0x00000026
    

    Als Delphi:

    const
      FILE_DEVICE_8042_PORT           = $00000027;
      FILE_DEVICE_ACPI                = $00000032;
      FILE_DEVICE_BATTERY             = $00000029;
      FILE_DEVICE_BEEP                = $00000001;
      FILE_DEVICE_BUS_EXTENDER        = $0000002a;
      FILE_DEVICE_CD_ROM              = $00000002;
      FILE_DEVICE_CD_ROM_FILE_SYSTEM  = $00000003;
      FILE_DEVICE_CHANGER             = $00000030;
      FILE_DEVICE_CONTROLLER          = $00000004;
      FILE_DEVICE_DATALINK            = $00000005;
      FILE_DEVICE_DFS                 = $00000006;
      FILE_DEVICE_DFS_FILE_SYSTEM     = $00000035;
      FILE_DEVICE_DFS_VOLUME          = $00000036;
      FILE_DEVICE_DISK                = $00000007;
      FILE_DEVICE_DISK_FILE_SYSTEM    = $00000008;
      FILE_DEVICE_DVD                 = $00000033;
      FILE_DEVICE_FILE_SYSTEM         = $00000009;
      FILE_DEVICE_FIPS                = $0000003a;
      FILE_DEVICE_FULLSCREEN_VIDEO    = $00000034;
      FILE_DEVICE_INPORT_PORT         = $0000000a;
      FILE_DEVICE_KEYBOARD            = $0000000b;
      FILE_DEVICE_KS                  = $0000002f;
      FILE_DEVICE_KSEC                = $00000039;
      FILE_DEVICE_MAILSLOT            = $0000000c;
      FILE_DEVICE_MASS_STORAGE        = $0000002d;
      FILE_DEVICE_MIDI_IN             = $0000000d;
      FILE_DEVICE_MIDI_OUT            = $0000000e;
      FILE_DEVICE_MODEM               = $0000002b;
      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_NETWORK_REDIRECTOR  = $00000028;
      FILE_DEVICE_NULL                = $00000015;
      FILE_DEVICE_PARALLEL_PORT       = $00000016;
      FILE_DEVICE_PHYSICAL_NETCARD    = $00000017;
      FILE_DEVICE_PRINTER             = $00000018;
      FILE_DEVICE_SCANNER             = $00000019;
      FILE_DEVICE_SCREEN              = $0000001c;
      FILE_DEVICE_SERENUM             = $00000037;
      FILE_DEVICE_SERIAL_MOUSE_PORT   = $0000001a;
      FILE_DEVICE_SERIAL_PORT         = $0000001b;
      FILE_DEVICE_SMARTCARD           = $00000031;
      FILE_DEVICE_SMB                 = $0000002e;
      FILE_DEVICE_SOUND               = $0000001d;
      FILE_DEVICE_STREAMS             = $0000001e;
      FILE_DEVICE_TAPE                = $0000001f;
      FILE_DEVICE_TAPE_FILE_SYSTEM    = $00000020;
      FILE_DEVICE_TERMSRV             = $00000038;
      FILE_DEVICE_TRANSPORT           = $00000021;
      FILE_DEVICE_UNKNOWN             = $00000022;
      FILE_DEVICE_VDM                 = $0000002c;
      FILE_DEVICE_VIDEO               = $00000023;
      FILE_DEVICE_VIRTUAL_DISK        = $00000024;
      FILE_DEVICE_WAVE_IN             = $00000025;
      FILE_DEVICE_WAVE_OUT            = $00000026;
    

    Function

    Gibt die vom Treiber durchzuführende Funktion an. Der Wertebereich unter $800 (2048) ist für Microsoft reserviert. In diesem Bereich ist das Custom-Bit nicht gesetzt. Der Wertebereich darüber darf von Erstausrüstern (Original Equipment Manufacturer - OEM) und unabhängigen Hardwareherstellern (Independent Hardware Vendor - IHV) genutzt werden.

    Die Werte der Funktionen beziehungsweise die Definitionen der I/O Control Codes findet man meist nur in den entsprechenden Headerdateien.

    Method (Transfer Type)

    Die Methode gibt an, wie der Buffer genutzt wird.

    METHOD_BUFFERED - Für die Übertragung kleiner Datenmengen wird ein Buffer verwendet. Diese Methode wird von den meisten Funktionen verwendet.

    METHOD_IN_DIRECT or METHOD_OUT_DIRECT - Die Methode wird typischerweise zum Lesen oder Schreiben großer Datenmengen verwendet, wobei DMA oder PIO verwendet werden.

    METHOD_IN_DIRECT - Die Daten werden direkt an den Treiber übergeben.

    METHOD_OUT_DIRECT - Die Daten werden direkt vom Treiber empfangen.

    METHOD_NEITHER - Die Daten werden weder gepuffert noch direkt übertragen.

    Die Konstanten sind:

    #define METHOD_BUFFERED                 0
    #define METHOD_IN_DIRECT                1
    #define METHOD_OUT_DIRECT               2
    #define METHOD_NEITHER                  3
    

    Als Delphi:

    const
      METHOD_BUFFERED   = 0;
      METHOD_IN_DIRECT  = 1;
      METHOD_OUT_DIRECT = 2;
      METHOD_NEITHER    = 3;
    

    Access

    Gibt den Zugriffstyp an, mit welchem der I/O-Manager auf den Treiber zugreifen soll, wenn die entsprechenden Zugriffsrechte vorhanden sind.

    FILE_ANY_ACCESS - Der I/O-Manager sendet den IRP für jeden, der ein Handle für das Dateiobjekt hat, das das Zielgerätobjekt darstellt.

    FILE_READ_ACCESS - Der I/O-Manager sendet den IRP nur wenn Lesezugriffsrechte bestehen.

    FILE_WRITE_ACCESS - Der I/O-Manager sendet den IRP nur wenn Schreibzugriffsrechte bestehen

    FILE_READ_ACCESS und FILE_WRITE_ACCESS können kombiniert werden.

    #define FILE_ANY_ACCESS                 0
    #define FILE_READ_ACCESS          ( 0x0001 )
    #define FILE_WRITE_ACCESS         ( 0x0002 )
    

    Als Delphi:

    const
      FILE_ANY_ACCESS   =     0;
      FILE_READ_ACCESS  = $0001;
      FILE_WRITE_ACCESS = $0002;
    

    Änderungen

    20.08.2017Erstellung der Seite.