Search
Module:
Directory

   Desktop Functions:

   Smart Device Functions:


Show Recent Changes
Subscribe (RSS)
Misc. Pages
Comments
FAQ
Helpful Tools
Playground
Suggested Reading
Website TODO List
Download Visual Studio Add-In

WNetGetUniversalName (advapi32)
 
.
Summary
TODO - a short description

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;

Wrapper

    using System.Runtime.InteropServices;

    static string GetUniversalName(string localPath)
    {
        // The return value.
        string retVal = null ;

        // 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.

After i have changed

retVal = Marshal.PtrToStringAuto(new IntPtr(buffer.ToInt64() + IntPtr.Size));

into

retVal = Marshal.PtrToStringAnsi(new IntPtr(buffer.ToInt64() + IntPtr.Size), size);

all worked fine.

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 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 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));

            rni = (_REMOTE_NAME_INFO)Marshal.PtrToStructure(buffer, typeof(_REMOTE_NAME_INFO));

            retVal.connectionName = Marshal.PtrToStringAuto(rni.lpConnectionName);
            retVal.remainingPath = Marshal.PtrToStringAuto(rni.lpRemainingPath);
            retVal.universalName = Marshal.PtrToStringAuto(rni.lpUniversalName);

            return retVal;
        }
        finally
        {
            // Release the buffer.
            Marshal.FreeCoTaskMem(buffer);
        }

        // First, allocate the memory for the structure.
        // That's all folks.
    }
}

.NET Use in VB

by Mike Gerbi

12/05/2007

Summary
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.

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

    End Class

End Namespace

Create An instance

Imports ScanningTools.Custom.Win32

Public Sample Class

Private path as String

Public Sub GetPath()

    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!

Documentation

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).

 
Access PInvoke.net directly from VS:
Terms of Use
Find References
Show Printable Version
Revisions