bool PortEnumerator::Next() { assert(!drivers_active.error()); TCHAR key_name[64]; while (drivers_active.enum_key(i++, key_name, 64)) { RegistryKey device(drivers_active, key_name, true); if (device.error()) continue; TCHAR device_key[64]; if (device.get_value(_T("Key"), device_key, 64) && IsSerialPort(device_key) && device.get_value(_T("Name"), name.buffer(), name.MAX_SIZE)) { display_name = name; const size_t length = display_name.length(); TCHAR *const tail = display_name.buffer() + length; const size_t remaining = display_name.MAX_SIZE - length - 3; if (GetDeviceFriendlyName(device_key, tail + 2, remaining)) { /* build a string in the form: "COM1: (Friendly Name)" */ tail[0] = _T(' '); tail[1] = _T('('); _tcscat(tail, _T(")")); } return true; } } return false; }
CDevice::OnPrepareHardware(IWDFDevice* pDevice) { HRESULT hr = S_OK; if (m_pWpdBaseDriver != NULL) { hr = m_pWpdBaseDriver->Initialize(); CHECK_HR(hr, "Failed to Initialize the driver class"); } // Initialize the WPD Class Extension. This will enable the appropriate WPD interface GUID, // as well as do any additional initialization (e.g. enabling Legacy Compatibility layers for those drivers // which requested support in their INF). if (hr == S_OK && m_pPortableDeviceClassExtension == NULL) { CComPtr<IPortableDeviceValues> pOptions; CComPtr<IPortableDevicePropVariantCollection> pContentTypes; hr = CoCreateInstance(CLSID_PortableDeviceClassExtension, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceClassExtension, (VOID**)&m_pPortableDeviceClassExtension); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceClassExtension"); if (hr == S_OK) { hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**)&pOptions); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues"); if (hr == S_OK) { // Get supported content types if (hr == S_OK) { hr = GetSupportedContentTypes(&pContentTypes); CHECK_HR(hr, "Failed to get supported content types"); } // Add the supported types to the options if (hr == S_OK) { hr = pOptions->SetIPortableDevicePropVariantCollectionValue(WPD_CLASS_EXTENSION_OPTIONS_SUPPORTED_CONTENT_TYPES, pContentTypes); CHECK_HR(hr, "Failed to set WPD_CLASS_EXTENSION_OPTIONS_SUPPORTED_CONTENT_TYPES"); } // Initialize the PortableDeviceClassExtension with a list of supported content types for the // connected device. This will ensure that the correct application compatibility settings will // be applied for your device. if (hr == S_OK) { hr = m_pPortableDeviceClassExtension->Initialize(pDevice, pOptions); CHECK_HR(hr, "Failed to Initialize portable device class extension object"); } // Since users commonly have the abiltity to customize their device even when it is not // connected to the PC, we need to make sure the PC is current when the driver loads. // // Send the latest device friendly name to the PortableDeviceClassExtension component // so the system is always updated with the current device name. // // This call should also be made after a successful property set operation of // WPD_DEVICE_FRIENDLY_NAME. LPWSTR wszDeviceFriendlyName = NULL; if (hr == S_OK) { hr = GetDeviceFriendlyName(&wszDeviceFriendlyName); CHECK_HR(hr, "Failed to get device's friendly name"); } if (hr == S_OK) { hr = UpdateDeviceFriendlyName(m_pPortableDeviceClassExtension, wszDeviceFriendlyName); CHECK_HR(hr, "Failed to update device's friendly name"); } // Free the memory. CoTaskMemFree ignores NULLs so no need to check. CoTaskMemFree(wszDeviceFriendlyName); } } } return hr; }
bool PortEnumerator::Next() { assert(!drivers_active.error()); TCHAR key_name[64]; /* enumerate regular serial ports first */ while (drivers_active.EnumKey(i++, key_name, 64)) { RegistryKey device(drivers_active, key_name, true); if (device.error()) continue; TCHAR device_key[64]; if (device.GetValue(_T("Key"), device_key, 64) && IsSerialPort(device_key) && device.GetValue(_T("Name"), name.buffer(), name.MAX_SIZE)) { display_name = name; const size_t length = display_name.length(); TCHAR *const tail = display_name.buffer() + length; const size_t remaining = display_name.MAX_SIZE - length - 3; if (GetDeviceFriendlyName(device_key, tail + 2, remaining)) { /* build a string in the form: "COM1: (Friendly Name)" */ tail[0] = _T(' '); tail[1] = _T('('); _tcscat(tail, _T(")")); } return true; } } /* virtual Bluetooth serial ports will not be found by the above; the following is necessary to enumerate those */ while (bluetooth_ports.EnumKey(j++, key_name, 64)) { RegistryKey port(bluetooth_ports, key_name, true); if (port.error()) continue; if (!port.GetValue(_T("Port"), name.buffer(), name.MAX_SIZE - 1)) continue; /* the trailing colon is missing in this part of the registry */ name.Append(_T(':')); display_name = name; /* see if we can find a human-readable name */ const TCHAR *kn = key_name; RegistryKey device(bluetooth_device, kn, true); while (device.error() && *kn == _T('0')) { /* turns out Windows CE strips four leading zeroes for the Bluetooth\Device\* key (12 digits instead of 16); this is an attempt to kludge around this weirdness */ ++kn; device = RegistryKey(bluetooth_device, kn, true); } if (!device.error()) { const size_t length = display_name.length(); TCHAR *const tail = display_name.buffer() + length; const size_t remaining = display_name.MAX_SIZE - length - 3; if (device.GetValue(_T("name"), tail + 2, remaining)) { /* build a string in the form: "COM1: (Friendly Name)" */ tail[0] = _T(' '); tail[1] = _T('('); _tcscat(tail, _T(")")); } } return true; } return false; }
// ---------------------------------------------------------------------------- // Function: // CSwapPropPage::OnInitDialog // // Description: // Dialog initialization routine // // Parameters: // hwndDlg - [in] Handle to dialog box // wParam - [in] Handle to control to receive the default keyboard focus // lParam - [in] Specifies additional message-specific information // // Return values: // TRUE to direct the system to set the keyboard focus to the control // specified by wParam. Otherwise, it should return FALSE to prevent the // system from setting the default keyboard focus. // ---------------------------------------------------------------------------- BOOL CSwapPropPage::OnInitDialog ( HWND hwndDlg, WPARAM wParam, LPARAM lParam ) { UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(lParam); HRESULT hr = S_OK; LPWSTR pwstrEndpointName = NULL; // Retrieve the endpoint's friendly name, system effects, and swap SFX and MFX states hr = GetDeviceFriendlyName(&pwstrEndpointName); IF_FAILED_JUMP(hr, Exit); hr = RetrieveSysFXState(&m_fDisableSysFX); IF_FAILED_JUMP(hr, Exit); hr = RetrieveSwapSFXState(&m_fEnableSwapSFX); IF_FAILED_JUMP(hr, Exit); hr = RetrieveSwapMFXState(&m_fEnableSwapMFX); IF_FAILED_JUMP(hr, Exit); hr = RetrieveDelaySFXState(&m_fEnableDelaySFX); IF_FAILED_JUMP(hr, Exit); hr = RetrieveDelayMFXState(&m_fEnableDelayMFX); IF_FAILED_JUMP(hr, Exit); // Update the property page with retrieved information SetWindowText(GetDlgItem(hwndDlg, IDC_SPP_ENDPOINT_NAME), pwstrEndpointName); // Based on the retrieved states, toggle the checkboxes to reflect them if (m_fDisableSysFX) { CheckDlgButton(hwndDlg, IDC_DISABLE_SYSFX, BST_CHECKED); // Disable APO toggling controls on the page EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_SWAP_SFX), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_SWAP_MFX), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_DELAY_SFX), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_DELAY_MFX), FALSE); } else { CheckDlgButton(hwndDlg, IDC_DISABLE_SYSFX, BST_UNCHECKED); // Enable APO toggling controls on the page EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_SWAP_SFX), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_SWAP_MFX), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_DELAY_SFX), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_DELAY_MFX), TRUE); } if (m_fEnableSwapSFX) { CheckDlgButton(hwndDlg, IDC_ENABLE_SWAP_SFX, BST_CHECKED); } else { CheckDlgButton(hwndDlg, IDC_ENABLE_SWAP_SFX, BST_UNCHECKED); } if (m_fEnableSwapMFX) { CheckDlgButton(hwndDlg, IDC_ENABLE_SWAP_MFX, BST_CHECKED); } else { CheckDlgButton(hwndDlg, IDC_ENABLE_SWAP_MFX, BST_UNCHECKED); } if (m_fEnableDelaySFX) { CheckDlgButton(hwndDlg, IDC_ENABLE_DELAY_SFX, BST_CHECKED); } else { CheckDlgButton(hwndDlg, IDC_ENABLE_DELAY_SFX, BST_UNCHECKED); } if (m_fEnableDelayMFX) { CheckDlgButton(hwndDlg, IDC_ENABLE_DELAY_MFX, BST_CHECKED); } else { CheckDlgButton(hwndDlg, IDC_ENABLE_DELAY_MFX, BST_UNCHECKED); } Exit: SAFE_COTASKMEMFREE(pwstrEndpointName); return(FALSE); }
CDevice::OnPrepareHardware(IWDFDevice* pDevice) { HRESULT hr = S_OK; if (m_pPortableDeviceClassExtension == NULL) { hr = CoCreateInstance(CLSID_PortableDeviceClassExtension, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceClassExtension, (VOID**)&m_pPortableDeviceClassExtension); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceClassLibrary"); // Initialize the WPD Class Extension. This will enable the appropriate WPD interface GUID, // as well as do any additional initialization (e.g. enabling Legacy Compatibility layers for those drivers // which requsted support in their INF). if (hr == S_OK) { CComPtr<IPortableDeviceValues> pOptions; CComPtr<IPortableDevicePropVariantCollection> pContentTypes; hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**)&pOptions); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceClassLibrary"); if (hr == S_OK) { hr = GetSupportedContentTypes(&pContentTypes); CHECK_HR(hr, "Failed to get supported content types"); // Add the supported types to the options if (hr == S_OK) { hr = pOptions->SetIPortableDevicePropVariantCollectionValue(WPD_CLASS_EXTENSION_OPTIONS_SUPPORTED_CONTENT_TYPES, pContentTypes); CHECK_HR(hr, "Failed to set WPD_CLASS_EXTENSION_OPTIONS_SUPPORTED_CONTENT_TYPES"); } if (hr == S_OK) { hr = m_pPortableDeviceClassExtension->Initialize(pDevice, pOptions); CHECK_HR(hr, "Failed to Initialize portable device class extension object"); } } } if (hr == S_OK) { DWORD dwLength = 0; WCHAR* pszDeviceName = NULL; hr = pDevice->RetrieveDeviceName(NULL, &dwLength); if(dwLength > 0) { pszDeviceName = new WCHAR[dwLength + 1]; if(pszDeviceName) { DWORD dwLengthTemp = dwLength; hr = pDevice->RetrieveDeviceName(pszDeviceName, &dwLengthTemp); CHECK_HR(hr, "Failed to get device name"); if (hr == S_OK) { pszDeviceName[dwLength] = L'\0'; if (m_pWpdBaseDriver != NULL) { hr = m_pWpdBaseDriver->Initialize(pszDeviceName, m_pPortableDeviceClassExtension); CHECK_HR(hr, "Failed to initialize the fake device"); } else { hr = E_UNEXPECTED; CHECK_HR(hr, "NULL driver class used, Driver may not be initialized"); } } delete[] pszDeviceName; pszDeviceName = NULL; } else { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate memory for device name"); } } else { CHECK_HR(hr, "Failed to get device name length"); } } // Send the latest device friendly name to the Portable Device class extension library to process if (hr == S_OK) { LPWSTR pwszDeviceFriendlyName = NULL; HRESULT hrTemp = GetDeviceFriendlyName(&pwszDeviceFriendlyName); CHECK_HR(hrTemp, "Failed to get the device friendly name"); if (hrTemp == S_OK) { hrTemp = UpdateDeviceFriendlyName(m_pPortableDeviceClassExtension, pwszDeviceFriendlyName); CHECK_HR(hrTemp, "Failed to update device friendly name information"); } CoTaskMemFree(pwszDeviceFriendlyName); pwszDeviceFriendlyName = NULL; } } return hr; }