Download the source code

The Local Authentication Subsystem (LASS) is a new feature of Windows Mobile 5. The LASS provides user authentication independent of any specific authentication mechanism. Before Windows CE 5.0 there was only password based authentication. LASS support different authentication mechanism through Local Authentication Plugin component (LAP). Windows Mobile by default comes with the password based LAP (lap_pw.dll). A developer can create a custom LAP that implements the desired authentication mechanism. For example, a developer can implement a biometric based authentication through writing a custom LAP that implements biometric mechanism.

The LAP is a DLL file that exports a set of functions defined by the LASS. They are:

BOOL InitLAP (InitLap* il);
VOID DeinitLAP();
BOOL LAPCreateEnrollmentConfigDialog(HWND hParentWindow,DWORD dwOptions);
BOOL VerifyUser(const GUID* AEKey,LPCWSTR pwszAEDisplayText,HWND hWndParent,DWORD dwOptions,PVOID pExtended);
VOID VerifyUserStart(const GUID* AEKey,LPCWSTR pwszAEDisplayText,HWND hWndParent,DWORD dwOptions,PVOID pExtended);
VOID VerifyUserStop();
VOID VerifyUserToTop();

LASS will load the current LAP and call InitLAP function. The function has one parameter which is a pointer to InitLap structure. This will contain the information regarding the LAP. The LAP should fill the capabilities member with the capabilities supported by the LAP. The loaded LAP will remain in memory until another LAP is loaded. When unloading the LAP the LASS will invoke DeinitLAP function just before unloading.

The LAPCreateEnrollmentConfigDialog will be called whenever the LASS wants to enroll the user and initialize the password. When this function is called the LAP displays a dialog from which the user can enable/disable authentication or change the password.

The VerifyUser function will be called whenever the LASS want to authenticate the user. When this function is called, the LAP displays a verification dialog. The user can enter the password or any other authentication data.

The VerifyUserStart function is called when LASS needs to call VerifyUser multiple times. This will be called just before the first call to the VerifyUser function. Just like the VerifyUserStart the LASS will call VerifyUserStop function just after the last call to the VerifyUser function.

The VerifyUserToTop is called whenever the LASS wants to make the verification dialog top of the z order.

An application can call LASS function when the user has to be authenticated. The LASS function VerifyUser can be called whenever the application needs to verify the user. Also if the user is not enrolled and the application wants to enroll the user programmatically, the application can call the LASS function CreateEnrollmentConfigDialog. The LASS will call the appropriate LAP function when an application call any of these functions.

To install a custom LAP, you have to create a subkey under the key HKEY_LOCAL_MACHINE\Comm\Security\LASSD\LAP. The key specifies the name of the custom LAP. Under this key the string entry Dll specifies the DLL file of the custom LAP. To activate the custom LAP, you have to specify the name (this is the name of subkey created under the key HKEY_LOCAL_MACHINE\Comm\Security\LASSD\LAP) of the custom LAP by using the ActiveLap value. The value of the ActiveLap determines the current LAP. For example if the value of ActiveLap is “lap_pw”, the DLL specified un the key HKEY_LOCAL_MACHINE\Comm\Security\LASSD\LAP\lap_pw will be loaded.

The sample LAP created here uses a simple password authentication mechanism. The enrollment screen looks like this:

Lapsample 225x300 Lapdraw 225x300

When the user pressed the “…” button another screen is displayed in which user can draw a specific pattern using the stylus/mouse. When the “OK” button is pressed the pattern will be converted to string using a lookup value. This lookup is a predefined one and to make program simple the lookup uses only the integers 1…9 and small letters a…o. An actual custom made LAP will use a complex algorithm to convert the pattern to password string.

Following steps describes the installation procedure of the sample LAP.

1. Compile the project
2. Sign the DLL file with appropriate certificate (we can use the developer certificate) and copy to windows folder
3. Create a subkey under the key HKEY_LOCAL_MACHINE\Comm\Security\LASSD\LAP\”LAP name”
4. Change the ActiveLap value to the name given (“LAP name”)

To test the LAP go to Settings->Lock, the sample LAP enrollment dialog will be displayed. It is very important that the DLL is signed with the appropriate certificate and install that certificate in the device also.

