inserted a usb and need to knowe which drive it occupies? want to eject a USB?
Use this:
the "*****" stand for the class you are using
Force USB Removal Project
Header file
static const GUID GUID_DEVCLASS_COMPUTER =
{ 0x4D36E966, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18} };
// Copy from HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses
static const GUID GUID_DEVINTERFACE_LIST[] =
{
// GUID_DEVINTERFACE_USB_DEVICE
{ 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } },
// GUID_DEVINTERFACE_DISK
{ 0x53f56307, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } },
// GUID_DEVINTERFACE_HID,
{ 0x4D1E55B2, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } },
// GUID_NDIS_LAN_CLASS
{ 0xad498944, 0x762f, 0x11d0, { 0x8d, 0xcb, 0x00, 0xc0, 0x4f, 0xc3, 0x35, 0x8c } }
};
private members:
SP_CLASSIMAGELIST_DATA m_imgList;
Link: Setupapi.lib
Source:
#include "winioctl.h"
#define MAX_DRIVES 26
BEGIN_MESSAGE_MAP(*****, CDialog)
//{{AFX_MSG_MAP(CRSDCDlg)
.
.
.
ON_MESSAGE(WM_DEVICECHANGE, OnMyDeviceChange)
ON_MESSAGE(WM_STATUS_MESAGE, OnStatusMessage)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
*****::OnInitDialog()
{
.
.
ZeroMemory(&m_imgList, sizeof(SP_CLASSIMAGELIST_DATA));
m_imgList.cbSize = sizeof(SP_CLASSIMAGELIST_DATA);
BOOL b = SetupDiGetClassImageList(&m_imgList);
ASSERT(b);
int nRootImg;
b = SetupDiGetClassImageIndex(&m_imgList, &GUID_DEVCLASS_COMPUTER, &nRootImg);
ASSERT(b);
HDEVNOTIFY hDevNotify;
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
for(int i=0; i{
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_LIST[i];
hDevNotify = RegisterDeviceNotification(this->GetSafeHwnd(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
if( !hDevNotify ) {
AfxMessageBox(CString("Can't register device notification: ")
+ _com_error(GetLastError()).ErrorMessage(), MB_ICONEXCLAMATION);
return FALSE;
}
}
.
.
}
//handle windows message regurding USB insertion
LRESULT *****::OnMyDeviceChange(WPARAM wParam, LPARAM lParam)
{
if ( DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam )
{
PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
PDEV_BROADCAST_DEVICEINTERFACE pDevInf;
PDEV_BROADCAST_HANDLE pDevHnd;
PDEV_BROADCAST_OEM pDevOem;
PDEV_BROADCAST_PORT pDevPort;
PDEV_BROADCAST_VOLUME pDevVolume;
switch( pHdr->dbch_devicetype )
{
case DBT_DEVTYP_DEVICEINTERFACE:
pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;
UpdateDevice(pDevInf, wParam);
break;
case DBT_DEVTYP_HANDLE:
pDevHnd = (PDEV_BROADCAST_HANDLE)pHdr;
break;
case DBT_DEVTYP_OEM:
pDevOem = (PDEV_BROADCAST_OEM)pHdr;
break;
case DBT_DEVTYP_PORT:
pDevPort = (PDEV_BROADCAST_PORT)pHdr;
break;
case DBT_DEVTYP_VOLUME:
pDevVolume = (PDEV_BROADCAST_VOLUME)pHdr;
HandleDrive(pDevVolume->dbcv_unitmask);
break;
}
}
return 0;
}
//
void *****::UpdateDevice(PDEV_BROADCAST_DEVICEINTERFACE pDevInf, WPARAM wParam)
{
// pDevInf->dbcc_name:
// \\?\USB#Vid_04e8&Pid_503b#0002F9A9828E0F06#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
// szDevId: USB\Vid_04e8&Pid_503b\0002F9A9828E0F06
// szClass: USB
ASSERT(lstrlen(pDevInf->dbcc_name) > 4);
CString szDevId = pDevInf->dbcc_name+4;
int idx = szDevId.ReverseFind(_T('#'));
ASSERT( -1 != idx );
szDevId.Truncate(idx);
szDevId.Replace(_T('#'), _T('\\'));
szDevId.MakeUpper();
CString szClass;
idx = szDevId.Find(_T('\\'));
ASSERT(-1 != idx );
szClass = szDevId.Left(idx);
if ( DBT_DEVICEARRIVAL == wParam )
{
//szTmp.Format(_T("Adding %s\r\n"), szDevId.GetBuffer());
m_bAdding = true;
printf("Adding %s\n", szDevId.GetBuffer());
} else
{
//szTmp.Format(_T("Removing %s\r\n"), szDevId.GetBuffer());
m_bAdding =false;
printf("Removing %s\n", szDevId.GetBuffer());
}
// seems we should ignore "ROOT" type....
if ( _T("ROOT") == szClass )
{
return;
}
DWORD dwFlag = DBT_DEVICEARRIVAL != wParam ?
DIGCF_ALLCLASSES : (DIGCF_ALLCLASSES | DIGCF_PRESENT);
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL,szClass,NULL,dwFlag);
if( INVALID_HANDLE_VALUE == hDevInfo )
{
AfxMessageBox(CString("SetupDiGetClassDevs(): ")
+ _com_error(GetLastError()).ErrorMessage(), MB_ICONEXCLAMATION);
return;
}
SP_DEVINFO_DATA spDevInfoData;
if ( FindDevice(hDevInfo, szDevId, spDevInfoData) )
{
// OK, device found
DWORD DataT ;
TCHAR buf[MAX_PATH];
DWORD nSize = 0;
// get Friendly Name or Device Description
if ( SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData,
SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, sizeof(buf), &nSize) )
{
printf("%s\n",GetClassDesc(&(spDevInfoData.ClassGuid)));
}
else if ( SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData,
SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize) )
{
printf("%s\n",GetClassDesc(&(spDevInfoData.ClassGuid)));
}
else
{
lstrcpy(buf, _T("Unknown"));
}
if(m_bAdding && GetClassDesc(&(spDevInfoData.ClassGuid)) == "Disk drives")
{
// drive was added handle this!!
}
else if(!m_bAdding) //remove
{
removeDevice(szDevId);
}
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
BOOL *****::FindDevice(HDEVINFO& hDevInfo,
CString& szDevId,
SP_DEVINFO_DATA& spDevInfoData)
{
spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for(int i=0; SetupDiEnumDeviceInfo(hDevInfo, i, &spDevInfoData); i++)
{
DWORD nSize=0 ;
TCHAR buf[MAX_PATH];
if ( !SetupDiGetDeviceInstanceId(hDevInfo, &spDevInfoData, buf, sizeof(buf), &nSize) )
{
printf(CString("SetupDiGetDeviceInstanceId(): ")
+ _com_error(GetLastError()).ErrorMessage());
return FALSE;
}
if ( szDevId == buf ) {
// OK, device found
return TRUE;
}
}
return FALSE;
}
CString *****::GetClassDesc(const GUID* pGuid)
{
TCHAR buf[MAX_PATH];
DWORD size;
if ( SetupDiGetClassDescription(pGuid, buf, sizeof(buf), &size) ) {
return CString(buf);
} else {
printf("Can't get class description: %s", _com_error(GetLastError()).ErrorMessage());
return _T("");
}
}
//disable the popup made via windows
void *****::UsbPopupDisable(CString sUSB)
{
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL,NULL,NULL,DIGCF_ALLCLASSES);
if( INVALID_HANDLE_VALUE == hDevInfo ) {
AfxMessageBox(CString("SetupDiGetClassDevs(): ")
+ _com_error(GetLastError()).ErrorMessage(), MB_ICONEXCLAMATION);
return;
}
SP_PROPCHANGE_PARAMS spPropChangeParams;
spPropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
spPropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
spPropChangeParams.Scope = DICS_FLAG_GLOBAL;
spPropChangeParams.StateChange = DICS_DISABLE;
spPropChangeParams.HwProfile = 0;
SP_DEVINFO_DATA spDevInfoData;
if ( FindDevice(hDevInfo, sUSB, spDevInfoData) )
{
if ( !SetupDiSetClassInstallParams(hDevInfo, &spDevInfoData,
(SP_CLASSINSTALL_HEADER*)&spPropChangeParams, sizeof(spPropChangeParams)) )
{
AfxMessageBox(CString("SetupDiSetClassInstallParams(): ")
+ _com_error(GetLastError()).ErrorMessage(), MB_ICONEXCLAMATION);
} else if ( !SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &spDevInfoData) )
{
AfxMessageBox(CString("SetupDiClassInstaller(): ")
+ _com_error(GetLastError()).ErrorMessage(), MB_ICONEXCLAMATION);
} else {
AfxMessageBox(_T("Dislabe OK"), MB_OK);
}
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
//Description
//
//Finds the first valid drive letter from a mask of drive letters.
//
//The mask must be in the format bit 0 = A, bit 1 = B, bit 3 = C,
//
//etc. A valid drive letter is defined when the corresponding bit
//
//is set to 1.
//
//Returns the first drive letter that was found.
char *****::FirstDriveFromMask (ULONG unitmask)
{
char i;
for (i = 0; i < 26; ++i)
{
if (unitmask & 0x1)
break;
unitmask = unitmask >> 1;
}
return (i + 'A');
}
void *****::HandleDrive(ULONG unitmask)
{
CFile systemNameFile;
CFileException fileError;
CString sDrive;
CString strFilePath;
int nSystemNameSize;
CString strSystemName;
char cSystemName[ MAX_SYSTEM_NAME ];
sDrive.Format("%c:",FirstDriveFromMask(unitmask));
printf("HandleDrive -%s\n",sDrive);
bool bExisted =false;
if(IsDriveAlreadyExist(sDrive,bExisted))
{
if(!bExisted)
{
printf("HandleDrive - %s already exist assuming removed\n",sDrive);
return; //probably device is detaching
}
else // drive was there before the application started
{
removeDevice(sDrive,true);
}
}
RSDC_Status * currentAvailableSlot;
currentAvailableSlot = GetFirstAvailableSlot(true);
if(!currentAvailableSlot)
return;
currentAvailableSlot->eStatus = USB_CONNECTED;
currentAvailableSlot->strDriveName=sDrive;
strFilePath =sDrive + BK_SLASH + SYSTEM_NAME_FILE;
if ( systemNameFile.Open( strFilePath , CFile::modeRead , &fileError ) )
{
printf("HandleDrive - Read file %s\n",strFilePath);
nSystemNameSize = systemNameFile.Read( cSystemName , MAX_SYSTEM_NAME );
cSystemName[ nSystemNameSize ] = '\0'; // puts NULL at the end of the name
strSystemName = A2T( cSystemName );
// If it's new then it is still idle:
}
else
{
printf("Found drive but no System file - Read file %s\n",strFilePath);
}
}
// Search for all of Hard drive devices in the system , and filter the USB's type
void ******::SearchForAllDevices()
{
HANDLE hHardDrive = INVALID_HANDLE_VALUE;
for(int i = 0; i< MAX_DRIVES; i++)
{
CString sFormat;
sFormat.Format("\\\\.\\%c:",'a'+i);
if ((hHardDrive= CreateFile(sFormat,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL)) == INVALID_HANDLE_VALUE)
{
CloseHandle(hHardDrive);
continue;
}
else
{
DISK_GEOMETRY geo;
STORAGE_HOTPLUG_INFO inf;
//GET_MEDIA_TYPES media_types;
DWORD dwSize = 0;
ZeroMemory(&geo,sizeof(geo));
BOOL bRes = DeviceIoControl( hHardDrive, IOCTL_STORAGE_GET_HOTPLUG_INFO , NULL, 0, &inf, sizeof(STORAGE_HOTPLUG_INFO),&dwSize, NULL); // the type of hard disk //geo.MediaType
//bRes = DeviceIoControl(hHardDrive,IOCTL_STORAGE_GET_MEDIA_TYPES_EX,NULL,0,&media_types, sizeof(GET_MEDIA_TYPES),&dwSize, NULL); // the type of hard disk //geo.MediaType
bRes = DeviceIoControl( hHardDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY , NULL, 0, &geo, sizeof(DISK_GEOMETRY),&dwSize, NULL); // the type of hard disk //geo.MediaType
CloseHandle(hHardDrive);
if(bRes && (geo.MediaType == RemovableMedia || geo.MediaType == FixedMedia) && inf.DeviceHotplug )
{
printf("USB found on :%c:\n",'a'+i);
}
else
{
printf("Found drive but no System file - Read file %s\n",strFilePath);
}
}
}
}
}
HANDLE ******::OpenVolume(TCHAR cDriveLetter,BOOL &bIsFixedMedia)
{
HANDLE hVolume;
UINT uDriveType;
TCHAR szVolumeName[8];
TCHAR szRootName[5];
DWORD dwAccessFlags;
LPTSTR szVolumeFormat = TEXT("\\\\.\\%c:");
LPTSTR szRootFormat = TEXT("%c:\\");
wsprintf(szRootName, szRootFormat, cDriveLetter);
uDriveType = GetDriveType(szRootName);
bIsFixedMedia = DRIVE_FIXED == uDriveType;
switch(uDriveType) {
case DRIVE_REMOVABLE:
case DRIVE_FIXED:
dwAccessFlags = GENERIC_READ | GENERIC_WRITE;
break;
case DRIVE_CDROM:
dwAccessFlags = GENERIC_READ;
break;
default:
_tprintf(TEXT("Cannot eject. Drive type is incorrect.\n"));
return INVALID_HANDLE_VALUE;
}
wsprintf(szVolumeName, szVolumeFormat, cDriveLetter);
hVolume = CreateFile( szVolumeName,
dwAccessFlags,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL );
if (hVolume == INVALID_HANDLE_VALUE)
{
printf("Error Opening %s\n",szVolumeFormat);
}
return hVolume;
}
BOOL *******::CloseVolume(HANDLE hVolume)
{
return CloseHandle(hVolume);
}
#define LOCK_TIMEOUT 10000 // 10 Seconds
#define LOCK_RETRIES 20
BOOL *******::LockVolume(HANDLE hVolume)
{
DWORD dwBytesReturned;
DWORD dwSleepAmount;
int nTryCount;
dwSleepAmount = LOCK_TIMEOUT / LOCK_RETRIES;
// Do this in a loop until a timeout period has expired
for (nTryCount = 0; nTryCount < LOCK_RETRIES; nTryCount++) {
if (DeviceIoControl(hVolume,
FSCTL_LOCK_VOLUME,
NULL, 0,
NULL, 0,
&dwBytesReturned,
NULL))
return TRUE;
Sleep(dwSleepAmount);
}
return FALSE;
}
BOOL *******::DismountVolume(HANDLE hVolume)
{
DWORD dwBytesReturned;
return DeviceIoControl( hVolume,
FSCTL_DISMOUNT_VOLUME,
NULL, 0,
NULL, 0,
&dwBytesReturned,
NULL);
}
BOOL ********::PreventRemovalOfVolume(HANDLE hVolume, BOOL fPreventRemoval)
{
DWORD dwBytesReturned;
PREVENT_MEDIA_REMOVAL PMRBuffer;
PMRBuffer.PreventMediaRemoval = fPreventRemoval;
return DeviceIoControl( hVolume,
IOCTL_STORAGE_MEDIA_REMOVAL,
&PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
NULL, 0,
&dwBytesReturned,
NULL);
}
BOOL *******::AutoEjectVolume(HANDLE hVolume)
{
DWORD dwBytesReturned;
return DeviceIoControl( hVolume,
IOCTL_STORAGE_EJECT_MEDIA,
NULL, 0,
NULL, 0,
&dwBytesReturned,
NULL);
}
//************************************
// Description : Eject the USB device
//************************************
BOOL ******::EjectVolume(TCHAR cDriveLetter)
{
HANDLE hVolume;
BOOL fRemoveSafely = FALSE;
BOOL fAutoEject = FALSE;
BOOL bIsFixedMedia = FALSE;
// Open the volume.
hVolume = OpenVolume(cDriveLetter,bIsFixedMedia);
if(bIsFixedMedia = TRUE)
{
if (hVolume == INVALID_HANDLE_VALUE)
return FALSE;
if (!CloseVolume(hVolume))
return FALSE;
//Eject the fixed drive
HINSTANCE hDll;
hDll = LoadLibrary("USBFixedDiskSafeRemoval");
if(hDll == NULL)
{
return FALSE;
}
eject = (EJECT)GetProcAddress(hDll,"fnUSBFixedDiskSafeRemoval");
int result;
if(eject != NULL)
result = (eject)(cDriveLetter);
else
{
FreeLibrary(hDll);
return FALSE;
}
FreeLibrary(hDll);
return TRUE;
}
if (hVolume == INVALID_HANDLE_VALUE)
return FALSE;
// Lock and dismount the volume.
if (LockVolume(hVolume) && DismountVolume(hVolume)) {
fRemoveSafely = TRUE;
// Set prevent removal to false and eject the volume.
if (PreventRemovalOfVolume(hVolume, FALSE) &&
AutoEjectVolume(hVolume))
fAutoEject = TRUE;
}
// Close the volume so other processes can use the drive.
if (!CloseVolume(hVolume))
return FALSE;
if (fAutoEject)
printf("Media in Drive %c has been ejected safely.\n",
cDriveLetter);
else {
if (fRemoveSafely)
printf("Media in Drive %c can be safely removed.\n",
cDriveLetter);
}
return TRUE;
}
0 תגובות:
Post a Comment