新手求教CreateFile()打开失败,返回5

加盾男爵 2017-09-01 10:51:40
以前没有接触过windows的API,因为程序有用到,所以从网上复制了一个函数

系统是win7,用工具激活为正版,VS2013社区版,程序启动方式为“右键-》已管理员身份运行”

函数功能是判断某个盘符是否为U盘还是移动硬盘(需要把这两个和本地硬盘区别),其中有段代码用到了CreateFile(),问题也是出现在这里,出错,返回5


WCHAR newDrive[256]; //改函数传递进来的参数是CHAR* drive,这里转换为WCHAR
memset(newDrive, 0, sizeof(newDrive));
MultiByteToWideChar(CP_ACP, 0, drive, strlen(drive)+1, newDrive, sizeof(newDrive)/sizeof(newDrive[0]));
_wsetlocale(LC_ALL, newDrive);
wprintf(L"%s", newDrive); //测试下转换是否正确,这里控制台显示结果"C:"而不是"C:/"
//----
hDevice = CreateFile(
newDrive, // 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()); //显示无法打开,错误5
return DWORD(-1);
}


我想问下为什么不能打开本地的C盘或者D盘或者E盘?
...全文
1872 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2017-09-11
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <windows.h>
#include <winioctl.h>

#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE
#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef enum _STORAGE_QUERY_TYPE { 
	PropertyStandardQuery,
	PropertyExistsQuery,
	PropertyMaskQuery,
	PropertyQueryMaxDefined
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;

typedef enum _STORAGE_PROPERTY_ID {
	StorageDeviceProperty,
	StorageAccessAlignmentProperty,
	StorageAdapterProperty,
	StorageDeviceIdProperty,
	StorageDeviceUniqueIdProperty,
	StorageDeviceWriteCacheProperty
} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;

typedef struct _STORAGE_PROPERTY_QUERY {
	STORAGE_PROPERTY_ID PropertyId;
	STORAGE_QUERY_TYPE QueryType;
	UCHAR AdditionalParameters[1];
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;

/*
typedef enum _STORAGE_BUS_TYPE { 
	BusTypeUnknown            = 0x00,
	BusTypeScsi               = 0x1,
	BusTypeAtapi              = 0x2,
	BusTypeAta                = 0x3,
	BusType1394               = 0x4,
	BusTypeSsa                = 0x5,
	BusTypeFibre              = 0x6,
	BusTypeUsb                = 0x7,
	BusTypeRAID               = 0x8,
	BusTypeiScsi              = 0x9,
	BusTypeSas                = 0xA,
	BusTypeSata               = 0xB,
	BusTypeSd                 = 0xC,
	BusTypeMmc                = 0xD,
	BusTypeVirtual            = 0xE,
	BusTypeFileBackedVirtual  = 0xF,
	BusTypeMax                = 0x10,
	BusTypeMaxReserved        = 0x7F
} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE;
*/

typedef struct _STORAGE_DESCRIPTOR_HEADER {
	ULONG Version;
	ULONG Size;
} STORAGE_DESCRIPTOR_HEADER, *PSTORAGE_DESCRIPTOR_HEADER;

typedef struct _STORAGE_DEVICE_DESCRIPTOR {
	DWORD Version;
	DWORD Size;
	BYTE DeviceType;
	BYTE DeviceTypeModifier;
	BOOLEAN RemovableMedia;
	BOOLEAN CommandQueueing;
	DWORD VendorIdOffset;
	DWORD ProductIdOffset;
	DWORD ProductRevisionOffset;
	DWORD SerialNumberOffset;
	STORAGE_BUS_TYPE BusType;
	DWORD RawPropertiesLength;
	BYTE RawDeviceProperties[1];
} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;

int main(int argc, char *argv[])
{
	TCHAR szDrive[] = TEXT("\\\\.\\D:");
	HANDLE hDevice = CreateFile(szDrive, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hDevice != INVALID_HANDLE_VALUE)
	{
		DWORD dwResult = 0;
		STORAGE_PROPERTY_QUERY spq = { 0 };
		STORAGE_DESCRIPTOR_HEADER sdh = { 0 };
		spq.PropertyId = StorageDeviceProperty;
		spq.QueryType = PropertyStandardQuery;
		BOOL bResult = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &spq, sizeof(spq), &sdh, sizeof(sdh), &dwResult, NULL);
		if (bResult && (sdh.Size > 0))
		{
			STORAGE_DEVICE_DESCRIPTOR *sdd = LocalAlloc(LPTR, sdh.Size);
			if (sdd != NULL)
			{
				bResult = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &spq, sizeof(spq), sdd, sdh.Size, &dwResult, NULL);
				if (bResult)
				{
					// 7 代表 USB 即可移动磁盘
					printf("[%s] => %d\n", szDrive, sdd->BusType);
				}
				LocalFree(sdd);
			}
		}
		CloseHandle(hDevice);
	}
	return 0;
}
「已注销」 2017-09-11
  • 打赏
  • 举报
