USB存储设备的5种打开方式以及其关系

发布日期:2025-10-09 22:59:38 分类:365bet网上网投 浏览:2730

1. USB存储设备的标识

USB存储设备插入电脑之后,系统会给设备分配物理驱动器号、设备路径、卷路径。

1.1. 物理驱动器号

StringMeaning\\.\PhysicalDrive0Opens the first physical drive.\\.\PhysicalDrive1Opens the third physical drive.1.2. 设备路径

DevicePath:

\\.\usbstor#disk&ven_usb&prod_flash_drive&rev_1.00#6&31e44d9c&3#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}

1.3. 卷路径

卷又被称为逻辑驱动器。

VolumePath:

\\.\Volume{65f4b646-a379-11e9-a35f-005056c00008}

1.3.1 卷设备名

一个卷都对应一个卷设备名。

VolumeName:

\\.\HarddiskVolume57

1.3.2 逻辑驱动器号

逻辑驱动器号它是操作系统方便用户直接访问卷而建立的一个映射。

即给卷分配挂载点(Mount Point),可以通过SetVolumeMountPoint来实现。挂载点有两种形式,一种是直接分配逻辑盘符(Logic disk letter),另一种是卷文件夹(Mounted folder)。如C盘空间不够,电脑插入一个新的硬盘,我们可以直接将这个硬盘挂载到C盘下作为C盘的一个文件夹。

Logic Disk Letter:

H:\

2. 设备标识之间的关系

2.1. 通过逻辑盘符获取物理设备号

DWORD GetPhysicalDriveFromDiskLetter(char letter)

{

CHAR path[DISK_PATH_LEN] = {0};

sprintf(path, "\\\\.\\%c:", letter);

HANDLE hDevice = CreateFile(path, // drive to open

GENERIC_READ | GENERIC_WRITE, // access to the drive

FILE_SHARE_READ | FILE_SHARE_WRITE, //share mode

NULL, // default security attributes

OPEN_EXISTING, // disposition

0, // file attributes

NULL); // do not copy file attribute

if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive

{

fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());

return DWORD(-1);

}

DWORD readed = 0; // discard results

STORAGE_DEVICE_NUMBER ; //use this to get disk numbers

BOOL result = DeviceIoControl(

hDevice, // handle to device

IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode

NULL, // lpInBuffer

0, // nInBufferSize

&number, // output buffer

sizeof(number), // size of output buffer

&readed, // number of bytes returned

NULL // OVERLAPPED structure

);

if (!result) // fail

{

fprintf(stderr, "IOCTL_STORAGE_GET_DEVICE_NUMBER Error: %ld\n", GetLastError());

(void)CloseHandle(hDevice);

return (DWORD)-1;

}

//printf("%d %d %d\n\n", number.DeviceType, number.DeviceNumber, number.PartitionNumber);

(void)CloseHandle(hDevice);

return number.DeviceNumber;

}

2.2. 通过卷名获取物理设备号

DWORD GetPhysicalDriveFromVolumeName(LPCSTR lpcVolumeName)

{

CHAR path[DISK_PATH_LEN] = {0};

sprintf(path, "\\\\.\\%s", lpcVolumeName);

// 如:"\\.\Volume{f0a05445-2d33-11e6-9b0b-806e6f6e6963}"

HANDLE hDevice = CreateFile(path, // drive to open

GENERIC_READ | GENERIC_WRITE, // access to the drive

FILE_SHARE_READ | FILE_SHARE_WRITE, //share mode

NULL, // default security attributes

OPEN_EXISTING, // disposition

0, // file attributes

NULL); // do not copy file attribute

if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive

{

fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());

return DWORD(-1);

}

DWORD readed = 0; // discard results

STORAGE_DEVICE_NUMBER number; //use this to get disk numbers

BOOL result = DeviceIoControl(

hDevice, // handle to device

IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode

NULL, // lpInBuffer

0, // nInBufferSize

&number, // output buffer

sizeof(number), // size of output buffer

&readed, // number of bytes returned

NULL // OVERLAPPED structure

);

if (!result) // fail

{

fprintf(stderr, "IOCTL_STORAGE_GET_DEVICE_NUMBER Error: %ld\n", GetLastError());

(void)CloseHandle(hDevice);

return (DWORD)-1;

}

//printf("%d %d %d\n\n", number.DeviceType, number.DeviceNumber, number.PartitionNumber);

(void)CloseHandle(hDevice);

return number.DeviceNumber;

}

2.3 获取所有的逻辑盘符

int GetAllDisk(std::vector& vecDrives)

{

char szbuf[MAX_PATH] = {0};

GetLogicalDriveStringsA(MAX_PATH,szbuf);

int nCount = 0;

char * pDrive = szbuf;

for(int nlen =strlen(szbuf); nlen == 3 ;nCount++)

{

CString strDrive = pDrive;

vecDrives.push_back(strDrive);

pDrive +=4;

nlen = strlen(pDrive);

}

return nCount;

}

2.4. 获取所有的卷

int GetAllVolume(vector& vstrVolume)

{

CHAR DeviceName[MAX_PATH] = "";

DWORD Error = ERROR_SUCCESS;

HANDLE FindHandle = INVALID_HANDLE_VALUE;

BOOL Found = FALSE;

size_t Index = 0;

BOOL Success = FALSE;

CHAR VolumeName[MAX_PATH] = "";

int nVolumeCnt = 0;

//

// Enumerate all volumes in the system.

FindHandle = FindFirstVolume(VolumeName, ARRAYSIZE(VolumeName));

if (FindHandle == INVALID_HANDLE_VALUE)

{

Error = GetLastError();

return 0;

}

for (;;)

{

//

// Skip the \\?\ prefix and remove the trailing backslash.

if (VolumeName[0] != L'\\' ||

VolumeName[1] != L'\\' ||

VolumeName[2] != L'?' ||

VolumeName[3] != L'\\' ||

VolumeName[Index] != L'\\')

{

Error = ERROR_BAD_PATHNAME;

break;

}

nVolumeCnt++;

vstrVolume.push_back(VolumeName);

// Move on to the next volume.

Success = FindNextVolume(FindHandle, VolumeName, ARRAYSIZE(VolumeName));

if ( !Success )

{

Error = GetLastError();

if (Error != ERROR_NO_MORE_FILES)

{

break;

}

//

// Finished iterating

// through all the volumes.

Error = ERROR_SUCCESS;

break;

}

}

FindVolumeClose(FindHandle);

FindHandle = INVALID_HANDLE_VALUE;

return nVolumeCnt;

}

2.5. 通过挂载点获取卷名

char szMountPointName[MAX_PATH]="J:\\";

char szVolumeName[MAX_PATH]="";

GetVolumeNameForVolumeMountPoint(szMountPointName,szVolumeName,MAX_PATH);

2.6. 遍历所有的卷、卷路径、挂载点

#include

#include

void DisplayVolumePaths(

__in PWCHAR VolumeName

)

{

DWORD CharCount = MAX_PATH + 1;

PWCHAR Names = NULL;

PWCHAR NameIdx = NULL;

BOOL Success = FALSE;

for (;;)

{

//

// Allocate a buffer to hold the paths.

Names = (PWCHAR) new BYTE [CharCount * sizeof(WCHAR)];

if ( !Names )

{

//

// If memory can't be allocated, return.

return;

}

//

// Obtain all of the paths

// for this volume.

Success = GetVolumePathNamesForVolumeNameW(

VolumeName, Names, CharCount, &CharCount

);

if ( Success )

{

break;

}

if ( GetLastError() != ERROR_MORE_DATA )

{

break;

}

//

// Try again with the

// new suggested size.

delete [] Names;

Names = NULL;

}

if ( Success )

{

//

// Display the various paths.

for ( NameIdx = Names;

NameIdx[0] != L'\0';

NameIdx += wcslen(NameIdx) + 1 )

{

wprintf(L" %s", NameIdx);

}

wprintf(L"\n");

}

if ( Names != NULL )

{

delete [] Names;

Names = NULL;

}

return;

}

