Sign in to follow this  
Followers 0

Unmount an USB-Drive or USB-Stick WITHOUT Admin-Rights in WIN32 XP?

11 posts in this topic

#1 ·  Posted (edited)

Well - my first post here - so Hello @ all at first :) ...

Now my problem:

I want to unmount my Portable USB-Drive or USB-Stick (means FIXED and REMOVEABLE Partitions) automatically.

Up until now I have used MountVol.exe + AutoIT for that purpose (if needed i can post the code) - but my problem is that it won't work unless I have Administrator-Rights on the Local Machine (which isn't the case on most of the systems).

Is there ANY alternative way (and i mean ANY - like an existing wrapper, function hook with autoit or c ... even an precompiled console-exe would be ok for my purposes) to unmount an USB-Drive or USB-Stick WITHOUT Admin-Rights (running under WIN32 XP) ???

I haven't found anything via Google or in this Forum so far and hope someone can give me a little advice/point me in the right direction here.

Argh, I just hate it when some kind of so-called "Network-Admin" spys on my sensitive data :) ...


As you probably allready know - there is the "Remove Hardware Safely"-Agent running on most of the systems (can that be deactivated/won't it work for Non-Admins?).

How are they dismounting the device? Would it be possible to use the same API Functions they are using to get what I want (autodismount even when beeing an Restricted-User)? If so - what functions are they using at all? Does anyone know that? :-/

Edited by Sosilo

Share this post

Link to post
Share on other sites


I'm not sure I follow what you are trying to do...

Some kind of auto start password checker and if the PW fails then unmount the drive?

[u]Helpful tips:[/u]If you want better answers to your questions, take the time to reproduce your issue in a small "stand alone" example script whenever possible. Also, make sure you tell us 1) what you tried, 2) what you expected to happen, and 3) what happened instead.[u]Useful links:[/u]BrettF's update to LxP's "How to AutoIt" pdfValuater's Autoit 1-2-3 Download page for the latest versions of Autoit and SciTE[quote]<glyph> For example - if you came in here asking "how do I use a jackhammer" we might ask "why do you need to use a jackhammer"<glyph> If the answer to the latter question is "to knock my grandmother's head off to let out the evil spirits that gave her cancer", then maybe the problem is actually unrelated to jackhammers[/quote]

Share this post

Link to post
Share on other sites

#3 ·  Posted (edited)

I found this on the net:

The examples is written in C though, so you would have to figure you the DllCall equivalent.

Otherwise, this might work:

I have tested neither of them though.


Found those by this simple googgle btw:

Edited by FreeFry

Share this post

Link to post
Share on other sites

#4 ·  Posted (edited)

Hey SpookMeister,

I just need a way to actually unmount an USB-Drive/Stick while beeing logged in as an Restricted-User on a WIN XP (32-Bit) System...

I don't have any problems on the other hand - all I need is a working method to achive that, nothing else.

€: Thanks FreeFry I'll have a look at that (haven't thought about using the term "programmatically" O.o)

Edited by Sosilo

Share this post

Link to post
Share on other sites

Hehe, it just came to me that some people have used that word on some sitatuations, and I tried it. ^___^

Share this post

Link to post
Share on other sites

#6 ·  Posted (edited)

Well ... ok i'm stuck atm ...

I first tryed it by manually unmounting each logical partition (getting the volumeIDs with WMI) - well and somehow it worked ...

BUT as the Win32_LogicalPartition Class hasn't implemented any method or element to check/get the InterfaceType (to check if it's an USB-/ FireWire-Device) I decited to switch over to the Win32_DiskDrive Class (

Now somehow it returns correct values for the Handle and the various methods (lock, unmount etc.) ... well at least it tells me that - in reality it does NOTHING :)

Here is what i got so far - maybe i'm just overworked and overlooking something really stupid ...

Help please! :)

Global $strComputer         = "."
Global $objWMIService     = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")

Func getPortableDrives()

    $driveList = $objWMIService.ExecQuery("Select * from Win32_DiskDrive");
    ; Model, Name, InterfaceType, MediaType 
    For $drive in $driveList

        If $drive.MediaType = "Removable" Or $drive.InterfaceType = "USB" Or $drive.InterfaceType = "1394" Then
            ConsoleWrite($drive.DeviceID & @CRLF)
            ConsoleWrite($drive.MediaType & " " & $drive.Name & " " & $drive.InterfaceType & @CRLF)
            Local $hVol = OpenVolume($drive.Name)
    ;Local $test[1] = ["0"]
    ;return $test 