回复
转码干什么,Windows API 有两个版本,一个 CreateFileA 一个 CreateFileW。你用 CreateFileA 不就得了。CreateFile 打开 X 磁盘的正确参数是 "\\.\X:",对于 C/C++/Java,转义之后是 "\\\\.\\X:",然后用 DeviceIoControl 就能得到是可移动磁盘还是固定的硬盘。
加盾男爵 2017-09-01
  • 打赏
  • 举报
回复
引用 1 楼 smwhotjay 的回复:
Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long 说明 判断一个磁盘驱动器的类型 下面是我用过的

void HDDScan(void)
{
	char		drive[4];

	drive[0] = 'a';
	drive[1] = ':';
	drive[2] = '\\';
	drive[3] = 0;

	int ret;

	// scan the drives
	for (drive[0] = 'a' ; drive[0] <= 'z' ; drive[0]++)
	{
		ret=GetDriveType (drive);
		switch (ret)
		{

		case DRIVE_CDROM:{
			printf("%s盘是DRIVE_CDROM\n",drive);
			break;
							}

		case DRIVE_REMOVABLE:{
			printf("%s盘是DRIVE_REMOVABLE\n",drive);
			break;
							 }
		case DRIVE_FIXED:{
			printf("%s盘是DRIVE_FIXED\n",drive);
			break;
						 }
		case DRIVE_REMOTE:{
			printf("%s盘是DRIVE_REMOTE\n",drive);
			break;
							 }
		case DRIVE_RAMDISK:{
			printf("%s盘是DRIVE_RAMDISK\n",drive);
			break;
						   }
		case DRIVE_UNKNOWN:{
			printf("%s盘是DRIVE_UNKNOWN\n",drive);
			break;
						   }
		}

	}
}
这个不行。。。。本地硬盘和移动硬盘都会识别为DRIVE_FIXED。。。
smwhotjay 2017-09-01
  • 打赏
  • 举报
回复
Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long 说明 判断一个磁盘驱动器的类型 下面是我用过的

void HDDScan(void)
{
	char		drive[4];

	drive[0] = 'a';
	drive[1] = ':';
	drive[2] = '\\';
	drive[3] = 0;

	int ret;

	// scan the drives
	for (drive[0] = 'a' ; drive[0] <= 'z' ; drive[0]++)
	{
		ret=GetDriveType (drive);
		switch (ret)
		{

		case DRIVE_CDROM:{
			printf("%s盘是DRIVE_CDROM\n",drive);
			break;
							}

		case DRIVE_REMOVABLE:{
			printf("%s盘是DRIVE_REMOVABLE\n",drive);
			break;
							 }
		case DRIVE_FIXED:{
			printf("%s盘是DRIVE_FIXED\n",drive);
			break;
						 }
		case DRIVE_REMOTE:{
			printf("%s盘是DRIVE_REMOTE\n",drive);
			break;
							 }
		case DRIVE_RAMDISK:{
			printf("%s盘是DRIVE_RAMDISK\n",drive);
			break;
						   }
		case DRIVE_UNKNOWN:{
			printf("%s盘是DRIVE_UNKNOWN\n",drive);
			break;
						   }
		}

	}
}

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