Jump to content

Change Status of a Disk to Offline or Online Without Diskpart


wtarkan
 Share

Recommended Posts

Hi , I Need to Change the Status of a Disk to Offline or Online Without Diskpart

I have tried all possibilities but no success , Finally find a C++ code but not sure if it is possible to convert it Autoit format , Or maybe somenone can help me to do it with autoit 

Here is the code 

BOOL disk_offline(HANDLE h_file, bool enable){
DWORD bytes_returned = 0;
BOOL b_offline = 0;
if(get_size_volume_disk(h_file)){
    SET_DISK_ATTRIBUTES disk_attr;
    ZeroMemory(&disk_attr, sizeof(disk_attr));
    disk_attr.Version = sizeof(SET_DISK_ATTRIBUTES);
    disk_attr.Attributes = enable? DISK_ATTRIBUTE_OFFLINE: 0;
    disk_attr.AttributesMask = DISK_ATTRIBUTE_OFFLINE;
    b_offline = DeviceIoControl(h_file, IOCTL_DISK_SET_DISK_ATTRIBUTES, &disk_attr, disk_attr.Version, NULL, 0, &bytes_returned, NULL);
    // Invalidates the cached partition table and re-enumerates the device.
    if(!enable) BOOL b_update = DeviceIoControl(h_file, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &bytes_returned, NULL);
}
return b_offline;
}

Source

http://tiku.io/questions/502405/take-disks-online-offline

Link to comment
Share on other sites

Link to comment
Share on other sites

#RequireAdmin
Opt("MustDeclareVars", 1)

MsgBox(64, "", _SET_DISK_ONLINE("\\.\PHYSICALDRIVE1"))

Func _SET_DISK_ONLINE($SourceDisk)
    ;Writede By BlueLife
    Local Const $OPEN_EXISTING = 3
    Local Const $GENERIC_WRITE = 0x40000000
    Local Const $GENERIC_READ = 0x80000000

    Local Const $FILE_SHARE_READ = 0x00000001
    Local Const $FILE_SHARE_WRITE = 0x00000002
    Local Const $FILE_ATTRIBUTE_NORMAL = 0x00000080

    Local Const $IOCTL_DISK_GET_DISK_ATTRIBUTES = 0x000700f0
    Local Const $IOCTL_DISK_SET_DISK_ATTRIBUTES = 0x0007c0f4
    Local Const $IOCTL_DISK_UPDATE_PROPERTIES = 459072

    ;https://msdn.microsoft.com/en-us/library/windows/desktop/hh706680%28v=vs.85%29.aspx
    Local $tag_GET_DISK_ATTRIBUTES = 'DWORD Version;int64 Reserved1;DWORD Attributes;'

    ;Error !!!!!!!!!!!!
    ;https://msdn.microsoft.com/en-us/library/windows/desktop/hh706683%28v=vs.85%29.aspx
    Local $tag_SET_DISK_ATTRIBUTES = DllStructCreate('DWORD Version;BOOLEAN Persist;BOOLEAN RelinquishOwnership;int64 Reserved1[2];INT64 Attributes; INT64 AttributesMask;DWORD Owner;')

    Local $hFile = _WinAPI_CreateFileEx($SourceDisk, $OPEN_EXISTING, BitOR($GENERIC_READ, $GENERIC_WRITE), BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), $FILE_ATTRIBUTE_NORMAL)
    If $hFile = 0 Then Return SetError(1, 0, 0)

    Local $tStrunct = DllStructCreate($tag_GET_DISK_ATTRIBUTES)
    DllStructSetData($tStrunct, 'Attributes', 1)
    DllStructSetData($tStrunct, 'Version', DllStructGetSize($tStrunct))

    Local $Error = 0
    ;https://msdn.microsoft.com/en-us/library/windows/desktop/hh706681%28v=vs.85%29.aspx
    If _WinAPI_DeviceIoControl($hFile, $IOCTL_DISK_GET_DISK_ATTRIBUTES, 0, 0, DllStructGetPtr($tStrunct), DllStructGetSize($tStrunct)) = 1 Then
        If BitAND(DllStructGetData($tStrunct, 2), 1) = 1 Then ;Offline
            MsgBox(64, "Info:", $SourceDisk & " Ofline Disk")

            ;!!!!!!!!!!!! Error !!!!!!!!!!!!
            Local $tStrunct = DllStructCreate($tag_SET_DISK_ATTRIBUTES) ;
            DllStructSetData($tStrunct, 'Attributes', 0) ;
            DllStructSetData($tStrunct, 'AttributesMask', 0)
            DllStructSetData($tStrunct, 'Version', DllStructGetSize($tStrunct))

            ;https://msdn.microsoft.com/en-us/library/windows/desktop/hh706682%28v=vs.85%29.aspx
            If _WinAPI_DeviceIoControl($hFile, $IOCTL_DISK_SET_DISK_ATTRIBUTES, 0, 0, DllStructGetPtr($tStrunct), DllStructGetSize($tStrunct)) = 1 Then
                _WinAPI_DeviceIoControl($hFile, $IOCTL_DISK_UPDATE_PROPERTIES)
            Else
                $Error = 2
            EndIf
        EndIf
    Else
        $Error = 1
    EndIf
    If $hFile Then DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hFile)
    Return SetError($Error, 0, $Error = 0)
