Over a million developers have joined DZone.

Windows Phone Native Series - Enumerating drivers

· Mobile Zone

Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud, brought to you in partnership with IBM.

It is time to move a little bit beyond the boundaries of the standard Windows Phone SDK - all the way to native development. It will require more effort, but you will be able to access much more information that way. Let's start with the basics - what will you need?

  • Some experience with C++
  • Visual Studio 2008
  • Windows Mobile 6 Professional SDK
  • Visual Studio 2010
  • Windows Phone SDK
  • Dump of the phone GAC
  • An actual Windows Phone device

Assuming that you have all the tools and skills necessary, let's start. First of all, you need to create an ATL Smart Device Project in Visual Studio 2008.

You need to make sure that the project is properly set up, so that it can be correctly used by a Windows Phone application. Details are available here (written by Heathcliff74 of XDA). My project is called NativeLink and the main class that I will be experimenting with is called CNativeAPI. Remember that there is also a dedicated interface called INativeAPI.

Open NativeAPI.cpp (I used the default naming conventions) and create a new method:

STDMETHODIMP CNativeAPI::GetDeviceDriverInformation(BSTR* Data)
{

} 

The binary string will be the returned value, listing all registered drivers. Now, open NativeLink.idl and make sure that you have a proper interface reference for this method:

interface INativeAPI : IUnknown{
	HRESULT GetDeviceDriverInformation(BSTR* Data);
};

This method has to also be declared in NativeAPI.h:

BEGIN_COM_MAP(CNativeAPI)
	COM_INTERFACE_ENTRY(INativeAPI)
END_COM_MAP()

STDMETHOD(GetDeviceDriverInformation)(BSTR* Data);

Let's get to the API itself. There are two methods that we can invoke to get the list of drivers - FindFirstDevice and FindNextDevice.

As a starting example I used this article.

FindFirstDevice gets the initial handle that will later be used by FindNextDevice to find the full set.

Let's declare the handle that will be used with the method:

HANDLE hDriver;

When invoking FindFirstDevice, I also need to specify the device search type. This can be done by using a DeviceSearchType instance:

DeviceSearchType DeviceSearch = DeviceSearchByLegacyName;

Of course, you can use a different device search type, but for convenience purposes I am going to work with the legacy names. I now need a DEVMGR_DEVICE_INFORMATION instance, that will actually store the information obtained through the handle.

DEVMGR_DEVICE_INFORMATION DeviceInfo;

The size of the structure can be easily defined with the help of sizeof.

DeviceInfo.dwSize = sizeof(DEVMGR_DEVICE_INFORMATION);

I can now invoke FindFirstDevice:

hDriver = FindFirstDevice(DeviceSearch,L"*",&DeviceInfo);

The first parameter is the search type. The second parameter specifies that the method has to look through all devices. DeviceInfo is referenced directly by its address in memory (pointer - thus, the ampersand prefix). Notice that according to the documentation for the method, the third parameters (pdi) is set to [out].

Assuming that the driver is valid, I can now read the returned values:

CComBSTR composite("");

if (hDriver != INVALID_HANDLE_VALUE)
{
do
{
CComBSTR ccLegacyName = SysAllocString(DeviceInfo.szLegacyName);
SysFreeString(ccLegacyName);
CComBSTR ccDeviceKey = SysAllocString(DeviceInfo.szDeviceKey);
SysFreeString(ccDeviceKey);
CComBSTR ccBusName = SysAllocString(DeviceInfo.szBusName);
SysFreeString(ccBusName);
CComBSTR ccDeviceName = SysAllocString(DeviceInfo.szDeviceName);
SysFreeString(ccDeviceName);

composite.AppendBSTR(ccLegacyName);
composite.AppendBSTR(ccDeviceKey);
composite.AppendBSTR(ccBusName);
composite.AppendBSTR(ccDeviceName);
composite.Append("\n");
} while (FindNextDevice(hDriver,&DeviceInfo));
}

