| 1403 | } |
| 1404 | |
| 1405 | int RemoveCallback(_In_ HDEVINFO Devs, _In_ PSP_DEVINFO_DATA DevInfo, _In_ DWORD Index, _In_ LPVOID Context) |
| 1406 | /*++ |
| 1407 | |
| 1408 | Routine Description: |
| 1409 | |
| 1410 | Callback for use by Remove |
| 1411 | Invokes DIF_REMOVE |
| 1412 | uses SetupDiCallClassInstaller so cannot be done for remote devices |
| 1413 | Don't use CM_xxx API's, they bypass class/co-installers and this is bad. |
| 1414 | |
| 1415 | Arguments: |
| 1416 | |
| 1417 | Devs )_ uniquely identify the device |
| 1418 | DevInfo ) |
| 1419 | Index - index of device |
| 1420 | Context - GenericContext |
| 1421 | |
| 1422 | Return Value: |
| 1423 | |
| 1424 | EXIT_xxxx |
| 1425 | |
| 1426 | --*/ |
| 1427 | { |
| 1428 | SP_REMOVEDEVICE_PARAMS rmdParams; |
| 1429 | GenericContext *pControlContext = (GenericContext*)Context; |
| 1430 | SP_DEVINSTALL_PARAMS devParams; |
| 1431 | LPCTSTR action = NULL; |
| 1432 | // |
| 1433 | // need hardware ID before trying to remove, as we wont have it after |
| 1434 | // |
| 1435 | TCHAR devID[MAX_DEVICE_ID_LEN]; |
| 1436 | SP_DEVINFO_LIST_DETAIL_DATA devInfoListDetail; |
| 1437 | |
| 1438 | UNREFERENCED_PARAMETER(Index); |
| 1439 | |
| 1440 | devInfoListDetail.cbSize = sizeof(devInfoListDetail); |
| 1441 | if((!SetupDiGetDeviceInfoListDetail(Devs,&devInfoListDetail)) || |
| 1442 | (CM_Get_Device_ID_Ex(DevInfo->DevInst,devID,MAX_DEVICE_ID_LEN,0,devInfoListDetail.RemoteMachineHandle)!=CR_SUCCESS)) { |
| 1443 | // |
| 1444 | // skip this |
| 1445 | // |
| 1446 | return EXIT_OK; |
| 1447 | } |
| 1448 | |
| 1449 | rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); |
| 1450 | rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE; |
| 1451 | rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL; |
| 1452 | rmdParams.HwProfile = 0; |
| 1453 | if(!SetupDiSetClassInstallParams(Devs,DevInfo,&rmdParams.ClassInstallHeader,sizeof(rmdParams)) || |
| 1454 | !SetupDiCallClassInstaller(DIF_REMOVE,Devs,DevInfo)) { |
| 1455 | // |
| 1456 | // failed to invoke DIF_REMOVE |
| 1457 | // |
| 1458 | action = pControlContext->strFail; |
| 1459 | } else { |
| 1460 | // |
| 1461 | // see if device needs reboot |
| 1462 | // |
nothing calls this directly
no outgoing calls
no test coverage detected