Mapping VolumeID to Disk partition Using the DeviceIOControl API


 


To map a volume with drive letter to disk partition, one may use some combination of WMI classes like


 


Win32_LogicalDisk,Win32_LogicalDiskToPartition,Win32_DiskPartition, Win32_DiskDriveToDiskPartition and Win32_DiskDrive.


 


Unfortunately WMI does not provide a way to map a disk partition that does not have a drive letter associated with it.  There is no WMI class  to associate a disk volume to disk partition directly.  However, one can use the low level DeviceIoControl API to request disk partition information directly from the disk device driver.


 


Below is a sample program to list all the volumeIDs with corresponding partitions and steps to build the sample using WDK.


 


1) Download and install the WDK from http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=36a2630f-5d56-43b5-b996-7633f2ec14ff


 


2) Start a command prompt and go to the bin directory in WinDDK installtion folder and run setenv.bat for whatever system you are building for, for example:


setenv C:\WinDDK\7268.0.0 chk WNET


 


3)  At this point you have a build environment pointing to the WDK install folders created within the CMD window. 


4)  Create a folder named ‘mounts’  in the build environment folder created in step 3 (in this example C:\WinDDK\7268.0.0) and create following files in it


 


                * A Header file named ‘enumvol.h’ using the code snippet given below under enumvol.h header


                * A ‘C’ source file named ‘mounts.c’ using code snippet given below under ‘mounts.c’header


                * A ‘MakeFile’ file named ‘MakeFile’using the text given under header ‘MakeFile’ header


                * A ‘Source’ file named ‘Source’using the text given under ‘Source’header


5) Navigate to the folder created in step 4  and run “bcz”, this will create an executable file that will display the disk partition information.


 


 


Source Files


================


 
  ‘===================================================================
  ‘ DISCLAIMER:
  ‘——————————————————————-
  ‘
  ‘ This sample is provided as is and is not meant for use on a
  ‘ production environment. It is provided only for illustrative
  ‘ purposes. The end user must test and modify the sample to suit
  ‘ their target environment.
  ‘
  ‘ Microsoft can make no representation concerning the content of
  ‘ this sample. Microsoft is providing this information only as a
  ‘ convenience to you. This is to inform you that Microsoft has not
  ‘ tested the sample and therefore cannot make any representations
  ‘ regarding the quality, safety, or suitability of any code or
  ‘ information found here.
  ‘
  ‘===================================================================


 


/**************************************************enumvol.h************************************************/


 


 


#ifndef _ENUMVOL_H_


#define _ENUMVOL_H_


 


//


// Command Descriptor Block constants.


//


 


#define CDB6GENERIC_LENGTH         6


#define CDB10GENERIC_LENGTH        10


#define SCSIOP_INQUIRY             0x12


 


 


#define BUF_LEN                 (8*1024)


#define DIRECT_ACCESS_DEVICE    0


 


 


// Define constants for \DosDevices\X:


 


#define DOSDEVICES_LENGTH       12


#define DRIVE_LETTER_LENGTH     14


#define DRIVE_LETTER_POSITION   12


#define DRIVE_COLON_POSITION    13


                               


#define MOUNTMGR_NAME           “\\\\.\\MountPointManager


 


//


// Bus Type


//


 


static char* BusType[] = {


    “UNKNOWN”,  // 0x00


    “SCSI”,


    “ATAPI”,


    “ATA”,


    “IEEE 1394”,


    “SSA”,


    “FIBRE”,


    “USB”,


    “RAID”


};


 


//


// SCSI Device Type


//


 


static char* DeviceType[] = {


    “Direct Access Device”, // 0x00


    “Tape Device”,          // 0x01


    “Printer Device”,       // 0x02


    “Processor Device”,     // 0x03


    “WORM Device”,          // 0x04


    “CDROM Device”,         // 0x05


    “Scanner Device”,       // 0x06


    “Optical Disk”,         // 0x07


    “Media Changer”,        // 0x08


    “Comm. Device”,         // 0x09


    “ASCIT8”,               // 0x0A


    “ASCIT8”,               // 0x0B


    “Array Device”,         // 0x0C


    “Enclosure Device”,     // 0x0D


    “RBC Device”,           // 0x0E


    “Unknown Device”        // 0x0F


};


 


 


typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS {


    SCSI_PASS_THROUGH Spt;


    ULONG             Filler;      // realign buffers to double word boundary


    UCHAR             SenseBuf[32];


    UCHAR             DataBuf[512];


} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS;


 


 


VOID PrintError( ULONG );


BOOL GetDeviceProperty( HDEVINFO, DWORD );


VOID DebugPrint( USHORT, PCHAR, … );


void PrintMountName(PMOUNTDEV_NAME mountName);


void PrintName(PWCHAR Name, USHORT Len);


void GetDriveLetter(PMOUNTDEV_NAME mountName);


void GetVolumeExtents(PWCHAR volumeGuid);


BOOL IsDriveLetter(PWCHAR Name, USHORT Len);


BOOL IsVolumeGuid(PWCHAR Name, USHORT Len);


 


 


#endif    // _ENUMVOL_H_


 


 


/**************************************************enumvol.h************************************************/


 


 


 


 


/**************************************************mounts.c*************************************************/


 


#include <stdio.h>


#include <stdlib.h>


#include <stddef.h>


#include <windows.h> 


#include <initguid.h>   // Guid definition


#include <devguid.h>    // Device guids


#include <setupapi.h>   // for SetupDiXxx functions.


#include <cfgmgr32.h>   // for SetupDiXxx functions.


#include <devioctl.h> 


#include <ntdddisk.h>


#include <ntddvol.h>


#include <ntddscsi.h>


#include <mountdev.h>


#include <mountmgr.h>


#include <enumvol.h>


 


BOOL GetStorageDeviceNumber(HANDLE device, PSTORAGE_DEVICE_NUMBER number)


{


    BOOL status;


    unsigned long returned_bytes;


    //unsigned long returned_bytes, errno;


 


    status = DeviceIoControl(device,


                             IOCTL_STORAGE_GET_DEVICE_NUMBER,


                             NULL,


                             0,


                             number,


                             sizeof(STORAGE_DEVICE_NUMBER),


                             &returned_bytes,


                             FALSE);


               


    if (!status) {


        errno = GetLastError();


        //printf(“Error getting storage device number: status %d, returned %d\n”, errno, returned_bytes);


        return FALSE;


    } else {


        //printf(“got storage device number: disk%d, part%d\n”,


        //    number->DeviceNumber, number->PartitionNumber);


    }


   


    return TRUE;


 


}


 


BOOL GetPartitionInfoEx(HANDLE device, PPARTITION_INFORMATION_EX PartInfo)


{


    BOOL status;


    unsigned long returned_bytes;


    //unsigned long returned_bytes, errno;


 


    status = DeviceIoControl(device,


                             IOCTL_DISK_GET_PARTITION_INFO_EX,


                             NULL,


                             0,


                             PartInfo,


                             sizeof(PARTITION_INFORMATION_EX),


                             &returned_bytes,


                             FALSE);


               


    if (!status) {


        errno = GetLastError();


        //printf(“Error getting partition info: status %d, returned %d\n”, errno, returned_bytes);


        return FALSE;


    } else {


        //printf(“got partition info: offset %I64x, length %I64x\n”, PartInfo->StartingOffset, PartInfo->PartitionLength);


    }


   


    return TRUE;


 


}


 


BOOL GetPartitionInfo(HANDLE device, PPARTITION_INFORMATION PartInfo)


{


    BOOL status;


    unsigned long returned_bytes;


    //unsigned long returned_bytes, errno;


 


    status = DeviceIoControl(device,


                             IOCTL_DISK_GET_PARTITION_INFO,


                             NULL,


                             0,


                             PartInfo,


                             sizeof(PARTITION_INFORMATION),


                             &returned_bytes,


                             FALSE);


               


    if (!status) {


        errno = GetLastError();


        //printf(“Error getting partition info: status %d, returned %d\n”, errno, returned_bytes);


        return FALSE;


    } else {


       //printf(“got partition info: offset %I64x, length %I64x\n”, PartInfo->StartingOffset, PartInfo->PartitionLength);


    }


   


    return TRUE;


 


}


 


 


