
bobsobol
Members-
Posts
13 -
Joined
-
Last visited
bobsobol's Achievements

Seeker (1/7)
0
Reputation
-
Hmm, yea... about that. Vista just Ate my source coz it was in the program files folder and the compiler had a split token at the time... So it's allowed to delete the source but not change or write it out... Nice, thanks Vista, no UAC warning or anything there, just poof your file's gone. And another lesson learned. Why is it (since I still have the exe, and while the comments and formatting are still in my mind) that the decompiler doesn't recognise my exe as a compiled AutoIt file? It is, and it runs, but I need to fix that bug that I was re-compiling for... :s
-
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.
-
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.
-
What you are looking for is RGB32 Alpha Blended window. It isn't 3 levels, because you are not getting what's behind your window and setting your window to that. If you do, your whole system will grind to a halt, or you will get lag trails under your window. It will look horrid. It's been tried a million times. You can do it on Linux with some trickery by stalling the XServer display refresh while you fiddle about. Recently (with Windows XP, and gdiplus.dll upgrade on 2K) you can get RGB32 windows in Windows natively, the only other way to do this, is to translate the whole screen to a DirectX layer, and manually insert your window using DirectX calls... somehow. I didn't understand the descussions on this, and it meant a lot of code which only just about worked in a reasonable time scale, provided no other program tried it and you didn't try to... play a game or watch a video, or TVin. GDI+ makes it possible. Don't ask me how, all I know is that a GDI Plus window is nothing like a regular window. You can't add a switch or tag to a window to make it a GDI+ window like you can uniform transparency in 2k+ and from what I can tell, if you use a GDI+ window you have to forgo buttons, lists, combo boxes and all the other ctrl3d.dll controls you are used to, and just draw the entire UI manually using GDI+ and DirectX calls to your new Windows Layer. This isn't going to be "added" to any standard AutoIt GUI commands, but would need to be a whole new library in it's self. How about AveDesk with AveScripter? or Samurize would they not be more suited? You can get AutoIt to run invisible and interact with these, I have done so, and it works. It's not easy though, but I don't think any solution will be till someone comes out with a UFD which links nicely to the APIs in gdiplus.dll. PS. if you think your C++ to AutoIt is up to the job I'd love to hear from you. Edit: I should have mentioned that this all came about because OS X has always had it natively with it's updated PDF like Cocoa and Aqua interfaces. Linux has a fix for this in recent variants, but it isn't IFAIK a standard part of X as yet. It is, however a large part of the new DirectX 11 compatible cards, and a large part of the new specs in PCI-E low level APIs which OS X and Windows Vista can then take advantage of as new hardware acceleration. Hence the push for PCI-E in order to use Vistas new transparency effects. A fast AGP card can cope with 4/5 of these things but then starts to grind to a halt without the Hardware and API specs to handel it. In DirectX games you don't normally have more than a couple of layers, for HUD or what have you. In the Windows Desktop you could well have 30-40 in an Office PC.
-
I'm trying to make an OnExitFunction which cleans up the temporary files it created if it finds half way through that it can't process the rest. Insufficient file/directory privaliges can cause this, and it's not just a matter of being an Admin. I can't test for it before I've created the Temporary files, because they will determine what directories and files you need to have write privalages for. My script will become very large if I need to write cleanup code for all the places it might fail so an OnExitFunction is ideal. (GoTo would do but it's only for onerror GoTo) Trouble is all the other Opt() functions need an Option name as String and a parameter as number. How do I set the parameter of Opt() for the "OnExitFunction" option? The help files description:- OnExitFunc Sets the name of the function called when AutoIt exits (default is OnAutoItExit). Isn't particulaly helpful as the line:- Opt("OnExitFunction",OnAutoItExit) or Opt("OnExitFunction","OnAutoItExit") Fails too. Anybody get this fascility to work who can provide a good example?