Camera Live Preview using DirectShow

Download source code

I was trying to create an application that Geotag the picture taken from camera. This application uses DirectShow to show the live camera preview. I think it is better to share the piece of code that show the live preview with you. I not able to successfully geotag the image taken from camera, I will post the code here once I complete the geotaging application.

Programatically forwarding calls using TAPI

Download the source code

Recently one of my friend asked me how to forward calls using the USSD commands. This link describes how to forward calls using USSD codes. I tried a lot using my previous article code but ended up with no success. The USSD command are sending successfully but always the result is “UNKNOWN APPLICATION”. Then I decided to work on a sample using the TAPI API lineForward.

The lineForward API is used to programatically forward calls. The syntax of the API is defined as:

LONG WINAPI lineForward(HLINE hLine,DWORD bAllAddresses,DWORD dwAddressID,LPLINEFORWARDLIST const lpForwardList,DWORD dwNumRingsNoAnswer,LPHCALL lphConsultCall,LPLINECALLPARAMS const lpCallParams);

The first parameter is the handle to the line (Cellular Line), second a boolean value indicating all originating addresses of the line or a single address of the line. Third is the address id of the line. Fourth is a pointer to variably sized structure that describes the forwarding instructions. Fifth is number of rings that has to be considered as no answer. Sixth is a pointer to handle to a call which will be filled with handle to a consultation call (only used in some telephony environments). Seventh is pointer to LINECALLPARAMS, if NULL specified default call parameter will be used.

Following steps are needed to forward calls:

1. Initialize TAPI
2. Open the Cellular Line
3. Allocate and initialize the LINEFORWARDLIST variable sized structure
4. Call lineForward API

Allocating and initializing the LINEFORWARDLIST structure is little bit complex. This is a pointer to a variable sized structure and is defined as:

typedef struct lineforwardlist_tag {
DWORD dwTotalSize;
DWORD dwNumEntries;
LINEFORWARD ForwardList[1];
} LINEFORWARDLIST, FAR* LPLINEFORWARDLIST;

The dwTotalSize member is the total size of the structure, dwNumEntries member is the number of ForwardList array. The LINEFORWARD structure is defined as:

typedef struct lineforward_tag {
DWORD dwForwardMode;
DWORD dwCallerAddressSize;
DWORD dwCallerAddressOffset;
DWORD dwDestCountryCode;
DWORD dwDestAddressSize;
DWORD dwDestAddressOffset;
DWORD dwCallerAddressType;
DWORD dwDestAddressType;
} LINEFORWARD, *LPLINEFORWARD;

The dwDestAddressOffset specifies the offset of the destination address from the starting of the structure. The dwDestAddressSize specifies the size of the destination address in bytes. Same in the case of dwCallerAddressOffset and dwCallerAddressSize and specifies the caller address and size. To allocate memory for the forward list, first we have to find out the total number of bytes needed. This will be:

sizeof(LINEFORWARDLIST) + (sizeof(LINEFORWARD) * number of entries - 1) + size of all phone numbers

After allocating the memory we need to initialize the members of the structure and append the phone numbers. The API lineForward returns a positive integer if successful otherwise a negative value indicating the error. To get the current status of the call forward, lineGetAddressStatus API is used. This returns the result in a variable sized array. The sample application presented here retrieves the call forward status and display it is dialog. Users can change the settings and upon exit the application sets new call forward information. Hope this gives you an introduction on how to programatically forward calls.

Sending USSD message using TAPI

Download the source code

Unstructured Supplementary Service Data (USSD) is GSM technology used to send short message from mobile device to GSM network. It uses the signaling channel of GSM connection and can have up to 182 bytes in length. The messages received on the device are not saved. It has different set of applications and most common use of USSD message is balance enquiry. For example “*123#” used for balance enquiry in India. For a more detailed explanation of USSD messages refer to the Wikipedia.

The TAPI API lineSendUSSD is used to send the USSD command. The syntax is defined as:

LONG WINAPI lineSendUSSD(HLINE hLine,const BYTE * const lpbUSSD,DWORD dwUSSDSize,DWORD dwFlags);

The hLine parameter is the handle to the line and lpbUSSD is a pointer to USSD command. The dwUSSDSize parameter is the length of th USSD command and dwFlags flags to the USSD command which will be 0 in most cases.

The function returns a positive request identifier and is completed asynchronously. A negative integer will returned if an error occurs. The sample application presented here uses a database to store USSD commands. The application lists all the commands in the database in a list control. You can add, edit or delete the entries. Upon double clicking an entry the application sends corresponding USSD command using the Cellular Line.

Retrieving list of known operators using Radio Interface Layer (RIL)

Download the source code

The RIL API RIL_GetAllOperatorsList retrieves all built-in known operators list. The API returns the operators list in an array of RILOPERATORNAMES structures. The structure is defined as:

typedef struct {
DWORD cbSize;
DWORD dwParams;
char szLongName[MAXLENGTH_OPERATOR_LONG];
char szShortName[MAXLENGTH_OPERATOR_SHORT];
char szNumName[MAXLENGTH_OPERATOR_NUMERIC];
char szCountryCode[MAXLENGTH_OPERATOR_COUNTRY_CODE];
} RILOPERATORNAMES;

The szLongName member contains the long name of the operator and szShortName contains the short name of the operator. The szNumName represents the numeric representation of the operator and the szCountryCode member represents the country/region code of the operator.

This function retrieves all known operators, to retrieve all available operators list use the API RIL_GetOperatorList. This function returns the list in an array of RILOPERATORINFO structures. The structure is defined as:

typedef struct {
DWORD cbSize;
DWORD dwParams;
DWORD dwIndex;
DWORD dwStatus;
RILOPERATORNAMES ronNames;
} RILOPERATORINFO;