ULONG   DebugLevel = 1;


                            // 0 = Suppress All Messages


                            // 1 = Display & Fatal Error Message


                            // 2 = Warning & Debug Messages


                            // 3 = Informational Messages


 


BOOL IsFixedDisk;


WCHAR FoundDevice[256];


BOOL  found = FALSE;


VOID DebugPrint( USHORT DebugPrintLevel, PCHAR DebugMessage, … )


/*++


 


Routine Description:


 


    This routine print the given string, if given debug level is <= to the


    current debug level.


 


Arguments:


 


    DebugPrintLevel – Debug level of the given message


 


    DebugMessage    – Message to be printed


 


–*/


{


 


    va_list args;


 


    va_start(args, DebugMessage);


 


    if (DebugPrintLevel <= DebugLevel) {


        char buffer[128];


        (VOID) vsprintf(buffer, DebugMessage, args);


        printf( “%s”, buffer );


    }


 


    va_end(args);


}


 


 


/*++


 


Routine Description:


 


    This function prints the given Unicode string.


 


Arguments:


 


    WCHAR string and length


 


–*/


 


void PrintName(PWCHAR Name, USHORT Len)


{


    SHORT i;


    for ( i = 0; i < (Len) ; i++ ) {


        printf(“%C”, Name[i]);


    }


}


 


void GetMounts()


{


    DWORD bytesReturned;


    UCHAR Bytes[10000];


    PMOUNTMGR_MOUNT_POINTS pMntPoints = (PMOUNTMGR_MOUNT_POINTS) Bytes;


    MOUNTMGR_MOUNT_POINT mntPoint, *pmnt;


    DWORD err = 0;


    HANDLE h;


    ULONG index;


    WCHAR symbolicName[MAX_PATH], deviceName[MAX_PATH], uniqueId[MAX_PATH];


 


                h = CreateFile(“\\\\.\\MountPointManager“,


                                       GENERIC_READ,


                                       FILE_SHARE_READ | FILE_SHARE_WRITE,


                                       NULL,


                                       OPEN_EXISTING,


                                       0,


                                       NULL);


 


                if (h == INVALID_HANDLE_VALUE) {


                                err = GetLastError();


                                printf(“can’t open: %d\n”, err);


        return;


                }


   


    ZeroMemory(pMntPoints, 10000);


    ZeroMemory(&mntPoint, sizeof(MOUNTMGR_MOUNT_POINT));


   


    pMntPoints->Size = 10000;


    if(DeviceIoControl(h,


                       IOCTL_MOUNTMGR_QUERY_POINTS,


                       &mntPoint,


                       sizeof(MOUNTMGR_MOUNT_POINT),


                       pMntPoints,


                       10000,


                       &bytesReturned,


                       NULL)) {


 


        if(bytesReturned && pMntPoints->Size && pMntPoints->NumberOfMountPoints) {


            for(index = 0; index < pMntPoints->NumberOfMountPoints; index++) {


                pmnt = &pMntPoints->MountPoints[index];


                ZeroMemory(symbolicName, MAX_PATH);


                ZeroMemory(deviceName, MAX_PATH);


                ZeroMemory(uniqueId, MAX_PATH);


 


                wcsncpy(symbolicName, (PWCHAR) &Bytes[pmnt->SymbolicLinkNameOffset], pmnt->SymbolicLinkNameLength/sizeof(WCHAR));


                wcsncpy(uniqueId, (PWCHAR) &Bytes[pmnt->UniqueIdOffset], pmnt->UniqueIdLength/sizeof(WCHAR));


                wcsncpy(deviceName, (PWCHAR) &Bytes[pmnt->DeviceNameOffset], pmnt->DeviceNameLength/sizeof(WCHAR));


                //if (IsVolumeGuid(symbolicName, pmnt->SymbolicLinkNameLength/sizeof(WCHAR))) {


                    printf(“%d) %ws => %ws\n”, index, symbolicName, deviceName);


                //}


                //printf(“%d) %ws => %ws\n”, index, symbolicName, deviceName);


            }


        }


           


    } else {


        err = GetLastError();


    }


   


    CloseHandle(h);


    printf(“err=%d  ret=%d\n”, err, bytesReturned);


 


}


 


