USB和裝置管理員問題? |
尚未結案
|
kyo319
一般會員 發表:2 回覆:1 積分:0 註冊:2008-12-18 發送簡訊給我 |
各位先進好~小弟碰到個關於USB的問題想請教各位...
情況是這樣的: 小弟想送訊息給OS,告知"我移除了USB裝置"(但事實上並未移除), 並且從裝置管理員中來看該USB裝置確實是消失的,目前利用: SetupDiCallClassInstaller() 以及 CM_Request_Device_Eject() 都可順利達成。但如今有個USB裝置,接上USB裝置後使用同樣的方式欲將該裝置移除, 但卻發生了ㄧ件事: 裝置管理員中看該裝置竟然還在!並且是黃色驚嘆號。 這是很奇怪的ㄧ件事,應當利用API告知OS我們移除裝置後,裝置管理員應當查覺並且UPDATE資訊,可是卻碰到這樣的事... 所以小弟想冒昧請問一下,是否有方法可以靠程式來控制裝置管理員中 "有黃色驚嘆號"的裝置可以自動忽略並update圖示呢? 又或者是可以利用註冊檔來控制 改變 這件事呢(?!) |
boss.tw
高階會員 發表:15 回覆:109 積分:194 註冊:2005-05-17 發送簡訊給我 |
[code cpp] // // RemoveDriveByLetter.cpp by Uwe Sieber - www.uwe-sieber.de // // Modified 09-05-2006 by Andy Walker to be included in u3-autorun.exe #include "stdafx.h" #include "u3-autorun.h" //------------------------------------------------- DEVINST GetDrivesDevInstByDiskNumber(long DiskNumber, UINT DriveType); //------------------------------------------------- //------------------------------------------------- //int RemoveDriveByLetter(char* argv[]) //int RemoveDriveByLetter(char argv[]) int RemoveDriveByLetter(char DriveLetter) { /*if ( argc != 2 ) { return 1; }*/ //char DriveLetter = argv[1][0]; //char DriveLetter = argv[0]; DriveLetter &= ~0x20; // uppercase if ( DriveLetter < 'A' || DriveLetter > 'Z' ) { return 1; } char szRootPath[] = "X:\\"; // "X:\" szRootPath[0] = DriveLetter; char szVolumeAccessPath[] = "\\\\.\\X:"; // "\\.\X:" szVolumeAccessPath[4] = DriveLetter; long DiskNumber = -1; HANDLE hVolume = CreateFile(szVolumeAccessPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL); if (hVolume == INVALID_HANDLE_VALUE) { return 1; } STORAGE_DEVICE_NUMBER sdn; DWORD dwBytesReturned = 0; long res = DeviceIoControl(hVolume, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dwBytesReturned, NULL); if ( res ) { DiskNumber = sdn.DeviceNumber; } CloseHandle(hVolume); if ( DiskNumber == -1 ) { return 1; } UINT DriveType = GetDriveType(szRootPath); DEVINST DevInst = GetDrivesDevInstByDiskNumber(DiskNumber, DriveType); if ( DevInst == 0 ) { return 1; } ULONG Status = 0; ULONG ProblemNumber = 0; PNP_VETO_TYPE VetoType = PNP_VetoTypeUnknown; WCHAR VetoNameW[MAX_PATH]; bool bSuccess = false; res = CM_Get_Parent(&DevInst, DevInst, 0); // disk's parent, e.g. the USB bridge, the SATA port.... res = CM_Get_DevNode_Status(&Status, &ProblemNumber, DevInst, 0); bool IsRemovable = ((Status & DN_REMOVABLE) != 0); for ( long tries=1; tries<=10; tries ) { // sometimes we need some tries... VetoNameW[0] = 0; if ( IsRemovable ) { res = CM_Request_Device_EjectW(DevInst, &VetoType, VetoNameW, sizeof(VetoNameW), 0); //res = CM_Request_Device_EjectW(DevInst, &VetoType, NULL, 0, 0); // with MessageBox or 'bubble' } else { res = CM_Query_And_Remove_SubTreeW(DevInst, &VetoType, VetoNameW, sizeof(VetoNameW), 0); // CM_Query_And_Remove_SubTreeA is not implemented under W2K! } bSuccess = (res==CR_SUCCESS && VetoType==PNP_VetoTypeUnknown); if ( bSuccess ) { break; } else { Sleep(200); // required to give the next tries a chance! } } if ( bSuccess ) { printf("Success\n\n"); return 0; } printf("failed\n"); printf("Result=0x%2X\n", res); if ( VetoNameW[0] ) { printf("VetoName=%ws)\n\n", VetoNameW); } return 1; } //----------------------------------------------------------- //----------------------------------------------------------- DEVINST GetDrivesDevInstByDiskNumber(long DiskNumber, UINT DriveType) { GUID* guid; switch (DriveType) { case DRIVE_REMOVABLE: 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 = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); //if ( pspdidd == NULL ) { // return 0; // damn //} 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 ) { // the device instance id string contains the serial number if the // device has one... // char szDevInstId[260] = {0}; // SetupDiGetDeviceInstanceId(hDevInfo, &spdd, szDevInstId, 260, NULL); // printf("DevInstId=%s\n", szDevInstId); 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); //HeapFree(GetProcessHeap(), 0, pspdidd); SetupDiDestroyDeviceInfoList(hDevInfo); return spdd.DevInst; } } CloseHandle(hDrive); } } //HeapFree(GetProcessHeap(), 0, pspdidd); } dwIndex ; } SetupDiDestroyDeviceInfoList(hDevInfo); return 0; } //----------------------------------------------------------- [/code]
編輯記錄
boss.tw 重新編輯於 2008-12-23 10:37:09, 註解 無‧
|
kyo319
一般會員 發表:2 回覆:1 積分:0 註冊:2008-12-18 發送簡訊給我 |
謝謝您的答覆~
該程式我研究過了,但似乎還是無法解決我的問題... 小弟我外接的裝置未被歸類到 "通用序列匯流排控制器" 中, 雖然確實是USB裝置,但被OS認為是自己獨立的裝置。 因此前輩您提供的程式無法 "控制" 我外接的裝置,甚至用 USB\VID_1234&PID_5678... VID的方式要它 Remove 會被視為 Invalid drive .... 我想我的問題應該在於 "如何移除裝置管理員中黃色驚嘆號?" 至於 "如何移除usb裝置" 我想我試的方式已經很多了~ 可能已經不是最重要的地方了。 裝置管理員中 remove 後的顯示,update 的資訊是小弟我困惑的地方,還有勞各位前輩多多幫忙了。 多謝^_^ |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |