移动磁盘插入后自动弹出的代码——即禁止移动磁盘
网上收集整理,并实际应用。
关键代码:
unsigned int CLeesProcessManager::DirverCheckThread(LPVOID lParam) { CLeesProcessManager* pThis=reinterpret_cast<CLeesProcessManager*>(lParam); //pThis->m_Loger.WriteLog(0,_T("DirverCheckThread Enter.")); while(pThis->m_bRunning) { if(pThis->m_bAutoEjectUsbDrv) { //pThis->m_Loger.WriteLog(0,_T("DirverCheckThread m_bAutoEjectUsbDrv=TRUE.")); DWORD dwDrivers=GetLogicalDrives(); /*for(int i='D';i<'Z';i++) { CString szRootPath=CString((char)i)+CString(":"); if(GetDriveType(szRootPath)==DRIVE_REMOVABLE) pThis->EjectDrive(i); }*/ DWORD dwMask=1; for(int i=0;i<26;i++) { dwMask<<=i; if(dwDrivers&dwMask>0) { CString szRootPath=CString((char)(i+'A'))+CString(":"); if(GetDriveType(szRootPath)==DRIVE_REMOVABLE) pThis->EjectDrive(i+'A'); } } } /*else pThis->m_Loger.WriteLog(0,_T("DirverCheckThread m_bAutoEjectUsbDrv=FALSE."));*/ Sleep(500); } return 0; }
void CLeesProcessManager::EjectDrive(int nUSBVolNum) { STORAGE_DEVICE_NUMBER sdn; DWORD dwBytesReturned = 0; DWORD accessMode = 0, shareMode = 0; HANDLE hDevice; shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; // default accessMode = GENERIC_WRITE | GENERIC_READ; // default CString vol_string = _T("\\\\.\\X:"); vol_string.SetAt(4,nUSBVolNum); hDevice = CreateFile(vol_string,accessMode,shareMode,NULL, OPEN_EXISTING, 0,NULL); if (hDevice == INVALID_HANDLE_VALUE) { //m_USBvolNum=0; return; } long bResult = DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dwBytesReturned, NULL); CloseHandle(hDevice); if (!bResult ) { return; } DWORD dwDiskNumber = sdn.DeviceNumber; CString szRootPath=CString((char)nUSBVolNum)+CString(":"); UINT DriveType = GetDriveType(szRootPath); DWORD dwDevInst = GetDrivesDevInstByDiskNumber(dwDiskNumber, DriveType); if ( dwDevInst == 0 ) { return; } ULONG ProblemNumber=0,Status=0; bResult = CM_Get_Parent(&dwDevInst, dwDevInst, 0); // disk's parent, e.g. the USB bridge, the SATA port... bResult = CM_Get_DevNode_Status(&Status, &ProblemNumber, dwDevInst, 0); PNP_VETO_TYPE VetoType = PNP_VetoTypeUnknown; WCHAR VetoNameW[MAX_PATH]; bool IsRemovable = ((Status & DN_REMOVABLE) != 0); bool bSuccess=false; for ( long tries=1; tries<=50; tries++ ) { // sometimes we need some tries... VetoNameW[0] = 0; if ( IsRemovable ) { bResult = CM_Request_Device_EjectW(dwDevInst, &VetoType, VetoNameW, sizeof(VetoNameW), 0); //res = CM_Request_Device_EjectW(DevInst, &VetoType, NULL, 0, 0); // with MessageBox or 'bubble' } else { bResult = CM_Query_And_Remove_SubTreeW(dwDevInst, &VetoType, VetoNameW, sizeof(VetoNameW), 0); // CM_Query_And_Remove_SubTreeA is not implemented under W2K! } bSuccess = (bResult==CR_SUCCESS && VetoType==PNP_VetoTypeUnknown); if ( bSuccess ) { break; } else { Sleep(100); // required to give the next tries a chance! } } } DWORD CLeesProcessManager::GetDrivesDevInstByDiskNumber(long DiskNumber, UINT DriveType) { GUID* guid; switch (DriveType) { case DRIVE_REMOVABLE: //break; case DRIVE_FIXED: guid = (GUID*)(void*)&GUID_DEVINTERFACE_DISK; break; case DRIVE_CDROM: guid = (GUID*)(void*)&GUID_DEVINTERFACE_CDROM; break; default: return 0; } // 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; 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, &devInterfaceData); if (!bRet) { break; } SetupDiEnumInterfaceDevice(hDevInfo, NULL, guid, dwIndex, &spdid); 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 ) { 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); } } } dwIndex++; } SetupDiDestroyDeviceInfoList(hDevInfo); return 0; }