Announcement

Collapse
No announcement yet.

Mount file/folder as drive

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Michael Zimmer
    replied
    Here is a working example for SetVolumeMountPoint() function.
    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "WIN32API.INC"
    
    DECLARE FUNCTION SetVolumeMountPoint LIB "KERNEL32.DLL" ALIAS "SetVolumeMountPointA" ( lpszVolumeMountPoint AS ASCIIZ, lpszVolumeName AS ASCIIZ ) AS DWORD
    DECLARE FUNCTION DeleteVolumeMountPoint LIB "KERNEL32.DLL" ALIAS "DeleteVolumeMountPointA" ( lpszVolumeMountPoint AS ASCIIZ ) AS DWORD
    'DECLARE FUNCTION GetVolumeNameForVolumeMountPoint LIB "KERNEL32.DLL" ALIAS "GetVolumeNameForVolumeMountPointA" (lpszVolumeMountPoint AS ASCIIZ, byval lpszVolumeName AS ASCIIZ ptr, Byval cchBufferLength AS DWORD) AS LONG
    
    '----------------------------------------------------------------------
    ' Function  SystemErrorMessageText
    '           deliver a text message for a given API-error number
    ' in        error code by GetLastError()
    ' out       error text
    '----------------------------------------------------------------------
    FUNCTION SystemErrorMessageText (BYVAL ECode AS LONG) AS STRING
    
      LOCAL Buffer  AS ASCIIZ * 255
      LOCAL sText   AS STRING
    
      FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %Null, ECode, %Null, buffer, SIZEOF(buffer), BYVAL %Null
      sText = FORMAT$(ECode, "##### ") & Buffer
      FUNCTION = TRIM$( sText )
    
    END FUNCTION
    
    
    
    FUNCTION PBMAIN () AS LONG
    
        LOCAL Drv       AS ASCIIZ * 30
        LOCAL Path      AS ASCIIZ * %Max_Path
        LOCAL buffer    AS ASCIIZ * %Max_Path
        LOCAL lResult   AS LONG
        LOCAL bufLen    AS DWORD
        LOCAL lerr      AS DWORD
    
        Drv = "C:\"
        Path= "K:\test\"
        buffer = STRING$(%Max_Path, " ")
        bufLen = SIZEOF(buffer)
        lResult = GetVolumeNameForVolumeMountPoint( Drv, buffer, bufLen )
        lerr = GetLastError
        IF lResult <> 0 THEN
            lResult = SetVolumeMountPoint( Path, buffer )
            lerr = GetLastError()
            IF lResult = 0 THEN
                MSGBOX "Buffer="+buffer+$CRLF+"SetVolumeMountPoint-Error "+SystemErrorMessageText(lerr)
            ELSE
                MSGBOX "Mount successful, look up in explorer!"
                MSGBOX "Dismount drive now: "+Drv
                lResult = DeleteVolumeMountPoint( Drv )
            END IF
        ELSE
            MSGBOX "Received no volumename for mountpoint. Error:"+SystemErrorMessageText(lerr)
        END IF
    
    END FUNCTION
    Also there is a fast way to display a folder as a new drive (loke DOS SUBST):
    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "WIN32API.INC"
    
    DECLARE FUNCTION SetVolumeMountPoint LIB "KERNEL32.DLL" ALIAS "SetVolumeMountPointA" ( lpszVolumeMountPoint AS ASCIIZ, lpszVolumeName AS ASCIIZ ) AS DWORD
    DECLARE FUNCTION DeleteVolumeMountPoint LIB "KERNEL32.DLL" ALIAS "DeleteVolumeMountPointA" ( lpszVolumeMountPoint AS ASCIIZ ) AS DWORD
    'DECLARE FUNCTION GetVolumeNameForVolumeMountPoint LIB "KERNEL32.DLL" ALIAS "GetVolumeNameForVolumeMountPointA" (lpszVolumeMountPoint AS ASCIIZ, byval lpszVolumeName AS ASCIIZ ptr, Byval cchBufferLength AS DWORD) AS LONG
    
    '----------------------------------------------------------------------
    ' Function  SystemErrorMessageText
    '           deliver a text message for a given API-error number
    ' in        error code by GetLastError()
    ' out       error text
    '----------------------------------------------------------------------
    FUNCTION SystemErrorMessageText (BYVAL ECode AS LONG) AS STRING
    
      LOCAL Buffer  AS ASCIIZ * 255
      LOCAL sText   AS STRING
    
      FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %Null, ECode, %Null, buffer, SIZEOF(buffer), BYVAL %Null
      sText = FORMAT$(ECode, "##### ") & Buffer
      FUNCTION = TRIM$( sText )
    
    END FUNCTION
    
    
    
    FUNCTION PBMAIN () AS LONG
    
        LOCAL Drv       AS ASCIIZ * 3
        LOCAL Path      AS ASCIIZ * 50
        LOCAL lResult   AS LONG
        LOCAL lerr      AS DWORD
    
        Drv = "Y:"
        Path= "\DosDevices\C:\Windows"
        lResult = DefineDosDevice(%DDD_RAW_TARGET_PATH, Drv, Path )
        lerr = GetLastError
        IF lResult = 0 THEN
            MSGBOX "DDD-error: "+SystemErrorMessageText(lerr)
        ELSE
            MSGBOX "success"
            lResult = DefineDosDevice( %DDD_REMOVE_DEFINITION, Drv, "")
            IF lResult <> 0 THEN
                MSGBOX "Drive "+Drv+" removed."
            ELSE
                MSGBOX "Could not remove drive "+Drv
            END IF
        END IF
    
    END FUNCTION
    Though the codes above is working, it does not what i intendet with. Searched MSDN for more information: if you want to mount a virtual drive with the contents of a file you need to write a devicedriver. This looks complicated and therefore a lot of books have been written for this.
    I will begin with this one: Developing Windows NT Device Drivers: A Programmer's Handbook (ISBN:0201695901) and with the MSDN DDK of course.

    Leave a comment:


  • Scott Hauser
    replied
    From MSDN: http://msdn2.microsoft.com/en-us/library/aa364994.aspx

    BOOL WINAPI GetVolumeNameForVolumeMountPoint(
    __in LPCTSTR lpszVolumeMountPoint,
    __out LPTSTR lpszVolumeName,
    __in DWORD cchBufferLength
    );
    Parameters
    lpszVolumeMountPoint
    The path of a volume mount point (with a trailing backslash, "\") or a drive letter indicating a root directory (in the form "D:\").

    lpszVolumeName
    A pointer to a string that receives the volume name. This name is a unique volume name of the form "\\?\Volume{GUID}\" where GUID is the GUID that identifies the volume.

    cchBufferLength
    The length of the output buffer, in TCHARs. A reasonable size for the buffer to accommodate the largest possible volume name is 50 characters.

    Return Value
    If the function succeeds, the return value is nonzero.
    Unless I completely mis-read the above, lpszVolumeName will be in the form of a GUID. It doesn't appear to be optional.

    I completely misread it: : dunce_cap:

    "\\?\Volume{GUID}\"

    where GUID is a globally unique identifier (GUID) that identifies the volume.

    The \\?\ prefix disables path parsing and is not parsed along with the path — for example, "\\?\C:\myworld\private" is parsed as "C:\myworld\private". By prepending paths with \\?\, you can specify paths that are 32,767 Unicode characters long. However, each component in the path cannot be more than a file-system-specific value returned by the function GetVolumeInformation.

    You must specify full paths when using specifying unique volume names with \\?\. This prefix can also be used with paths constructed according to the universal naming convention (UNC), such as "\\OtherComputer\Directory\Filename.ext".

    All volume mount point functions that take a unique volume name as a parameter require the trailing backslash; and all volume mount point functions that return a unique volume name provide the trailing backslash. However, this is not the case with CreateFile. You can open a volume by calling CreateFile and omit the trailing backslash from the volume name you specify. CreateFile processes a unique volume name with an appended backslash as the root directory of the volume.

    Scott
    Last edited by Scott Hauser; 19 Feb 2008, 02:07 AM.

    Leave a comment:


  • Michael Mattias
    replied
    SHELLing SUBST might work. I use SUBST all the time, and as soon as I open a command prompt and type the SUBST command, Explorer refreshes itself with the SUBST'd drive in the tree on the left hand panel.

    (But I do like this SetVolumeMountPoint call, and shall have to play with it. Might be nice to have 'in-process alias' to replace these ultra-long path/file names I often end up with)

    Leave a comment:


  • Chris Holbrook
    replied
    Michael,

    If you look in WIN32API.INC you will see that it is already declared, parameters as ASCIZ, ASCIZ, DWORD resp., result is LONG.

    Leave a comment:


  • Michael Zimmer
    started a topic Mount file/folder as drive

    Mount file/folder as drive

    Hello.

    I'am trying to mount a file (such as ZIP, encrypted file etc.) or a folder as a local drive (like SUBST). I thought i could work with SetVolumeMountPoint function, but i cannot pass a path to it directly i think. So i looked up some C example and found GetVolumeNameforVolumeMountPoint function. In C (WIN.H) it is declared as follwows:

    BOOL WINAPI GetVolumeNameforVolumeMountPointA(LPCSTR,LPSTR,DWORD);

    This is my implementation, but i does not compile (mismatch with prior definition): Any ideas?

    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "WIN32API.INC"
    
    DECLARE FUNCTION SetVolumeMountPoint LIB "KERNEL32.DLL" ALIAS "SetVolumeMountPointA" ( lpszVolumeMountPoint AS ASCIIZ, lpszVolumeName AS ASCIIZ ) AS DWORD
    DECLARE FUNCTION DeleteVolumeMountPoint LIB "KERNEL32.DLL" ALIAS "DeleteVolumeMountPointA" ( lpszVolumeMountPoint AS ASCIIZ ) AS DWORD
    DECLARE FUNCTION GetVolumeNameForVolumeMountPoint LIB "KERNEL32.DLL" ALIAS "GetVolumeNameForVolumeMountPointA" (lpszVolumeMountPoint AS ASCIIZ, lpszVolumeName AS ASCIIZ, cchBufferLength AS DWORD) AS DWORD
    
    '----------------------------------------------------------------------
    ' Function  SystemErrorMessageText
    '           deliver a text message for a given API-error number
    ' in        error code by GetLastError()
    ' out       error text
    '----------------------------------------------------------------------
    FUNCTION SystemErrorMessageText (BYVAL ECode AS LONG) AS STRING
    
      LOCAL Buffer  AS ASCIIZ * 255
      LOCAL sText   AS STRING
    
      FormatMessage %FORMAT_MESSAGE_FROM_SYSTEM, BYVAL %Null, ECode, %Null, buffer, SIZEOF(buffer), BYVAL %Null
      sText = FORMAT$(ECode, "##### ") & Buffer
      FUNCTION = TRIM$( sText )
    
    END FUNCTION
    
    
    
    FUNCTION PBMAIN () AS LONG
    
        LOCAL Drv   AS ASCIIZ * 30
        LOCAL Path  AS ASCIIZ * %Max_Path
        LOCAL lResult   AS LONG
    
        Drv = "Y:\"
        'Path= "\\?\T:\VMmachines\"
        Path= "T:\VMmachines\"
        lResult = SetVolumeMountPoint( Drv, Path )
        'lResult = SetVolumeMountPoint( Drv, Path )
        IF lResult = 0 THEN
            lResult = GetLastError()
            MSGBOX "error "+SystemErrorMessageText(lResult)
        ELSE
            MSGBOX "Mount successful"
            lResult = DeleteVolumeMountPoint( Drv )
        END IF
    
    END FUNCTION
Working...
X