0

How do I determine a mapped drive's details like its actual path, FreeSize, and so on? So if I have a mapped drive on a machine called "MP" how can I using C++/Win32 or Qt determine the machine and path for the mapped folder and also other practical details?

I wanted to get extract information from the remote machine filesystem. I can make an SMB connection with the remote machine and get access to shared drive but I wanted to enumerate all information as possible from its file system. How can I do that?

There is a command in Powershell which we can use it to enumerate such information like the following command:

get-WmiObject win32_logicaldisk -Computername remotecomputer

However, I wanted to get such information with written some code in my application and show those information in user friendly format to the user.

  • What details do you need? Total size or others? – Louis Go Jul 15 '20 at 03:13
  • Does this answer your question? [Win32: API calls to list available network shares on a server?](https://stackoverflow.com/questions/899995/win32-api-calls-to-list-available-network-shares-on-a-server) – Christian.K Jul 15 '20 at 03:48
  • @chr Unless I've overlooked something, that proposed duplicate doesn't contain information on how to query for things like available disk space. – IInspectable Jul 15 '20 at 07:09
  • So, do you want to get this `win32_logicaldisk` WMI class in C++? If so, could you check if this sample could help? [Retrieving Part of a WMI Instance Using C++](https://learn.microsoft.com/en-us/windows/win32/wmisdk/retrieving-part-of-an-instance#retrieving-part-of-a-wmi-instance-using-c) – Drake Wu Jul 15 '20 at 07:48
  • @LouisGo Total Size and Free Space. –  Jul 15 '20 at 08:59

1 Answers1

0

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;
};
Drake Wu
  • 6,927
  • 1
  • 7
  • 30
  • Can you edit it to run the "get-WmiObject win32_logicaldisk -Computername remotecomputer" command? I am not familiar with COM things. –  Jul 17 '20 at 07:46
  • This document [Example: Getting WMI Data from a Remote Computer](https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-a-remote-computer) and [this sample](https://stackoverflow.com/a/26369137/10611792) of calling `Win32_LogicalDisk.Chkdsk` may be helpful to you. Use the method to obtain a `Win32_LogicalDisk` instance, and then call the method as my answer. – Drake Wu Jul 17 '20 at 07:58