void __cdecl wmain(void)

{

DWORD CharCount = 0;

WCHAR DeviceName[MAX_PATH] = L"";

DWORD Error = ERROR_SUCCESS;

HANDLE FindHandle = INVALID_HANDLE_VALUE;

BOOL Found = FALSE;

size_t Index = 0;

BOOL Success = FALSE;

WCHAR VolumeName[MAX_PATH] = L"";

//

// Enumerate all volumes in the system.

FindHandle = FindFirstVolumeW(VolumeName, ARRAYSIZE(VolumeName));

if (FindHandle == INVALID_HANDLE_VALUE)

{

Error = GetLastError();

wprintf(L"FindFirstVolumeW failed with error code %d\n", Error);

return;

}

for (;;)

{

//

// Skip the \\?\ prefix and remove the trailing backslash.

Index = wcslen(VolumeName) - 1;

if (VolumeName[0] != L'\\' ||

VolumeName[1] != L'\\' ||

VolumeName[2] != L'?' ||

VolumeName[3] != L'\\' ||

VolumeName[Index] != L'\\')

{

Error = ERROR_BAD_PATHNAME;

wprintf(L"FindFirstVolumeW/FindNextVolumeW returned a bad path: %s\n", VolumeName);

break;

}

//

// QueryDosDeviceW does not allow a trailing backslash,

// so temporarily remove it.

VolumeName[Index] = L'\0';

CharCount = QueryDosDeviceW(&VolumeName[4], DeviceName, ARRAYSIZE(DeviceName));

VolumeName[Index] = L'\\';

if ( CharCount == 0 )

{

Error = GetLastError();

wprintf(L"QueryDosDeviceW failed with error code %d\n", Error);

break;

}

wprintf(L"\nFound a device:\n %s", DeviceName);

wprintf(L"\nVolume name: %s", VolumeName);

wprintf(L"\nPaths:");

DisplayVolumePaths(VolumeName);

//

// Move on to the next volume.

Success = FindNextVolumeW(FindHandle, VolumeName, ARRAYSIZE(VolumeName));

if ( !Success )

{

Error = GetLastError();

if (Error != ERROR_NO_MORE_FILES)

{

wprintf(L"FindNextVolumeW failed with error code %d\n", Error);

break;

}

//

// Finished iterating

// through all the volumes.

Error = ERROR_SUCCESS;

break;

}

}

FindVolumeClose(FindHandle);

FindHandle = INVALID_HANDLE_VALUE;

return;

}

2.7. 获取所有的磁盘设备路径

DWORD GetAllDiskDevicePath(vector& vstrDevice)

{

GUID* guid = (GUID*)&GUID_DEVINTERFACE_DISK;

// Get device interface info set handle

// for all devices attached to system

HDEVINFO hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL,

DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

if ( hDevInfo == INVALID_HANDLE_VALUE ) {

return 0;

}

// Retrieve a context structure for a device interface

// of a device information set.

DWORD dwIndex = 0;

BOOL bRet = FALSE;

BYTE Buf[1024];

PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;

SP_DEVICE_INTERFACE_DATA spdid;

SP_DEVINFO_DATA spdd;

DWORD dwSize;

spdid.cbSize = sizeof(spdid);

while ( true )

{

bRet = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guid, dwIndex, &spdid);

if ( !bRet )

{

break;

}

dwSize = 0;

SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, NULL, 0, &dwSize, NULL);

if ( dwSize!=0 && dwSize<=sizeof(Buf) )

{

pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!

ZeroMemory((PVOID)&spdd, sizeof(spdd));

spdd.cbSize = sizeof(spdd);

long res = SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, pspdidd,

dwSize, &dwSize, &spdd);

if ( res )

{

vstrDevice.push_back(pspdidd->DevicePath);

}

}

dwIndex++;

}

SetupDiDestroyDeviceInfoList(hDevInfo);

return dwIndex;

}