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 advapi32, prefix the name with the module name and a period.
WNetGetUniversalName (advapi32)
.
C# Signature:
[DllImport("mpr.dll")]
[return:MarshalAs(UnmanagedType.U4)]
static extern int WNetGetUniversalName(
string lpLocalPath,
[MarshalAs(UnmanagedType.U4)] int dwInfoLevel,
IntPtr lpBuffer,
[MarshalAs(UnmanagedType.U4)] ref int lpBufferSize);
VB Signature:
Declare Function WNetGetUniversalName Lib "advapi32.dll" (TODO) As TODO
Constants:
const int UNIVERSAL_NAME_INFO_LEVEL = 0x00000001;
const int REMOTE_NAME_INFO_LEVEL = 0x00000002;
const int ERROR_MORE_DATA = 234;
const int NOERROR = 0;
// The pointer in memory to the structure.
IntPtr buffer = IntPtr.Zero;
// Wrap in a try/catch block for cleanup.
try
{
// First, call WNetGetUniversalName to get the size.
int size = 0;
// Make the call.
// Pass IntPtr.Size because the API doesn't like null, even though
// size is zero. We know that IntPtr.Size will be
// aligned correctly.
int apiRetVal = WNetGetUniversalName(localPath, UNIVERSAL_NAME_INFO_LEVEL, (IntPtr) IntPtr.Size, ref size);
// If the return value is not ERROR_MORE_DATA, then
// raise an exception.
if (apiRetVal != ERROR_MORE_DATA)
// Throw an exception.
throw new Win32Exception(apiRetVal);
// Allocate the memory.
buffer = Marshal.AllocCoTaskMem(size);
// Now make the call.
apiRetVal = WNetGetUniversalName(localPath, UNIVERSAL_NAME_INFO_LEVEL, buffer, ref size);
// If it didn't succeed, then throw.
if (apiRetVal != NOERROR)
// Throw an exception.
throw new Win32Exception(apiRetVal);
// Now get the string. It's all in the same buffer, but
// the pointer is first, so offset the pointer by IntPtr.Size
// and pass to PtrToStringAuto.
retVal = Marshal.PtrToStringAuto(new IntPtr(buffer.ToInt64() + IntPtr.Size));
}
finally
{
// Release the buffer.
Marshal.FreeCoTaskMem(buffer);
}
// First, allocate the memory for the structure.
// That's all folks.
return retVal;
}
Notes:
Note by Günter Prossliner 2005-08-29
PtrToStringAuto doesn't work on my system. I have tested in on a clean WindowsXP professional maschine. The PtrToStringAuto function just returns garbage. After stepping into the function with the debugger I was looking a the Memory - Windows pointing to the address of "buffer". What I've seen there was a "normal" zero - terminated ANSI String.
If you take a look at the IL - Code of Marshal.PtrToStringAuto(IntPtr) you can see that this function calls 'kernel32:lstrlen' and 'kernel32:lstrcpy' using a buffer (StringBuilder) with the size of lstrlen.
The code of Marshal.PtrToStringAuto(IntPtr, Int32 size) looks quite different: It checks out the Marshal.SystemDefaultCharSize field and simply calls 'PtrToStringAnsi' or 'PtrToStringUni'.
Tips & Tricks:
Please add some!
Sample Code:
/* This needs cleaning up -- errr but I'm paid by the hour so I don't have the time. I mostly ripped the wrapper and modified it. It provides an alternative to pointer arithmetic though...*/
/*
typedef struct _REMOTE_NAME_INFO
{
LPTSTR lpUniversalName;
LPTSTR lpConnectionName;
LPTSTR lpRemainingPath;
} REMOTE_NAME_INFO;
*/
[StructLayout(LayoutKind.Sequential)]
struct _REMOTE_NAME_INFO
{
public IntPtr lpUniversalName;
public IntPtr lpConnectionName;
public IntPtr lpRemainingPath;
}
public struct RemoteNameInfo
{
public string universalName;
public string connectionName;
public string remainingPath;
}
public class WNet
{
const int UNIVERSAL_NAME_INFO_LEVEL = 0x00000001;
const int REMOTE_NAME_INFO_LEVEL = 0x00000002;
const int ERROR_MORE_DATA = 234;
const int ERROR_NOT_CONNECTED = 2250;
const int NOERROR = 0;
[DllImport("mpr.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.U4)]
private static extern int WNetGetUniversalNameW(
string lpLocalPath,
[MarshalAs(UnmanagedType.U4)] int dwInfoLevel,
IntPtr lpBuffer,
[MarshalAs(UnmanagedType.U4)] ref int lpBufferSize);
public static RemoteNameInfo GetRemoteNameInfo(string localPath)
{
// The return value.
RemoteNameInfo retVal;
_REMOTE_NAME_INFO rni;
// The pointer in memory to the structure.
IntPtr buffer = IntPtr.Zero;
// Wrap in a try/catch block for cleanup.
try
{
// First, call WNetGetUniversalName to get the size.
int size = 0;
// Make the call.
// Pass IntPtr.Size because the API doesn't like null, even though
// size is zero. We know that IntPtr.Size will be
// aligned correctly.
int apiRetVal = WNetGetUniversalNameW(localPath, REMOTE_NAME_INFO_LEVEL, (IntPtr)IntPtr.Size, ref size);
// if the return value is ERROR_NOT_CONNECTED, then
// this is a local path
if (apiRetVal == ERROR_NOT_CONNECTED)
{
retVal = new RemoteNameInfo();
retVal.connectionName = Path.GetPathRoot(localPath);
retVal.remainingPath = localPath.Substring(Path.GetPathRoot(localPath).Length);
retVal.universalName = localPath;
return retVal;
}
// If the return value is not ERROR_MORE_DATA, then
// raise an exception.
if (apiRetVal != ERROR_MORE_DATA)
// Throw an exception.
throw new System.ComponentModel.Win32Exception();
// Allocate the memory.
buffer = Marshal.AllocCoTaskMem(size);
// Now make the call.
apiRetVal = WNetGetUniversalNameW(localPath, REMOTE_NAME_INFO_LEVEL, buffer, ref size);
// If it didn't succeed, then throw.
if (apiRetVal != NOERROR)
// Throw an exception.
throw new System.ComponentModel.Win32Exception();
// Now get the string. It's all in the same buffer, but
// the pointer is first, so offset the pointer by IntPtr.Size
// and pass to PtrToStringAuto.
//retVal = Marshal.PtrToStringAuto(new IntPtr(buffer.ToInt64() + IntPtr.Size));
// First, allocate the memory for the structure.
// That's all folks.
}
}
.NET Use in VB
by Mike Gerbi
12/05/2007
Make A New Class
Imports System.Runtime.InteropServices
Namespace Custom.Win32
'You can add more functionality from this DLL in this namespace and import it in future projects to get everything.
Public Class MPR_DotNET_Version
Private bufSize As Integer = 1000
Private myPath As String = ""
Private lpBuffer As IntPtr = Marshal.AllocHGlobal(bufSize)
Public Enum INFO_LEVEL As Integer
UNIVERSAL_NAME_INFO_LEVEL = 1
REMOTE_NAME_INFO_LEVEL = 2
End Enum
Public Sub New(ByVal path As String)
myPath = path
End Sub
Public Function GetUnivseralName() As String
Dim uname As New UNIVERSAL_NAME_INFO
Try
Dim result As String = myPath
Dim ret As Int32 = GetUName(result, INFO_LEVEL.UNIVERSAL_NAME_INFO_LEVEL, lpBuffer, bufSize)
If ret = 0 Then
Marshal.PtrToStructure(lpBuffer, uname)
ElseIf ret = 2250 Then
Throw New ArgumentException("Not Connected")
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
Marshal.FreeHGlobal(lpBuffer)
End Try
Return uname.UniversalName.ToString
End Function
<DllImport("mpr.dll", Entrypoint:="WNetGetUniversalName", CharSet:=CharSet.Auto, SetLastError:=False)> _
Private Shared Function GetUName(ByVal Path As String, ByVal outName As INFO_LEVEL, _
ByVal bObj As IntPtr, ByRef bSize As Integer) As Integer
End Function
End Class
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto), Serializable()> Class UNIVERSAL_NAME_INFO
<MarshalAs(UnmanagedType.LPTStr)> Public UniversalName As String
<MarshalAs(UnmanagedType.LPTStr)> Public ConnectionName As String
<MarshalAs(UnmanagedType.LPTStr)> Public RemainingPath As String
Dim result As DialogResult = mainFolderBrowserDialog.ShowDialog
If result = Windows.Forms.DialogResult.OK Then
Dim dirInfo As DirectoryInfo = New DirectoryInfo(mainFolderBrowserDialog.SelectedPath)
path = mainFolderBrowserDialog.SelectedPath
'Here I get the UNC path and use it later in another routine.
Dim UNI As MPR_DotNET_Version = New MPR_DotNET_Version(path)
path = UNI.GetUnivseralName
For Each f As FileInfo In dirInfo.GetFiles
If f.Extension = ".txt" Then
TextFileListView.Items.Add(f.Name)
ElseIf f.Extension = ".pdf" Then
PDFListView.Items.Add(f.Name)
End If
Next
ElseIf result = Windows.Forms.DialogResult.Cancel Then
Me.Close()
Else
Throw New System.Exception
End If
Catch ex As System.Exception
MsgBox(ex.Message)
WriteToErrorLog(ex)
End Try
End Sub
Alternative Managed API:
Do you know one? Please contribute it!
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
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
This utilizes the WNetGetUniversalName method in MPR.dll. Once implemented, all you have to do is create an instance of the MPR_DotNET_Version class and use the GetUniversalName method. You can also add on to this class for other functionality if you choose. Hope this helps.
6/13/2012 12:15:52 PM - -24.132.191.153
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).