How to Determine a Mapped Drive's Actual Path

How do I determine a mapped drive's actual path?

Here are some code samples:

  • Using P/Invoke

All of the magic derives from a Windows function:

    [DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int WNetGetConnection(
[MarshalAs(UnmanagedType.LPTStr)] string localName,
[MarshalAs(UnmanagedType.LPTStr)] StringBuilder remoteName,
ref int length);

Example invocation:

var sb = new StringBuilder(512);
var size = sb.Capacity;
var error = Mpr.WNetGetConnection("Z:", sb, ref size);
if (error != 0)
throw new Win32Exception(error, "WNetGetConnection failed");
var networkpath = sb.ToString();

How do I determine a mapped drive's details

You could use WMI class win32_logicaldisk in C++, here is the sample:

#include <stdio.h>
#define _WIN32_DCOM
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
#include <iostream>
using namespace std;
#include <comdef.h>

void PrintDriveDetails(wstring drive)
{
HRESULT hr;

IWbemLocator* pWbemLocator = NULL;
IWbemServices* pServices = NULL;
IWbemClassObject* pDrive = NULL;
hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, 0);

if (FAILED(hr))
{
CoUninitialize();
cout << "Failed to initialize security. Error code = 0x" << hex << hr << endl;
return;
}

hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (void**)&pWbemLocator);
if (FAILED(hr))
{
CoUninitialize();
cout << "Failed to CoCreateInstance. Error code = 0x" << hex << hr << endl;
return;
}

_bstr_t bstrNamespace = L"root\\cimv2";

hr = pWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pServices);
if (FAILED(hr))
{
pWbemLocator->Release();
CoUninitialize();
cout << "Failed to Connect to the Server. Error code = 0x" << hex << hr << endl;
return;
}
pWbemLocator->Release();
printf("Successfully connected to namespace.\n");

hr = CoSetProxyBlanket(
pServices,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE
);
if (FAILED(hr))
{
pServices->Release();
cout << "Could not set proxy blanket. Error code = 0x" << hex << hr << endl;
CoUninitialize();
return; // Program has failed.
}

wstring bstrPath = L"Win32_LogicalDisk.DeviceID=\"" + drive + L"\"";

// *******************************************************//
// Perform a full-instance retrieval.
// *******************************************************//
hr = pServices->GetObject(BSTR(bstrPath.c_str()),
0, 0, &pDrive, 0);
if (FAILED(hr))
{
pServices->Release();
CoUninitialize();
cout << "failed GetObject. Error code = 0x" << hex << hr << endl;
return;
}
// Display the object
BSTR bstrDriveObj;
hr = pDrive->GetObjectText(0, &bstrDriveObj);
if (FAILED(hr))
{
pServices->Release();
CoUninitialize();
cout << "failed GetObjectText. Error code = 0x" << hex << hr << endl;
return;
}
printf("%S\n\n", bstrDriveObj);

VARIANT freesize, totlesize;
hr = pDrive->Get(L"FreeSpace", 0, &freesize, 0, NULL);
if (FAILED(hr))
{
pServices->Release();
CoUninitialize();
cout << "failed Get FreeSpace. Error code = 0x" << hex << hr << endl;
return;
}
printf("freesize %S\n", freesize.bstrVal);

hr = pDrive->Get(L"Size", 0, &totlesize, 0, NULL);
if (FAILED(hr))
{
pServices->Release();
CoUninitialize();
cout << "failed Get Size. Error code = 0x" << hex << hr << endl;
return;
}
printf("totlesize : %S\n", totlesize.bstrVal);

VariantClear(&freesize);
VariantClear(&totlesize);
pDrive->Release();
pServices->Release();
pServices = NULL;
}

void main(void)
{
HRESULT hr = S_OK;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

PrintDriveDetails(L"Z:");
CoUninitialize();

return;
};

Determine network path of shared drive on Windows in Python

I was able to resolve the full network path by using the subprocess module with net share, which will list all shared drives.

import platform
import subprocess

def get_network_path(drive_letter: str):
s = subprocess.check_output(['net', 'share']).decode() # get shared drives
for row in s.split("\n")[4:]: # check each row after formatting
split = row.split()
if len(split) == 2: # only check non-default shared drives
if split[1] == '{}:\\'.format(drive_letter):
return r"\\{}\{}".format(platform.node(), split[0])

print(get_network_path("D"))
>>> \\computer-name\data

How to get the UNC path of a mapped network drive in a Java application

Answer taken from the following link:

How to retrieve the UNC path instead of mapped drive path from JFileChooser

The answer was edited into the question.

find specific folder in any mapped drive and report its full UNC path

Mapped drives are not available from an elevated prompt when UAC is configured to "Prompt for credentials" in Windows.

Next code snippet should work even from an elevated command prompt:

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion

set "_FolderToSearch=models" folder name to be searched for

echo no recursion: folder in the root of the drive share:

for /F "delims=" %%D in ('reg query "HKCU\Network"') do (
for /F "tokens=1,2,*" %%f in ('reg query "%%~D" /v RemotePath ^| find /I "RemotePath"') do (
if exist "%%~h\%_FolderToSearch%\" echo # FOUND [%%~nD:] "%%~h\%_FolderToSearch%"
)
)

echo recursive search:

for /F "delims=" %%D in ('reg query "HKCU\Network"') do (
for /F "tokens=1,2,*" %%f in ('reg query "%%~D" /v RemotePath ^| find /I "RemotePath"') do (
for /F "delims=" %%# in ('dir /B /S /AD "%%~h\%_FolderToSearch%*" 2^>NUL') do (
if /I "%%~nx#"=="%_FolderToSearch%" echo # found [%%~nD:] "%%~#"
)
)
)

Detecting if path is on a windows mapped network drive

GetDriveType is one option.

Get Path root (local, mapped network drive or UNC)

The simplest thing you could use for this is

[System.IO.path]::GetPathRoot($path)

It works for UNC paths, network drives and local drives. It does not work will all providers though. Registry for example would not work.

PS M:\> [System.IO.path]::GetPathRoot("C:\temp")
C:\

PS M:\> [System.IO.path]::GetPathRoot("hklm:\temp")

PS M:\> [System.IO.path]::GetPathRoot("\\s5000\Software\Windows\win.ini")
\\s5000\Software

PS M:\> [System.IO.path]::GetPathRoot("M:\DRAFT.docx")
M:\


Related Topics



Leave a reply



Submit