static bool IsDeviceHotplug(DEVINST hDevInst) { bool Result = false; dev_info Info; if (Info.Create(hDevInst)) { SP_DEVINFO_DATA DeviceInfoData = {sizeof(DeviceInfoData)}; if(Info.OpenDeviceInfo(DeviceInfoData)) { DWORD Capabilities = 0; if(Info.GetDeviceRegistryProperty(DeviceInfoData, SPDRP_CAPABILITIES, nullptr, reinterpret_cast<PBYTE>(&Capabilities), sizeof(Capabilities), nullptr)) { DWORD Status = 0, Problem = 0; if (CM_Get_DevNode_Status(&Status, &Problem, hDevInst, 0) == CR_SUCCESS) { if ((Problem != CM_PROB_DEVICE_NOT_THERE) && (Problem != CM_PROB_HELD_FOR_EJECT) && //возможно, надо провер¤ть на наличие проблем вообще (Problem != CM_PROB_DISABLED) && (Capabilities & CM_DEVCAP_REMOVABLE) && (!(Capabilities & CM_DEVCAP_SURPRISEREMOVALOK) || IsChildDeviceHotplug(hDevInst)) && !(Capabilities & CM_DEVCAP_DOCKDEVICE)) Result = true; } } } } return Result; }
/* * Flag phantom/removed devices for reinstallation. See: * http://msdn.microsoft.com/en-us/library/aa906206.aspx */ void check_removed(char* device_hardware_id) { unsigned i, removed = 0; DWORD size, reg_type, config_flags; ULONG status, pbm_number; HDEVINFO dev_info; SP_DEVINFO_DATA dev_info_data; char hardware_id[STR_BUFFER_SIZE]; // List all known USB devices (including non present ones) dev_info = SetupDiGetClassDevsA(NULL, "USB", NULL, DIGCF_ALLCLASSES); if (dev_info == INVALID_HANDLE_VALUE) { return; } // Find the ones that are driverless for (i = 0; ; i++) { dev_info_data.cbSize = sizeof(dev_info_data); if (!SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data)) { break; } // Find the hardware ID if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_HARDWAREID, ®_type, (BYTE*)hardware_id, STR_BUFFER_SIZE, &size)) { continue; } // Match? if (safe_strncmp(hardware_id, device_hardware_id, STR_BUFFER_SIZE) != 0) { continue; } // Unplugged? if (CM_Get_DevNode_Status(&status, &pbm_number, dev_info_data.DevInst, 0) != CR_NO_SUCH_DEVNODE) { continue; } // Flag for reinstall on next plugin if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_CONFIGFLAGS, ®_type, (BYTE*)&config_flags, sizeof(DWORD), &size)) { plog("could not read SPDRP_CONFIGFLAGS for phantom device %s", hardware_id); continue; } config_flags |= CONFIGFLAG_REINSTALL; if (!SetupDiSetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_CONFIGFLAGS, (BYTE*)&config_flags, sizeof(DWORD))) { plog("could not write SPDRP_CONFIGFLAGS for phantom device %s", hardware_id); continue; } removed++; } if (removed) { plog("flagged %d removed devices for reinstallation", removed); } }
static bool IsEnabled(PSP_DEVINFO_DATA pDevInfoData) { ULONG status = 0; ULONG problem = 0; if (CM_Get_DevNode_Status(&status, &problem, pDevInfoData->DevInst, 0) != CR_SUCCESS) return FALSE; return (status & (DN_HAS_PROBLEM|DN_NEED_RESTART)) == 0; }
static bool IsDisabled(PSP_DEVINFO_DATA pDevInfoData) { ULONG status = 0; ULONG problem = 0; if (CM_Get_DevNode_Status(&status, &problem, pDevInfoData->DevInst, 0) != CR_SUCCESS) return FALSE; return (status & DN_HAS_PROBLEM) != 0 && problem == CM_PROB_DISABLED; }
// Moves up one node in the device tree and returns its device info data along with an info set only // including that device for further processing // See https://msdn.microsoft.com/en-us/library/windows/hardware/ff549417(v=vs.85).aspx static bool GetParentDevice(const DEVINST& child_device_instance, HDEVINFO* parent_device_info, PSP_DEVINFO_DATA parent_device_data) { ULONG status; ULONG problem_number; CONFIGRET result; // Check if that device instance has device node present result = CM_Get_DevNode_Status(&status, &problem_number, child_device_instance, 0); if (result != CR_SUCCESS) { return false; } DEVINST parent_device; // Get the device instance of the parent result = CM_Get_Parent(&parent_device, child_device_instance, 0); if (result != CR_SUCCESS) { return false; } std::vector<WCHAR> parent_device_id(MAX_DEVICE_ID_LEN); ; // Get the device id of the parent, required to open the device info result = CM_Get_Device_ID(parent_device, parent_device_id.data(), (ULONG)parent_device_id.size(), 0); if (result != CR_SUCCESS) { return false; } // Create a new empty device info set for the device info data (*parent_device_info) = SetupDiCreateDeviceInfoList(nullptr, nullptr); // Open the device info data of the parent and put it in the emtpy info set if (!SetupDiOpenDeviceInfo((*parent_device_info), parent_device_id.data(), nullptr, 0, parent_device_data)) { SetupDiDestroyDeviceInfoList(parent_device_info); return false; } return true; }
void WinNetCard::EnumNetCards(NetCardList *NetDeviceList) { CString DevValue; DWORD Status, Problem; LPTSTR Buffer = NULL; DWORD BufSize = 0; HDEVINFO hDevInfo = 0; if( INVALID_HANDLE_VALUE == (hDevInfo = SetupDiGetClassDevs(NULL,NULL,0,DIGCF_PRESENT|DIGCF_ALLCLASSES))) return; SP_DEVINFO_DATA DeviceInfoData ={sizeof(SP_DEVINFO_DATA)}; PNetCardStruct NetCard = new TNetCardStruct; for(DWORD DeviceId=0;SetupDiEnumDeviceInfo(hDevInfo,DeviceId,&DeviceInfoData);DeviceId++) { if (CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData.DevInst,0) != CR_SUCCESS) continue; if(GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_CLASS , &Buffer, (PULONG)&BufSize)) DevValue = Buffer; if (DevValue == _T("Net")) { if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_ENUMERATOR_NAME , &Buffer, (PULONG)&BufSize)) DevValue = Buffer; if (/*DevValue != "ROOT"*/1) { NetCard->Id = DeviceId; NetCard->Name = "<Unknown Device>"; if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DRIVER , &Buffer, (PULONG)&BufSize)) if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC , &Buffer, (PULONG)&BufSize)) NetCard->Name = Buffer; NetCard->Disabled = (Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem); NetCard->Changed = false; NetDeviceList->push_back(*NetCard); } } } delete NetCard; }
static bool UpdateRebootRequired(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData, BOOL *pRebootRequired) { if (!pRebootRequired) return TRUE; if (*pRebootRequired) return TRUE; ULONG status = 0; ULONG problem = 0; *pRebootRequired = CM_Get_DevNode_Status(&status, &problem, pDevInfoData->DevInst, 0) == CR_SUCCESS && (status & DN_NEED_RESTART) != 0; //if (*pRebootRequired) // Trace("Enumerated status=0x%lX problem=0x%lX\n", status, problem); if (*pRebootRequired) return TRUE; SP_DEVINSTALL_PARAMS installParams; memset(&installParams, 0, sizeof(installParams)); installParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if (!SetupDiGetDeviceInstallParams(hDevInfo, pDevInfoData, &installParams)) { ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiGetDeviceInstallParams()"); return FALSE; } *pRebootRequired = (installParams.Flags & (DI_NEEDREBOOT|DI_NEEDRESTART)) ? TRUE : FALSE; //if (*pRebootRequired) // Trace("Enumerated Flags=0x%lX\n", installParams.Flags); return TRUE; }
HDEVINFO GetNonPresentDevices( _In_ LPCWSTR Enumerator OPTIONAL, _In_ LPCWSTR HardwareID ) /*++ Routine Description: This routine retrieves any non-present devices matching the specified criteria, and returns them in a device information set. Arguments: Enumerator - Optionally, supplies the name of the Enumerator under which this device may be found. If the device may show up under more than one enumerator, the routine can be called with Enumerator specified as NULL, in which case all device instances in the registry are examined. HardwareID - Supplies the hardware ID to be searched for. This will be compared against each of the hardware IDs for all device instances in the system (potentially filtered based on Enumerator), present or not. Return Value: If any non-present devices are discovered, this routine returns a device information set containing those devices. This set must be freed via SetupDiDestroyDeviceInfoList by the caller. If no such devices are encountered (or if an error occurs), the return value is INVALID_HANDLE_VALUE. GetLastError will indicate the cause of failure. --*/ { HDEVINFO AllDevs, ExistingNonPresentDevices; DWORD i, Err; SP_DEVINFO_DATA DeviceInfoData; LPWSTR HwIdBuffer, CurId; DWORD HwIdBufferLen, RegDataType, RequiredSize; BOOL bRet; ULONG Status, Problem; TCHAR DeviceInstanceId[MAX_DEVNODE_ID_LEN]; ExistingNonPresentDevices = INVALID_HANDLE_VALUE; AllDevs = SetupDiGetClassDevs(NULL, Enumerator, NULL, DIGCF_ALLCLASSES ); if(AllDevs == INVALID_HANDLE_VALUE) { // // last error has already been set during the above call. // return INVALID_HANDLE_VALUE; } // // Iterate through each device we found, comparing its hardware ID(s) // against the one we were passed in. // DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); HwIdBuffer = NULL; HwIdBufferLen = 0; Err = NO_ERROR; bRet = FALSE; i = 0; while(SetupDiEnumDeviceInfo(AllDevs, i, &DeviceInfoData)) { // // Retrieve the HardwareID property for this device info element // if(!SetupDiGetDeviceRegistryProperty(AllDevs, &DeviceInfoData, SPDRP_HARDWAREID, &RegDataType, (PBYTE)HwIdBuffer, HwIdBufferLen, &RequiredSize)) { // // If the failure was due to buffer-too-small, we can resize and // try again. // if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(HwIdBuffer) { GlobalFree(HwIdBuffer); } HwIdBuffer = GlobalAlloc(0, RequiredSize); if(HwIdBuffer) { HwIdBufferLen = RequiredSize; // // try again // continue; } else { // // We failed to allocate the buffer we needed. This is // considered a critical failure that should cause us to // bail. // Err = ERROR_NOT_ENOUGH_MEMORY; break; } } else { // // We failed to retrieve the property for some other reason. // Skip this device and move on to the next. // i++; continue; } } if((RegDataType != REG_MULTI_SZ) || (RequiredSize < sizeof(TCHAR))) { // // Data is invalid--this should never happen, but we'll skip the // device in this case... // i++; continue; } // // If we get to here, then we successfully retrieved the multi-sz // hardware id list for this device. Compare each of those IDs with // the caller-supplied one. // for(CurId = HwIdBuffer; CurId && *CurId; CurId += (lstrlen(CurId) + 1)) { if(!lstrcmpi(CurId, HardwareID)) { // // We found a match! // bRet = TRUE; // // If the device isn't currently present (as indicated by // failure to retrieve its status), then add it to the list of // such devices to be returned to the caller. // if(CR_SUCCESS != CM_Get_DevNode_Status(&Status, &Problem, (DEVNODE)DeviceInfoData.DevInst, 0)) { if(ExistingNonPresentDevices == INVALID_HANDLE_VALUE) { // // This is the first non-present device we've // encountered--we need to create the HDEVINFO set. // ExistingNonPresentDevices = SetupDiCreateDeviceInfoList(NULL, NULL); if(ExistingNonPresentDevices == INVALID_HANDLE_VALUE) { // // Failure to create this set is a critical error! // Err = GetLastError(); bRet = FALSE; break; } } // // We need to get the device instance's name so we can // open it up into our "non-present devices" list // if(!SetupDiGetDeviceInstanceId(AllDevs, &DeviceInfoData, DeviceInstanceId, sizeof(DeviceInstanceId) / sizeof(TCHAR), NULL)) { // // Should never fail, but considered critical if it // does... // Err = GetLastError(); bRet = FALSE; break; } // // Now open up the non-present device into our list. // if(!SetupDiOpenDeviceInfo(ExistingNonPresentDevices, DeviceInstanceId, NULL, 0, NULL)) { // // This failure is also considered critical! // Err = GetLastError(); bRet = FALSE; } break; } } } if(Err != NO_ERROR) { // // Critical error encountered--bail! // break; } // // Move onto the next device instance // i++; } if(HwIdBuffer) { GlobalFree(HwIdBuffer); } // // We can now destroy our temporary list of all devices under consideration // SetupDiDestroyDeviceInfoList(AllDevs); if((Err != NO_ERROR) && (ExistingNonPresentDevices != INVALID_HANDLE_VALUE)) { // // We encountered a critical error, so we need to destroy the (partial) // list of non-present devices we'd built. // SetupDiDestroyDeviceInfoList(ExistingNonPresentDevices); ExistingNonPresentDevices = INVALID_HANDLE_VALUE; } SetLastError(Err); return ExistingNonPresentDevices; }
// // After the adapter parameter is changed, should call this function to active it. // BOOL ControlAdapter( DWORD dwStatus, CONST TCHAR* GUIDString) // _T("4D36E972-E325-11CE-BFC1-08002BE10318"); { BOOL bRet = FALSE; if ( 0 == dwStatus ) { return FALSE; } //TCHAR* GUIDString = _T("4D36E972-E325-11CE-BFC1-08002BE10318"); GUID guid; ZeroMemory( &guid, sizeof( GUID ) ); if ( RPC_S_OK != UuidFromString( (unsigned char*)GUIDString, &guid ) ) { bRet = FALSE; } else { HDEVINFO hDevInfo = NULL; hDevInfo = SetupDiGetClassDevs( &guid, REGSTR_KEY_PCIENUM, NULL, DIGCF_PRESENT ); if ( INVALID_HANDLE_VALUE == hDevInfo ) { bRet = FALSE; } else { DWORD i = 0; SP_DEVINFO_DATA DeviceInfoData; ZeroMemory( &DeviceInfoData, sizeof( SP_DEVINFO_DATA ) ); DeviceInfoData.cbSize = sizeof( SP_DEVINFO_DATA ); for ( i = 0; SetupDiEnumDeviceInfo( hDevInfo, i, &DeviceInfoData ); ++i ) { // 获得设备的状态 DWORD dwProblem = 0, dwDeviceStatus = 0; if ( CR_SUCCESS != CM_Get_DevNode_Status( &dwDeviceStatus, &dwProblem, DeviceInfoData.DevInst, 0 ) ) { continue; } // 获取设备注册表项描述 CString strText; if ( !GetDeviceRegistryProperty( hDevInfo, &DeviceInfoData, SPDRP_CLASS, strText ) ) { continue; } TRACE( _T("\n The %d device instance handle : %d, Class : %s\n"), i, DeviceInfoData.DevInst, strText ); if ( 0 == lstrcmp( strText, _T("Net") ) ) { TRACE( _T("This is the adapter device that I want.\n") ); ////////////////////////////////////////////////////////////////////////// #ifdef _DEBUG if ( GetDeviceRegistryProperty( hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, strText ) ) { TRACE( _T("SPDRP_DEVICEDESC : %s\n"), strText ); } #endif ////////////////////////////////////////////////////////////////////////// if ( ChangeStatus( dwStatus, i, hDevInfo ) ) { bRet = TRUE; } } } // 释放 device information set bRet = SetupDiDestroyDeviceInfoList( hDevInfo ); } } return bRet; }
HRESULT DEVI(PTSTR ptzCmd) { // Lookup device HDEVINFO hDev = SetupDiGetClassDevs(NULL, NULL, 0, DIGCF_ALLCLASSES); if (hDev == INVALID_HANDLE_VALUE) { return E_FAIL; } // Build SPDRP_HARDWAREID list TCHAR tzDevID[MAX_DevID]; PTSTR p = tzDevID + 1; SP_DEVINFO_DATA sdDev = {sizeof(SP_DEVINFO_DATA)}; for (UINT i = 0; (NUM_DevID < MAX_DevID) && SetupDiEnumDeviceInfo(hDev, i, &sdDev); i++) { #if (_MSC_VER < 1300) PCM_Get_DevNode_Status CM_Get_DevNode_Status = (PCM_Get_DevNode_Status) GetProcAddress(GetModuleHandle(TEXT("SetupAPI")), "CM_Get_DevNode_Status"); if (CM_Get_DevNode_Status) #endif { // Exclude configured device ULONG uProblem = 0; ULONG uStatus = DN_HAS_PROBLEM; CM_Get_DevNode_Status(&uStatus, &uProblem, sdDev.DevInst, 0); if (uProblem != CM_PROB_NOT_CONFIGURED) { #ifndef _DEBUG continue; #endif } } // Get device ID if (SetupDiGetDeviceRegistryProperty(hDev, &sdDev, SPDRP_HARDWAREID, NULL, (PBYTE) p, MAX_DevID - NUM_DevID, NULL) && UStrCmpNI(p, TEXT("ACPI"), 4)) { Log(IDS_FoundDevice, p); // Trim some stuff for quick search UINT j = 0; for (UINT k = 0; p[j]; j++) { if ((p[j] == '&') && (++k == 2)) { break; } } p[-1] = j; for (p += j; *p; p++); p += 2; } } p[-1] = 0; SetupDiDestroyDeviceInfoList(hDev); if (tzDevID[0] == 0) { // No device return ERROR_NO_MATCH; } // Parse param BOOL bInstall = (ptzCmd[0] == '$'); if (bInstall) ptzCmd++; PTSTR ptzClass = UStrChr(ptzCmd, ','); if (ptzClass) *ptzClass++ = 0; if (UStrCmpI(ptzCmd + UStrLen(ptzCmd) - 4, TEXT(".CAB"))) { // Lookup driver from directory return DevDir(ptzCmd, tzDevID, ptzClass); } else { // Lookup CAB file TCHAR tzDevInf[MAX_PATH * 16]; g_ptzDevInf = tzDevInf; HRESULT hResult = SetupIterateCabinet(ptzCmd, 0, (PSP_FILE_CALLBACK) DevCab, tzDevID) ? S_OK : E_FAIL; if (bInstall) { for (PTSTR p = tzDevInf; p < g_ptzDevInf; p += UStrLen(p) + 1) { PTSTR ptzDevID = p; p += UStrLen(p) + 1; DevIns(ptzDevID, p); } } return hResult; } }
bool WinNetCard::NetCardStateChange(void * NetCardPoint, bool Enabled) { PNetCardStruct NetCard = (PNetCardStruct)NetCardPoint; DWORD DeviceId = NetCard->Id; HDEVINFO hDevInfo = 0; if (INVALID_HANDLE_VALUE == (hDevInfo = SetupDiGetClassDevs(NULL,NULL,0,DIGCF_PRESENT|DIGCF_ALLCLASSES))) { return false; } /* SetupDiGetClassDevs( (LPGUID) &GUID_DEVCLASS_NET, // GUID_DEVCLASS_NET表示仅列出网络设备 NULL, this->m_hWnd, DIGCF_PRESENT); */ SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; DWORD Status, Problem; if (!SetupDiEnumDeviceInfo(hDevInfo,DeviceId,&DeviceInfoData)) // return false; if (CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData.DevInst,0) != CR_SUCCESS) //读取网卡状态 return false; SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTALL_HEADER)}; PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; PropChangeParams.Scope = DICS_FLAG_GLOBAL; if (Enabled) { if (!((Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem))) { NetCard->Disabled = false; return false; } PropChangeParams.StateChange = DICS_ENABLE; } else { if ((Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem)) { NetCard->Disabled = true; return false; } if (!((Status & DN_DISABLEABLE) && (CM_PROB_HARDWARE_DISABLED != Problem))) return false; PropChangeParams.StateChange = DICS_DISABLE; } if (!SetupDiSetClassInstallParams(hDevInfo, &DeviceInfoData,(SP_CLASSINSTALL_HEADER *)&PropChangeParams, sizeof(PropChangeParams))) {//功能:设置网卡有效或无效 return false; } if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &DeviceInfoData)) { return false; } if (CM_Get_DevNode_Status(&Status, &Problem,DeviceInfoData.DevInst,0) == CR_SUCCESS) { NetCard->Disabled = (Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem); } return true; }
//功能: 枚举机器上的所有的物理网卡(不包括虚拟网卡) //参数: NIC结构体的列表,调用成功包含所有的物理网卡的相关系统 //返回值: 调用成功返回TRUE,否则返回FALSE //调用成功后必须调用FreeNicListBuffer释放内存 BOOL NetworkInterfaces(NICLIST **Niclist) { if (NULL==Niclist) { return FALSE; } else { *Niclist=NULL; } HDEVINFO hDevInfo=INVALID_HANDLE_VALUE; //if (INVALID_HANDLE_VALUE == (hDevInfo =SetupDiGetClassDevs(&GUID_NDIS_LAN_CLASS/*NULL*/,NULL,NULL, DIGCF_DEVICEINTERFACE/*DIGCF_PRESENT |DIGCF_ALLCLASSES*/))) if (INVALID_HANDLE_VALUE == (hDevInfo =SetupDiGetClassDevs(&GUID_NDIS_LAN_CLASS, NULL, NULL, DIGCF_DEVICEINTERFACE))) { return FALSE; } Garbage DevListGC(hDevInfo); DWORD i =0, Status =0, Problem =0; NIC CurNic; SP_DEVINFO_DATA DeviceInfoData ={sizeof(SP_DEVINFO_DATA)}; TCHAR Buffer[MY_BUFFER_SIZE] ={0}; DWORD Length =sizeof(Buffer); std::list<NIC> nics_list; for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,&DeviceInfoData);i++) { if (CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData.DevInst,0) == CR_SUCCESS) { if ( ((Status & DN_NO_SHOW_IN_DM)==0)&&(!IsClassHidden(&DeviceInfoData.ClassGuid)) ) //if ( ((Status & DN_NO_SHOW_IN_DM)==0) ) { CurNic.m_dwId=i; if (SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, NULL,(PBYTE)Buffer, Length, &Length)) { Buffer[Length]=TEXT('\0'); //CurNic.m_strDevDesc=Buffer; _tcscpy(CurNic.m_chDevDesc,Buffer); Length=sizeof(Buffer); } else { //CurNic.m_strDevDesc=TEXT("Nic without description"); _tcscpy(CurNic.m_chDevDesc,TEXT("Nic without description")); } CurNic.m_bDisabled=(Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem); CurNic.m_dwNicType=0; //CurNic.m_strDevGuid.clear(); CurNic.m_chDevGuid[0]=TEXT('\0'); DWORD dwSizeRequired = 0; TCHAR szPnpInstanceId[MY_BUFFER_SIZE+1]; if (SetupDiGetDeviceInstanceId(hDevInfo, &DeviceInfoData, szPnpInstanceId, MY_BUFFER_SIZE, &dwSizeRequired)) { std::list<TString> GuidList; int iMedia =0; if (GetNicGuid(szPnpInstanceId,GuidList)&&(!GuidList.empty())) { //CurNic.m_strDevGuid=GuidList.front(); _tcscpy(CurNic.m_chDevGuid,GuidList.front().c_str()); if ((iMedia=GetNicMediaType(GuidList.front()))>0) { CurNic.m_dwNicType=iMedia; } } } if (IsPhysicalNic(/*CurNic.m_strDevGuid.c_str()*/CurNic.m_chDevGuid)) { //TString strDevGuid=CurNic.m_chDevGuid; //_tcscpy(CurNic.m_chDevGuid,strDevGuid.substr(1,36).c_str());//去掉GUID的大括号 nics_list.push_back(CurNic); } }//if }//if } //for if (nics_list.size()!=0) { *Niclist=new NICLIST; NICLIST *lpTemp=*Niclist; lpTemp->dwCount =nics_list.size(); lpTemp->lpNics =new NIC[lpTemp->dwCount]; int k=0; for (std::list<NIC>::iterator i=nics_list.begin();i!=nics_list.end();++i,++k) { lpTemp->lpNics[k].m_bDisabled =i->m_bDisabled; lpTemp->lpNics[k].m_dwId =i->m_dwId; lpTemp->lpNics[k].m_dwNicType =i->m_dwNicType; _tcscpy(lpTemp->lpNics[k].m_chDevDesc,i->m_chDevDesc); _tcscpy(lpTemp->lpNics[k].m_chDevGuid,i->m_chDevGuid); } return TRUE; } else { *Niclist=NULL; return FALSE; } }
int usb_install_driver_np(const char *inf_file) { HDEVINFO dev_info; SP_DEVINFO_DATA dev_info_data; INFCONTEXT inf_context; HINF inf_handle; DWORD config_flags, problem, status; BOOL reboot; char inf_path[MAX_PATH]; char id[MAX_PATH]; char tmp_id[MAX_PATH]; char *p; int dev_index; HINSTANCE newdev_dll = NULL; HMODULE setupapi_dll = NULL; update_driver_for_plug_and_play_devices_t UpdateDriverForPlugAndPlayDevices; setup_copy_oem_inf_t SetupCopyOEMInf; newdev_dll = LoadLibrary("newdev.dll"); if(!newdev_dll) { usb_error("usb_install_driver(): loading newdev.dll failed\n"); return -1; } UpdateDriverForPlugAndPlayDevices = (update_driver_for_plug_and_play_devices_t) GetProcAddress(newdev_dll, "UpdateDriverForPlugAndPlayDevicesA"); if(!UpdateDriverForPlugAndPlayDevices) { usb_error("usb_install_driver(): loading newdev.dll failed\n"); return -1; } setupapi_dll = GetModuleHandle("setupapi.dll"); if(!setupapi_dll) { usb_error("usb_install_driver(): loading setupapi.dll failed\n"); return -1; } SetupCopyOEMInf = (setup_copy_oem_inf_t) GetProcAddress(setupapi_dll, "SetupCopyOEMInfA"); if(!SetupCopyOEMInf) { usb_error("usb_install_driver(): loading setupapi.dll failed\n"); return -1; } dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA); /* retrieve the full .inf file path */ if(!GetFullPathName(inf_file, MAX_PATH, inf_path, NULL)) { usb_error("usb_install_driver(): .inf file %s not found\n", inf_file); return -1; } /* open the .inf file */ inf_handle = SetupOpenInfFile(inf_path, NULL, INF_STYLE_WIN4, NULL); if(inf_handle == INVALID_HANDLE_VALUE) { usb_error("usb_install_driver(): unable to open .inf file %s\n", inf_file); return -1; } /* find the .inf file's device description section marked "Devices" */ if(!SetupFindFirstLine(inf_handle, "Devices", NULL, &inf_context)) { usb_error("usb_install_driver(): .inf file %s does not contain " "any device descriptions\n", inf_file); SetupCloseInfFile(inf_handle); return -1; } do { /* get the device ID from the .inf file */ if(!SetupGetStringField(&inf_context, 2, id, sizeof(id), NULL)) { continue; } /* convert the string to lowercase */ strlwr(id); reboot = FALSE; /* copy the .inf file to the system directory so that is will be found */ /* when new devices are plugged in */ SetupCopyOEMInf(inf_path, NULL, SPOST_PATH, 0, NULL, 0, NULL, NULL); /* update all connected devices matching this ID, but only if this */ /* driver is better or newer */ UpdateDriverForPlugAndPlayDevices(NULL, id, inf_path, INSTALLFLAG_FORCE, &reboot); /* now search the registry for device nodes representing currently */ /* unattached devices */ /* get all USB device nodes from the registry, present and non-present */ /* devices */ dev_info = SetupDiGetClassDevs(NULL, "USB", NULL, DIGCF_ALLCLASSES); if(dev_info == INVALID_HANDLE_VALUE) { SetupCloseInfFile(inf_handle); break; } dev_index = 0; /* enumerate the device list to find all attached and unattached */ /* devices */ while(SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data)) { /* get the harware ID from the registry, this is a multi-zero string */ if(SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data, SPDRP_HARDWAREID, NULL, (BYTE *)tmp_id, sizeof(tmp_id), NULL)) { /* check all possible IDs contained in that multi-zero string */ for(p = tmp_id; *p; p += (strlen(p) + 1)) { /* convert the string to lowercase */ strlwr(p); /* found a match? */ if(strstr(p, id)) { /* is this device disconnected? */ if(CM_Get_DevNode_Status(&status, &problem, dev_info_data.DevInst, 0) == CR_NO_SUCH_DEVINST) { /* found a device node that represents an unattached */ /* device */ if(SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data, SPDRP_CONFIGFLAGS, NULL, (BYTE *)&config_flags, sizeof(config_flags), NULL)) { /* mark the device to be reinstalled the next time it is */ /* plugged in */ config_flags |= CONFIGFLAG_REINSTALL; /* write the property back to the registry */ SetupDiSetDeviceRegistryProperty(dev_info, &dev_info_data, SPDRP_CONFIGFLAGS, (BYTE *)&config_flags, sizeof(config_flags)); } } /* a match was found, skip the rest */ break; } } } /* check the next device node */ dev_index++; } SetupDiDestroyDeviceInfoList(dev_info); /* get the next device ID from the .inf file */ } while(SetupFindNextLine(&inf_context, &inf_context)); /* we are done, close the .inf file */ SetupCloseInfFile(inf_handle); usb_registry_stop_libusb_devices(); /* stop all libusb devices */ usb_registry_start_libusb_devices(); /* restart all libusb devices */ return 0; }