EndFunc   ;==>_SET_DISK_ONLINE

Func _WinAPI_DeviceIoControl($hDevice, $iControlCode, $pInBuffer = 0, $iInBufferSize = 0, $pOutBuffer = 0, $iOutBufferSize = 0)
    Local $Ret = DllCall("kernel32.dll", 'int', 'DeviceIoControl', 'ptr', $hDevice, 'dword', $iControlCode, 'ptr', $pInBuffer, 'dword', $iInBufferSize, 'ptr', $pOutBuffer, 'dword', $iOutBufferSize, 'dword*', 0, 'ptr', 0)
    If (@error) Or (Not $Ret[0]) Then Return SetError(1, 0, 0)
    Return SetError(0, $Ret[7], 1)
EndFunc   ;==>_WinAPI_DeviceIoControl

Func _WinAPI_CreateFileEx($sFile, $iCreation, $iAccess = 0, $iShare = 0, $iFlagsAndAttributes = 0, $tSecurity = 0, $hTemplate = 0)
    Local $Ret = DllCall("kernel32.dll", 'ptr', 'CreateFileW', 'wstr', $sFile, 'dword', $iAccess, 'dword', $iShare, 'ptr', DllStructGetPtr($tSecurity), 'dword', $iCreation, 'dword', $iFlagsAndAttributes, 'ptr', $hTemplate)

    If (@error) Or ($Ret[0] = Ptr(-1)) Then
        Return SetError(1, 0, 0)
    EndIf
    Return $Ret[0]
EndFunc   ;==>_WinAPI_CreateFileEx

I have tried something but the "$IOCTL_DISK_SET_DISK_ATTRIBUTES " part is problematic , I hope some experienced forum members can help to fix it.

Good luck...

Link to comment
Share on other sites

As far I see your Structure is wrong.

Should be.

 

Global Const $sTag_SET_DISK_ATTRIBUTES = 'DWORD Version;BOOLEAN Persist;BOOLEAN Reserved1[3];INT64 Attributes;INT64 AttributesMask;DWORD Reserved2[4];'

Saludos

Link to comment
Share on other sites

Does diskpart work?

(I have just one disk I can't try your example...)

Saludos

Link to comment
Share on other sites

You were using DeviceIoControl Wrong. I wrote my own...

 

#include <WinAPIFiles.au3>
#include <WinAPI.au3>

#RequireAdmin

Global Const $DISK_ATTRIBUTE_OFFLINE = 0x0000000000000001
Global Const $IOCTL_DISK_SET_DISK_ATTRIBUTES = 0x0007c0f4
Global Const $sTag_SET_DISK_ATTRIBUTES = 'DWORD Version;BOOLEAN Persist;BOOLEAN Reserved1[3];INT64 Attributes;INT64 AttributesMask;DWORD Reserved2[4];'


_SetDiskoffline("\\.\PHYSICALDRIVE1")

Func _SetDiskoffline($sSourceDisk, $bEnable = True);true=set offilne (defalut)  ;false set online

    Local $hFile = _WinAPI_CreateFileEx($sSourceDisk, $OPEN_EXISTING, BitOR($GENERIC_READ, $GENERIC_WRITE), BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), 0)
    If @error Then Return
    ConsoleWrite($hFile & @CRLF)
    Local $tSetAttributes = DllStructCreate($sTag_SET_DISK_ATTRIBUTES)
    $tSetAttributes.Version = DllStructGetSize($tSetAttributes)
    $tSetAttributes.Attributes = $bEnable
    $tSetAttributes.AttributesMask = $DISK_ATTRIBUTE_OFFLINE

    If _WinAPI_DeviceIoControl($hFile, $IOCTL_DISK_SET_DISK_ATTRIBUTES, DllStructGetPtr($tSetAttributes), DllStructGetSize($tSetAttributes)) Then
        Return _WinAPI_DeviceIoControl($hFile, $IOCTL_DISK_UPDATE_PROPERTIES)
    Else
        Return False
    EndIf

EndFunc   ;==>_SetDiskoffline

Saludos

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...