Note: Be very careful while using this sample. If you are entering the password by drawing a pattern and forget the pattern, you may not able to unlock the device. You may have to re-flash the device in order to unlock it.

{ 1 comment }

Programming HTTPD in Windows Mobile

by Krishnaraj Varma on November 1, 2008

in Windows Mobile

Download the source code

By default the Windows Mobile does not include a Web Server. But it is available as an installable Optional Server Components. The installation contains MSMQ, HTTPD, PeerNet, UPnPCtrl and UPnPHost components. The HTTPD component installs a Web Server on your Windows Mobile.

We can extend the HTTPD server by using an ISAPI filter or ISAPI extension. There are different examples of ISAPI in the Windows CE Platform Builder samples. These can be found in the folder x:\ C:\WINCE500\PUBLIC\SERVERS\SDK\SAMPLES\HTTP where x is the drive you have installed the Windows CE Platform Builder.

Once you installed the server components and restart the device, you can access the Web Server using the phone’s IP address. If your device is connected to the computer using ActiveSync, you can access the Web Server using the ActiveSync IP address http://169.254.2.1/. This will show up the default HTML page. If you are connected to the internet using GPRS or 3G connection you can use the phone’s IP address to reach the Web Server.

The sample application presented here is an ISAPI filter DLL that lists the call log. The filter can be accessed using http://169.254.2.1/calllog. The ISAPI filter DLL exports three functions: GetFilterVersion, HttpFilterProc and TerminateFilter. For detailed information about the ISAPI Filters and Extensions please refer to the MSDN documentation.

When the Web Server is started, it looks for an entry Filter Dlls under the registry key HKEY_LOCAL_MACHINE\Comm\HTTPD. This entry lists all the Filter Dlls that are installed separated by comma. The HTTPD server loads all the DLLs listed. After loading the DLL the server will call the function GetFilterVersion. The TerminateFilter function will be called when the DLL is unloaded. The server will call HttpFilterProc for various event notifications.

To install this ISAPI dll, you have to copy the DLL WMWeb.dll to the Windwos folder and manually add the DLL name to the entry Filter Dlls under the key HKEY_LOCAL_MACHINE\Comm\HTTPD.

Writing Service Applications in Windows CE

by Krishnaraj Varma on October 24, 2008

in Windows Mobile

Download the source code

Service applications are very common in desktop world. Before Windows CE 4.0, CE did not have the concept of service applications. From Windows CE 4.0 the Service Manager (services.exe) was added. Service Manager loads service application based on a particular registry entries on system startup or upon request from an application. A service application is a normal DLL file which exports 8 predefined function. A normal service application should export at least 5 of the required 8 functions. The other 3 are optional and only needed if you are creating a service the supports read and write operations. The function that has to be exported by a service application are:

DWORD xxx_Init(DWORD)
BOOL xxx_Deinit(DWORD)
BOOL xxx_Open(DWORD dwData,DWORD dwAccess,DWORD dwShareMode)
BOOL xxx_Close( DWORD dwData )
BOOL xxx_IOControl( DWORD dwData, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut )
DWORD xxx_Read(DWORD dwData,LPVOID pBuf,DWORD dwLen)
DWORD xxx_Write(DWORD dwData,LPCVOID pInBuf,DWORD dwInLen)
DWORD xxx_Seek(DWORD dwData,long pos,DWORD type)

The xxx represents the three letter abbreviation used by the service. This 3 letter is defined by the service and is specified in the service entry in registry. The client application used this 3 letter and an index value when trying to open using the API CreateFile.

DWORD xxx_Init(DWORD);: This function is called by the Service Manager when the service is first loaded. We can perform initialization of any resource that are used by the service application. The only parameter is the initial state of the service. This can be SERVICE_INIT_STARTED, which indicates the service is started and SERVICE_INIT_STOPPED, which indicates the service is stopped. The return value indicates success or failure, 0 indicates failure and any value greater that 0 indicates success. If the service application returns other than 0, the Service Manager will pass this value to other service functions.

BOOL xxx_Deinit(DWORD);: This function is called by the Service Manager when the service is unloaded. We can perform and resource cleanup tasks when this function is called. The only parameter is a DWORD value. This is the value that is returned by the xxx_Init function.