Notice that as I am performing string conversion from WCHAR, I am building one composite CComBSTR that will be used to keep the entire list. Since FindNextDevice has a BOOL returned value, it can be easily integrated as a part of a do...while loop.

All I need to do to end the method is return the data by detaching from the composite CComBSTR and closing the handle:

*Data = composite.Detach();

FindClose(hDriver);

return S_OK;

If you want to check what the entire method looks like, here is the snippet:

STDMETHODIMP CNativeAPI::GetDeviceDriverInformation(BSTR* Data)
{
	HANDLE hDriver;
	DeviceSearchType DeviceSearch = DeviceSearchByLegacyName;

	DEVMGR_DEVICE_INFORMATION DeviceInfo;

	DeviceInfo.dwSize = sizeof(DEVMGR_DEVICE_INFORMATION);

	hDriver = FindFirstDevice(DeviceSearch,L"*",&DeviceInfo);

	CComBSTR composite("");
	
	if (hDriver != INVALID_HANDLE_VALUE)
	{
		do
		{
			CComBSTR ccLegacyName = SysAllocString(DeviceInfo.szLegacyName);
			SysFreeString(ccLegacyName);
			CComBSTR ccDeviceKey = SysAllocString(DeviceInfo.szDeviceKey);
			SysFreeString(ccDeviceKey);
			CComBSTR ccBusName = SysAllocString(DeviceInfo.szBusName);
			SysFreeString(ccBusName);
			CComBSTR ccDeviceName = SysAllocString(DeviceInfo.szDeviceName);
			SysFreeString(ccDeviceName);

			composite.AppendBSTR(ccLegacyName);
			composite.AppendBSTR(ccDeviceKey);
			composite.AppendBSTR(ccBusName);
			composite.AppendBSTR(ccDeviceName);
			composite.Append("\n");
		} while (FindNextDevice(hDriver,&DeviceInfo));
	}

	*Data = composite.Detach();

	FindClose(hDriver);

    return S_OK;
}

Let's see how we can now integrate this in the Windows Phone application. Create a new Mango project (7.1) and follow (once again) the general pre-setup instructions here. If you are wondering where you can get Microsoft.Phone.InteropServices.dll, you can either use Reflection or dump the GAC libraries from the emulator image.

Since you will need the interface and the co-class GUIDs, here is where to find them in the IDL file:

That being said, in the Windows Phone application I have these declarations in the main namespace:

[ComImport, ClassInterface(ClassInterfaceType.None), Guid("8848DEB3-66B6-4AE3-A6F6-4A9C2F6595A5")]
public class CNativeAPI
{
}

