Polyphem Posted November 7, 2007 Posted November 7, 2007 (edited) Hello Folks,i'm trying to mount a dir as a drive with the api below (i know i could use subst, but my final goal is to play around with HDD drives GUID).DllCall("kernel32.dll", "int", "SetVolumeMountPoint", "str", "\\?\C:\test_dir", "str", "w:\")The functions are described here:http://msdn2.microsoft.com/en-us/library/aa365561.aspxThe directory is empty as required. @error gives me a 0, so the call seems okay, but nothing happens. Anyone got an idea?Any input on this? Thanks and cheers... Edited November 7, 2007 by Polyphem This post will be edited again by Polyphem: Tomorrow, 11:55 AM
CoePSX Posted November 7, 2007 Posted November 7, 2007 There's no function called SetVolumeMountPoint in kernel32.dll. Because this function deals with strings, it's actually implemented as ANSI and Unicode versions. Scroll down the MSDN page and you'll see: Implemented as SetVolumeMountPointW (Unicode) and SetVolumeMountPointA (ANSI). Since AutoIt can be either ANSI or Unicode, you could do something like this: If @Unicode Then DllCall("kernel32.dll", "int", "SetVolumeMountPointW", "str", "\\?\C:\test_dir", "str", "w:\") Else DllCall("kernel32.dll", "int", "SetVolumeMountPointA", "str", "\\?\C:\test_dir", "str", "w:\") EndIf [quote name='Valik' post='301213' date='Jan 31 2007, 10:36 PM']You seem to have a habit of putting things in the wrong place. I feel sorry for any female you attempt to have sex with.[/quote][font="Lucida Sans Unicode"]╔══════════════════════════════╗║░░██░░░░░░░░██░░███░░░████░░░█║║░█░░█░░██░░█░░█░█░░█░█░░░░█░█░║║░█░░░░█░░█░████░███░░░██░░░█░░║║░█░░█░█░░█░█░░░░█░░░░░░░█░█░█░║║░░██░░░██░░░██░░█░░░░███░█░░░█║╚══════════════════════════════╝[/font]
BrettF Posted November 7, 2007 Posted November 7, 2007 There's no function called SetVolumeMountPoint in kernel32.dll. Because this function deals with strings, it's actually implemented as ANSI and Unicode versions. Scroll down the MSDN page and you'll see: Since AutoIt can be either ANSI or Unicode, you could do something like this: If @Unicode Then DllCall("kernel32.dll", "int", "SetVolumeMountPointW", "str", "\\?\C:\test_dir", "str", "w:\") Else DllCall("kernel32.dll", "int", "SetVolumeMountPointA", "str", "\\?\C:\test_dir", "str", "w:\") EndIfoÝ÷ Ûú®¢×¥v}ý¶Ø^¥ªÚÆÞ³r.)¶¬jëh×6If @Unicode Then DllCall("kernel32.dll", "int", "SetVolumeMountPointW", "str", "x:\", "str", "\\?\C:\test_dir") Else DllCall("kernel32.dll", "int", "SetVolumeMountPointA", "str", "x:\", "str", "\\?\C:\test_dir") EndIf Vist my blog!UDFs: Opens The Default Mail Client | _LoginBox | Convert Reg to AU3 | BASS.au3 (BASS.dll) (Includes various BASS Libraries) | MultiLang.au3 (Multi-Language GUIs!)Example Scripts: Computer Info Telnet Server | "Secure" HTTP Server (Based on Manadar's Server)Software: AAMP- Advanced AutoIt Media Player | WorldCam | AYTU - Youtube Uploader Tutorials: Learning to Script with AutoIt V3Projects (Hardware + AutoIt): ArduinoUseful Links: AutoIt 1-2-3 | The AutoIt Downloads Section: | SciTE4AutoIt3 Full Version!
Polyphem Posted November 7, 2007 Author Posted November 7, 2007 There's no function called SetVolumeMountPoint in kernel32.dll. Because this function deals with strings, it's actually implemented as ANSI and Unicode versions.I see, thanks, i'm new to this dll stuff ... sadly, neither example above works for me... This post will be edited again by Polyphem: Tomorrow, 11:55 AM
Polyphem Posted November 7, 2007 Author Posted November 7, 2007 Digged on and come up with this expandcollapse popupIf @Unicode Then $volumemountpoint = DllCall("kernel32.dll", "int", "GetVolumeNameForVolumeMountPointW", "str", "c:\test_dir\") ; DllCall("kernel32.dll", "int", "SetVolumeMountPointW", "str", "w:\", "str", "\\?\C:\test_dir\") DllCall("kernel32.dll", "int", "SetVolumeMountPointW", "str", "w:\", "str", $volumemountpoint) Else $volumemountpoint = DllCall("kernel32.dll", "int", "GetVolumeNameForVolumeMountPointA", "str", "c:\test_dir\") ; DllCall("kernel32.dll", "int", "SetVolumeMountPointA", "str", "w:\", "str", "\\?\C:\test_dir\") DllCall("kernel32.dll", "int", "SetVolumeMountPointW", "str", "w:\", "str", $volumemountpoint) EndIf MsgBox(0,"",_GetLastErrorMessage()) ;=============================================== ; _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") $ret = DllCall("kernel32.dll","int","FormatMessage","int",$FORMAT_MESSAGE_FROM_SYSTEM,"ptr",0,"int",$ret[0],"int",0,"ptr",DllStructGetPtr($p),"int",4096,"ptr",0) $s = DllStructGetData($p,1) If $DisplayMsgBox <> "" Then MsgBox(0,"_GetLastErrorMessage",$DisplayMsgBox & @CRLF & $s) return $s EndFunc Sadly, still not working ... but the doc says i have to add GetVolumeNameForVolumeMountPointW... maybe anyone willing to dig with me, i'll continue to try... This post will be edited again by Polyphem: Tomorrow, 11:55 AM
doudou Posted November 7, 2007 Posted November 7, 2007 It should work like this: If @Unicode Then Local $retStruct = DllStructCreate ("wstr szBuff") DllCall("kernel32.dll", "int", "GetVolumeNameForVolumeMountPointW", "str", "c:\test_dir\", "ptr", DllStructGetPtr($retStruct, 1), "dword", 32768) ; DllCall("kernel32.dll", "int", "SetVolumeMountPointW", "str", "w:\", "str", "\\?\C:\test_dir\") DllCall("kernel32.dll", "int", "SetVolumeMountPointW", "wstr", "w:\", "wstr", DllStructGetData($retStruct, 1)) $retStruct = 0 Else Local $retStruct = DllStructCreate ("str szBuff") $volumemountpoint = DllCall("kernel32.dll", "int", "GetVolumeNameForVolumeMountPointA", "str", "c:\test_dir\", "ptr", DllStructGetPtr($retStruct, 1), "dword", 32768) ; DllCall("kernel32.dll", "int", "SetVolumeMountPointA", "str", "w:\", "str", "\\?\C:\test_dir\") DllCall("kernel32.dll", "int", "SetVolumeMountPointA", "str", "w:\", "str", DllStructGetData($retStruct, 1)) $retStruct = 0 EndIf UDFS & Apps: Spoiler DDEML.au3 - DDE Client + ServerLocalization.au3 - localize your scriptsTLI.au3 - type information on COM objects (TLBINF emulation)TLBAutoEnum.au3 - auto-import of COM constants (enums)AU3Automation - export AU3 scripts via COM interfacesTypeLibInspector - OleView was yesterday Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE
Polyphem Posted November 7, 2007 Author Posted November 7, 2007 (edited) Thanks for your reply. Sadly If @Unicode Then Local $retStruct = DllStructCreate ("wstr szBuff") DllCall("kernel32.dll", "int", "GetVolumeNameForVolumeMountPointW", "str", "\\?\c:\test_dir", "ptr", DllStructGetPtr($retStruct, 1), "dword", 32768) DllCall("kernel32.dll", "int", "SetVolumeMountPointW", "wstr", "w:\", "wstr", DllStructGetData($retStruct, 1)) $retStruct = 0 Else Local $retStruct = DllStructCreate ("str szBuff") DllCall("kernel32.dll", "int", "GetVolumeNameForVolumeMountPointA", "str", "\\?\c:\test_dir", "ptr", DllStructGetPtr($retStruct, 1), "dword", 32768) DllCall("kernel32.dll", "int", "SetVolumeMountPointA", "str", "w:\", "str", DllStructGetData($retStruct, 1)) $retStruct = 0 EndIf _GetLastErrorMessage("Last Error:") ;=============================================== ; _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") $ret = DllCall("kernel32.dll","int","FormatMessage","int",$FORMAT_MESSAGE_FROM_SYSTEM,"ptr",0,"int",$ret[0],"int",0,"ptr",DllStructGetPtr($p),"int",4096,"ptr",0) $s = DllStructGetData($p,1) If $DisplayMsgBox <> "" Then MsgBox(0,"_GetLastErrorMessage",$DisplayMsgBox & @CRLF & $s) return $s EndFunc still gives me a "filename, dirname or volume label syntax is incorrect". Maybe i'll have to dig a little depper into the docs ... Edited November 7, 2007 by Polyphem This post will be edited again by Polyphem: Tomorrow, 11:55 AM
doudou Posted November 7, 2007 Posted November 7, 2007 Perhaps my error in @Unicode block. Wrong: DllCall("kernel32.dll", "int", "GetVolumeNameForVolumeMountPointW", "str", "\\?\c:\test_dir", "ptr", DllStructGetPtr($retStruct, 1), "dword", 32768) Right: DllCall("kernel32.dll", "int", "GetVolumeNameForVolumeMountPointW", "wstr", "\\?\c:\test_dir", "ptr", DllStructGetPtr($retStruct, 1), "dword", 32768) UDFS & Apps: Spoiler DDEML.au3 - DDE Client + ServerLocalization.au3 - localize your scriptsTLI.au3 - type information on COM objects (TLBINF emulation)TLBAutoEnum.au3 - auto-import of COM constants (enums)AU3Automation - export AU3 scripts via COM interfacesTypeLibInspector - OleView was yesterday Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE
Polyphem Posted November 7, 2007 Author Posted November 7, 2007 Nope, same error ... This post will be edited again by Polyphem: Tomorrow, 11:55 AM
doudou Posted November 7, 2007 Posted November 7, 2007 Well I should test my code before posting it. Me stupid, sorry. Now: If @Unicode Then Local $res = DllCall("kernel32.dll", "int", "GetVolumeNameForVolumeMountPointW", "wstr", "w:\", "wstr", "", "dword", 32768) If $res[0] Then DllCall("kernel32.dll", "int", "SetVolumeMountPointW", "wstr", "c:\test_dir\", "wstr", $res[2]) Else Local $res = DllCall("kernel32.dll", "int", "GetVolumeNameForVolumeMountPointA", "str", "w:\", "str", "", "dword", 32768) If $res[0] Then DllCall("kernel32.dll", "int", "SetVolumeMountPointA", "str", "c:\test_dir\", "str", $res[2]) EndIf _GetLastErrorMessage("Last Error:") UDFS & Apps: Spoiler DDEML.au3 - DDE Client + ServerLocalization.au3 - localize your scriptsTLI.au3 - type information on COM objects (TLBINF emulation)TLBAutoEnum.au3 - auto-import of COM constants (enums)AU3Automation - export AU3 scripts via COM interfacesTypeLibInspector - OleView was yesterday Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE
Polyphem Posted November 7, 2007 Author Posted November 7, 2007 Thanks for your efforts doudou... but still doenst work for me ... doesnt complain about the syntax though, but that system cannot find the source file (directory)... This post will be edited again by Polyphem: Tomorrow, 11:55 AM
BrettF Posted November 7, 2007 Posted November 7, 2007 Lets see now... Its got to do with the DllStructCreate has it not? There isn't a wstr in the Struct.... Vist my blog!UDFs: Opens The Default Mail Client | _LoginBox | Convert Reg to AU3 | BASS.au3 (BASS.dll) (Includes various BASS Libraries) | MultiLang.au3 (Multi-Language GUIs!)Example Scripts: Computer Info Telnet Server | "Secure" HTTP Server (Based on Manadar's Server)Software: AAMP- Advanced AutoIt Media Player | WorldCam | AYTU - Youtube Uploader Tutorials: Learning to Script with AutoIt V3Projects (Hardware + AutoIt): ArduinoUseful Links: AutoIt 1-2-3 | The AutoIt Downloads Section: | SciTE4AutoIt3 Full Version!
Gibbo Posted October 21, 2008 Posted October 21, 2008 Just wondering if anyone solved this? I'm trying to write a program to assign letters to USB drives.
Gibbo Posted October 22, 2008 Posted October 22, 2008 For those that are interested I have worked it out (unicode) examples are below. ; GetVolumeNameForVolumeMountPoint Local $retStruct = DllStructCreate ("wchar var1[50]") DllCall("kernel32.dll", "int", "GetVolumeNameForVolumeMountPointW", "wstr", "P:\", "ptr", DllStructGetPtr($retStruct), "dword", 32768) ConsoleWrite(@LF & DllStructGetData($retStruct,1) & @LF) ; SetVolumeNameForVolumeMountPoint DllCall("kernel32.dll", "int", "SetVolumeMountPointW", "wstr", "c:\testdir\", "wstr", "\\?\Volume{da700b4a-9bf8-11dd-b5fd-001b7851e030}\") ; DeleteVolumeMountPoint DllCall("kernel32.dll", "int", "DeleteVolumeMountPointW", "wstr", "c:\testdir\")
rasim Posted October 22, 2008 Posted October 22, 2008 (edited) For those that are interested I have worked it out (unicode) examples are below. Your example doesn't work. Try this: expandcollapse popup$Volume = "C:\" $PointPath = "D:\MyPointFolder\" $UniqName = _VolumeGetUniqName($Volume) If @error Then Exit _VolumeSetMountPoint($PointPath, $UniqName) If @error Then Exit ;_VolumeDeleteMountPoint($PointPath) Func _VolumeGetUniqName($sVolume) Local Const $MAX_VOLUME_NAME = 1024 Local $vNameBuffer = DllStructCreate("wchar[" & $MAX_VOLUME_NAME & "]") $aRet = DllCall("kernel32.dll", "int", "GetVolumeNameForVolumeMountPointW", _ "wstr", $sVolume, _ "ptr", DllStructGetPtr($vNameBuffer), _ "int", $MAX_VOLUME_NAME) If $aRet[0] = 0 Then Return SetError(1, 0, 0) Return DllStructGetData($vNameBuffer, 1) EndFunc Func _VolumeSetMountPoint($sPath, $sUniqName) If Not FileExists($sPath) Then If Not DirCreate($sPath) Then Return SetError(1, 0, 0) EndIf $aRet = DllCall("kernel32.dll", "int", "SetVolumeMountPointW", _ "wstr", $sPath, _ "wstr", $sUniqName) If $aRet[0] = 0 Then Return SetError(2, 0, 0) Return 1 EndFunc Func _VolumeDeleteMountPoint($sPointPath) $aRet = DllCall("kernel32.dll", "int", "DeleteVolumeMountPointW", "wstr", $sPointPath) If $aRet[0] = 0 Then Return SetError(2, 0, 0) Return 1 EndFunc Info: GetVolumeNameForVolumeMountPoint SetVolumeMountPoint DeleteVolumeMountPoint Edit: Comment the _VolumeDeleteMountPoint() function Edited October 22, 2008 by rasim
ProgAndy Posted October 22, 2008 Posted October 22, 2008 (edited) With the VolumeMountPoint funcs, you can mount a VOLUME as Directory or drive, but NOT a DIRECTORY as drive //Edit: sorry, didn't read right Should be possible, though.Well, i was right But you can use thisto mount a directoryGlobal Const $DDD_EXACT_MATCH_ON_REMOVE = 0x00000004 Global Const $DDD_NO_BROADCAST_SYSTEM = 0x00000008 Global Const $DDD_RAW_TARGET_PATH = 0x00000001 Global Const $DDD_REMOVE_DEFINITION = 0x00000002 $DriveLetter = "J:" $Directory = "\DosDevices\D:\Vista" $ret = DllCall("Kernel32.dll","long_ptr","DefineDosDeviceA","dword",$DDD_RAW_TARGET_PATH,"str",$DriveLetter,"str",$Directory) MsgBox(0, '', $Directory & "mounted as " & $DriveLetter & @CRLF & "Click OK to dismount") $ret = DllCall("Kernel32.dll","long_ptr","DefineDosDeviceA","dword",$DDD_REMOVE_DEFINITION,"str",$DriveLetter,"ptr",0) Edited October 22, 2008 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes
Gibbo Posted October 23, 2008 Posted October 23, 2008 With the VolumeMountPoint funcs, you can mount a VOLUME as Directory or drive...So far I have had no success with mounting a volume as a drive.Anyone know how to assign a drive letter to a volume (say a USB stick for example) not mount the volume in a directory.I am trying to solve the horrid XP problem where windows assigns the first available letter to a new USB device, completely ignoring network drives already using that letter. Replicating (at least in part) what this program does.
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