static int EjectLogDisk(const char *discId)
{
DWORD accessMode = GENERIC_WRITE | GENERIC_READ;
DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
HANDLE hDevice;
long bResult = 0;
DWORD retu = 0;
DWORD dwError;
DWORD dwBytesReturned;
DWORD dwSleepAmount;
int nTryCount;
char szDriv[10];
if(discId == NULL){
return 0;
}
dwSleepAmount = LOCK_TIMEOUT/LOCK_RETRIES;
sprintf(szDriv,"\\\\.\\%s:",discId);
hDevice = CreateFile(szDriv,accessMode,shareMode,NULL,OPEN_EXISTING,0,NULL);
if(hDevice == INVALID_HANDLE_VALUE){
printf("uninstallusb createfile failed error:%d\n",GetLastError());
return -1;
}
#if 1
//卸载U盘卷,不论是否在使用
dwBytesReturned = 0;
if(!DeviceIoControl(hDevice,FSCTL_DISMOUNT_VOLUME,NULL,0,NULL,0,&dwBytesReturned,NULL)){
printf("deviceIoConrol FSCTL_DISMOUNT_VOLUME failed\n");
}
//此循环是用于锁定要弹出的U盘设备,如果U盘在使用,则循环等待
// Do this in a loop until a timeout period has expired
for(nTryCount = 0;nTryCount < LOCK_RETRIES;nTryCount++){
if(DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&dwBytesReturned,NULL)){
break;
}
}
#endif
dwBytesReturned = 0;
PREVENT_MEDIA_REMOVAL PMRBuffer;
PMRBuffer.PreventMediaRemoval = FALSE;
if(!DeviceIoControl(hDevice,IOCTL_STORAGE_MEDIA_REMOVAL,&PMRBuffer,sizeof(PREVENT_MEDIA_REMOVAL),NULL,0,&dwBytesReturned,NULL)){
printf("DeviceIoControl IOCTL_STORAGE_MEDIA_REMOVAL failed:%d\n",GetLastError());
}
bResult = DeviceIoControl(hDevice,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&retu,NULL);
if(!bResult){
CloseHandle(hDevice);
printf("uninstallusb DeviceIoControl failed error:%d\n",GetLastError());
return -1;
}
CloseHandle(hDevice);
return 0;
}
此方法的作用与从右下角托盘中安全删除并弹出媒体的功能一致,设置之后,设备的错误码为47。并且设备只能通过断上电重新接入电脑才可用。
#include
#include "setupapi.h"
#include "cfgmgr32.h"
#pragma comment(lib,"setupapi.lib")
DEVINST GetDrivesDevInstByDiskNumber(long DiskNumber)
{
GUID* guid = (GUID*)(void*)&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;
SP_DEVICE_INTERFACE_DATA devInterfaceData = {0};
devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
BOOL bRet = FALSE;
PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd;
SP_DEVICE_INTERFACE_DATA spdid;
SP_DEVINFO_DATA spdd;
DWORD dwSize;
spdid.cbSize = sizeof(spdid);
while ( true )
{
bRet = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guid, dwIndex,
&devInterfaceData);
if (!bRet)
{
break;
}
SetupDiEnumInterfaceDevice(hDevInfo, NULL, guid, dwIndex, &spdid);
dwSize = 0;
SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, NULL, 0, &dwSize,NULL);
if ( dwSize )
{
pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, dwSize);
if ( pspdidd == NULL )
{
continue; // autsch
}
pspdidd->cbSize = sizeof(*pspdidd);
ZeroMemory((PVOID)&spdd, sizeof(spdd));
spdd.cbSize = sizeof(spdd);
long res = SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid,pspdidd, dwSize, &dwSize, &spdd);
if ( res )
{
HANDLE hDrive = CreateFile(pspdidd->DevicePath, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
if ( hDrive != INVALID_HANDLE_VALUE )
{
STORAGE_DEVICE_NUMBER sdn;
DWORD dwBytesReturned = 0;
res = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER,NULL, 0, &sdn, sizeof(sdn), &dwBytesReturned, NULL);
if ( res )
{
if ( DiskNumber == (long)sdn.DeviceNumber )
{
CloseHandle(hDrive);
SetupDiDestroyDeviceInfoList(hDevInfo);
return spdd.DevInst;
}
}
CloseHandle(hDrive);
}
}
HeapFree(GetProcessHeap(), 0, pspdidd);
}
dwIndex++;
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return 0;
}
static int EjectUSBDisk(char *discId)
{
DWORD accessMode = GENERIC_WRITE | GENERIC_READ;
DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
HANDLE hDevice;
long bResult = 0;
DWORD retu = 0;
DWORD dwError;
DWORD dwBytesReturned;
int nTryCount;
char szDriv[10];
if(discId == NULL)
{
return 0;
}
sprintf(szDriv,"\\\\.\\%s:",discId);
hDevice = CreateFile(szDriv,accessMode,shareMode,NULL,OPEN_EXISTING,0,NULL);
if(hDevice == INVALID_HANDLE_VALUE)
{
printf("uninstallusb createfile failed error:%d\n",GetLastError());
return -1;
}
//使用CM_Request_Device_Eject弹出USB设备
STORAGE_DEVICE_NUMBER sdn;
long DiskNumber = -1;
long res = DeviceIoControl(hDevice,IOCTL_STORAGE_GET_DEVICE_NUMBER,NULL,0,&sdn,sizeof(sdn),&dwBytesReturned,NULL);
if(!res)
{
printf("DeviceIoControl IOCTL_STORAGE_GET_DEVICE_NUMBER failed:%d\n",GetLastError());
CloseHandle(hDevice);
return -1;
}
CloseHandle(hDevice);
DiskNumber = sdn.DeviceNumber;
if(DiskNumber == -1)
{
printf("DiskNumber == -1\n");
return -1;
}
DEVINST DevInst = GetDrivesDevInstByDiskNumber(DiskNumber);
if(DevInst == 0)
{
printf("GetDrivesDevInstDiskNumber failed\n");
return -1;
}
ULONG Status = 0;
ULONG ProblemNumber = 0;
PNP_VETO_TYPE VetoType = PNP_VetoTypeUnknown;
char VetoName[MAX_PATH];
bool bSuccess = false;
res = CM_Get_Parent(&DevInst,DevInst,0); //disk's parent, e.g. the USB bridge, the SATA controller....
res = CM_Get_DevNode_Status(&Status,&ProblemNumber,DevInst,0);
bool IsRemovable = ((Status & DN_REMOVABLE) != 0);
printf("isremovable:%d\n",IsRemovable);
long i;
// try 3 times
for(i = 0;i < 3;i++)
{
VetoName[0] = '\0';
if(IsRemovable)
{
res = CM_Request_Device_Eject(DevInst,&VetoType,VetoName,MAX_PATH,0);
}
else
{
res = CM_Query_And_Remove_SubTree(DevInst,&VetoType,VetoName,MAX_PATH,0);
}
bSuccess = (res == CR_SUCCESS && VetoName[0] == '\0');
if(bSuccess)
{
break;
}
else
{
Sleep(200);
}
}
if(bSuccess){
printf("Success\n\n");
}else{
printf("failed\n");
}
return 0;
}