Func OpenVolume($szVolumeName)

    Local $dwAccessFlags, $hVolume
    Local $uDriveType = DriveGetType($szVolumeName)
    ;$szVolumeName = "\\.\" & "G" & ":"
    ConsoleWrite($szVolumeName & " "& $uDriveType & @CRLF)

        Case $uDriveType == "Removable"
            $dwAccessFlags = BitOR($GENERIC_READ,$GENERIC_WRITE)
        Case $uDriveType == "Fixed"
            $dwAccessFlags = $GENERIC_ALL
        Case $uDriveType == "CDROM"
            $dwAccessFlags = $GENERIC_READ
        Case Else
            MsgBox(4096,"Error","Cannot eject. Drive type is incorrect.")
            Return $INVALID_HANDLE_VALUE

    $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 $hVolume[0] = $INVALID_HANDLE_VALUE Then 
    ConsoleWrite("Volume Handle: "& $hVolume[0] & @CRLF)
    Return $hVolume[0]

Func ReportError($szMsg)
    $ret = DLLCall("kernel32.dll","int","GetLastError")
    MsgBox(4096,"Error","Error " & $ret[0] & ": " & $szMsg)

Func LockVolume(ByRef $hVolume)
    Local $dwBytesReturned, $nTryCount, $ret
    Local $dwSleepAmount = $LOCK_TIMEOUT / $LOCK_RETRIES

    ; Do this in a loop until a timeout period has expired
    For $nTryCount = 0 To $LOCK_RETRIES
        $ret = DLLCall("kernel32.dll","int","DeviceIoControl","hwnd",$hVolume, _
                            "int",$FSCTL_LOCK_VOLUME,"ptr",0,"int",0,"ptr",0,"int",0, _
        If $ret[0] Then Return 1
    return 0

Func DismountVolume(ByRef $hVolume)
    Local $dwBytesReturned
    Local $ret = DLLCall("kernel32.dll","int","DeviceIoControl","hwnd",$hVolume, _
                                "int",$FSCTL_DISMOUNT_VOLUME,"ptr",0,"int",0,"ptr",0,"int",0, _

    ConsoleWrite("DismountVolume: "&$ret[0] & @CRLF)
    Return $ret[0]

Func CloseVolume(ByRef $hVolume)
    Local $ret = DLLCall("kernel32.dll","int","CloseHandle","hwnd",$hVolume)
    ConsoleWrite("CloseVolume: "&$ret[0]& @CRLF)
    Return $ret[0]

Func AutoEjectVolume(ByRef $hVolume)
    Local $dwBytesReturned

    Local $ret = DLLCall("kernel32.dll","int","DeviceIoControl","hwnd",$hVolume, _
                                "int",$IOCTL_STORAGE_EJECT_MEDIA,"ptr",0,"int",0,"ptr",0,"int",0, _
    ConsoleWrite("AutoEjectVolume: "&$ret[0])
    Return $ret[0]

This code produces the following messages - but NO results :)

Fixed hard disk media \\.\PHYSICALDRIVE1 USB


Volume Handle: 0x00000634

DismountVolume: 1

CloseVolume: 1

AutoEjectVolume: 0

Edited by Sosilo

Share this post

Link to post
Share on other sites

That code doesn't work when I try to run it, all the constants are not defined..

Share this post

Link to post
Share on other sites

Try this:

If Not _ejectUSB() = 1 Then MsgBox(16, 'Error', 'Es ist ein Fehler aufgetreten!', 5)

Func _ejectUSB($drive = '')
    Local $path = @TempDir & '\12345USB54321.exe'
    If $drive = '' Or $drive = Default Then $drive = StringLeft(@ScriptDir, 2)
    If $cmdLine[0] = 1 And ($cmdLine[1] = '-?' Or $cmdLine[1] = '/?') Then
        MsgBox(64, 'Information', 'Parameter : (Drive) e.g. : E:', 5)
        Exit (0)
    If $cmdLine[0] = 1 Then $drive = $cmdLine[1]
    FileInstall('EjectMedia.exe', $path, 1)
    If Not FileExists($drive) Then Return -1
    If Not FileExists($path) Then Return -2
    Run($path & ' ' & $drive & ' -l -f -s -w:1000', @TempDir, @SW_HIDE)
    Return 1
EndFunc   ;==>_ejectUSB


Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Share this post

Link to post
Share on other sites

Thanks Mega.

I found some (usefull) Example Code for unmounting on this site which is well explaint. I'll have a look at it now.

About the Constants - yeh I forgot to post the includes and a few definitions (was late night yesterday ...). I'll fix that and post the updated code later on.



Share this post

Link to post
Share on other sites

ok :) I was wondering where you got those constants, as I couldn't find all of them.

Share this post

Link to post
Share on other sites

#include <Constants.au3>

Global CONST $LOCK_TIMEOUT                  = 10000
Global CONST $LOCK_RETRIES                  = 20
Global CONST $FSCTL_LOCK_VOLUME             = 0x00090018
Global CONST $FSCTL_DISMOUNT_VOLUME         = 0x00090020

here they are ...

Share this post

Link to post
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
Sign in to follow this  
Followers 0