Announcement

Collapse
No announcement yet.

Laufwerk "sperren" (DeviceIOControl)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Laufwerk "sperren" (DeviceIOControl)

    HI!
    weiß irgendjemand wie man beispielsweise das CD-ROM Laufwerk sperren kann, sprich der Benutzer es mit dem Auswurf-Knopf nicht mehr öffnen kann??
    In diesem Zusammenhang gibt es die API-Funktion DeviceIOCOntrol, die ja den zugriff auf Laufwerke am Dateisystem vorbei erlaubt. Und es gibt sogar einen Parameter mit dem man die Möglichkeit, einen Wechseldatenträger auszuwerfen, verbieten kann. (IOCTL_STORAGE_MEDIA_REMOVAL)
    Kann es sein, dass dieser Aufruf nur unter NT/2000 gelingt??
    Abgesehen davon muss es aber eine Möglichkeit geben, denn Command&Conquer 3
    schafft das auch (unter Win98).
    Wäre cool wenn mir da jemand helfen könnte

    Gruß MeMger

  • #2
    ...

    <pre>
    begin
    result:=ldoit; if not result then result:=ldoit;
    end;

    function WinIOCTL(action: integer; drive: char) : boolean;
    var i1 : integer;
    h1 : THandle;
    b1 : integer;
    w1 : DWORD;
    s1 : string;
    const // DeviceType Access Function
    IOCTL_STORAGE_MEDIA_REMOVAL : DWORD = ($2D shl 16) or (1 shl 14) or ($201 shl 2);
    IOCTL_STORAGE_EJECT_MEDIA : DWORD = ($2D shl 16) or (1 shl 14) or ($202 shl 2);
    FSCTL_LOCK_VOLUME : DWORD = ( $9 shl 16) or (0 shl 14) or ( $6 shl 2);
    FSCTL_UNLOCK_VOLUME : DWORD = ( $9 shl 16) or (0 shl 14) or ( $7 shl 2);
    begin
    result:=false;
    drive:=Upcase(drive); if (drive<'A') or (drive>'Z') then exit;
    case action of
    0: s1:= 'Sperren des Volumes "'+drive+':".';
    1: s1:= 'Entsperren des Volumes "'+drive+':".';
    end;
    i1:=GENERIC_READ; if action=5 then i1:=i1+GENERIC_WRITE;
    h1:=CreateFile(PChar('\\.\'+drive+':'), i1,
    FILE_SHARE_READ+FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
    if h1=INVALID_HANDLE_VALUE then begin
    // error
    exit;
    end;
    try
    case action of
    0,1: begin
    b1:=1-action;
    result:=DeviceIOControl(h1, IOCTL_STORAGE_MEDIA_REMOVAL, @b1,
    SizeOf(b1), nil, 0, w1, nil);
    end;
    end;
    finally CloseHandle(h1) end;
    end;

    function LockDrive(drive: char) : boolean;
    begin
    result:=false;
    drive:=UpCase(drive);
    if not (drive in ['A'..'Z']) then exit;
    case GetOperatingSystem of
    osWin95,osWin98: result:=DosIOCTL(0,drive);
    osWinNT: result:=WinIOCTL(0,drive);
    end;
    end;

    function UnlockDrive(drive: char) : boolean;
    begin
    result:=false;
    drive:=UpCase(drive);
    if not (drive in ['A'..'Z']) then exit;
    case GetOperatingSystem of
    osWin95,osWin98: result:=DosIOCTL(1,drive);
    osWinNT: result:=WinIOCTL(1,drive);
    end;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    LockDrive('F');
    end;

    procedure TForm1.Button2Click(Sender: TObject);
    begin
    UnlockDrive('F');
    end;
    </pre>

    Tschüss..

    Comment


    • #3
      Danke Tim....genau das was ich gesucht habe!

      thx MeMger&#174

      Comment


      • #4
        Hallo,

        Diese Methode dürfte das Problem lösen:

        <pre>
        type TOperatingSystem = (osWin311, osWin95, osWin98, osWinNT, osUnknown);

        function GetOperatingSystem : TOperatingSystem;
        var os1 : TOSVersionInfo;
        begin
        os1.dwOSVersionInfoSize:=sizeOf(os1); GetVersionEx(os1);
        case os1.dwPlatformID of
        VER_PLATFORM_WIN32s : result:=osWin311;
        VER_PLATFORM_WIN32_WINDOWS : if (os1.dwMajorVersion=4) and (os1.dwMinorVersion=0) then
        result:=osWin95
        else if (os1.dwMajorVersion=4) and (os1.dwMinorVersion=10) then
        result:=osWin98
        else result:=osUnknown;
        VER_PLATFORM_WIN32_NT : result:=osWinNT;
        else result:=osUnknown;
        end;
        end;

        function DosIOCTL(action: integer; drive: char) : boolean;

        function ldoit : boolean;
        var hDevice : THandle;
        cb : DWORD;
        s1,s2 : string;
        reg : record
        reg_EBX, reg_EDX, reg_ECX, reg_EAX : DWORD;
        reg_EDI, reg_ESI, reg_Flags : DWORD;
        end;
        pb : packed record
        operation, NumLocks : BYTE;
        end;
        const VWIN32_DIOC_DOS_IOCTL = 1;
        begin
        result:=false;
        drive:=Upcase(drive); if (drive<'A') or (drive>'Z') then exit;
        case action of
        0: begin
        s2:='Sperren des Volumes "'+drive+':".';
        reg.reg_EAX:=$440D; // IOCTL for block devices
        reg.reg_EBX:=ord(drive)-ord('A')+1; // zero-based drive ID
        reg.reg_ECX:=$0848; // Lock / Unlock Volume command
        reg.reg_EDX:=DWORD(@pb); // Paramblock
        pb.numLocks := 0;
        pb.operation:=0; // Lock
        //pb.numLocks := 0;
        end;
        1: begin
        s2:='Entsperren des Volumes "'+drive+':".';
        reg.reg_EAX:=$440D; // IOCTL for block devices
        reg.reg_EBX:=ord(drive)-ord('A')+1; // zero-based drive ID
        reg.reg_ECX:=$0848; // Lock / Unlock Volume command
        reg.reg_EDX:=DWORD(@pb); // Paramblock
        pb.numLocks := 0;
        pb.operation:=1; // Unlock
        //pb.numLocks := 0;
        end;
        end;
        reg.reg_Flags:=1; // assume error (carry flag set)
        hDevice:=CreateFile('\\.\vwin32', 0, 0, nil, 0, 0, 0);
        if hDevice=INVALID_HANDLE_VALUE then begin
        // error
        exit;
        end;
        s1:='';
        if (not DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL,
        @reg, sizeof(reg), @reg, sizeof(reg), cb, nil)) or
        odd(reg.reg_Flags) then begin
        case reg.reg_EAX of
        $01: s1:='Diese Funktion ist nicht unterstützt.';
        $05: s1:='Zugriff verweigert oder kein Volume eingelegt.';
        $B0: s1:='Das Volume im Laufwerk ist nicht gesperrt.';
        $B1: s1:='Das Volume im Laufwerk ist gesperrt.';
        $B2: s1:='Das Volume ist nicht "Removable".';
        $B4: s1:='Der Sperrzähler ist übergelaufen.';
        $B5: s1:='Die Herauswerfen-Anforderung ist fehlgeschlagen.';
        end;
        if s1='' then s1:='windows error ' + IntToStr(GetLastError);
        //MessageBox(0, pchar(s1), 'error', 0);
        exit;
        end;
        end;
        </pre>

        ..

        Comment

        Working...
        X