int __cdecl main()


/*++


 


Routine Description:


 


    This is the main function. It takes no arguments from the user.


 


Arguments:


 


    None


 


Return Value:


 


  Status


 


–*/


{


    HDEVINFO        hIntDevInfo;


    DWORD           index;


    BOOL            status;


 


    //


    // Open the device using device interface registered by the driver


    //


 


    found = FALSE;


    //


    // Get the interface device information set that contains all devices of event class.


    //


 


    hIntDevInfo = SetupDiGetClassDevs (


                 (LPGUID) &VolumeClassGuid, //&GUID_DEVCLASS_VOLUMESNAPSHOT, //&MOUNTDEV_MOUNTED_DEVICE_GUID, //


                 NULL,                                   // Enumerator


                 NULL,                                   // Parent Window


                 (DIGCF_PRESENT | DIGCF_INTERFACEDEVICE  // Only Devices present & Interface class


                 ));


 


    if( hIntDevInfo == INVALID_HANDLE_VALUE ) {


        DebugPrint( 1, “SetupDiGetClassDevs failed with error: %d\n”, GetLastError() );


        exit(1);


    }


 


    //


    //  Enumerate all the disk devices


    //


    index = 0;


 


    while (TRUE) {


        status = GetDeviceProperty( hIntDevInfo, index );


        if ( status == FALSE ) {


            break;


        }


        index++;


    }


    SetupDiDestroyDeviceInfoList(hIntDevInfo);


 


    return 0;


}


 


#define MAX_COMP_INSTID 2096


#define MAX_COMP_DESC   2096


#define MAX_FRIENDLY    2096


BOOL GetDeviceProperty(HDEVINFO IntDevInfo, DWORD Index )


/*++


 


Routine Description:


 


    This routine enumerates the volumes using the Device interface


    GUID VolumeClassGuid. Gets the Adapter & Device property from the port


    driver. Get the mount name, SCSI address and locks the volume for exclusive


    access, if possible.


 


Arguments:


 


    IntDevInfo – Handles to the interface device information list


 


    Index      – Device member


 


Return Value:


 


  TRUE / FALSE. This decides whether to continue or not


 


–*/


