我注意到,一些 USB 存储设备没有在 Windows 中注册为常规驱动器,因为它们甚至没有分配驱动器号。因此,我显然无法使用标准文件操作 C API 访问它们。
我可以使用哪些 WinAPI 调用在那些奇怪的设备上执行一些正常的文件操作 - 所以:
- 完全查找/枚举这些设备,
- 浏览设备上的文件/目录树并获取一些文件统计信息(大小、修改日期等),
- 读/写文件的内容,
- 创建/删除文件/目录?
此外,这些设备/协议已知/调用的一般关键字是什么?
如果您谈论的是看起来像已安装卷但没有任何已安装点的移动设备,那么它们被称为Windows便携式设备,它们不是已安装的卷。
Windows 不直接访问文件系统,它只通过媒体传输协议( MTP ) 或图片传输协议( PTP ) 与它们通信,并创建一个shell 命名空间扩展来向用户呈现一个虚拟文件夹。
如果您想与这类设备进行通信,那么您很可能希望使用WPD API。
如果您谈论的是没有分配任何驱动器号的USB 大容量存储设备,那么它只是一个没有安装点的卷。您需要在读取/写入之前安装该卷。
您可以使用卷管理功能:
GUID
这是一个用 C 语言快速编写的示例,它列出了所有现有的卷、挂载未挂载的卷并显示有关每个卷的一些信息:
char volumeID[256], volumePathName[256], volumeName[256], volumeFS[256];
char newMountPoint[4] = " :\\";
unsigned long volumeSerialNumber;
unsigned long size;
HANDLE handle = FindFirstVolume(volumeID, 256);
do {
printf("Volume GUID = %s\n", volumeID);
GetVolumePathNamesForVolumeName(volumeID, volumePathName, 256, &size);
if(strlen(volumePathName) == 0) {
printf("Not mounted\n");
newMountPoint[0] = firstFreeLetter();
if(SetVolumeMountPoint(newMountPoint, volumeID)) {
GetVolumePathNamesForVolumeName(volumeID, volumePathName, 256, &size);
printf("Now mounted on %s\n", volumePathName);
}
}
else {
printf("Mounted on %s\n", volumePathName);
}
GetVolumeInformation(volumePathName, volumeName, 256, &volumeSerialNumber,
NULL, NULL, volumeFS, 256);
printf("Volume name = %s, FS = %s, serial = %lu\n\n",
volumeName, volumeFS, volumeSerialNumber);
}while(FindNextVolume(handle, volumeID, 256));
FindVolumeClose(handle);
我故意简化了这个例子,但是一个卷可以有多个挂载点(volumePathName
实际上是一个多字符串)。它使用此函数获取第一个可用字母(在 之后'C'
)以安装驱动器:
char firstFreeLetter() {
unsigned long freeLetters = GetLogicalDrives();
if(freeLetters < 4) return 0;
char letter = 'C';
for(unsigned long i=4; (freeLetters & i) != 0; ++letter, i <<= 1);
return letter;
}
是的。在少数情况下 USB 驱动器没有驱动器号。
我相信你的情况是#2。
为了访问存储设备中的文件,您需要将其强制安装为带有驱动器号的存储设备。除非您有挂载点,否则您无法访问我相信的文件。这取决于设备。某些设备 (MTP) 具有内部设置来决定是否检测为存储。您可以探索 MTP 设备中的设置。
否则需要通过代码强制所有存储设备挂载。