移动磁盘插入后自动弹出的代码——即禁止移动磁盘

网上收集整理,并实际应用。

关键代码:

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;
}

 

posted @ 2013-10-18 23:28  吾非无心  阅读(753)  评论(0编辑  收藏  举报