{


    SP_DEVICE_INTERFACE_DATA            interfaceData;


    PSP_DEVICE_INTERFACE_DETAIL_DATA    interfaceDetailData = NULL;


    STORAGE_PROPERTY_QUERY              query;


    PSTORAGE_ADAPTER_DESCRIPTOR         adpDesc;


    PSTORAGE_DEVICE_DESCRIPTOR          devDesc;


    SCSI_PASS_THROUGH_WITH_BUFFERS      sptwb;


    PMOUNTDEV_NAME                      mountName;


    PSCSI_ADDRESS                       scsiAddress;


    HANDLE                              hDevice;


    BOOL                                status;


    PUCHAR                              p;


    UCHAR                               outBuf[BUF_LEN];


    ULONG                               returnedLength;


    ULONG                               length = 0,


                                        returned = 0;


    DWORD                               interfaceDetailDataSize,


                                        reqSize,


                                        errorCode,


                                        i;


    PMOUNTDEV_UNIQUE_ID                 mountId;


    STORAGE_DEVICE_NUMBER               number;


    SP_DEVINFO_DATA deid;


    DWORD           dwRegType;


    char           szPdoName[MAX_FRIENDLY];


    char buffer[2048];


    //PDRIVE_LAYOUT_INFORMATION_EX  DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX) buffer;


    PDRIVE_LAYOUT_INFORMATION  DriveLayout = (PDRIVE_LAYOUT_INFORMATION) buffer;


    PARTITION_INFORMATION               PartInfo;


    PARTITION_INFORMATION_EX            PartInfoEx;


 


    interfaceData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);


 


    status = SetupDiEnumDeviceInterfaces (


                IntDevInfo,               // Interface Device Info handle


                0,                        // Device Info data


                (LPGUID)&VolumeClassGuid,


                Index,                    // Member


                &interfaceData            // Device Interface Data


                );


 


    if ( status == FALSE ) {


        errorCode = GetLastError();


        if ( errorCode == ERROR_NO_MORE_ITEMS ) {


            DebugPrint( 2, “No more interfaces\n” );


        }


        else {


            DebugPrint( 1, “SetupDiEnumDeviceInterfaces failed with error: %d\n”, errorCode  );


        }


        return FALSE;


    }


       


    //


    // Find out required buffer size, so pass NULL


    //


 


    status = SetupDiGetDeviceInterfaceDetail (


                IntDevInfo,         // Interface Device info handle


                &interfaceData,     // Interface data for the event class


                NULL,               // Checking for buffer size


                0,                  // Checking for buffer size


                &reqSize,           // Buffer size required to get the detail data


                NULL                // Checking for buffer size


                );


 


    //


    // This call returns ERROR_INSUFFICIENT_BUFFER with reqSize


    // set to the required buffer size. Ignore the above error and


    // pass a bigger buffer to get the detail data


    //


 


    if ( status == FALSE ) {


        errorCode = GetLastError();


        if ( errorCode != ERROR_INSUFFICIENT_BUFFER ) {


            DebugPrint( 1, “SetupDiGetDeviceInterfaceDetail failed with error: %d\n”, errorCode   );


            return FALSE;


        }


    }


 


    //


    // Allocate memory to get the interface detail data


    // This contains the devicepath we need to open the device


    //


 


    interfaceDetailDataSize = reqSize;


    interfaceDetailData = malloc (interfaceDetailDataSize);


    if ( interfaceDetailData == NULL ) {


        DebugPrint( 1, “Unable to allocate memory to get the interface detail data.\n” );


        return FALSE;


    }


    interfaceDetailData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);


 


    status = SetupDiGetDeviceInterfaceDetail (


                  IntDevInfo,               // Interface Device info handle


                  &interfaceData,           // Interface data for the event class


                  interfaceDetailData,      // Interface detail data


                  interfaceDetailDataSize,  // Interface detail data size


                  &reqSize,                 // Buffer size required to get the detail data


                  NULL);                    // Interface device info


 


    if ( status == FALSE ) {


        DebugPrint( 1, “Error in SetupDiGetDeviceInterfaceDetail failed with error: %d\n”, GetLastError() );


        return FALSE;


    }


 


    //printf(“Interface: %s\n”, interfaceDetailData->DevicePath);


    memset(szPdoName, 0, MAX_FRIENDLY);


    deid.cbSize = sizeof(SP_DEVINFO_DATA);


    SetupDiEnumDeviceInfo(IntDevInfo, Index, &deid);


    SetupDiGetDeviceRegistryProperty(IntDevInfo, &deid,


                                     SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,


                                     &dwRegType,


                                     (BYTE*) szPdoName,


                                     MAX_FRIENDLY,


                                     NULL);


    //printf(”    PdoName      : %s\n”,   szPdoName);


    //


    // Now we have the device path. Open the device interface


    // to send Pass Through command


 


    hDevice = CreateFile(


                interfaceDetailData->DevicePath,    // device interface name


                GENERIC_READ | GENERIC_WRITE,       // dwDesiredAccess


                FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode


                NULL,                               // lpSecurityAttributes


                OPEN_EXISTING,                      // dwCreationDistribution


                0,                                  // dwFlagsAndAttributes


                NULL                                // hTemplateFile


                );


               


    if (hDevice == INVALID_HANDLE_VALUE) {


        DebugPrint( 1, “CreateFile failed with error: %d\n”, GetLastError() );


        return TRUE;


    }


 


    free (interfaceDetailData);


    if (hDevice == INVALID_HANDLE_VALUE) {


        DebugPrint( 1, “CreateFile failed with error: %d\n”, GetLastError() );


        return TRUE;


    }


 


    IsFixedDisk = FALSE;


    status = DeviceIoControl(


                    hDevice,               


                    IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,


                    &outBuf,


                    BUF_LEN,


                    &outBuf,                  


                    BUF_LEN,                     


                    &returnedLength,     


                    NULL                   


                    );


    if ( !status ) {


        DebugPrint( 1, “\nIOCTL_MOUNTDEV_QUERY_DEVICE_NAME failed with error code: %d.\n\n”, GetLastError() );


    }


    else {


        mountName = (PMOUNTDEV_NAME)&outBuf;


#if 0


        if (!found) {


            if (wcsstr(mountName->Name, L”Volume\0″)) {


                wcsncpy(FoundDevice, mountName->Name, mountName->NameLength);


                //swprintf(FoundDevice, L”%s”, mountName->Name);


                found = TRUE;


                printf(“\noh yeah we found the device = %ws\n”, FoundDevice);


            }


        }


#endif


    }


 


    // Get Drive letter from mount name


    if (GetStorageDeviceNumber(hDevice, &number)) {


        if (number.PartitionNumber != -1) {


                                GetDriveLetter(mountName);


            printf(“Disk #%d, Partition #%d”, number.DeviceNumber, number.PartitionNumber);


                    if (GetPartitionInfoEx(hDevice, &PartInfoEx)) {


                printf(“\tOffset 0x%I64x\n”, PartInfoEx.StartingOffset);


            } else {


                printf(“[not available for this device]\n”);


            }


        }


    }


 


    // Close handle the driver


    if ( !CloseHandle(hDevice) )     {


        DebugPrint( 2, “Failed to close device.\n”);


    }


 


    return TRUE;


}


 


