This article is just a small effort to save my SmartPhone :). The Mobile Tracker application is designed not only to keep track of your device, but for the end developer to learn about TAPI, Phone/SMS API, Registry reading and writing, P/Invoke, IMSI and IMEI etc...
Points of Interest
- The Registry
The first option is to use the Registry to launch processes during the boot process of the device. The Registry key for launching applications is HKEY_LOCAL_MACHINE\Init, but the main drawback is a dependency chain within the boot process. Processes are started and need to signal back to the OS that the process has launched (using the
SignalStarted API) so that other dependent processes can also start. Here, I have launched this as the last process.
For example, you have two applications to launch at startup, and the second one is dependent on the first one (all are dependent on the Windows Shell):
Launch50 : explorer.exe
Depend50: 32 00
Launch90 : appli1.exe
Depend90: 32 00 (Shell dependency)
Launch100 : appli2.exe
Depend100: 32 00 5A 00 (Shell dependency and application 1 dependency)
In application 1, when you want, the second application is automatically launched. You just have to call
SignalStarted with its sequence identifier character string (converted to
DWORD) on the command line of the
WinMain entry point. Then, application 2 is launched. If another application depends on this one, you call
SignalStared again. If
SignalStarted is not called in application 1, application 2 that is dependent on its launch will never run.
The LaunchXX number is used to specify the order things are started in, but you will need to use the Depend values to specify applications that the system must be running before the LaunchXX applications run. For example: Depend90= 32 00 3C 00 means it depends on Launch50 (32 in hex) and Launch60 (3C in hex).
- Persistent Registry
The RAM-based Registry stores its data in the object store, which resides in the Random Access Memory (RAM). The data persists as long as power is maintained in the RAM (even when the device is off), but the data is lost if RAM is not powered. Providing power to the Registry at all times is not always desirable. Therefore, the RAM-based Registry contains some mechanisms for persisting data by writing to other storage media. When the
RegFlushKey API is called, the OS makes a series of calls to
WriteRegistryToOEM to pass the whole Registry to the OEM, which stores the data on a persistent media. Then, when the system boots, the OS makes another series of calls to
ReadRegistryFromOEM to receive the data from wherever the OEM stored the data.
To address the performance problems and the implementation difficulties of these mechanisms, the Windows CE .NET 4.0 release includes a new type of Registry that is named the hive-based Registry. The hive-based Registry maintains all of its data in files that can be stored on any file system and that can be stored on any media. Therefore, there is no extra work that you must do to persist data on the hive-based Registry. Because Windows CE .NET provides a RAM-based Registry as an optional component, the persistence mechanisms that are described in this article are still supported on the RAM-based Registry. However, the hive-based Registry provides a persistence mechanism that is more efficient and that requires no code development by the OEM.
- In order to retrieve IMSI and IMEI, we have to deal with the Telephony API and P/Invoke.
Sample code is attached, check it out for more details.
- To launch the application through the Registry requires the path of the Windows folder, so I have created a shortcut file for Mobiletracker.exe (Mobiletracker.lnk) which I am copy to the Windows folder during installation.
Using the code
If you look in to the Registry entry HKEY_LOCAL_MACHINE\Init, you will see the various values for depend and launch, and also a key BootVars. Here, I have created one more key, Userinfo, and in that key, the subkey "Ownerinfo" is created to store the reference mobile number. IMEI, IMSI numbers in encoded format are stored for future references. The IMSI number is of the SIM from which you are going to run the application. We store values in a multi-string format which is an array of null terminated strings separated by two null characters. Below is the code snippet:
string DeviceInfo = struct_ui.Mobile_IMEI + "\0\0" + struct_ui.Mobile_IMSI +
"\0\0" + struct_ui.RefMobileno1 + "\0\0" + struct_ui.RefMobileno2 + "\0\0";
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
Byte val = encoding.GetBytes(DeviceInfo);
UIntPtr handletonewkey = UIntPtr.Zero;
int retkeyval = RegCreateKeyEx((UIntPtr)RegRoot.HKEY_LOCAL_MACHINE,
"init\\UserInfo", 0, String.Empty, 0, 0, 0,
ref handle, ref handletonewkey);
if (retkeyval != 0)
MessageBox.Show("Cant Create UserInfo Key");
int ret1 = RegOpenKeyEx((UIntPtr)RegRoot.HKEY_LOCAL_MACHINE, "init\\UserInfo",
0, KeyAccess.SetValue, ref handle);
int ret2 = RegSetValueEx(handle, "OwnerInfo", 0,
(uint)RegistryValueKind.MultiString, val, (uint)val.Length);
Now, in the code snippet below, we register the application in the Registry so that on reboot, it could launch and run a similar EXE. In the launch value, you must give the path to the EXE. Here, I gave the path of the link file which internally launches the same.
int ret3 = RegOpenKeyEx((UIntPtr)RegRoot.HKEY_LOCAL_MACHINE,
"init", 0, KeyAccess.SetValue, ref handle);
byte userval = new byte;
userval = 50;
userval = 0;
int ret4 = RegSetValueEx(handle, "Depend101", 0,
IntPtr iptr = Marshal.StringToBSTR("MobileTracker.lnk");
string unicodestring = Marshal.PtrToStringUni(iptr);
Encoding en = Encoding.Unicode;
byte barray = en.GetBytes(unicodestring);
int ret5 = RegSetValueEx(handle, "Launch101", 0,
(uint)RegistryValueKind.String, barray, (uint)barray.Length);
Here, you need to call
RegFlushKey to store the Registry permanently.
int ret6 = RegFlushKey(handle);
I'm sure there are a whole load of improvements that could be made, but here is a list of some of the major ones:
- User should able to launch the same application after registration.
- Ability to deactivate the application.