BOOL xxx_Open(DWORD dwData,DWORD dwAccess,DWORD dwShareMode): This is called when a client application uses CreateFile API to open the service. The first paramter will be the value that is returned by the xxx_Init function. The second parameter will be access mode used by the client application. The third parameter is the share mode used by the client application. A return value of TRUE indicates success and FALSE indicates failure.

BOOL xxx_Close( DWORD dwData ): This function is called when the client application used CloseHandle API to close the service. The only parameter is the value that returned by the xxx_Init function. TRUE indicates success and FALSE indicates failure.

BOOL xxx_IOControl( DWORD dwData, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut ): This is called when the client application uses DeviceIoControl API to pass the control codes to the service. The first parameter is the value returned by the xxx_Init function. The second parameter is the IOCTL code used by the application. The third and fourth parameter are the input buffer and it’s length. These are used by client application to pass any data to the service. The fifth and sixth parameter is the output buffer and it’s length used to pass any data to the client application from the service. The seventh parameter is the length of the data that is passed to the client application, the service should fill this parameter with the actual data that is filled in.

There are different Service IOCTL commands that can be used to control the service application, please refer to the MSDN help to study more about the common IOCTL commands.

DWORD xxx_Read(DWORD dwData,LPVOID pBuf,DWORD dwLen): This function is called when the client application used ReadFile API to read data from the service. This is an optional function and is needed when the service application supports read and write. The first parameter is the value that is returned by the xxx_Init function. Second and third parameter is the output buffer and it’s length. The service application should return the actual number of bytes that is written to the buffer.

DWORD xxx_Write(DWORD dwData,LPCVOID pInBuf,DWORD dwInLen): This is the function called when the client application uses WriteFile API to write data to the service. This is optional and only needed if the service application supports read and write. The second and third parameter is the input buffer and it’s length. The service should return the actual number of bytes written.

DWORD xxx_Seek(DWORD dwData,long pos,DWORD type): This function is called when the client application uses SetFilePointer API. The first parameter is the value returned by the xxx_Init function. The second parameter is the number of bytes to move and third parameter specifies the start of the seek operation. This can be FILE_BEGIN, FILE_CURRENT or FILE_END. This function is optional and is only needed if the service supports the seek operation.

The service application should have a registry entry under the key HKEY_LOCAL_MACHINE\Services\. There are different registry values to create for a service, some of them they are:

Description: Description of the service.
DisplayName: Name of the service.
Dll: DLL name of the service.
Index: Service index. This index is used along with the “Prefix” to open the service.
Keep: If this is 0 then the service will be unloaded immediately after the initialization.
Prefix: Prefix of the service DLL. This along with the index is used to open the service.

We can use the RegisterService API to register the service, but it is not recommended. It is better to manually register the service and use the ActivateService API in order to activate the service.

To open the service, we can use CreateFile API with a service file name, for example in the sample service the prefix is “UID” and the index is 1 so the file name will be “UID1:”. After obtaining the handle to the service, we can issue different IOCTL commands or read and write to the file.

The sample application presented here is a very simple service that is used to get unique device identifier. The GetDeviceUniqueID API is used to get the unique identifier. The client application starts the service and send the IOCTL_UID_SERVICE_GETID IOCTL command (which is custom IOCTL command defined by the service application) to get the unique id. The id returned by the service is displayed in an edit control.

In order to start the service you should copy the service DLL to the windows directory and run the client application. The client application register the service and activate it. An additional exported function RegisterUIDService is defined in the service DLL in order to make the registration process easy. The client application uses this function to register the service.

This is a very simple service application and I hope this will give you an introduction to the services in Windows CE.

{ 0 comments }

Using NDIS in Windows CE

by Krishnaraj Varma on October 19, 2008

in Windows Mobile

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

in Windows Mobile

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

in Windows Mobile

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

in Windows Mobile

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

in Windows Mobile

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 Card\Vol:”. 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

in Windows Mobile

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.

{ 0 comments }

Disclaimer: This is a personal weblog. The information in this weblog is provided “AS IS” with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion.