Enumerating Fonts in Windows Mobile

by Krishnaraj Varma on January 5, 2009

Download the source code

To enumerate installed fonts in Windows Mobile, we can use the APIs EnumFonts or EnumFontFamiliesEx. The EnumFontFamiliesEx API is preferred than EnumFonts. The syntax of the EnumFontFamiliesEx is:

int EnumFontFamiliesEx(HDC hdc,LPLOGFONT lpLogfont,
FONTENUMPROC lpEnumFontFamExProc,LPARAM lParam,DWORD dwFlags);

The first parameter is the handle to a Device Context. The second parameter s pointer to a LOGFONT structure. Only lfCharset, lfFaceName, lfPitchAndFamily members are important. The third parameter is pointer to the callback function which will be called for each font found while enumerating. Fourth an parameter is application defined value which will be passed to the callback function. Fifth parameter should be 0 and is not used.

The syntax of the callback function is:

int CALLBACK EnumFontFamExProc(CONST LOGFONT *,
CONST TEXTMETRIC *, DWORD, LPARAM);

The first parameter will be a pointer to ENUMLOGFONTEX structure which contains the font information. The second parameter is a pointer to the TEXTMETRIC structure which contains the attributes of the font. The third parameter is the type of the font which will be DEVICE_FONTTYPE, RASTER_FONTTYPE or TRUETYPE_FONTTYPE. The fourth parameter is the application defined lParam value.

The sample application presented here enumerate all the fonts installed in the device. The EnumFontFamiliesEx is called two times. First to get all the face name and second to enumerate all the fonts of each face name.

{ 0 comments }

Using Remote API 2 (RAPI2) – Part 3

by Krishnaraj Varma on January 4, 2009

Download the source code

This part of the Using RAPI series explains how to enumerate files and folders of the connected device. In previous part I explained how to enumerate database on the connected device.

After creating the IRAPISession using the CreateSession, we can use the CeFindFirstFile and CeFindNextFile to enumerate all the files and folders. This will return the file information in CE_FIND_DATA structure. The CE_FIND_DATA is defined as:

typedef struct CE_FIND_DATA
{
    DWORD    dwFileAttributes;
    FILETIME ftCreationTime;
    FILETIME ftLastAccessTime;
    FILETIME ftLastWriteTime;
    DWORD    nFileSizeHigh;
    DWORD    nFileSizeLow;
    DWORD    dwOID;
    WCHAR    cFileName[MAX_PATH];
} CE_FIND_DATA;

The CeFindFirstFile’s first parameter is file pattern and second parameter is a pointer to CE_FIND_DATA structure which receives the information about the file. The function returns a find handle. The CeFindNextFile’s first parameter is the handle returned by the CeFindFirstFile and second parameter is a pointer to the CE_FIND_DATA structure. The function returns TRUE is a file is found otherwise FALSE.

The sample application presented here is a regular MFC application which lists all the folders in left pane and files in right pane. The application is created using Visual Studio 2008.

{ 0 comments }

Using Remote API 2 (RAPI2) – Part 2

by Krishnaraj Varma on December 14, 2008

Download the source code

In the part 1 of Using RAPI series, I explained how to enumerate the connected device and get the details. This part of the series explains how to enumerate the database on the device.

When we enumerate the device using IRAPIDesktop::EnumDevices and IRAPIEnumDevices::Next we get a pointer to the IRAPIDevice that represents a particular device. The IRAPIDevice has a method CreateSession which is used to create a session. The syntax of CreateSession is:

HRESULT CreateSession(IRAPISession** ppISession);

This function create an IRAPISession which can be used to perform operations on the connected device. Once the session is created, you should call the CeRapiInit method of the IRAPISession interface. This will initialize the communication to the connected device. It is very important to call this method, otherwise all other methods will fail.

To enumerate all the mounted databases on the device, we can use the methods CeFindFirstDatabaseEx and CeFindNextDatabaseEx of the IRAPISession interface. The CeFindFirstDatabaseEx returns a handle to the enumeration. The CeFindNextDatabaseEx method returns a CEOID which is an identifier of the database. To get the information about the database we can call CeOidGetInfoEx method of the IRAPISession. This will return the information such as name, number of records, database type, etc… CeFindNextDatabaseEx function returns 0 when it is finished with the enumeration.

The sample application presented here lists all databases that are on the device memory and display the name and number of records. The application is created in Visual Studio 2008 using MFC. In the next part I will try to explain how to enumerate file system.

{ 0 comments }

Using Remote API 2 (RAPI2) – Part 1

by Krishnaraj Varma on November 30, 2008

Download the source code

The RAPI2 library is used by the desktop applications to communicate to the connected Windows CE based devices. The desktop applications can perform actions such as create, edit or delete the file system, database or registry.

This article describes how to enumerate the connected devices and get information such as name, platform, etc… Next part of the series will describe how to manipulate the file system and database.

RAPI2 uses the ActiveSync application to communicate to the connected device. Users should install the ActiveSync in order to work with the RAPI2 library.

IRAPIDesktop
IRAPIDevice
IRAPIEnumDevices
IRAPISession
IRAPISink

IRAPIDesktop serves as the connection point container of all the devices. This interface is used to enumerate the connected devices. This interface has following methods:

HRESULT Advise(IRAPISink* pISink,DWORD* pdwContext);
HRESULT EnumDevices(IRAPIEnumDevices** ppIEnum);
HRESULT FindDevices(RAPIDEVICEID *pDeviceID,RAPI_GETDEVICEOPCODE opFlags,IRAPIDevice** ppIDevice);
HRESULT UnAdvise(DWORD dwContext);

The Advice method is used to register the IRAPISink interface to receive the device notifications. The pISink parameter is a pointer to an interface that implements the IRAPISink. The IRAPISink has two methods:

HRESULT OnDeviceConnected(IRAPIDevice* pIDevice);
HRESULT OnDeviceDisconnected(IRAPIDevice* pIDevice);

The OnDeviceConnected will be called when a device is connected and OnDeviceDisconnected will be called when a device is disconnected. Both methods has one argument. This is a pointer to the IRAPIDevice interface which represents the device connected or disconnected.

The EnumDevices method is used to enumerate connected device. This accepts one argument which is pointer to pointer to IRAPIEnumDevices interface. We can use this IRAPIEnumDevices interface to start enumerating the devices.

The FindDevices is used to find a particular device. The function accepts a Device ID and a RAPI_GETDEVICEOPCODE enumeration which will always be RAPI_GETDEVICE_NONBLOCKING. The third parameter is an out parameter which will be filled with IRAPIDevice interface.

The UnAdvise is used to cancel the already registered device notification.

The sample is a simple application that lists all the devices connected to the system. The application registers for the device notification and enumerate already connected devices. When a device is connected or disconnected the application add or delete the device from the connected device list.

In the next part, I will try to explain how to manipulate the file system and databases of the connected device.

{ 0 comments }

Using Radio Interface Layer to hangup unwanted calls

by Krishnaraj Varma on November 23, 2008

Download the source code

Radio Interface Layer (RIL) is an interface between the radio hardware and the CellCore system. This is an abstraction layer which enables to create single driver modal for different radio hardware. For a more detailed information about RIL refer to my article Using Radio Interface Layer (RIL) to retrieve Cell Tower Information on Windows Mobile

When a call is coming, the RIL will call our NotifyCallback functon. The first call will be with RIL_NOTIFY_RING notification code. The it will be called with RIL_NOTIFY_CALLERID notification code. At this point the the lpData member will contain the pointer to the structure RILREMOTEPARTYINFO. The raAddress member contains the caller address (number).

The RIL function RIL_Hangup can be used to hangup a call. The behavior of this function is defined by the RIL driver component. The function hangups a data call if one is active or a voice call in one is present. If both are active at the time of calling, it will hangup the voice call.

The sample application presented here is a single document interface document using MFC. Upon receiving the RIL_NOTIFY_CALLERID, the application searches a database to see whether the number is present or not. If the number is present in the database it will hangup the call. Using the main user interface you can insert, edit or delete the numbers in the database.

To compile this sample you should install Windows CE. An evaluation copy can be downloaded from the Microsoft Windows CE website.

{ 0 comments }

Writing Control Panel application for Windows Mobile

by Krishnaraj Varma on November 16, 2008

Download the source code

Control Panel application is normal DLL that exports one function CPlApplet. The system will load all control panel application that are in the Windows folder. The application should have the extension .CPL. The control panel application can be accessed from the Settings.

The syntax for the function CPlApplet is :

LONG APIENTRY CPlApplet(HWND hwndCPl,UINT uMessage,LPARAM lParam1,LPARAM lParam2);

This function will be called by the Settings application. The hwndCPL member will be main window of the controlling application. This can be used as a parent window. The uMessage parameter is the message that is passed to the application. The parameters lParam1 and lParam2 depends on the message parameter.

Below are the possible messages and their descriptions:

CPL_INIT This message is the first message that will be send to the application. The application can initialize any resource for future use. The application should return TRUE if the initialization is successful otherwise FALSE.
CPL_GETCOUNT This is the second message passed to the application. Application should return the number if control panel application supported. A control panel DLL can support more that one application.
CPL_NEWINQUIRE This will be the third message passed to the application. The lParam1 will be the application number and the lParam2 will be a pointer to NEWCPLINFO structure. The application should fill the NEWCPLINFO structure with the information about the application such as name, description, icon, etc… The application should return 0 if successful otherwise a nonzero value.
CPL_STOP This message is passed to the application whenever the system is about the close the application. The application can perform any cleanup operation. A value of zero indicates success and nonzero value indicates failure.
CPL_EXIT This message is passed to the application when the system is about to free the control panel DLL. A value of zero indicates success and nonzero value indicates failure.

The sample provided here is a simple control panel application that will just display the memory usage of the system using a message box. A real control panel application may create a dialog and allow the user to set/change some of the system properties.

{ 0 comments }

Capture Still Image using DirectShow

by Krishnaraj Varma on November 16, 2008

Download the source code

I am working on creating an extension to the Windows Mobile HTTP server using ISAPI. I need to automatically capture still image without user action using DirectShow. I created a DLL using the Windows Mobile SDK sample CameraCapture. I think it is better to share this with you.

{ 1 comment }

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_MACHINECommSecurityLASSDLAP. 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_MACHINECommSecurityLASSDLAP) 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_MACHINECommSecurityLASSDLAPlap_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_MACHINECommSecurityLASSDLAP”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.

{ 2 comments }

Programming HTTPD in Windows Mobile

by Krishnaraj Varma on November 1, 2008

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:WINCE500PUBLICSERVERSSDKSAMPLESHTTP 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_MACHINECommHTTPD. 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_MACHINECommHTTPD.

{ Comments on this entry are closed }

Writing Service Applications in Windows CE

by Krishnaraj Varma on October 24, 2008

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_MACHINEServices. 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 }