void GetDriveLetter(PMOUNTDEV_NAME mountName)


{


    HANDLE                  hDevice;


    BOOL                    status;


    ULONG                   returnedLength,


                            nameLength,


                            mountPointsSize;


    UCHAR                   outBuf[BUF_LEN];


    PMOUNTMGR_MOUNT_POINTS  mountMgrQueryPoints;


    PMOUNTMGR_MOUNT_POINT   pMountPoint;


    USHORT                  i;


    WCHAR                   volumeGuid[255];


    BOOL                    showedDevice;


    PWCHAR                  pName;


 


    hDevice = CreateFile(


                MOUNTMGR_NAME,                      // device interface name


                GENERIC_READ,                       // dwDesiredAccess


                FILE_SHARE_READ,                    // dwShareMode


                NULL,                               // lpSecurityAttributes


                OPEN_EXISTING,                      // dwCreationDistribution


                0,                                  // dwFlagsAndAttributes


                NULL                                // hTemplateFile


                );


               


    if (hDevice == INVALID_HANDLE_VALUE) {


        DebugPrint( 1, “CreateFile failed with error: %d\n”, GetLastError() );


        return;


    }


    nameLength =  mountName->NameLength;


    mountPointsSize = sizeof(MOUNTMGR_MOUNT_POINT) + nameLength;


 


    pMountPoint = malloc(mountPointsSize);


    ZeroMemory(pMountPoint, mountPointsSize );


    pMountPoint->DeviceNameOffset = (USHORT) sizeof(MOUNTMGR_MOUNT_POINT);


    pMountPoint->DeviceNameLength = (USHORT) nameLength;


    memcpy( pMountPoint + 1, mountName->Name, nameLength );


 


    ZeroMemory(outBuf, BUF_LEN );


 


    // Get the triples (symbolic links, mount name & unique ID) from Mount Manager


 


    status = DeviceIoControl(


                    hDevice,               


                    IOCTL_MOUNTMGR_QUERY_POINTS,


                    pMountPoint,


                    mountPointsSize,


                    &outBuf,


                    BUF_LEN,


                    &returnedLength,     


                    NULL                   


                    );


    if ( !status ) {


        DebugPrint( 1, “\nIOCTL_MOUNTMGR_QUERY_POINTS failed with error code: %d.\n\n”, GetLastError() );


    }


    mountMgrQueryPoints = (PMOUNTMGR_MOUNT_POINTS) outBuf;


 


    showedDevice = TRUE;


    for (i = 0; i < mountMgrQueryPoints->NumberOfMountPoints – 1; i++ ) {


        pMountPoint = &mountMgrQueryPoints->MountPoints[i];


        if (!showedDevice) {


            if (pMountPoint->DeviceNameLength) {


                DebugPrint( 1, ”    Device Name:  “);


                PrintName( (PWCHAR)((PCHAR)mountMgrQueryPoints + pMountPoint->DeviceNameOffset), pMountPoint->DeviceNameLength/2);


                printf(“\n”);


            }


            if (pMountPoint->UniqueIdLength) {


                DebugPrint( 1, ”    Unique Id: “);


                PrintName( (PWCHAR)((PCHAR)mountMgrQueryPoints + pMountPoint->UniqueIdOffset), pMountPoint->UniqueIdLength/2);


                printf(“\n”);


            }


            showedDevice = TRUE;


        }


        if (pMountPoint->SymbolicLinkNameLength) {


            //pName = (PWCHAR)((PCHAR)mountMgrQueryPoints + pMountPoint->SymbolicLinkNameOffset);


            //if (wcsstr(pName, L”DosDevices”)) {


            //    printf(“got DosDevices…\n”);


            //    //PrintName( pName, (pMountPoint->SymbolicLinkNameLength/2));


            //    PrintName( (PWCHAR)((PCHAR)mountMgrQueryPoints + pMountPoint->SymbolicLinkNameOffset), (pMountPoint->SymbolicLinkNameLength/2));


            //    printf(“\n”);


            //}


            pName = (PWCHAR)((PCHAR)mountMgrQueryPoints + pMountPoint->SymbolicLinkNameOffset);


            if (wcsstr(pName, L”Volume”)) {


                pName = (PWCHAR)((PCHAR)mountMgrQueryPoints + pMountPoint->SymbolicLinkNameOffset);


                pName += 11;


                PrintName( pName, (pMountPoint->SymbolicLinkNameLength/2)-12);


                printf(“\t”);


            }


            //PrintName( (PWCHAR)((PCHAR)mountMgrQueryPoints + pMountPoint->SymbolicLinkNameOffset), (pMountPoint->SymbolicLinkNameLength/2));


        }


    }


 


    //


    // Close handle the driver


    if ( !CloseHandle(hDevice) )     {


        DebugPrint( 1, “Failed to close device.\n”);


    }


    free(pMountPoint);


 


    return;


 


}


 


 


 


