Using NDIS in Windows CE

by Krishnaraj Varma on October 19, 2008

Download the sample code

Network Driver Interface Specification (NDIS) is an API to communicate with Network Interface Cards (NIC) developed by Microsoft and 3Com Corporation. It is library of functions (wrapper) to hide the complexity of the network cards. Using NDIS developers can create device drivers that communicate with the NICs and enables the developer to create protocol stacks that send and receive data packets. These packets are usually called frame.

The sample program presented here lists the adapters present and the protocol names that are associated with each adapters. The application first opens the NDIS device driver. This is done by using the API CreateFile. The first parameter is the device name which will be NDS0: most of the time. The following snippet opens the “NDS0:” device:

m_hDevice = CreateFile(TEXT("NDS0:"),GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE);

After opening the device, the application retrieves all the adapters present and lists the names in a combobox. This is done using the API DeviceIoControl with IOCTL_NDIS_GET_ADAPTER_NAMES control code. Following code shows the operation:

DeviceIoControl(m_hDevice,IOCTL_NDIS_GET_ADAPTER_NAMES,NULL,0,LPVOID)szBuffer,MAX_ADAPTER_BUFFER,&dwSize,NULL);

When completed successfully the szBuffer will have the names of the adapters separated by NULL. The end of the buffer is represented by two NULLs.

When an adapter is selected the protocol names that are associated with it are displayed in a listbox. To retrieve the protocol names, first we have to bind the selected adapter, this is done by using the DeviceIoControl API with IOCTL_NDIS_BIND_ADAPTER control code:

DeviceIoControl(m_hDevice,IOCTL_NDIS_BIND_ADAPTER,(LPVOID)lpszAdapter,wcslen(lpszAdapter),NULL,0,NULL,NULL);

The pszAdapter parameter is the name of the adapter to bind. After binding the adapter we can retrieve the protocol list by using the IOCTL_NDIS_GET_PROTOCOL_NAMES control code:

DeviceIoControl(m_hDevice,IOCTL_NDIS_GET_PROTOCOL_NAMES,NULL,0,LPVOID)szBuffer,MAX_ADAPTER_BUFFER,&dwSize,NULL);

Again the szBuffer will be multi-string that contains all the protocol names associated with the adapter. This a very simple application and I hope this will give you an introduction to NIDS. I am working on more samples and will post here whenever it is completed.

{ 0 comments }

Controlling Notification LED in Windows Mobile

by Krishnaraj Varma on October 14, 2008

To control the Notification LEDs in Windows Mobile, we can use the API NLedSetDevice. The syntax of is defined as:

BOOL WINAPI NLedSetDevice(UINT nDeviceId,void* pInput);

The nDeviceId parameter specifies the type of information to set. The only supported value is NLED_SETTINGS_INFO_ID, which set the sets the settings for the Notification LED. The second parameter is a pointer to NLED_SETTINGS_INFO structure, which is defined as:

struct NLED_SETTINGS_INFO {
UINT LedNum;
INT OffOnBlink;
LONG TotalCycleTime;
LONG OnTime;
LONG OffTime;
INT MetaCycleOn;
INT MetaCycleOff;
};

There could be more than one LED present in the device. You can specify which LED to control in the LedNum member. The following code snippet controls the LED on or off:

void SetLED(int nLed,BOOL bOn)
{
NLED_SETTINGS_INFO sInfo;

ZeroMemory(&sInfo,sizeof(NLED_SETTINGS_INFO));

sInfo.LedNum = nLed;
sInfo.OffOnBlink = bOn ? 1 : 0;

NLedSetDevice(NLED_SETTINGS_INFO_ID, &sInfo);
}

The following code retrieves the number of LEDs present in the device:

NLED_COUNT_INFO sCount = {0};

NLedGetDeviceInfo(NLED_COUNT_INFO_ID,&sCount);

{ 0 comments }

Download source code

My previous article demonstrates the use of the IImagingFactory interface to enumerate the installed encoders and decoders. The above interface can be used to load any supported image file. The CreateImageFromFile method can be used to load an image from file. The syntax of the method is:

HRESULT CreateImageFromFile(const WCHAR* filename,IImage** image);

The filename parameter is the name of the file to load and the image parameter is an out parameter and will be filled with a pointer to IImage interface. The Draw method of the IImage can be used to draw image on a device context.

The sample application displays all the images from the “My Pictures” folder of the device. You can move forward and backward using the toolbar buttons.

{ 0 comments }

Using IImagingFactory to enumerate codec list

by Krishnaraj Varma on October 11, 2008

Download source code

The imaging interface IImagingFactory is used to create, load and manipulate images using image encoders and decoders (more on this later). We can enumerate the installed encoders and decoders using GetInstalledDecoders and GetInstalledEncoders methods. These methods returns an array of ImageCodecInfo structure. Here is a simple application that lists all the encoders and decoders installed on the mobile device.

{ 0 comments }

Formatting Storage Card using Storage APIs

by Krishnaraj Varma on October 8, 2008

CAUTION: Be very careful while using the sample provided. Do not try to format any system stores, that will damage your device permanently.

Download the source code

The Storage API provides facility to program the Storage Manager. Using Storage Manager we can perform various operations on storage card like mount, dismount, enumerate, format, etc…

To enumerate storage cards we can use the APIs FindFirstStore and FindNextStore. This will fill the STOREINFO structure with the information about the storage card found. Each store contains one or more partitions. We can use the API FindFirstPartition and FindNextPartition to enumerate the partitions in that store.

To format a partition first we open the store and the partition, then we can use the API FormatVolume or FormatVolumeEx to format it. Before formatting we should dismount the partition using the API DismountPartition and after formatting we can mount the partition using MountPartition

