static VOID EnumDeviceClasses( HWND hTreeView, HTREEITEM hRoot, PDEVCLASS_ENTRY pClassArray, ULONG ClassCount) { WCHAR ClassName[MAX_DEV_LEN]; WCHAR ClassDesc[MAX_DEV_LEN]; PDEVCLASS_ENTRY pClass; ULONG ClassIndex; DWORD dwSize; LONG lSize; HKEY hKey; CONFIGRET cr; for (ClassIndex = 0; ClassIndex < ClassCount; ClassIndex++) { pClass = &pClassArray[ClassIndex]; cr = CM_Enumerate_Classes(ClassIndex, &pClass->ClassGuid, 0); if (cr == CR_NO_SUCH_VALUE) return; dwSize = MAX_CLASS_NAME_LEN; if (!SetupDiClassNameFromGuid(&pClass->ClassGuid, ClassName, dwSize, &dwSize)) { ClassName[0] = _T('\0'); } if (!SetupDiGetClassImageIndex(&ImageListData, &pClass->ClassGuid, &pClass->ClassImage)) { /* FIXME: can we do this? * Set the blank icon: IDI_SETUPAPI_BLANK = 41 * it'll be image 24 in the imagelist */ pClass->ClassImage = 24; } hKey = SetupDiOpenClassRegKeyEx(&pClass->ClassGuid, MAXIMUM_ALLOWED, DIOCR_INSTALLER, NULL, 0); if (hKey != INVALID_HANDLE_VALUE) { lSize = MAX_DEV_LEN; if (RegQueryValue(hKey, NULL, ClassDesc, &lSize) != ERROR_SUCCESS) { ClassDesc[0] = _T('\0'); } RegCloseKey(hKey); } pClass->hItem = InsertIntoTreeView(hTreeView, hRoot, (ClassDesc[0] != _T('\0')) ? ClassDesc : ClassName, NULL, pClass->ClassImage, 0); } }
extern "C" DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR mask) { BOOL ok; DWORD ret = 0; GUID netGuid; HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA DeviceInfoData; SP_DRVINFO_DATA DriverInfoData; SP_DEVINSTALL_PARAMS DeviceInstallParams; TCHAR className[MAX_PATH]; TCHAR temp[MAX_PATH]; DWORD index = 0; BOOL found = FALSE; BOOL registered = FALSE; BOOL destroyList = FALSE; PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail; DWORD detailBuf[2048]; // for our purposes, 8k buffer is more // than enough to obtain the hardware ID // of the loopback driver. HKEY hkey = NULL; DWORD cbSize; DWORD dwValueType; TCHAR pCfgGuidString[40]; // initialize the structure size DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA); // copy the net class GUID memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET)); // create an empty device info set associated with the net class GUID hDeviceInfo = SetupDiCreateDeviceInfoList(&netGuid, NULL); if (hDeviceInfo == INVALID_HANDLE_VALUE) return GetLastError(); // get the class name from GUID ok = SetupDiClassNameFromGuid(&netGuid, className, MAX_PATH, NULL); if (!ok) { ret = GetLastError(); goto cleanup; } // create a device info element and add the new device instance // key to registry ok = SetupDiCreateDeviceInfo(hDeviceInfo, className, &netGuid, NULL, NULL, DICD_GENERATE_ID, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // select the newly created device info to be the currently // selected member ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // build a list of class drivers ok = SetupDiBuildDriverInfoList(hDeviceInfo, &DeviceInfoData, SPDIT_CLASSDRIVER); if (!ok) { ret = GetLastError(); goto cleanup; } destroyList = TRUE; // enumerate the driver info list while (TRUE) { BOOL ret; ret = SetupDiEnumDriverInfo(hDeviceInfo, &DeviceInfoData, SPDIT_CLASSDRIVER, index, &DriverInfoData); // if the function failed and GetLastError() returned // ERROR_NO_MORE_ITEMS, then we have reached the end of the // list. Othewise there was something wrong with this // particular driver. if(!ret) { if(GetLastError() == ERROR_NO_MORE_ITEMS) break; else { index++; continue; } } pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf; pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); // if we successfully find the hardware ID and it turns out to // be the one for the loopback driver, then we are done. if (SetupDiGetDriverInfoDetail(hDeviceInfo, &DeviceInfoData, &DriverInfoData, pDriverInfoDetail, sizeof(detailBuf), NULL)) { TCHAR * t; // pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the // whole list and see if there is a match somewhere. t = pDriverInfoDetail->HardwareID; while (t && *t && t < (TCHAR *) &detailBuf[sizeof(detailBuf)/sizeof(detailBuf[0])]) { if (!_tcsicmp(t, DRIVERHWID)) break; t += _tcslen(t) + 1; } if (t && *t && t < (TCHAR *) &detailBuf[sizeof(detailBuf)/sizeof(detailBuf[0])]) { found = TRUE; break; } } index++; } if (!found) { ret = GetLastError(); ReportMessage(0,"Could not find the driver to install", DRIVER_DESC, NULL, 0); goto cleanup; } // set the loopback driver to be the currently selected ok = SetupDiSetSelectedDriver(hDeviceInfo, &DeviceInfoData, &DriverInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // register the phantom device to repare for install ok = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // registered, but remove if errors occur in the following code registered = TRUE; // ask the installer if we can install the device ok = SetupDiCallClassInstaller(DIF_ALLOW_INSTALL, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); if (ret != ERROR_DI_DO_DEFAULT) { goto cleanup; } else ret = 0; } // install the files first ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // get the device install parameters and disable filecopy DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); ok = SetupDiGetDeviceInstallParams(hDeviceInfo, &DeviceInfoData, &DeviceInstallParams); if (ok) { DeviceInstallParams.Flags |= DI_NOFILECOPY; ok = SetupDiSetDeviceInstallParams(hDeviceInfo, &DeviceInfoData, &DeviceInstallParams); if (!ok) { ret = GetLastError(); goto cleanup; } } // // Register any device-specific co-installers for this device, // ok = SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // // install any installer-specified interfaces. // and then do the real install // ok = SetupDiCallClassInstaller(DIF_INSTALLINTERFACES, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } PAUSE; ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICE, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); PAUSE; goto cleanup; } /* Skip to the end if we aren't setting the name */ if (!pConnectionName) goto cleanup; // Figure out NetCfgInstanceId hkey = SetupDiOpenDevRegKey(hDeviceInfo, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ); if (hkey == INVALID_HANDLE_VALUE) { ret = GetLastError(); goto cleanup; } cbSize = sizeof(pCfgGuidString); ret = RegQueryValueEx(hkey, _T("NetCfgInstanceId"), NULL, &dwValueType, (LPBYTE)pCfgGuidString, &cbSize); RegCloseKey(hkey); ret = RenameConnection(pCfgGuidString, pConnectionName); if (ret) { ReportMessage(0,"Could not set the connection name", NULL, pConnectionName, 0); goto cleanup; } if (!ip) goto cleanup; ret = SetIpAddress(pCfgGuidString, ip, mask); if (ret) { ReportMessage(0,"Could not set the ip address and network mask",NULL,NULL,ret); goto cleanup; } ret = LoopbackBindings(pCfgGuidString); if (ret) { ReportMessage(0,"Could not properly set the bindings",NULL,NULL,0); goto cleanup; } ret = !UpdateHostsFile( pConnectionName, ip, "hosts", FALSE ); if (ret) { ReportMessage(0,"Could not update hosts file",NULL,NULL,0); goto cleanup; } ret = !UpdateHostsFile( pConnectionName, ip, "lmhosts", TRUE ); if (ret) { ReportMessage(0,"Could not update lmhosts file",NULL,NULL,0); goto cleanup; } cleanup: // an error has occured, but the device is registered, we must remove it if (ret != 0 && registered) SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData); found = SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData); // destroy the driver info list if (destroyList) SetupDiDestroyDriverInfoList(hDeviceInfo, &DeviceInfoData, SPDIT_CLASSDRIVER); // clean up the device info set if (hDeviceInfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(hDeviceInfo); return ret; };
static INT EnumDeviceClasses(INT ClassIndex, LPWSTR DevClassName, LPWSTR DevClassDesc, BOOL *DevPresent, INT *ClassImage) { GUID ClassGuid; HKEY KeyClass; WCHAR ClassName[MAX_STR_SIZE]; DWORD RequiredSize = MAX_STR_SIZE; UINT Ret; *DevPresent = FALSE; *DevClassName = L'\0'; Ret = CM_Enumerate_Classes(ClassIndex, &ClassGuid, 0); if (Ret != CR_SUCCESS) { /* All classes enumerated */ if(Ret == CR_NO_SUCH_VALUE) { hDevInfoTypes = NULL; return -1; } if (Ret == CR_INVALID_DATA) { ; /* FIXME: What should we do here? */ } /* Handle other errors... */ } if (SetupDiClassNameFromGuid(&ClassGuid, ClassName, RequiredSize, &RequiredSize)) { lstrcpy(DevClassName, ClassName); } if (!SetupDiGetClassImageIndex(&ImageListData, &ClassGuid, ClassImage)) { /* FIXME: Can we do this? * Set the blank icon: IDI_SETUPAPI_BLANK = 41 * It'll be image 24 in the imagelist */ *ClassImage = 24; } /* Get device info for all devices of a particular class */ hDevInfoTypes = SetupDiGetClassDevs(&ClassGuid, NULL, NULL, DIGCF_PRESENT); if (hDevInfoTypes == INVALID_HANDLE_VALUE) { hDevInfoTypes = NULL; return 0; } KeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid, MAXIMUM_ALLOWED, DIOCR_INSTALLER, NULL, 0); if (KeyClass != INVALID_HANDLE_VALUE) { LONG dwSize = MAX_STR_SIZE; if (RegQueryValue(KeyClass, NULL, DevClassDesc, &dwSize) != ERROR_SUCCESS) { *DevClassDesc = L'\0'; } } else { return -3; } *DevPresent = TRUE; RegCloseKey(KeyClass); return 0; }