/**************************************************mounts.c*************************************************/


 


/*************************************************MakeFile**************************************************/


 


 


#


# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source


# file to this component.  This file merely indirects to the real make file


# that is shared by all the driver components of the Windows NT DDK


#


 


!INCLUDE $(NTMAKEENV)\makefile.def


 


/*************************************************MakeFile**************************************************/


 


/*************************************************Sources***************************************************/


 


TARGETNAME=enumvol


TARGETTYPE=PROGRAM


 


UMTYPE=console


UMBASE=0x1000000


USE_LIBCMT=1


 


TARGETPATH=obj


 


INCLUDES=$(DDK_INC_PATH); \


         $(BASEDIR)\inc; \


         $(BASEDIR)\inc\ddk;


 


TARGETLIBS= $(DDK_LIB_PATH)\setupapi.lib


 


SOURCES=mounts.c


 


/*************************************************Sources**********************************************


 


Comments (1)

  1. cbf says:

    There's a memory corruption error in the GetDrive function. fee is called on a pointer that didn't come from the heap.

    Near the top:

       pMountPoint = malloc(mountPointsSize);

    Later, the loop for (i = 0; i < mountMgrQueryPoints->NumberOfMountPoints – 1; i++ ) contains:

     pMountPoint = &mountMgrQueryPoints->MountPoints[i];

    thereby bashing the original pMountPoint

    then right before the return, fee is called:

     free(pMountPoint);

    but that's no longer the pMountPoint we got from malloc.

    I simply changed the pMountPoint assignment within the loop to be:

     PMOUNTMGR_MOUNT_POINT pMountPoint = &mountMgrQueryPoints->MountPoints[i];

    so it's a locally scoped pMountPoint and doesn't bash the one that came from malloc.