Jump to content

CD Drive Status


Recommended Posts

I was wondering if there is a function that can return the current status of the drive, in particular a CD drive. So it would possibly return 1 if the drive is open, or 0 if it's closed? I looked into DriveStatus but I don't really understand it that much, thanks guys.

Link to comment
Share on other sites

Try this

$var = DriveStatus( "h:\" )

MsgBox(4096,"Status",$var)

Change H to your CD Drive letter. It will return "READY" if the CD drive is closed and "NOTREADY" if its open. Only way I know how to do what you are talking about.

Link to comment
Share on other sites

Change H to your CD Drive letter. It will return "READY" if the CD drive is closed and "NOTREADY" if its open. Only way I know how to do what you are talking about.

Sorry, but it does not return "ready" even if the drive is closed unless there is a CD ready for reading inside. :rambo::rolleyes:

[font="Comic Sans MS"]-ronriel[/font][topic="48542"]r4r media player[/topic][topic="80836"]OCR & Paste[/topic]

Link to comment
Share on other sites

Sorry, but it does not return "ready" even if the drive is closed unless there is a CD ready for reading inside. :rambo::rolleyes:

Ah sorry your right, I wasn't thinking. Should have read the post slower ^.^

Link to comment
Share on other sites

I don't know exactly how to do this, but I'd say you need to look into using COM objects for this. I'm sure it's possible, I'm just not familiar enough with COM objects yet to write out an example for you. Hopefully I can at least steer you in the right direction. :rolleyes:

Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt
Link to comment
Share on other sites

Have a look @ a combination of these commands:

DriveStatus()

DriveSpaceFree()

DriveSpaceTotal()

DriveStatus to check the status of the drive(cd in or out)

DriveSpaceFree and/or DriveSpaceTotal to determine if a cd is in or not.

Just a suggestion if you don't want to try with the DllCall idea that's used in the thread bhoar linked to. :rolleyes:

Link to comment
Share on other sites

DriveSpaceFree and/or DriveSpaceTotal to determine if a cd is in or not.

You can check it with DriveStatus() only (READY/NOTREADY).

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

Sorry, but it does not return "ready" even if the drive is closed unless there is a CD ready for reading inside. :rambo::rolleyes:

You can check it with DriveStatus() only (READY/NOTREADY).

Apparently not, anyways it's a way to determine if a cd is in or not too.

Edited by FreeFry
Link to comment
Share on other sites

Have a look @ a combination of these commands:

DriveStatus()

DriveSpaceFree()

DriveSpaceTotal()

DriveStatus to check the status of the drive(cd in or out)

DriveSpaceFree and/or DriveSpaceTotal to determine if a cd is in or not.

Unfortunately, that fails on blank CD-Rs, other unformatted writable media, and heavily damaged discs.

Just a suggestion if you don't want to try with the DllCall idea that's used in the thread bhoar linked to. :rolleyes:

Right, I understand my method is a bit complicated.

The DLLcall approach has the following pros/cons:

Pros:

Actually tracks the physical location of the tray as reported by the drive. If you're working with disc robotics, as I am, I'm convinced you need to know this

Cons:

Only works with contemporary optical drives. Older units may not implement the command. So, always test.

May not work with most laptop drives.

May require Administrator access.

Tested only under 2000 and XP.

-brendan

Link to comment
Share on other sites

I was wondering if there is a function that can return the current status of the drive, in particular a CD drive. So it would possibly return 1 if the drive is open, or 0 if it's closed? I looked into DriveStatus but I don't really understand it that much, thanks guys.

This might be the answer :

If drive is open or empty it returns 0 otherwise -1 in autoit , "True " in delphi & others

$strComputer = "." 
 $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") 
 $colItems = $objWMIService.ExecQuery( _
    "SELECT * FROM Win32_CDROMDrive") 
For $objItem in $colItems 
    MsgBox(4096, "","Loaded        "& $objItem.MediaLoaded&@CRLF _ 
                 &" Drive:            "&$objItem.Drive&@CRLF _ 
                 &" CD/DVD:       "&$objItem.MediaType)
Next
Link to comment
Share on other sites

Wow thanks everyone I didn't expect all of this but what I was looking for and I think I found it is a command just to tell me if the drive is open or closed, so I think with all your guys help it should be easy thanks everyone.

Link to comment
Share on other sites

This might be the answer :

If drive is open or empty it returns 0 otherwise -1 in autoit , "True " in delphi & others

$strComputer = "." 
 $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") 
 $colItems = $objWMIService.ExecQuery( _
    "SELECT * FROM Win32_CDROMDrive") 
For $objItem in $colItems 
    MsgBox(4096, "","Loaded        "& $objItem.MediaLoaded&@CRLF _ 
                 &" Drive:            "&$objItem.Drive&@CRLF _ 
                 &" CD/DVD:       "&$objItem.MediaType)
Next

Autosc ! Thanks ... what i was looking for ....

What about to identify the model of my CD in the same script ? is it possible ?

Link to comment
Share on other sites

  • 10 months later...

Gordon Bennett, what a lot of palarva.

I too was simply looking for a means to identify if a removable media (CD/DVD, Tape Drive, Floppy) has, what we used to call "Door Open" or "Door Closed" back in the days when the premiere OS DOS came on a 360K floppy. Even floppy disks had a lock / door to stop the disk flying out during reading... and yes, floppy disks really were floppy, but if you folded them (or ran them through the typewriter) good luck reading the data off them again. And yes, I still have a 5½" Floppy drive that will still work on a modern motherboard. :) I wonder what OS X 10.5 would make of it. hmm.

In any case, what I want is to write a hotkey script which does something different depending on whether the tray is out or in, regardless of what (if any) media is in the tray. The only reason is that my new PC has some goofy trendy facier over the optical drive, whos door obscures the insert/eject button when the tray is out and I don't hold with straining the teeth of the track mechanism by pressing on the tray till the drive gets the message that you want it to suck the tray back in.

So far I can find lots of software means to eject the tray programmatically, but that isn't the problem, inserting it is. It would make sense to insert it using the same key, and using Macs as well as Windows I'd like it to be the Numlock key... then my script can also keep numlock "on". Which is the only state which makes sense since we switched from XT to AT Extended keyboards which have all the functions of unlocked Numberpad on their own keys.

Honestly, sometimes I think people are deliberately making computers more and more unfriendly for the user. :(

There used to be a simple int 21 API call for DOS that returned a flag byte with flags indicating "Open/Closed" "Media/No Media" "Single/Double Density" and other stuff that really isn't relevant any more. I'd be very surprised if there isn't a Win32 API in shell32.dll, if not Kernel32.dll that supports an equivalent. I'm surprised "Open" isn't one of the returns from DriveStatus() in AutoIt though.

This thread is old, I will research and report back if I find anything useful tho.

Edited by bobsobol
Link to comment
Share on other sites

Okay... so the solution seems a little convoluted, and is eventually found on this very forum here. Thanks Brendan[/ur].

I'll link it in because this thread was what I kept finding in my searches, not the one with the solution. :(

Here's the code I produced to solve this issue:-

CODE

#cs ----------------------------------------------------------------------------

AutoIt Version: 3.2.10.0

Author: bobsobol

Script Function: Use NumLock as Eject (Mac style) and Substitute Scroll Lock key for NumLock.

#ce ----------------------------------------------------------------------------

;-----------------------------------------------------

; Setup Globals Environment

;-----------------------------------------------------

Global Const $INVALID_HANDLE_VALUE = 0xFFFFFFFF

Global Const $GENERIC_READ = 0x80000000

Global Const $GENERIC_WRITE = 0x40000000

Global Const $FILE_SHARE_READ = 0x00000001

Global Const $FILE_SHARE_WRITE = 0x00000002

Global Const $OPEN_EXISTING = 3

Global Const $IOCTL_SCSI_PASS_THROUGH = 0x0004D004; (0x00000004 << 16) | ((0x0001 | 0x0002) << 14) | (0x0401 << 2) | 0 [from CTL_CODE macro]

Global Const $SCSI_IOCTL_DATA_IN = 0x01

Global Const $SCSI_IOCTL_DATA_OUT = 0x00

Global Const $SCSI_IOCTL_DATA_UNSPECIFIED = 0x02

Global Const $SPTCDBSIZE = 0x10; always sixteen, IOCTL_SCSI_PASS_THROUGH requires this - windows checks to make sure the size of $spt = 44.

Global Const $REALCDBSIZE = 0x0c; twelve - more compatible than sixteen for ATAPI drives

Global Const $SENSEBUFFERSIZE = 0xF0;240 is max (was 32, then 255, which was stupid for byte alignment reasons)

Global Const $DATABUFFERSIZE = 0x0400;1024 should handle most calls, except IO, firmware and large changers. Increase? (was 512)

Global Const $VK_NUMLOCK = 0x90

Global Const $VK_SCROLL = 0x91

Global Const $VK_CAPITAL = 0x14

Global $cdb

Global $spt

Global $sptwb

Global $Numlock = True

;-----------------------------------------------------

; Main Routine

;-----------------------------------------------------

HotKeySet("{NUMLOCK}","ToggleTray")

HotKeySet("{SCROLLLOCK}","SetNumLock")

While 1

Sleep(1000)

WEnd

Func ToggleTray()

;Call routine to create structures to use with DLLs

CreateDLLStructures()

$hVolume = OpenVolume(0)

Sleep(95)

If $Numlock Then

HotKeySet("{NUMLOCK}")

Send("{NUMLOCK on}")

HotKeySet("{NUMLOCK}","ToggleTray")

Else

HotKeySet("{NUMLOCK}")

Send("{NUMLOCK off}")

HotKeySet("{NUMLOCK}","ToggleTray")

EndIf

If $hVolume <> $INVALID_HANDLE_VALUE Then

If IsTrayOpen($hVolume) Then

LoadDisc($hVolume)

Else

UnLoadDisc($hVolume)

EndIf

EndIf

EndFunc

Func SetNumLock()

If $Numlock Then

$Numlock=False

HotKeySet("{NUMLOCK}")

Send("{NUMLOCK off}")

HotKeySet("{NUMLOCK}","ToggleTray")

Else

$Numlock=True

HotKeySet("{NUMLOCK}")

Send("{NUMLOCK on}")

HotKeySet("{NUMLOCK}","ToggleTray")

EndIf

Sleep(95)

If _GetScrollLock() Then

HotKeySet("{SCROLLLOCK}")

Send("{SCROLLLOCK off}")

HotKeySet("{SCROLLLOCK}","SetNumLock")

EndIf

EndFunc

;-----------------------------------------------------

; Top-level Function Definitions

;-----------------------------------------------------

Func CreateDLLStructures()

$CDB_STRUCT = ("ubyte[" & String($SPTCDBSIZE) & "]")

$SCSI_PASS_THROUGH = "ushort;ubyte;ubyte;ubyte;ubyte;ubyte;ubyte;ubyte;ubyte[3];uint;uint;uint;uint;ubyte[" & String($SPTCDBSIZE) & "]"

$SCSI_PASS_THROUGH_WITH_BUFFERS = $SCSI_PASS_THROUGH & ";ubyte[" & String($SENSEBUFFERSIZE) & "];ubyte[" & String($DATABUFFERSIZE) & "]"

$cdb = DllStructCreate($CDB_STRUCT)

$spt = DllStructCreate($SCSI_PASS_THROUGH);used only for length calculations

$sptwb = DllStructCreate($SCSI_PASS_THROUGH_WITH_BUFFERS)

EndFunc ;==>CreateDLLStructures

Func PopulateCDB_TrayStatus()

$CDBCOMMAND = 0xBD;Mechanism Status in hex

DllStructSetData($cdb, 1, $CDBCOMMAND, 1)

DllStructSetData($cdb, 1, 0x00, 2)

DllStructSetData($cdb, 1, 0x00, 3)

DllStructSetData($cdb, 1, 0x00, 4)

DllStructSetData($cdb, 1, 0x00, 5)

DllStructSetData($cdb, 1, 0x00, 6)

DllStructSetData($cdb, 1, 0x00, 7)

DllStructSetData($cdb, 1, 0x00, 8)

DllStructSetData($cdb, 1, 0x00, 9)

DllStructSetData($cdb, 1, 0x08, 10);Request that the device returns only 08 bytes into our databuffer, which is the defined size of the header We could do more if we had a changer, which would want to give more info, but by setting 8 here, we tell the device not to send more than the header anyway.

DllStructSetData($cdb, 1, 0x00, 11)

DllStructSetData($cdb, 1, 0x00, 12)

;The next four are not used for ATAPI compatibility, but should be set to zero anyway.

DllStructSetData($cdb, 1, 0x00, 13)

DllStructSetData($cdb, 1, 0x00, 14)

DllStructSetData($cdb, 1, 0x00, 15)

DllStructSetData($cdb, 1, 0x00, 16)

EndFunc ;==>PopulateCDB_TrayStatus

Func PopulateCDB_LoadDisc()

$CDBCOMMAND = 0x1B;Start/Stop Unit

DllStructSetData($cdb, 1, $CDBCOMMAND, 1)

DllStructSetData($cdb, 1, 0x00, 2)

DllStructSetData($cdb, 1, 0x00, 3)

DllStructSetData($cdb, 1, 0x00, 4)

DllStructSetData($cdb, 1, 0x03, 5);00000011 = Load Disc and Spin Up

DllStructSetData($cdb, 1, 0x00, 6)

DllStructSetData($cdb, 1, 0x00, 7)

DllStructSetData($cdb, 1, 0x00, 8)

DllStructSetData($cdb, 1, 0x00, 9)

DllStructSetData($cdb, 1, 0x00, 10)

DllStructSetData($cdb, 1, 0x00, 11)

DllStructSetData($cdb, 1, 0x00, 12)

;The next four are not used for ATAPI compatibility, but should be set to zero anyway.

DllStructSetData($cdb, 1, 0x00, 13)

DllStructSetData($cdb, 1, 0x00, 14)

DllStructSetData($cdb, 1, 0x00, 15)

DllStructSetData($cdb, 1, 0x00, 16)

EndFunc ;==>PopulateCDB_LoadDisc

Func PopulateCDB_UnLoadDisc()

$CDBCOMMAND = 0x1B;Start/Stop Unit

DllStructSetData($cdb, 1, $CDBCOMMAND, 1)

DllStructSetData($cdb, 1, 0x00, 2)

DllStructSetData($cdb, 1, 0x00, 3)

DllStructSetData($cdb, 1, 0x00, 4)

DllStructSetData($cdb, 1, 0x02, 5);00000010 = Spin Down and UnLoad Disc

DllStructSetData($cdb, 1, 0x00, 6)

DllStructSetData($cdb, 1, 0x00, 7)

DllStructSetData($cdb, 1, 0x00, 8)

DllStructSetData($cdb, 1, 0x00, 9)

DllStructSetData($cdb, 1, 0x00, 10)

DllStructSetData($cdb, 1, 0x00, 11)

DllStructSetData($cdb, 1, 0x00, 12)

;The next four are not used for ATAPI compatibility, but should be set to zero anyway.

DllStructSetData($cdb, 1, 0x00, 13)

DllStructSetData($cdb, 1, 0x00, 14)

DllStructSetData($cdb, 1, 0x00, 15)

DllStructSetData($cdb, 1, 0x00, 16)

EndFunc ;==>PopulateCDB_UnLoadDisc

Func PopulateSPTWB()

$Len_spt = DllStructGetSize($spt)

;Are these necessary if the optical drive is at a drive letter and we pass the handle, right?

;docs seem to suggest that the port driver fills these in if we are using an enumerated device

$Bus = 0x00

$ID = 0x00

$Lun = 0x00

DllStructSetData($sptwb, 1, $Len_spt);Length of pre-filler to be set before making call

DllStructSetData($sptwb, 2, 0x00);Checked on return from call

DllStructSetData($sptwb, 3, $Bus);SCSI bus # - I believe the port driver fills this in

DllStructSetData($sptwb, 4, $ID);SCSI ID # - I believe the port driver fills this in

DllStructSetData($sptwb, 5, $Lun);SCSI Lun # -I believe the port driver fills this in

DllStructSetData($sptwb, 6, $REALCDBSIZE);Length of CDB to be set before making call (12 for ATAPI compatibility)?

DllStructSetData($sptwb, 7, $SENSEBUFFERSIZE);Length of Sense buffer to be set before making call - or always 32?

DllStructSetData($sptwb, 8, $SCSI_IOCTL_DATA_IN);Flag for Data Transfer direction to be set before making call

;item #9 is simple a placehold for byte alignment, so ignore it

DllStructSetData($sptwb, 10, $DATABUFFERSIZE);Length of Data buffer to be set before making call - or always 512

DllStructSetData($sptwb, 11, 0x05);Timeout for call - to be set before making call

DllStructSetData($sptwb, 12, $Len_spt + $SENSEBUFFERSIZE);Offset from first byte to beginning of data buffer

DllStructSetData($sptwb, 13, $Len_spt);Offset from first byte to beginning of sense buffer

For $i = 1 To $SPTCDBSIZE

DllStructSetData($sptwb, 14, DllStructGetData($cdb, 1, $i), $i);12 bytes of data representing the CDB

Next

DllStructSetData($sptwb, 15, 0x00, 1);Sense Buffer - leave alone before call

DllStructSetData($sptwb, 16, 0x00, 1);Data Buffer - leave alone before call

EndFunc ;==>PopulateSPTWB

;-----------------------------------------------------

; Lower-level Function Definitions

;-----------------------------------------------------

Func DoSCSICall(ByRef $hVolume)

$returnvalue = DllStructCreate("ptr")

;!!! DeviceIOControl expects ptr;long;ptr;long;ptr;long;ptr;ptr !!!

$ret = DllCall( _

"kernel32.dll", "int", _

"DeviceIoControl", _

"hwnd", $hVolume, _

"int", $IOCTL_SCSI_PASS_THROUGH, _

"ptr", DllStructGetPtr($sptwb), _

"int", DllStructGetSize($spt), _

"ptr", DllStructGetPtr($sptwb), _

"int", DllStructGetSize($sptwb), _

"int*", $returnvalue, _

"ptr", 0 _

)

If @error Then

MsgBox(1, "EXITING...", "DeviceIoControl DLLCall failed with error level: " & String(@error) & "!")

exit (1)

EndIf

If $ret[0] = 0 Then

_GetLastErrorMessage("Error in DeviceIoControl call to IOCTL_SCSI_PASS_THROUGH:")

exit (1)

EndIf

EndFunc ;==>DoSCSICall

Func IsTrayOpen(ByRef $hVolume)

;Call routine to set up the CDB of this SCSI transaction's SRB, in this case 0xBD

PopulateCDB_TrayStatus()

;Call routine to set up the SCSI_PASS_THROUGH_WITH_BUFFERS stucture - this is general purpose, though the sizes of globals might need to be adjusted for certain SRBs

PopulateSPTWB(); to ensure a fresh SRB each time

;Perform the SCSI transaction

DoSCSICall($hVolume)

$second_byte = DllStructGetData($sptwb, 16, 2);should be the second byte

;now we need the bit here 00010000

$traystatus = BitAND($second_byte, 0x10)

If $traystatus = 0x10 Then

Return (True)

Else

Return (False)

EndIf

EndFunc ;==>IsTrayOpen

Func LoadDisc(ByRef $hVolume)

;Call routine to set up the CDB of this SCSI transaction's SRB

PopulateCDB_LoadDisc()

;Call routine to set up the SCSI_PASS_THROUGH_WITH_BUFFERS stucture - this is general purpose, though the sizes of globals might need to be adjusted for certain SRBs

PopulateSPTWB(); to ensure a fresh SRB each time

;Perform the SCSI transaction

DoSCSICall($hVolume)

;TODO: Analyze sense data to verify this worked.

EndFunc ;==>LoadDisc

Func UnLoadDisc(ByRef $hVolume)

;Call routine to set up the CDB of this SCSI transaction's SRB

PopulateCDB_UnLoadDisc()

;Call routine to set up the SCSI_PASS_THROUGH_WITH_BUFFERS stucture - this is general purpose, though the sizes of globals might need to be adjusted for certain SRBs

PopulateSPTWB(); to ensure a fresh SRB each time

;Perform the SCSI transaction

DoSCSICall($hVolume)

;TODO: Analyze sense data to verify this worked.

EndFunc ;==>UnLoadDisc

Func OpenVolume($cDriveNumber)

; From AUTOIT forums

Local $hVolume, $uDriveType, $szVolumeName, $dwAccessFlags

Local $szRootName = "\\.\CdRom" & $cDriveNumber

;We need write access in order to send scsi commands.

$dwAccessFlags = BitOR($GENERIC_READ, $GENERIC_WRITE)

$szVolumeName = "\\.\CdRom0"

;in addition to getting the handle, the following also verifies write access, which is required to use the scsi pass through

$hVolume = DllCall( _

"kernel32.dll", "hwnd", _

"CreateFile", _

"str", $szVolumeName, _

"long", $dwAccessFlags, _

"long", BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), _

"ptr", 0, _

"long", $OPEN_EXISTING, _

"long", 0, _

"long", 0 _

)

If @error Then

MsgBox(1, "EXITING...", "CreateFile DLLCall failed!")

exit (1)

EndIf

Return $hVolume[0]

EndFunc ;==>OpenVolume

;===============================================

; _GetLastErrorMessage($DisplayMsgBox="")

; Format the last windows error as a string and return it

; if $DisplayMsgBox <> "" Then it will display a message box w/ the error

; Return Window's error as a string

;===============================================

Func _GetLastErrorMessage($DisplayMsgBox = "")

Local $ret, $s

Local $p = DllStructCreate("char[4096]")

Local Const $FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000

If @error Then Return ""

$ret = DllCall("Kernel32.dll", "int", "GetLastError")

$LastError = $ret[0]

$ret = DllCall("kernel32.dll", "int", "FormatMessage", _

"int", $FORMAT_MESSAGE_FROM_SYSTEM, _

"ptr", 0, _

"int", $LastError, _

"int", 0, _

"ptr", DllStructGetPtr($p), _

"int", 4096, _

"ptr", 0)

$s = DllStructGetData($p, 1)

If $DisplayMsgBox <> "" Then MsgBox(0, "_GetLastErrorMessage", $DisplayMsgBox & @CRLF & String($LastError) & "-" & $s)

Return $s

EndFunc ;==>_GetLastErrorMessage

Func _GetNumLock()

Local $ret

$ret = DllCall("user32.dll","long","GetKeyState","long",$VK_NUMLOCK)

Return $ret[0]

EndFunc

Func _GetScrollLock()

Local $ret

$ret = DllCall("user32.dll","long","GetKeyState","long",$VK_SCROLL)

Return $ret[0]

EndFunc

I've removed stuff about Lock disc / tray, I'm using only CdRom0 but have adapted to work from any \\.\CdRomX NT device by passing x (0-99 and maybe more) because the SEPTI code will only work on NT anyway, and drive letters are only a DOS hang up in truth. I almost never use them unless I have to for compatibility reasons. If you had 99 CD Drives NT could cope with that fine, but what drive letter would you give the 26th one you mounted? Let alone the 23rd 24th and 25th (A, B and C being preassigned for other things).

I also used the routines here to check the state of Num Lock and Scroll Lock. Thanks GrayFox.

It strikes me that the Tray state could do with either building in to AutoIt, or at least creating a UDF for. :)

Anyway, my thanks go out to this forum for having all the information I needed, even if it wasn't quite where I was looking for it. That's probably as much my fault as anything.

Edited by bobsobol
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...