[ComImport, Guid("57C3A135-837D-486F-93E3-BF878F61892B"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface INativeAPI
{
    [return: MarshalAs(UnmanagedType.BStr)]
    string GetDeviceDriverInformation();
}

When the page is loaded, I am registering the COM and instantiating the hook class:

INativeAPI NativeAPIHook;
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    ComBridge.RegisterComDll("NativeLink.dll", new Guid("8848DEB3-66B6-4AE3-A6F6-4A9C2F6595A5"));
    NativeAPIHook = (INativeAPI)new CNativeAPI();
}

I added a single button that will show the driver information in a MessageBox:

private void btnDriverInfo_Click(object sender, RoutedEventArgs e)
{
    string data = NativeAPIHook.GetDeviceDriverInformation();
    MessageBox.Show(data);
}

Can you test this in the emulator? No. The reason for this are the library architecture ties (ARMV4I).

Your output can be similar to this:

$device\DAL1$bus\BuiltInPhase1_0_8_0$bus\BuiltInPhase1_0_8_0$device\DAL1
$device\CCS0$bus\BuiltInPhase1_0_11_0$bus\BuiltInPhase1_0_11_0$device\CCS0
$device\ERR1$bus\BuiltInPhase1_0_19_0$bus\BuiltInPhase1_0_19_0$device\ERR1
$device\PMD1$bus\BuiltInPhase1_0_17_0$bus\BuiltInPhase1_0_17_0$device\PMD1
Drivers\BuiltIn\DM$device\DMV1$bus\BuiltInPhase1_0_7_0$device\DMV1
$device\DSK1$bus\BuiltInPhase1_0_6_0$bus\BuiltInPhase1_0_6_0$device\DSK1
$device\SME1$bus\BuiltInPhase1_0_4_0$bus\BuiltInPhase1_0_4_0$device\SME1
Drivers\BuiltIn\RPC$device\RPC1$bus\BuiltInPhase1_0_3_0$device\RPC1
$device\DAL0$bus\BuiltInPhase1_0_2_0$bus\BuiltInPhase1_0_2_0$device\DAL0
$device\DAM1$bus\BuiltInPhase1_0_1_0$bus\BuiltInPhase1_0_1_0$device\DAM1
$device\RMT1Drivers\BuiltIn\RemoteApisSvc$bus\BuiltInPhase1_0_18_0$device\RMT1
$device\CRM1$bus\BuiltInPhase1_0_0_0$bus\BuiltInPhase1_0_0_0$device\CRM1
$device\SDC1$bus\BuiltInPhase1_0_9_0$bus\BuiltInPhase1_0_9_0$device\SDC1
$device\SHC1$bus\BuiltInPhase1_0_15_0$bus\BuiltInPhase1_0_15_0$device\SHC1
$device\GIO1$bus\BuiltInPhase1_0_16_0$bus\BuiltInPhase1_0_16_0$device\GIO1
$device\MCD1$bus\BuiltInPhase1_0_10_0$bus\BuiltInPhase1_0_10_0$device\MCD1
$device\PMS1$bus\BuiltInPhase1_0_14_0$bus\BuiltInPhase1_0_14_0$device\PMS1
$bus\SDBus_0_0_0\Drivers\SDCARD\ClientDrivers\Class\SDMemory_Class\High_Capacity$device\DSK2$device\DSK2
$bus\BuiltIn_0_56_0Drivers\BuiltIn\CriticalAppMonitor$device\CPM0$device\CPM0
$bus\BuiltIn_0_60_0Drivers\BuiltIn\ErrorReporting$device\DWX1$device\DWX1
Notify$bus\NFY0$bus\NFY0$device\NFY0
Drivers\BuiltIn\QEM$bus\BuiltIn_0_5_0$device\QEM1$device\QEM1
$bus\BuiltIn_0_46_0Drivers\BuiltIn\WAPIMAN$device\WAM1$device\WAM1
$bus\BuiltIn_0_47_0Drivers\BuiltIn\ALPCD$device\LPC2$device\LPC2
$bus\BuiltIn_0_57_0Drivers\BuiltIn\DelayedBootWork$device\DBW0$device\DBW0
$bus\BuiltIn_0_64_0Drivers\BuiltIn\NTLMSSP_SVC$device\SSP0$device\SSP0
$bus\BuiltIn_0_77_0Drivers\BuiltIn\SqmEngine$device\SQM1$device\SQM1
$bus\BuiltIn_0_45_0Drivers\BuiltIn\AudioRtgMgr$device\ARM1$device\ARM1
$bus\BuiltIn_0_65_0Drivers\BuiltIn\credsvc$device\CRD0$device\CRD0
$bus\BuiltIn_0_8_0Drivers\BuiltIn\runQuiet$device\RQT1$device\RQT1
$bus\BuiltIn_0_36_0Drivers\BuiltIn\CLKREGIM$device\CRM2$device\CRM2
$bus\BuiltIn_0_18_0Drivers\BuiltIn\MSM_TIME$device\TMS1$device\TMS1
$bus\BuiltIn_0_33_0Drivers\BuiltIn\I2CMDD$device\I2C1$device\I2C1
$bus\BuiltIn_0_6_0Drivers\BuiltIn\SerialHS2$device\COM2$device\COM2
$bus\BuiltIn_0_17_0Drivers\BuiltIn\SerialHS$device\COM9$device\COM9
$bus\BuiltIn_0_32_0Drivers\BuiltIn\Battery$device\BAT1$device\BAT1
$bus\BuiltIn_0_41_0Drivers\BuiltIn\UsbFn$device\UFN1$device\UFN1
$bus\USBFN_1_0\Drivers\USB\FunctionDrivers\CompositeFN$device\UFC1$device\UFC1
$bus\USBCFN_1_29\Drivers\USB\FunctionDrivers\MtpClientDrvUsb$device\MUT1$device\MUT1
$bus\USBCFN_1_30\Drivers\USB\FunctionDrivers\Serial_Class$device\COM1$device\COM1
$bus\BuiltIn_0_21_0Drivers\BuiltIn\SPIbus$device\SPI1$device\SPI1
Drivers\BuiltIn\RIL$bus\BuiltIn_0_76_0$device\RIL1$device\RIL1
Drivers\BuiltIn\GSL$bus\BuiltIn_0_7_0$device\GSL1$device\GSL1
$bus\BuiltIn_0_16_0Drivers\BuiltIn\WaveDev$device\WAV1$device\WAV1
Drivers\BuiltIn\SIM$bus\BuiltIn_0_68_0$device\SIM1$device\SIM1
Drivers\BuiltIn\SMS$bus\BuiltIn_0_69_0$device\SMS1$device\SMS1
$bus\BuiltIn_0_87_0Drivers\BuiltIn\NDIS$device\NDS0$device\NDS0
Comm\nwifi$bus\NWF1$bus\NWF1$device\NWF1
Drivers\BuiltIn\KBD$bus\BuiltIn_0_2_0$device\KPD1$device\KPD1
$bus\BuiltIn_0_3_0Drivers\BuiltIn\Accelerometer$device\ACC1$device\ACC1
$bus\BuiltIn_0_24_0Drivers\BuiltIn\NLed$device\NLD1$device\NLD1
$bus\BuiltIn_0_15_0Drivers\BuiltIn\DCVS$device\DVS1$device\DVS1
Drivers\BuiltIn\QVD$bus\BuiltIn_0_14_0$device\QVD1$device\QVD1
$bus\IPS0Comm\Devices\TCPIP\WfpIPSec$device\IPS0$device\IPS0
$bus\WFP0Comm\Devices\TCPIP\WfpKfd$device\WFP0$device\WFP0
$bus\DP60Comm\Devices\TCPIP6\DHCPV6L$device\DP60$device\DP60
$bus\NAT0Comm\ConnectionSharing\Driver$device\NAT0$device\NAT0
$bus\DP40Comm\Devices\TCPIP\DHCP$device\DP40$device\DP40
Drivers\BuiltIn\WWN$bus\BuiltIn_0_72_0$device\WWN0$device\WWN0
Drivers\BuiltIn\BFE$bus\BuiltIn_0_79_0$device\BFE0$device\BFE0
$bus\BuiltIn_0_82_0Drivers\BuiltIn\Ws2Serv$device\WSS1$device\WSS1
$bus\SDBus_0_1_1\Drivers\SDCARD\ClientDrivers\Custom\MANF-02D0-CARDID-4329-FUNC-1$device\NDL1$device\NDL1
Drivers\BuiltIn\BTD$bus\BuiltIn_0_49_0$device\BTD0$device\BTD0
$bus\BuiltIn_0_86_0Drivers\BuiltIn\NDISUIO$device\UIO1$device\UIO1
$bus\BuiltIn_0_20_0Drivers\BuiltIn\Magnetometer$device\MAG1$device\MAG1
$bus\BuiltIn_0_51_0Drivers\BuiltIn\btavctp$device\AVC0$device\AVC0
$bus\BuiltIn_0_52_0Drivers\BuiltIn\btavdtp$device\AVD0$device\AVD0
$bus\BuiltIn_0_31_0Drivers\BuiltIn\Compass2$device\CMP1$device\CMP1
$bus\BuiltIn_0_30_0Drivers\BuiltIn\SensorFusion$device\FUS1$device\FUS1
$bus\BuiltIn_0_50_0Drivers\BuiltIn\btavrcp$device\AVR0$device\AVR0
$bus\BuiltIn_0_53_0Drivers\BuiltIn\BtA2dpSnd$device\WAV8$device\WAV8
Drivers\BuiltIn\ALS$bus\BuiltIn_0_28_0$device\ALS1$device\ALS1
$bus\BuiltIn_0_27_0Drivers\BuiltIn\Proximity$device\PRX1$device\PRX1
$bus\BuiltIn_0_0_0Drivers\BuiltIn\Backlight$device\BKL1$device\BKL1
$bus\BuiltIn_0_11_0Drivers\BuiltIn\VencDriverNewpm$device\Vpm2$device\Vpm2
$bus\BuiltIn_0_12_0Drivers\BuiltIn\Ven_Driver$device\Ven1$device\Ven1
$bus\BuiltIn_0_13_0Drivers\BuiltIn\Ven_DriverNew$device\Ven2$device\Ven2
$bus\BuiltIn_0_10_0Drivers\BuiltIn\VencDriverPm$device\Vpm1$device\Vpm1
$bus\BuiltIn_0_59_0Drivers\BuiltIn\gpsdriver$device\GPS0$device\GPS0
$bus\BuiltIn_0_4_0Drivers\BuiltIn\QisdaModemBridge$device\QAT1$device\QAT1
$bus\BuiltIn_0_74_0Drivers\BuiltIn\ModemBridge$device\MBG1$device\MBG1
$bus\BuiltIn_0_73_0Drivers\BuiltIn\RemoteAtcop$device\RAT1$device\RAT1
$bus\BuiltIn_0_35_0Drivers\BuiltIn\BrcmHCI$device\BBF1$device\BBF1
$bus\BuiltIn_0_34_0Drivers\BuiltIn\BrcmTest$device\BTT1$device\BTT1
$bus\BuiltIn_0_63_0Drivers\BuiltIn\EAP3SVC$device\ETS0$device\ETS0
$bus\BuiltIn_0_85_0Drivers\BuiltIn\NSIPROXY$device\NSI1$device\NSI1
$bus\BuiltIn_0_93_0Drivers\BuiltIn\AudioTuner$device\TNR1$device\TNR1
$bus\BuiltIn_0_84_0Drivers\BuiltIn\NSISVC$device\NSI0$device\NSI0
$bus\BuiltIn_0_62_0Drivers\BuiltIn\EAPSVC$device\EHS0$device\EHS0
$bus\BuiltIn_0_71_0Drivers\BuiltIn\CmService$device\CMS0$device\CMS0
$bus\BuiltIn_0_78_0Drivers\BuiltIn\TSKSCHRDF$device\RDF1$device\RDF1
$bus\BuiltIn_0_48_0Drivers\BuiltIn\LASS$device\LSS0$device\LSS0
$bus\BuiltIn_0_61_0Drivers\BuiltIn\WISPrService$device\WCS0$device\WCS0
$bus\BuiltIn_0_80_0Drivers\BuiltIn\IKEEXT$device\IKE0$device\IKE0
$bus\BuiltIn_0_67_0Drivers\BuiltIn\CameraDriver$device\CAM1$device\CAM1
$bus\BuiltIn_0_55_0Drivers\BuiltIn\MSDVFS$device\MCD2$device\MCD2
Drivers\Touch$bus\TCH1$bus\TCH1$device\TCH1
$device\AEF0$bus\services_0_40_0$bus\services_0_40_0$device\AEF0
Services\LPCD$device\LPC1$bus\services_0_45_0$device\LPC1
Services\SioUsbConn$device\SIO1$bus\services_0_48_0$device\SIO1
Services\BNSS$device\BNS1$bus\services_0_12_0$device\BNS1
Services\DCOMSSD$device\DCM1$bus\services_0_44_0$device\DCM1
Services\BATSVC$device\BAT0$bus\services_0_35_0$device\BAT0
Services\BTAGSVC$device\BAG0$bus\services_0_10_0$device\BAG0
Services\TWS$device\TWS0$bus\services_0_17_0$device\TWS0
Services\GPSID$device\GPD0$bus\services_0_37_0$device\GPD0
$bus\GPD9SYSTEM\CurrentControlSet\GPS Intermediate Driver\Multiplexer\ActiveDevice$device\GPD9$device\GPD9
Services\CRSVC$device\CRS0$bus\services_0_15_0$device\CRS0
Services\OBEX$device\OBX0$bus\services_0_36_0$device\OBX0
Services\LFSVC$device\LOC0$bus\services_0_41_0$device\LOC0
Services\WLIDSVC$device\WLI1$bus\services_0_27_0$device\WLI1
Services\SNService$device\SNS0$bus\services_0_42_0$device\SNS0
Services\GpsHelper$device\GPH0$bus\services_0_33_0$device\GPH0
Services\SqmUpload$device\SQM0$bus\services_0_20_0$device\SQM0
Services\DSTSVC$device\DST0$bus\services_0_28_0$device\DST0
Services\A2DPNotify$device\ROU1$bus\services_0_47_0$device\ROU1
Services\TIPC$device\TIP0$bus\services_0_13_0$device\TIP0
Services\MTFServer$device\MTF0$bus\services_0_16_0$device\MTF0
$bus\services_0_4_0Services\SmsTransport$device\SMT0$device\SMT0
Services\Proxy$device\PXY0$bus\services_0_23_0$device\PXY0
$device\TSH0$bus\services_0_18_0$bus\services_0_18_0$device\TSH0
Services\CfmService$device\CFM0$bus\services_0_21_0$device\CFM0
Services\DuaSvc$device\DUA0$bus\services_0_46_0$device\DUA0
Services\ZConfig$bus\services_0_8_0$device\ZCO0$device\ZCO0
Services\ZMedia$bus\services_0_9_0$device\ZME0$device\ZME0
$device\MIT0$bus\services_0_25_0$bus\services_0_25_0$device\MIT0
Services\PUSH$device\PSH1$bus\services_0_11_0$device\PSH1
Services\Znet$device\ZNE0$bus\services_0_24_0$device\ZNE0
Services\MtpSvc$device\MTP0$bus\services_0_26_0$device\MTP0
Services\Hotspot$device\HPT0$bus\services_0_22_0$device\HPT0
$bus\services_0_7_0Services\MPNSClientManager$device\PNM0$device\PNM0
Services\ICS$device\ICS0$bus\services_0_14_0$device\ICS0
$bus\services_0_1_0Services\PimIndexMaintenance$device\PIM1$device\PIM1
$bus\services_0_2_0Services\ContactsTokenService$device\CTS1$device\CTS1
$device\MPI0$bus\services_0_31_0$bus\services_0_31_0$device\MPI0
$bus\services_0_5_0Services\MsgNotificationService$device\MNS0$device\MNS0
$bus\services_0_3_0Services\MsgMaintenance$device\MSG0$device\MSG0
Services\AgeOut$device\UAO0$bus\services_0_30_0$device\UAO0
$device\LMU0$bus\services_0_32_0$bus\services_0_32_0$device\LMU0
Services\LIM$bus\services_0_6_0$device\LIM1$device\LIM1
Services\CommSync$device\CSS0$bus\services_0_39_0$device\CSS0
Services\SNApi$device\SNA0$bus\services_0_29_0$device\SNA0
$bus\WAP1Comm\Cellular\WAP\Driver$device\WAP1$device\WAP1
$bus\PIN1Software\Microsoft\DirectX\DirectShow\Capture\PIN1$device\PIN1$device\PIN1
$bus\services_1_1_0services\DelayLoad\FBAuthService$device\FBA0$device\FBA0
$bus\KIS0Comm\Security\Cryptography\Keyiso$device\KIS0$device\KIS0
$device\MYP0$bus\services_1_208_0$bus\services_1_208_0$device\MYP0
$bus\BTS0Software\Microsoft\BtServ$bus\BTS0$device\BTS0
$bus\ZMF0Software\Microsoft\Zune\ZMFService$device\ZMF0$device\ZMF0

The Mobile Zone is brought to you in partnership with Strongloop and IBM.  Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud.

Topics:

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}