Type a page name and press Enter. You'll jump to the page if it exists, or you can create it if it doesn't.
To create a page in a module other than kernel32, prefix the name with the module name and a period.
Declare Function GetVolumePathNamesForVolumeName Lib "kernel32.dll" (TODO) As TODO
VB Signature #2:
Imports System.Runtime.InteropServices
Partial Public Class Win32Methods
'''Return Type: BOOL->int
'''param0: LPCTSTR->LPCWSTR->WCHAR*
'''param1: LPTSTR->LPWSTR->WCHAR*
'''param2: DWORD->unsigned int
'''param3: PDWORD->DWORD*
<DllImportAttribute("kernel32.dll", SetLastError:=True, EntryPoint:="GetVolumePathNamesForVolumeNameW")> _
Public Shared Function GetVolumePathNamesForVolumeNameW(
<[In]()> <MarshalAs(UnmanagedType.LPTStr)>
ByVal sVolumeName As String, _
<MarshalAs(UnmanagedType.LPWStr)> _
ByVal lpBuffer As IntPtr, _
ByVal uintBufferLen As UInteger, _
<Out()> ByRef uintReturnLen As UInteger) _
As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Updated: VB code now uses IntPtr instead of StringBuilder - see sample below
Using StringBuilder for the buffer does not work since this function returns the names as a bunch of strings separated by the null character ('\0'). So StringBuilder would only report the first item. Therefore we store it in a char array, which can later be converted to a bunch of strings.
Tips & Tricks:
Please add some!
Sample Code:
UInt32 dwRequired = 0;
char[] buffer = new char[260];
if (!GetVolumePathNamesForVolumeName(volumeName, buffer, (uint)buffer.Length, ref dwRequired))
{
// Not enough room in buffer perhaps? Try a bigger one
buffer = new char[dwRequired];
if (!GetVolumePathNamesForVolumeName(volumeName, buffer, (uint)buffer.Length, ref dwRequired))
throw new Win32Exception();
}
Sample Code 2:
public List<string> GetMountPointsForVolume(string volumeDeviceName)
{
List<string> result = new List<string>();
// GetVolumePathNamesForVolumeName is only available on Windows XP/2003 and above
int osVersionMajor = Environment.OSVersion.Version.Major;
int osVersionMinor = Environment.OSVersion.Version.Minor;
if (osVersionMajor < 5 || (osVersionMajor == 5 && osVersionMinor < 1))
{
return result;
}
if (!GetVolumePathNamesForVolumeNameW(volumeDeviceName, buffer, lpcchReturnLength, ref lpcchReturnLength))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
string[] mounts = buffer.Split('\0');
foreach (string mount in mounts)
{
if (mount.Length > 0)
{
result.Add(mount);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return result;
}
Sample VB.Net Code (.Net Framework 3.5sp1)
Private Sub ListMountPoints(Optional strVolumeName As String = "")
' if no Volume GUID passed to sub, use this one (corresponds to my USB stick)
If strVolumeName = "" Then
strVolumeName = "\\?\Volume{9a615499-414c-11e0-bd72-78e7d1722cbc}\"
End If
' make this a static in order to stop race condition/thread lock - suspect garbage collector
Static lpBuffer As IntPtr = Marshal.AllocHGlobal(1)
Dim uintBufferLen As UInteger = 0, uintBuffReqLen As UInteger = 0
Const ERROR_MORE_DATA = 234, ERROR_FILE_NOT_FOUND = 2
Dim retval As Boolean = False
Try
' call function to get Required Buffer Length first
retval = Win32Methods.GetMountPointsIntPtr(strVolumeName, lpBuffer, uintBufferLen, uintBuffReqLen)
If Not retval Then
Dim errVal As Integer = Marshal.GetLastWin32Error()
If errVal = ERROR_MORE_DATA Then
'MsgBox("The last Win32 error was: ERROR_MORE_DATA")
ElseIf errVal = ERROR_FILE_NOT_FOUND Then
MsgBox("File not found, did you remember to plug in the USB drive?")
Exit Sub
Else
MsgBox("Error! The last Win32 error was: " + CStr(errVal))
End If
End If
' now set the buffer length
uintBufferLen = uintBuffReqLen
'zero out the length indicator
uintBuffReqLen = 0
Catch ex As Exception
Dim errVal As Integer = Runtime.InteropServices.Marshal.GetLastWin32Error()
MsgBox(ex.Message + ". The last Win32 error was: " + CStr(errVal))
End Try
' now call the function again with the right buffer length
lpBuffer = Runtime.InteropServices.Marshal.ReAllocHGlobal(lpBuffer, CType(uintBuffReqLen, IntPtr))
' uintBufferLen = uintBuffReqLen
uintBuffReqLen = 0
Try
If CBool(Not (Win32Methods.GetMountPointsIntPtr(strVolumeName, lpBuffer, uintBufferLen, uintBuffReqLen))) Then
Dim errVal As Integer = Runtime.InteropServices.Marshal.GetLastWin32Error()
MsgBox("The last Win32 error was: " + CStr(errVal))
End If
Catch ex As Exception
Dim errVal As Integer = Runtime.InteropServices.Marshal.GetLastWin32Error()
MsgBox(ex.Message + ". The last Win32 error was: " + CStr(errVal))
End Try
Dim strOutput As String = Runtime.InteropServices.Marshal.PtrToStringUni(lpBuffer, CInt(uintBuffReqLen))
Dim tmp As Integer = InStr(strOutput, vbNullChar)
strOutput = Strings.Replace(strOutput, vbNullChar, vbCrLf, , , vbBinaryCompare)
' Free the buffer.
Runtime.InteropServices.Marshal.FreeHGlobal(lpBuffer)
lpBuffer = IntPtr.Zero
MsgBox(strVolumeName + vbCrLf + " has the following mountpoints: " + vbCrLf + strOutput.ToString)
End Sub
Click to read this page
10/2/2011 2:35:57 AM - txzhgh-89.110.151.174
An IntPtr is a pointer to a memory location (unmanaged) that adapts to the platform it is running on (64-bit, etc.) UNLIKE a standard int/Integer. You should always use this type for unmanaged calls that require it, even though an int will appear to work on your development machine.
1/13/2008 4:00:13 AM - Damon Carr-72.43.165.29
Click to read this page
10/2/2011 2:35:57 AM - txzhgh-89.110.151.174
Click to read this page
10/2/2011 2:35:57 AM - txzhgh-89.110.151.174
Click to read this page
10/2/2011 2:35:57 AM - txzhgh-89.110.151.174
Please edit this page!
Do you have...
helpful tips or sample code to share for using this API in managed code?
corrections to the existing content?
variations of the signature you want to share?
additional languages you want to include?
Select "Edit This Page" on the right hand toolbar and edit it! Or add new pages containing supporting types needed for this API (structures, delegates, and more).