The ronNames contains the operator details.

Programatically Controlling Radio State using TAPI

Download the source code

The TAPI function lineSetEquipmentState can be used to programmatically control the radio state. To change the radio state first initialize the TAPI and find the cellular line (line name is CELLTSP_LINENAME_STRING), then use the lineSetEquipmentState with appropriate flag. The syntax of the lineSetEquipmentState API is:

LONG WINAPI lineSetEquipmentState(HLINE hLine,DWORD dwState);

The hLine parameter is the cellular line handle. Second parameter dwState is the state of the radio and can be one of the following values.

LINEEQUIPSTATE_MINIMUM
LINEEQUIPSTATE_RXONLY
LINEEQUIPSTATE_TXONLY
LINEEQUIPSTATE_NOTXRX
LINEEQUIPSTATE_FULL

Most of the devices accepts only LINEEQUIPSTATE_MINIMUM and LINEEQUIPSTATE_FULL. The LINEEQUIPSTATE_MINIMUM will turn the radio off and LINEEQUIPSTATE_FULL will turn the radio on.

The sample application provided here displays the radio state and a button. Clicking the button will toggle the radio state.

Using Windows Mobile Connection Manager APIs

Download the source code

Connection Manager is a Windows Mobile component that manages and monitors different types of network connections such as PPP, RAS, GPRS, etc… Connection Manager provides a set of native code APIs which can be used to establish voice and data connections. When an application requests a connection, the connection manager determines which is the optimal connection type and establishes the connection. The Connection Manager also tracks which connections are active and disconnect connections which are idle for a given period of time.

The Connection Manager supports two types of destination networks, Internet Network and Work Network. Internet Network is used to connect to the wider internet and Work Network is used to connect to the corporate network directly or through VPN connection. Before using the Connection Manager you have to configure these two network settings.

Following are some of the main parts of Connection Manager:

Connection Manager Application (ConnMgr.exe): When an application request a connection, the Connection Manager application determines the path to the target network. Once the Connection Manager found all the paths it requests the Connection Manager to determine the best connection to the target network.
Connection Planner (ConnPlann.dll): Connection Planner is responsible for determine the best path to the target network. Connection Planner uses Connection Manager Configuration Service Providers to find out the cost, bandwidth, etc… before deciding the best connection path. Connection Planner is also responsible for determining the priority of the connection. When a higher priority connection is made and if there is a lower priority connection is active, then Connection Planner disconnects the lower priority connection.
Connection Service Providers: These are dynamic link libraries (DLLs) that provide the connection information such as route and cost to the Connection Manager application and store this information. There are different connection service providers such as CSPNet, CSPProxy, CSPRas, CSPVoice, etc…

Connection Manager provides a set of native code APIs for the applications to request and manage network connection. An application can use these APIs to request a connection, register for status notification, etc… Following are some of the important Connection Manager APIs:

ConnMgrConnectionStatus This function retrieves the status of the current connection.
ConnMgrEnumDestinations This function enumerates available networks.
ConnMgrEstablishConnection This function creates a connection request.
ConnMgrEstablishConnectionSync This function creates a connection request.
ConnMgrMapConRef This function maps a connection reference to its corresponding GUID.
ConnMgrMapURL This function maps a URL to the GUID of a destination network.
ConnMgrRegisterScheduledConnection This function registers a scheduled connection.
ConnMgrReleaseConnection This function deletes a specified connection request, potentially dropping the physical connection.
ConnMgrUnregisterScheduledConnection This function unregisters a scheduled connection.
ConnMgrRegisterForStatusNotification Registers a window handle for connection status notifications.

For a complete list of Connection Manager APIs refer to the Connection Manager Function documentation

To enumerate the available network details ConnMgrEnumDestinations API is used. The syntax is defined as:

HRESULT WINAPI ConnMgrEnumDestinations(int Index,CONNMGR_DESTINATION_INFO *pDestInfo);

To enumerate all the available networks, an application calls this API with index 0 and increment until the API returns an error.

To establish a connection we can use the API ConnMgrEstablishConnection or ConnMgrEstablishConnectionSync. The syntax of the functions are:

HRESULT WINAPI ConnMgrEstablishConnection(CONNMGR_CONNECTIONINFO *pConnInfo, HANDLE *phConnection);
HRESULT WINAPI ConnMgrEstablishConnectionSync(CONNMGR_CONNECTIONINFO *pConnInfo, HANDLE *phConnection, DWORD dwTimeout, DWORD *pdwStatus);

The pConnInfo parameter is a pointer to the structure CONNMGR_CONNECTIONINFO and provides the information about the request. The phConnection parameter receives the handle of the connection when the connection is established. The dwTimeout specifies the timeout in millisecond for the connection establishment. The pdwStatus parameter specifies the status of the connection upon exit.

ConnMgrEstablishConnection is asynchronous in nature. It will request a connection and return immediately. The Connection Manager will post a message to the window handle specified by the hWnd member of the CONNMGR_CONNECTIONINFO structure . The uMsg member specifies what message should be used to send the status change notification. The wParam of the message will be the status of the connection. There are different status values defined in connmgr.h header file which describes the current status of the connection.

ConnMgrEstablishConnectionSync is synchronous in nature. It will request a connection and wait for specified time and return. Upon exit the pdwStatus will have the connection status.

The sample application provided here lists all available networks in a combo box. When connection is requested the selected network is used to establish the connection. The status of the connection will be displayed in a static text box. Hope this gives you an introduction to the Connection Manager APIs.

Enumerating Fonts in Windows Mobile

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.

Using Remote API 2 (RAPI2) – Part 3

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.

Using Remote API 2 (RAPI2) – Part 2

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.

Using Remote API 2 (RAPI2) – Part 1

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.