ptrex Posted March 13, 2007 Share Posted March 13, 2007 (edited) USB Monitor - using WMI Event notificationSome one in the Support Section asked if it was possible to have a notification if a USB drive was Connected / Disconnected.Well here is an example using the WMI Event notification :$strComputer = "." $objWMIService = ObjGet("winmgmts:" & $strComputer & "rootcimv2") $colEvents = $objWMIService.ExecNotificationQuery _ ("Select * From __InstanceOperationEvent Within 5 Where " _ & "TargetInstance isa 'Win32_LogicalDisk'") While 1 $objEvent = $colEvents.NextEvent If $objEvent.TargetInstance.DriveType = 2 Then Select Case $objEvent.Path_.Class()="__InstanceCreationEvent" Consolewrite("Drive " & $objEvent.TargetInstance.DeviceId & "has been added." & @CR) Case $objEvent.Path_.Class()="__InstanceDeletionEvent" Consolewrite("Drive " & $objEvent.TargetInstance.DeviceId & "has been removed."& @CR) EndSelect EndIf WEndEnjoy !!ptrex Edited September 14, 2012 by ptrex Earthshine 1 Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
Irongeek Posted March 15, 2007 Share Posted March 15, 2007 I just wanted to say thanks. This will really help me on one of my projects. I'll be sure to mention you in the credits. Link to comment Share on other sites More sharing options...
ptrex Posted March 15, 2007 Author Share Posted March 15, 2007 @Irongeek Thanks You are welcome If it is an interesting project you can share it with rest of us. regards ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
Irongeek Posted March 15, 2007 Share Posted March 15, 2007 I plan to. All the stuff I've done from my site in Autoit I've put the source code out for. Link to comment Share on other sites More sharing options...
sshrum Posted April 9, 2007 Share Posted April 9, 2007 (edited) I think I like your way...I've been doing mine like this: run through all the drive letters and check for changes in drivestatus...just make sure to skip floppy drives :-) for $i = 1 to 25 $aDriveStatus[$i] = DriveStatus(chr($i+65) & ":\") Next while 1 for $i = 1 to 25 $sDriveStatus = DriveStatus(chr($i+65) & ":\") if $aDriveStatus[$i] <> $sDriveStatus then $aDriveStatus[$i] = $sDriveStatus if $sDriveStatus = "READY" Then ;CODE TO RUN EndIf EndIf Next WEnd I'll give yours a try tonight Edited April 9, 2007 by sshrum Sean Shrum :: http://www.shrum.net All my published AU3-based apps and utilities 'Make it idiot-proof, and someone will make a better idiot' Link to comment Share on other sites More sharing options...
alwaysZeroHour Posted June 25, 2007 Share Posted June 25, 2007 Hey, It seems to work well but its grinding my floppy drive all the time. Any ideas for a fix? Cheers Z Link to comment Share on other sites More sharing options...
arcker Posted June 25, 2007 Share Posted June 25, 2007 it's because the current query ask for all the drivesso if you want to just monitor the removable drive, try this$strComputer = "." $objWMIService = ObjGet("winmÛ]ÎÌLÉÌLÉ][ÝÈ [È ÌÍÜÝÛÛ] [È ][ÝÉÌLÜÛÝ ÌL6×c"gV÷C² ¢b33c¶6öÄWfVçG2Òb33c¶ö&¥tÔ6W'f6RäWV4æ÷Ff6FöåVW'( ÅÕ½ÐíM±Ð¨É½´}}%¹Íѹ=ÁÉÑ¥½¹Ù¹Ð]¥Ñ¡¥¸Ô]¡ÉÅÕ½Ðì|( & "TargetInstance isa 'Win32_LogicalDisk' and "ÈÈ [È ][ÝÕÙ][Ý[ÙK]UHH][ÝÈ BÚ[HBb33c¶ö&¤WfVçBÒb33c¶6öÄWfVçG2äæWDWfVç@¢bb33c¶ö&¤WfVçBåF&vWDÍѹ¹É¥ÙQåÁôÈQ¡¸(M±Ð( ÍÀÌØí½©Ù¹Ð¹ath_.Class()="__InstanceCreationEvent" ConsolewriJ ][ÝÑ]H ][ÝÈ [È ÌÍÛØ][Ù][Ý[ÙK]XÙRY [È ]÷C¶2&VVâFFVBâgV÷C²fײ5"¢66Rb33c¶ö&¤WfVçBåFòä6ÍÌ ¤ôÅÕ½Ðí}}%¹Íѹ±Ñ¥½¹Ù¹ÐÅÕ½Ðì( ½¹Í½±ÝÉ¥Ñ ÅÕ½;Drive " & $objEvent.TargetInstance.DeviceId & "has Y[[[ÝY][ÝÉ[ÈÔB[Ù[XÝ[YÑ[the drivetype = 2 is the removable drivefor more information take a look at this :http://msdn2.microsoft.com/en-us/library/aa394173.aspx -- Arck System _ Soon -- Ideas make everything "La critique est facile, l'art est difficile" Projects :[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list] Link to comment Share on other sites More sharing options...
Elkie Posted August 3, 2007 Share Posted August 3, 2007 (edited) Thank you very much now i can implement this to secure my computer from unwanted UFD activity. I hope this will help, thanks again! . Say why is my floppy drive still grinding even using the latest script? Edited August 3, 2007 by Elkie Link to comment Share on other sites More sharing options...
arcker Posted August 3, 2007 Share Posted August 3, 2007 simple : you ask the logical drive class, so it queries all the disk before filter it, wherever you place this filter, i think. your floppy is usb connected ? -- Arck System _ Soon -- Ideas make everything "La critique est facile, l'art est difficile" Projects :[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list] Link to comment Share on other sites More sharing options...
Elkie Posted August 3, 2007 Share Posted August 3, 2007 simple : you ask the logical drive class, so it queries all the disk before filter it, wherever you place this filter, i think. your floppy is usb connected ?Nope, that's the problem i use coventional floppy controller, but when i run the script it keep running the floppy drive every 5 sec Link to comment Share on other sites More sharing options...
UglyBob Posted August 6, 2007 Share Posted August 6, 2007 (edited) Nope, that's the problem i use coventional floppy controller, but when i run the script it keep running the floppy drive every 5 seccheers ptrexI too had this problem with the script. However, I've found a fix.Instead of the initial query searching within the 'Win32_LogicalDisk' WMI I've created a different query which checks 'Win32_PnPEntity' $colEvents = $objWMIService.ExecNotificationQuery _ ("Select * From __InstanceOperationEvent Within 5 Where " _ & "TargetInstance isa 'Win32_PnPEntity' and " _ & "(TargetInstance.Description = 'USB FloppyDisk Drive' or " _ & "TargetInstance.Description = 'CD-ROM Drive' or " _ & "TargetInstance.Description = 'Disk Drive')" )You could also check for 'Generic Volume'. The description filters completely depend on what you wish to search on.-----------------------I've expanded on the original script to automatically disconnect the USB device if the logged on user is not a member of a particular Active Directory group.This amalgamates this script and another script created by 'arcker': http://www.autoitscript.com/forum/index.ph...=disconnect+USBwith some additional tweaking to suit my needs:When the: Case $objEvent.Path_.Class()="__InstanceCreationEvent"occurs I then run : $objWMIService.ExecQuery("Select * From Win32_LogicalDisk Where DriveType = 2" ) (this will of course still cause the Floppy disk to trigger, but this will only occur once. I was hopping to find a WMI query other than win32_logicaldisk that would give me the drive letter for the particular USB device, so far I can't find it).a FOR...NEXT loops through the results and checks if the user is allowed to use the device.So far, so good. I've tested quite a few USB drives and all have been detected and disconnected.The reference material used to create the queries are:Microsoft Script Guy: http://www.microsoft.com/technet/scriptcen...06/hey0213.mspxWMI queries: http://msdn2.microsoft.com/en-us/library/aa394173.aspxand, if you ever want to find out what the 'descriptions' are to other USB devices that are connected which the script misses you can use the Microsoft vb script: http://www.microsoft.com/technet/scriptcen...05/hey0315.mspxIf anyone is interested (once I've completed the script and improved my lousy coding ) I'll post the complete script. Edited August 6, 2007 by UglyBob "My God, you're looking hideously ugly today, Ugly Bob." Link to comment Share on other sites More sharing options...
arcker Posted August 6, 2007 Share Posted August 6, 2007 hehe excellent for a first try ! i don't understand understand pnpentity but i will take a look for sure ! i've provide a script that continuosly monitor the usb drive but... there is more simple you can just : - verify AD group membership - unload possible connected key by my script provided (eject key) - block by registry - block by ntfs (calc or better, win32_logicalfilesetsecuritydescriptor) please post your script either, it sounds really interesting. -- Arck System _ Soon -- Ideas make everything "La critique est facile, l'art est difficile" Projects :[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list] Link to comment Share on other sites More sharing options...
Elkie Posted August 7, 2007 Share Posted August 7, 2007 Hmmh, interesting indeed, at first i thought i could use CMI_USBDisk or something for the WMI script but it's not working at all. I'll try it thanks, Link to comment Share on other sites More sharing options...
ptrex Posted August 7, 2007 Author Share Posted August 7, 2007 (edited) @UglyBob Good job !! You did quit some investigation on this matter. When you have some code running please post it in this thread, so others can benifit of it as well. Good to see you get inspired by this !! ; http://www.microsoft.com/technet/scriptcenter/resources/qanda/mar05/hey0315.mspx $strComputer = "." $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2") $colDevices = $objWMIService.ExecQuery ("Select * From Win32_USBControllerDevice") For $objDevice in $colDevices $strDeviceName = $objDevice.Dependent $strQuotes = Chr(34) $strDeviceName = StringReplace($strDeviceName, $strQuotes, "") $arrDeviceNames = StringSplit($strDeviceName, "=") $strDeviceName = $arrDeviceNames[2] $colUSBDevices = $objWMIService.ExecQuery ("Select * From Win32_PnPEntity Where DeviceID = '" & $strDeviceName & "'") For $objUSBDevice in $colUSBDevices MsgBox(0,"USB Description",$objUSBDevice.Description) Next MsgBox(0,"USB Devices",$strDeviceName) Next PS: added the USB device descriptions script. regards, ptrex Edited August 7, 2007 by ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
Elkie Posted August 7, 2007 Share Posted August 7, 2007 @UglyBob Good job !! You did quit some investigation on this matter. When you have some code running please post it in this thread, so others can benifit of it as well. Good to see you get inspired by this !! ; [url="http://www.microsoft.com/technet/scriptcenter/resources/qanda/mar05/hey0315.mspx"]http://www.microsoft.com/technet/scriptcen...05/hey0315.mspx[/url] $strComputer = "." $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2") $colDevices = $objWMIService.ExecQuery ("Select * From Win32_USBControllerDevice") For $objDevice in $colDevices $strDeviceName = $objDevice.Dependent $strQuotes = Chr(34) $strDeviceName = StringReplace($strDeviceName, $strQuotes, "") $arrDeviceNames = StringSplit($strDeviceName, "=") $strDeviceName = $arrDeviceNames[2] $colUSBDevices = $objWMIService.ExecQuery ("Select * From Win32_PnPEntity Where DeviceID = '" & $strDeviceName & "'") For $objUSBDevice in $colUSBDevices MsgBox(0,"USB Description",$objUSBDevice.Description) Next MsgBox(0,"USB Devices",$strDeviceName) Next PS: added the USB device descriptions script. regards, ptrex Sorry for my noob question, is this mean i have to combine this script with the first post to create the USB insert detection (monitoring) script? Link to comment Share on other sites More sharing options...
ptrex Posted August 7, 2007 Author Share Posted August 7, 2007 @Elkie Yes indead. But I am hoping the Mr. UglyBob is doing that for you. Regards, ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
UglyBob Posted August 7, 2007 Share Posted August 7, 2007 thanks for the au3 version of the USB list ptrex. Right, here's my script so far. As mentioned previously this amalgamates a couple scripts and functions together (with the odd tweak here and there to suit). Apologies for any incorrect command useage you may find, I'm still learning. expandcollapse popup; ==================================================================================================== ====================================== ; Created by UglyBob - 03/08/2007 ; Thanks to: ; Yoan Roblet (Arcker) (AutoIT member) - For the code (functions) which disconnect the detected USB device from the workstation ; ptrex (AutoIT member) - For the initial USB detection code) ; Johny Clelland (AutoIT member) - For the initial AD code to query group membership ; Reference Material - ; http://support.microsoft.com/kb/165721 ; Microsoft Script Guy USB Monitor - http://www.microsoft.com/technet/scriptcen...06/hey0213.mspx ; WMI queries - http://msdn2.microsoft.com/en-us/library/aa394173.aspx ; Microsoft Script Guy ID USB Devices - http://www.microsoft.com/technet/scriptcen...05/hey0315.mspx ; Version Control ; --------------- ; Updated - 06/08/2007 - Added filters to the initial SELECT query for USB devices that also create floppy & CD-ROM drives ; Updated - 07/08/2007 - Added filters to the win32_logicaldisk query to ignore already disconnected USB devices ; ==================================================================================================== ====================================== #include <A3LWinApi.au3> #include <Constants.au3> ; ------------------------------------------------------------------------------------------------------------ ; Variables $AllowUser = False $objWMIService = ObjGet("winmgmts:\\.\root\cimv2") $Offline = False $OpenVolume = "" $szVolumeFormat = "\\\\.\\%s" $szRootFormat = "%s\\" $szErrorFormat = "Error %d: %s\n" $USB_Allow_Group = "USB storage Users" $colEvents = $objWMIService.ExecNotificationQuery _ ("Select * From __InstanceOperationEvent Within 5 Where " _ & "TargetInstance isa 'Win32_PnPEntity' and " _ & "(TargetInstance.Description = 'USB FloppyDisk Drive' or " _ & "TargetInstance.Description = 'CD-ROM Drive' or " _ & "TargetInstance.Description = 'Disk Drive')" ) ; Additional filter = TargetInstance.Description = 'Generic Volume' ;------------------------------------------ ;Arbitrary variables Global Const $INVALID_HANDLE_VALUE = 0 ;------------------------------------------ ;DeviceIoControl Contants Global Const $FSCTL_LOCK_VOLUME = int(0x090018) Global Const $FSCTL_DISMOUNT_VOLUME = int(0x00090020) Global Const $IOCTL_STORAGE_EJECT_MEDIA = int(0x002D4808) Global Const $IOCTL_STORAGE_MEDIA_REMOVAL = int(0x002D4804) ;------------------------------------------ ;Retry Constants Global Const $LOCK_TIMEOUT = 10000 ; 10 Seconds Global Const $LOCK_RETRIES = 3 ;------------------------------------------ ; AD LDAP variables Dim $objConnection, $oUsr, $objRootDSE $objConnection = ObjCreate("ADODB.Connection") ; Create COM object to AD $objConnection.Provider = "ADsDSOObject" $objConnection.Open ("Active Directory Provider") ; Open connection to AD $objRootDSE = ObjGet("LDAP://RootDSE") ; If there is no response from LDAP then the script will treat the computer running the script as 'offline'. ; Ideal when a laptop is not connected to the network. If @Error then $Offline = True Else ConsoleWrite ( "Domain = " & $objRootDSE.Get ("defaultNamingContext") & @CRLF ) ConsoleWrite ( "Offline = " & $Offline & @CRLF ) $strDNSDomain = $objRootDSE.Get ("defaultNamingContext") ;Retrieve the current AD domain name (DN) EndIf ; ------------------------------------------------------------------------------------------------------------ While 1 $objEvent = $colEvents.NextEvent Select Case $objEvent.Path_.Class()="__InstanceCreationEvent" ConsoleWrite ( "Detected Device = " & $objEvent.TargetInstance.DeviceID & " - " & $objEvent.TargetInstance.Description & @CRLF ) $Event = $objWMIService.ExecQuery("Select * From Win32_LogicalDisk Where (DriveType = 2 and MediaType != 5 and (FileSystem = 'FAT' or FileSystem = 'FAT32'))" ) For $objItem in $Event $OpenVolume = $objItem.DeviceID ConsoleWrite ( $objItem.DeviceID & " - " & $objItem.VolumeName & " - " & $objItem.FileSystem & @CRLF ) If $Offline = False Then If memberof($AllowUser) = False Then EjectVolume($OpenVolume) MsgBox (16, "USB Drive Detected", "Drive " & $OpenVolume & " has been added to your PC." & @CRLF & @CRLF & "You are not authorised to use such portable media." & @CRLF & @CRLF & "Please contact the ICT dept. for further assistance.") EndIf Else MsgBox (64, "USB Drive Notification", "Drive " & $OpenVolume & " has been added to your PC.") EndIf Next $OpenVolume = "" ; The 'case' statement below is no longer required for this particular script but is useful for reporting successful USB disconnections ;Case $objEvent.Path_.Class()="__InstanceDeletionEvent" ; MsgBox (64, "USB Drive", "Drive " & $OpenVolume & " has been Removed.") EndSelect WEnd ; --------------------------------- ; ; FUNCTIONS ; ; --------------------------------- Func ReportError($szMsg) ConsoleWrite(StringFormat($szErrorFormat, _API_GetLastErrorMessage (), $szMsg) & @CRLF) Exit EndFunc ;==>ReportError Func OpenVolume($cDriveLetter) ;HANDLE hVolume ;UINT uDriveType ;TCHAR szVolumeName[8] ;TCHAR szRootName[5] ;DWORD dwAccessFlags $szRootName = StringFormat($szRootFormat, $cDriveLetter) $uDriveType = DriveGetType($szRootName); ConsoleWrite($szRootName & @tab & $uDriveType & @crlf) Switch $uDriveType Case "Removable" $dwAccessFlags = 6 Case "CDROM" $dwAccessFlags = 2 Case Else ConsoleWrite("Cannot eject. Drive type is incorrect." & @CRLF) Return $INVALID_HANDLE_VALUE EndSwitch $szVolumeName = StringFormat($szVolumeFormat, $cDriveLetter) ;$szVolumeName = $szVolumeFormat & $cDriveLetter ConsoleWrite($szVolumeName & @crlf ) $hVolume = _API_CreateFile ($szVolumeName, 2,$dwAccessFlags, 6) #cs hVolume = CreateFile( szVolumeName, dwAccessFlags, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); #ce If ($hVolume == $INVALID_HANDLE_VALUE) Then ReportError("CreateFile"); Return $hVolume; EndFunc ;==>OpenVolume Func CloseVolume($hVolume) Return _API_CloseHandle ($hVolume); EndFunc ;==>CloseVolume Func LockVolume($hVolume) Local $dwBytesReturned Local $dwSleepAmount Local $nTryCount local $iRead $dwSleepAmount = $LOCK_TIMEOUT / $LOCK_RETRIES; ; Do this in a loop until a timeout period has expired For $nTryCount = 0 To $nTryCount < $LOCK_RETRIES If _Device_Control($hVolume, $FSCTL_LOCK_VOLUME, $iRead) Then Return True Else Sleep($dwSleepAmount); EndIf Next Return False; EndFunc ;==>LockVolume Func DismountVolume($hVolume) ConsoleWrite("Dismount " & $hVolume & @crlf) Local $dwBytesReturned, $iRead local $aResult = _Device_Control($hVolume, $FSCTL_DISMOUNT_VOLUME, $iRead) ;msgbox(0,"",$aResult) Return $aResult ;Return $dwBytesReturned EndFunc ;==>DismountVolume Func PreventRemovalOfVolume($hVolume, $fPreventRemoval) Local $dwBytesReturned Local $aResult Local $lpInbuffer,$nInBufferSize,$lpOutBuffer,$nOutBufferSize,$lpOverlapped $PMRBUFFER = DllStructCreate("bool PreventMediaRemoval") DllStructSetData($PMRBUFFER,"PreventMediaRemoval",$fPreventRemoval) $lpBytesReturned = DllStructCreate("int Read") $pRead = DllStructGetPtr($lpBytesReturned, "Read") $aResult = Dllcall("kernel32.dll","int","DeviceIoControl","hwnd",$hVolume,"uint",$IOCTL_STORAGE_MEDIA_REMOVAL,"ptr",DllStructGetPtr($PMRBUFFER),"uint",DllStructGetSize($PMRBUFFER), _ "ptr",$lpOutBuffer,"uint",$nOutBufferSize,"ptr",$pRead,"ptr",$lpOverlapped) if $aResult = 0 then msgbox(0,"",_API_GetLastErrorMessage()) Return $aResult <> 0 ;& PMRBuffer, sizeof (PREVENT_MEDIA_REMOVAL), ;NULL, 0, ; & dwBytesReturned, ;NULL); EndFunc ;==>PreventRemovalOfVolume Func AutoEjectVolume($hVolume) Local $aResult, $iRead; $aResult = _Device_Control($hVolume, $IOCTL_STORAGE_EJECT_MEDIA, $iRead) Return $aResult EndFunc ;==>AutoEjectVolume Func EjectVolume($cDriveLetter) Local $hVolume; Local $fRemoveSafely = False; Local $fAutoEject = False; ; Open the volume. $hVolume = OpenVolume($cDriveLetter); If $hVolume == $INVALID_HANDLE_VALUE Then Return False ; Lock and dismount the volume. If LockVolume($hVolume) And DismountVolume($hVolume) Then $fRemoveSafely = True; ConsoleWrite("Volume Locked and Dismounted, trying to eject " & @crlf) ; Set prevent removal to false and eject the volume. If PreventRemovalOfVolume($hVolume, False) And AutoEjectVolume($hVolume) Then $fAutoEject = True; EndIf Else ConsoleWrite("Volume can't be locked or dismounted, please close possible opened files" & @crlf) EndIf ; Close the volume so other processes can use the drive. If CloseVolume($hVolume) = False Then Return False; EndIf If $fAutoEject Then ConsoleWrite(StringFormat("Media in Drive %s has been ejected safely.\n", $cDriveLetter)) Else If $fRemoveSafely Then ConsoleWrite(StringFormat("Media in Drive %s can be safely removed.\n", $cDriveLetter)) EndIf EndIf Return True; EndFunc ;==>EjectVolume Func _Device_Control($hDevice, $dwIoControlCode, ByRef $iRead) Local $aResult Local $lpInbuffer,$nInBufferSize,$lpOutBuffer,$nOutBufferSize,$lpOverlapped $tRead = DllStructCreate("int Data") $aResult = Dllcall("kernel32.dll","int","DeviceIoControl","hwnd",$hDevice,"uint",$dwIoControlCode,"ptr",$lpInBuffer,"uint",0, _ "ptr",$lpOutBuffer,"uint",0,"ptr",DllStructGetPtr($tRead),"ptr",$lpOverlapped) $iRead = DllStructGetData($tRead, "Data") ConsoleWrite("Device Control " & $iRead & @CRLF) Return $aResult<>0 EndFunc ;==>_Device_Control Func Memberof($AllowUser) Dim $usergroups[1], $i = 1 Local $groups $strQuery = "<LDAP://" & $strDNSDomain & ">;( samAccountName=" & @UserName & ");ADsPath;subtree" $objRecordSet = $objConnection.Execute ($strQuery) ; Retrieve the FQDN for the logged on user If $objRecordSet.RecordCount = 1 Then $ldap_entry = $objRecordSet.fields (0).value $oUsr = ObjGet($ldap_entry) ; Retrieve the COM Object for the logged on user $groups = $oUsr.groups ; Get the list of group objects from the user For $groupname In $groups ReDim $usergroups[UBound($usergroups) + 1] $usergroups[0] += 1 ; Increment the count of groups $usergroups[$i] = StringTrimLeft($groupname.name, 3) If $usergroups[$i] = $USB_Allow_Group Then $AllowUser = True Return $AllowUser ConsoleWrite ( "Allow = " & $AllowUser & @CRLF ) ExitLoop EndIf $i += 1 Next EndIf ConsoleWrite ( "Allow = " & $AllowUser & @CRLF ) EndFunc ;==>memberof The reason why I have the filter: (DriveType = 2 and MediaType != 5 and (FileSystem = 'FAT' or FileSystem = 'FAT32')) when checking the drives is to filter the floppy disk drive and to ignore a USB device that has already been disconnected by the script but the drive is still physically attached to the PC. There may be a slightly better WMI field to query, but so far this works, you may want to add 'NTFS' should you wish to disconnect any such devices too. I did spot a simpler script somewhere on this forum regarding the listing of a user's groups, but the AD function works so hey why change it. "My God, you're looking hideously ugly today, Ugly Bob." Link to comment Share on other sites More sharing options...
Rozek Posted August 16, 2007 Share Posted August 16, 2007 Incredible, incredible! I still can't believe what's possible with AutoIt (and the proper knowledge of Windows, of course) Just to give a little bit back of what I got from AutoIt and this forum: I had to integrate the check for removable volumes into a message event loop which controls an AutoIt GUI. After a little bit of research and some experiments I found the following solution (presented as a skeleton - you may add your own code where necessary) expandcollapse popup; **** add a COM error handler (see below) **** global $ErrorHandler = ObjEvent("AutoIt.Error","handleCOMError") func handleCOMError () if ($ErrorHandler.number = -2147352567) then ; i.e. if timeout occurred sleep(100) ; just wait a moment (then try again) return ; continue processing endif with $ErrorHandler ConsoleWriteError("COMError.number = " & string(.number) & @LF) ConsoleWriteError("COMError.windescription = " & string(.windescription) & @LF) ConsoleWriteError("COMError.source = " & string(.source) & @LF) ConsoleWriteError("COMError.description = " & string(.description) & @LF) ConsoleWriteError("COMError.helpfile = " & string(.helpfile) & @LF) ConsoleWriteError("COMError.helpcontext = " & string(.helpcontext) & @LF) ConsoleWriteError("COMError.lastdllerror = " & string(.lastdllerror) & @LF) ConsoleWriteError("COMError.scriptline = " & string(.scriptline) & @LF) endwith exit ; abort program in case of a real error endfunc ; **** set-up the WMIService object and register a query **** ; ... <= create WMIService and ExecNotificationQuery as required ; **** now continously check for WMI "events" **** while true $objEvent = $colEvents.NextEvent(1) ; do not wait longer than 1 msec if ($objEvent <> 0) then ; did we get a *real* result? ; ... <= process the WMI "event" as required endif wend The basic "trick" to provide a "timeout" (given in milliseconds) when calling ".NextEvent" and to catch the "timeout" (which is an error from the WMIService' point of view) Hope this is of any help! Kind regards, Andreas Rozek Link to comment Share on other sites More sharing options...
BullGates Posted August 17, 2007 Share Posted August 17, 2007 (edited) This is giving me some ideas to improve my concept as posted before in here:#366233But the big problem I find in using COM is that the script can break easily if the error processing doesn't predict all the situations.The posted script by UgglyBob looks interesting, but offline mode does not work and crashes easilly if you disconnect the network - if a user knows that, it will crash the script and he can then use the USB storage device. With my initial script, if it crashes at least he might be protected... It's a nice idea to use USB events to trigger some checks and avoid traffic to the domain controllers I guess. Oh by the way, how would you implement such script? As a service? As normal user I guess it won't have permissions to work right... Edited August 17, 2007 by BullGates [topic="51913"]Restrict USB Storage usage to group membership[/topic] * [topic="48699"]Using nircmd library[/topic] * Some admin notes Link to comment Share on other sites More sharing options...
UglyBob Posted August 18, 2007 Share Posted August 18, 2007 well, it was (and still is) of course work in progress. One of the other fundamental flaws in the script is the fact that you can plug the USB device prior to script actually running (such as booting up). This would not be picked up by '__InstanceCreationEvent '. I'm working on an improved script. I've ditched the above WMI query, and instead am using Win32_DiskDrive as the initial check, which will query every 5 seconds for any USB drives (regardless of whether they have been plugged in before the script has started). As for the AD issue, well this all depends on how you want to control USB devices. My main thought is to prevent users connecting USB devices allowing them to copy data from network servers or try to use software stored on said devices. That subject has many other issues and ways of circumvention, I guess you gotta start somewhere.... so... 1) Do you block ALL USB drives? 2) Do you allow authorised domain/local users to plug in USB devices? If so, do you query AD or local workstation groups? 3) Do you allow offline connectivity when laptops are not connected to the network? So far, my latest version is working (it doesn't fall over, or hang when offline). The script now dismounts drives unless it can confirm that the logged on user is a member of a specific AD group. As for how to run the script, that's still up for debate, but I think a service may be the option (I guess this all depends on the environment and situations that the script will be used). More testing to do.... "My God, you're looking hideously ugly today, Ugly Bob." Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now