The sample program displays all the stores found in a Combo Box. Upon selecting a store, all the partitions in that stores will be displayed in a List Control. You can right click each entry and format that partition.

I only tested this on my HTC TyTN II and with the microSD card. I didn’t try to format any system stores. Only the microSD card is formatted. Again be very careful while using the sample, formatting a system partition may damage you device permanently.

{ 0 comments }

Enumerating Flash Card in Windows Mobile

by Krishnaraj Varma on October 5, 2008

Sometimes we need to open the Storage Card of the device and get a handle, we can use the CreateFile API for that by giving the file name as “Storage CardVol:”. The problem with this approach is that we are hard coding the name of the storage card which may not be same for all devices. We can overcome this by using the API FindFirstFlashCard and FindNextFlashCard APIs. These APIs enumerate the flash cards and return the details in WIN32_FIND_DATA structure. The name of the card can be found in the cFileName member of the structure. The code snippet below enumerate the flash cards and insert the name in to a CListCtrl:


WIN32_FIND_DATA wfd;
HANDLE hFind = FindFirstFlashCard(&wfd);
BOOL bContinue = (INVALID_HANDLE_VALUE != hFind);
int nItem = 0;
int nIndex = 0;

while(bContinue)
{
nItem = pList->InsertItem(nIndex,wfd.cFileName);

bContinue = FindNextFlashCard(hFind,&wfd);

++nIndex;
}

{ 0 comments }

Getting Unique Device ID using GetDeviceUniqueID API

by Krishnaraj Varma on October 3, 2008

Download the source code

The API GetDeviceUniqueID is used to retrieve unique device hash that can be used to uniquely identify the device. To use this function we have to supply an application specific value that will be used to create the unique hash value. Giving the same application specific value will generate the same hash value even if the device is re-flashed or cold-booted.

The syntax of the function is:

HRESULT GetDeviceUniqueID(LPBYTE pbApplicationData,DWORD cbApplictionData,DWORD dwDeviceIDVersion,LPBYTE pbDeviceIDOutput,DWORD *pcbDeviceIDOutput);

The first parameter is the application specific value and the second is the length of application specific value. This value should be at least 8 characters in length otherwise the API will fail. The third parameter should be 1. Fourth is an out paramter which will be filled with the device specific unique id. The fifth one is the length of the fourth paramter. Before calling this API we set this parameter to the size of the fourth one and when the API returns this will contain the length of the hash value generated. This size should be at least GETDEVICEUNIQUEID_V1_OUTPUT which is 20 bytes.

The sample application get the unique id and just display it on and edit control.

{ 2 comments }

Enumerating services running on Windows Mobile

by Krishnaraj Varma on October 1, 2008

Download the source code

The service.exe API function EnumServices can be used to enumerate services that are running on Windows Mobile. The API returns an array of ServiceEnumInfo structure. A better approach is to enumerate the services registry key. All the service that are installed in the device will have a registry entry under the key: HKEY_LOCAL_MACHINEServices. Each entry contains the details of the service. Enumerating this registry key will give you more detail about the service like Service Name, Description, Load Order, etc…

Here is a sample program that enumerate this registry key and displays the information about the running services.

{ 0 comments }

Getting device phone number using extended TAPI

by Krishnaraj Varma on September 30, 2008

The phone number of the mobile device can be retrieved using the API lineGetAddressCaps. The API fills the LINEADDRESSCAPS structure that is passed in with information about the address capabilities of the given line. The member dwAddressOffset represents the offset from the start of the structure to the line address. The syntax of the function is:

LONG WINAPI lineGetAddressCaps(HLINEAPP hLineApp,DWORD dwDeviceID,DWORD dwAddressID,DWORD dwAPIVersion,DWORD dwExtVersion,LPLINEADDRESSCAPS lpAddressCaps);

You can copy the string using the code:

WCHAR* pAddress = (WCHAR*)(((BYTE*)pAddressCaps) + pAddressCaps->dwAddressOffset);

This will give you the phone number of the device. You have to check whether the dwAddressOffset member is zero or not. If it is non zero then the system found a phone number.

{ 2 comments }

Download the source code

The Extended TAPI function lineGetGeneralInfo can be used to retrieve the IMEI and IMSI numbers of the phone and SIM card. The syntax is defined as:

LONG WINAPI lineGetGeneralInfo(HLINE hLine, LPLINEGENERALINFO lpLineGeneralInfo);

The hLine parameter is the handle to the line you are interested. The handle is returned by the API lineOpen. The LINEGENERALINFO pointer that is passed in will be filled with the general information. You have to set the dwTotalSize of the pointer to the size you have allocated. If this size is small, then the system will set the dwNeededSize with the size in bytes that is needed to hold all the information. After successful completion of the function the memory will be filled with the general information.

The Extended TAPI function lineGetOperatorStatus is used to retrieve the operator status of the given line. The syntax is defined as:

LONG WINAPI lineGetOperatorStatus(HLINE hLine, LPLINEOPERATORSTATUS pOperatorStatus);

A sample application is provided to demonstrate the use of these APIs. The application displays the IMEI, IMSI, Operator Names along with some other information in a list control.

Since this is sample uses Extended TAPI functions, to run this you have to sign this application with a valid certificate. For testing purpose you can use the Developer Certificate (SDKSamplePrivDeveloper.pfx) that is provided with the Windows Mobile SDK. You can find this in the folder drive:Program FilesWindows CE Toolswce500Windows Mobile 5.0 Pocket PC SDKTools.

Note that the lineGetOperatorStatus function may take some time to complete and return so it may take some time to load the application.

{ 0 comments }