Related
I have a background service DLL running on Windows Mobile 2003 in Services.exe.
I now wish to port it to run in Devices.exe. I have so far been unable to get it to run. Instead when I run the ActivateDevice or ActivateDeviceEx it returns with error 1,2 or 120.
What is required by my DLL to be compatable with Devices.exe?
I have added what I assume are the correct registry settings under HKLM\\Devices\\Name so i can only assume it is something wrong with the DLL itself.
If anyone can assist me with this problem it would be greatly appreciated.
Cheers Gerard
Do I need to use the Developer Platform to create the driver or is Embedded fine?
You can use eVC to create drivers.
To make your driver recognized by OS you should add registry keys:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\_name_]
"Prefix"="BLA" - 3 CAPS letters, it is your driver prefix
"Index"=dword:00000001
"Dll"="yourdriver.Dll"
And your driver should export functions:
BLA_Close
BLA_Deinit
BLA_IOControl
BLA_Init
BLA_Open
BLA_PowerDown
BLA_PowerUp
BLA_Read
BLA_Seek
BLA_Write
Later you can use CreateFile(L"BLA1:",...) to communicate with your driver. Read MSDN for more.
I have those entries in the registry and my DLL exports those functions.
However, I can not get the DLL to start through ActivateDeviceEx or ActivateDevice. If I reset the device the device freezes and requires a hard reset.
My DLL works fine in Services.exe but must need some changes to operate in Device.exe. The problem being that I can't find any examples where a Device Driver was written in C++ (all .c) and also can't find any examples of a Service being converted to a Device driver.
Any suggestions greatly appreciated
You don't need to call ActivateDexice[Ex] if you have manually added these keys to registry. The reason that your device hangs is in your DLL's entry point or in one of the exported functions. Probably BLA_Init or one of the power functions. You should add diagnostics code that outputs a trace log to SD-card or built-in storage so that you can read this file after hard reset. Or the reason may be that your driver is loaded before the one of the needed drivers, for example SD-card. In this case you should play with the "order" key.
I've wrote several drivers in C++. But none of them used C++ exceptions, I don't know how devices.exe would behave if exception is thrown. And you should remember not to allocate huge arrays/variables on stack.
I've found a small tutorial on MSDN - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnembedded/html/spotwincerambl.asp
Posted: Wed Mar 09, 2005 18:19
--------------------------------------------------------------------------------
So if I already have the registry entries in do I start the DLL with CreateFile or something similar? I assumed that the DLL was hanging on device startup due to attempting to include an unloaded module but this still occurs when setting Order to 99.
At the moment for testing purposes I am just getting all my exported functions to write to a log file... however none are ever entered. What is the DLL's entry point? Init? PowerUp? An additional method? Have you an example that I could possibly have a look at?
Thanks for your help.
Gerard
The first entry point is DllMain. Then init function is called. Then open when your device is opened. If you have global classes with constructors - constructors are called before DllMain (I have not tested that), one of them may be the reason of crash.
The sample is in the link I gave in the prev. post. or here is a sample driver that is a wrapper around Serial_BTUR.dll
Code:
// Serial.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "Serial.h"
#include <psapi.h>
#include <Mmsystem.h>
struct HCI_
{
char *Text;
int Code;
} Cmds[]=
{
"HCI_NOP",0x0000,
"HCI_Inquiry",0x0401,
"HCI_Inquiry_Cancel",0x0402,
"HCI_Periodic_Inquiry_Mode",0x0403,
"HCI_Exit_Periodic_Inquiry_Mode",0x0404,
"HCI_Create_Connection",0x0405,
"HCI_Disconnect",0x0406,
"HCI_Add_SCO_Connection",0x0407,
"HCI_Accept_Connection_Request",0x0409,
"HCI_Reject_Connection_Request",0x040a,
"HCI_Link_Key_Request_Reply",0x040b,
"HCI_Link_Key_Request_Negative_Reply",0x040c,
"HCI_PIN_Code_Request_Reply",0x040d,
"HCI_PIN_Code_Request_Negative_Reply",0x040e,
"HCI_Change_Connection_Packet_Type",0x040f,
"HCI_Authentication_Requested",0x0411,
"HCI_Set_Connection_Encryption",0x0413,
"HCI_Change_Connection_Link_Key",0x0415,
"HCI_Master_Link_Key",0x0417,
"HCI_Remote_Name_Request",0x0419,
"HCI_Read_Remote_Supported_Features",0x041b,
"HCI_Read_Remote_Version_Information",0x041d,
"HCI_Read_Clock_Offset",0x041f,
"HCI_Hold_Mode",0x0801,
"HCI_Sniff_Mode",0x0803,
"HCI_Exit_Sniff_Mode",0x0804,
"HCI_Park_Mode",0x0805,
"HCI_Exit_Park_Mode",0x0806,
"HCI_QoS_Setup",0x0807,
"HCI_Role_Discovery",0x0809,
"HCI_Switch_Role",0x080b,
"HCI_Read_Link_Policy_Settings",0x080c,
"HCI_Write_Link_Policy_Settings",0x080d,
"HCI_Set_Event_Mask",0x0c01,
"HCI_Reset",0x0c03,
"HCI_Set_Event_Filter",0x0c05,
"HCI_Flush",0x0c08,
"HCI_Read_PIN_Type",0x0c09,
"HCI_Write_PIN_Type",0x0c0a,
"HCI_Create_New_Unit_Key",0x0c0b,
"HCI_Read_Stored_Link_Key",0x0c0d,
"HCI_Write_Stored_Link_Key",0x0c11,
"HCI_Delete_Stored_Link_Key",0x0c12,
"HCI_Change_Local_Name",0x0c13,
"HCI_Read_Local_Name",0x0c14,
"HCI_Read_Connection_Accept_Timeout",0x0c15,
"HCI_Write_Connection_Accept_Timeout",0x0c16,
"HCI_Read_Page_Timeout",0x0c17,
"HCI_Write_Page_Timeout",0x0c18,
"HCI_Read_Scan_Enable",0x0c19,
"HCI_Write_Scan_Enable",0x0c1a,
"HCI_Read_PageScan_Activity",0x0c1b,
"HCI_Write_PageScan_Activity",0x0c1c,
"HCI_Read_InquiryScan_Activity",0x0c1d,
"HCI_Write_InquiryScan_Activity",0x0c1e,
"HCI_Read_Authentication_Enable",0x0c1f,
"HCI_Write_Authentication_Enable",0x0c20,
"HCI_Read_Encryption_Mode",0x0c21,
"HCI_Write_Encryption_Mode",0x0c22,
"HCI_Read_Class_Of_Device",0x0c23,
"HCI_Write_Class_Of_Device",0x0c24,
"HCI_Read_Voice_Setting",0x0c25,
"HCI_Write_Voice_Setting",0x0c26,
"HCI_Read_Automatic_Flush_Timeout",0x0c27,
"HCI_Write_Automatic_Flush_Timeout",0x0c28,
"HCI_Read_Num_Broadcast_Retransmissions",0x0c29,
"HCI_Write_Num_Broadcast_Retransmissions",0x0c2a,
"HCI_Read_Hold_Mode_Activity",0x0c2b,
"HCI_Write_Hold_Mode_Activity",0x0c2c,
"HCI_Read_Transmit_Power_Level",0x0c2d,
"HCI_Read_SCO_Flow_Control_Enable",0x0c2e,
"HCI_Write_SCO_Flow_Control_Enable",0x0c2f,
"HCI_Set_Host_Controller_To_Host_Flow_Control",0x0c31,
"HCI_Host_Buffer_Size",0x0c33,
"HCI_Host_Number_Of_Completed_Packets",0x0c35,
"HCI_Read_Link_Supervision_Timeout",0x0c36,
"HCI_Write_Link_Supervision_Timeout",0x0c37,
"HCI_Read_Number_Of_Supported_IAC",0x0c38,
"HCI_Read_Current_IAC_LAP",0x0c39,
"HCI_Write_Current_IAC_LAP",0x0c3a,
"HCI_Read_Page_Scan_Period_Mode",0x0c3b,
"HCI_Write_Page_Scan_Period_Mode",0x0c3c,
"HCI_Read_Page_Scan_Mode",0x0c3d,
"HCI_Write_Page_Scan_Mode",0x0c3e,
"HCI_Read_Local_Version_Information",0x1001,
"HCI_Read_Local_Supported_Features",0x1003,
"HCI_Read_Buffer_Size",0x1005,
"HCI_Read_Country_Code",0x1007,
"HCI_Read_BD_ADDR",0x1009,
"HCI_Read_Failed_Contact_Counter",0x1401,
"HCI_Reset_Failed_Contact_Counter",0x1402,
"HCI_Get_Link_Quality",0x1403,
"HCI_Read_RSSI",0x1405,
"HCI_Read_Loopback_Mode",0x1801,
"HCI_Write_Loopback_Mode",0x1802,
"HCI_Enable_Device_Under_Test_Mode",0x1803,
0,0
},Events[]=
{
"HCI_Inquiry_Complete_Event",0x01,
"HCI_Inquiry_Result_Event",0x02,
"HCI_Connection_Complete_Event",0x03,
"HCI_Connection_Request_Event",0x04,
"HCI_Disconnection_Complete_Event",0x05,
"HCI_Authentication_Complete_Event",0x06,
"HCI_Remote_Name_Request_Complete_Event",0x07,
"HCI_Encryption_Change_Event",0x08,
"HCI_Change_Connection_Link_Key_Complete_Event",0x09,
"HCI_Master_Link_Key_Complete_Event",0x0a,
"HCI_Read_Remote_Supported_Features_Complete_Event",0x0b,
"HCI_Read_Remote_Version_Information_Complete_Event",0x0c,
"HCI_QoS_Setup_Complete_Event",0x0d,
"HCI_Command_Complete_Event",0x0e,
"HCI_Command_Status_Event",0x0f,
"HCI_Hardware_Error_Event",0x10,
"HCI_Flush_Occured_Event",0x11,
"HCI_Role_Change_Event",0x12,
"HCI_Number_Of_Completed_Packets_Event",0x13,
"HCI_Mode_Change_Event",0x14,
"HCI_Return_Link_Keys_Event",0x15,
"HCI_PIN_Code_Request_Event",0x16,
"HCI_Link_Key_Request_Event",0x17,
"HCI_Link_Key_Notification_Event",0x18,
"HCI_Loopback_Command_Event",0x19,
"HCI_Data_Buffer_Overflow_Event",0x1a,
"HCI_Max_Slots_Change_Event",0x1b,
"HCI_Read_Clock_Offset_Complete_Event",0x1c,
"HCI_Connection_Packet_Type_Changed_Event",0x1d,
"HCI_QoS_Violation_Event",0x1e,
"HCI_Page_Scan_Mode_Change_Event",0x1f,
"HCI_Page_Scan_Repetition_Mode_Change_Event",0x20,
0,0
};
char *FindEvent(int id)
{
for(int i=0; Events[i].Text;i++)
{
if(Events[i].Code==id)
return Events[i].Text;
}
return "HCI_???";
}
char *FindMessage(int id)
{
for(int i=0; Cmds[i].Text;i++)
{
if(Cmds[i].Code==id)
return Cmds[i].Text;
}
return "HCI_???";
}
typedef BOOL t_COM_Deinit(DWORD dwOpenData);
typedef BOOL t_COM_IOControl(
DWORD dwOpenData,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut
);
typedef HANDLE t_COM_Init(
ULONG Identifier
);
typedef HANDLE t_COM_Open(
HANDLE pContext,
DWORD AccessCode,
DWORD ShareMode
);
typedef BOOL t_COM_PowerDown(
HANDLE pContext
);
typedef BOOL t_COM_PowerUp(
HANDLE pContext
);
typedef ULONG t_COM_Read(
HANDLE pContext,
PUCHAR pTargetBuffer,
ULONG BufferLength
);
typedef ULONG t_COM_Write(
HANDLE COM_Write,
PUCHAR pSourceBytes,
ULONG NumberOfBytes
);
typedef BOOL t_COM_Close(
DWORD pContext
);
t_COM_Deinit *_COM_Deinit=0;
t_COM_IOControl *_COM_IOControl=0;
t_COM_Init *_COM_Init=0;
t_COM_Open *_COM_Open=0;
t_COM_PowerDown *_COM_PowerDown=0;
t_COM_PowerUp *_COM_PowerUp=0;
t_COM_Read *_COM_Read=0;
t_COM_Write *_COM_Write=0;
t_COM_Close *_COM_Close=0;
HANDLE hEvent=0;
char* Dump(const unsigned char *Buff, int count)
{
static char Out[65536];
char* p=Out;
if(count==0)
{
p+=sprintf(p,"\n");
return Out;
}
{
bool OnlyASCII=true;
for(int i=0; i<count; i++)
if((Buff[i]&255)<32||Buff[i]==127)
{
if((i==count-1 && Buff[i]==0)||Buff[i]==0x0d||Buff[i]==0x0a||Buff[i]==9)
continue;
OnlyASCII=false;
break;
}
if(OnlyASCII)
{
p+=sprintf(p,"--- Plain text\n");
for(int i=0; i<count; i++)
if(Buff[i]!='\r')
p+=sprintf(p,"%c",Buff[i]);
// if(Buff[count-1]!='\n')
// fprintf(Log,"\n");
p+=sprintf(p,"\n--- End of text\n\n");
return Out;
}
int Pos=0;
char OBuff[3*16+2+1];
char Str[17];
for(i=0; i<(count+15)/16; i++)
{
for(int j=0; j<16; j++,Pos++)
{
if(Pos<count)
{
sprintf(OBuff+3*j+(j>7),"%02X ",Buff[Pos]&255);
if((Buff[Pos]&255)<32||Buff[Pos]==127)
Str[j]='.';
else
Str[j]=Buff[Pos];
} else
{
sprintf(OBuff+3*j+(j>7)," ");
Str[j]=' ';
}
}
Str[16]=0;
OBuff[3*16+1]=0;
p+=sprintf(p,"%08X: %s \"%s\"\n",i*16,OBuff,Str);
}
}
p+=sprintf(p,"\n");
return Out;
}
bool IsLogging(void)
{
return true;
// return WaitForSingleObject(hEvent,0)==WAIT_OBJECT_0;
}
void LogData(PUCHAR Data, int NBytes)
{
if(!IsLogging())
return;
HANDLE h=CreateFile(L"\\logging.txt",GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
0,OPEN_ALWAYS,0,0);
if(h==INVALID_HANDLE_VALUE)
return;
SetFilePointer(h,0,0,FILE_END);
DWORD W;
WriteFile(h,Data,NBytes,&W,0);
CloseHandle(h);
}
void LogStr(char*Str)
{
LogData((PUCHAR)Str, strlen(Str));
LogData((PUCHAR)"\n",1);
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#undef SERIAL_API
#define SERIAL_API extern "C" __declspec(dllexport)
SERIAL_API BOOL COM_Close(
DWORD pContext
)
{
LogStr("COM_Close");
return _COM_Close(pContext);
}
SERIAL_API BOOL COM_Deinit(DWORD pContext)
{
LogStr("COM_Deinit");
return _COM_Deinit(pContext);
}
SERIAL_API BOOL COM_IOControl(
DWORD dwOpenData,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut
)
{
char Buff[1024];
sprintf(Buff,"COM_IOControl: %04X ",dwCode);
LogStr(Buff);
LogStr(Dump(pBufIn,dwLenIn));
return _COM_IOControl(
dwOpenData,
dwCode,
pBufIn,
dwLenIn,
pBufOut,
dwLenOut,
pdwActualOut);
}
SERIAL_API HANDLE COM_Init(
wchar_t* Identifier
)
{
LogStr("COM_Init");
if(hEvent==0)
{
hEvent=CreateEvent(0,TRUE,FALSE,L"seRILal logging event");
HINSTANCE H=LoadLibrary(L"Serial_BTUR.dll");
if(H==0)
{
LogStr("Error loading DLL");
return 0;
}
_COM_Deinit=(t_COM_Deinit*)GetProcAddress(H,L"COM_Deinit");
if(_COM_Deinit==0)
LogStr("COM_Deinit==0");
_COM_IOControl=(t_COM_IOControl*)GetProcAddress(H,L"COM_IOControl");
if(_COM_IOControl==0)
LogStr("COM_IOControl==0");
_COM_Init=(t_COM_Init*)GetProcAddress(H,L"COM_Init");
if(_COM_Init==0)
LogStr("COM_Init==0");
_COM_Open=(t_COM_Open*)GetProcAddress(H,L"COM_Open");
if(_COM_Open==0)
LogStr("COM_Open==0");
_COM_PowerDown=(t_COM_PowerDown*)GetProcAddress(H,L"COM_PowerDown");
if(_COM_PowerDown==0)
LogStr("COM_PowerDown==0");
_COM_PowerUp=(t_COM_PowerUp*)GetProcAddress(H,L"COM_PowerUp");
if(_COM_PowerUp==0)
LogStr("COM_PowerUp==0");
_COM_Read=(t_COM_Read*)GetProcAddress(H,L"COM_Read");
if(_COM_Read==0)
LogStr("COM_Read==0");
_COM_Write=(t_COM_Write*)GetProcAddress(H,L"COM_Write");
if(_COM_Write==0)
LogStr("COM_Write==0");
_COM_Close=(t_COM_Close*)GetProcAddress(H,L"COM_Close");
if(_COM_Close==0)
LogStr("COM_Close==0");
LogStr("DLL loaded");
}
HANDLE H=_COM_Init((DWORD)Identifier);
return H;
}
SERIAL_API HANDLE COM_Open(
HANDLE pContext,
DWORD AccessCode,
DWORD ShareMode
)
{
LogStr("COM_Open");
return _COM_Open(
pContext,
AccessCode,
ShareMode);
}
SERIAL_API BOOL COM_PowerDown(
HANDLE pContext
)
{
LogStr("COM_PowerDown");
return _COM_PowerDown(pContext);
}
SERIAL_API BOOL COM_PowerUp(
HANDLE pContext
)
{
LogStr("COM_PowerUp");
return _COM_PowerUp(pContext);
}
int SCO_Handle=0;
SERIAL_API ULONG COM_Read(
HANDLE pContext,
PUCHAR pTargetBuffer,
ULONG BufferLength
)
{
int L=_COM_Read(
pContext,
pTargetBuffer,
BufferLength);
if(L)
{
LogStr("COM_Read");
if(L>2&&pTargetBuffer[0]==4)
{
char Buff[1024];
int m=pTargetBuffer[1];
sprintf(Buff,"%s - %02X",FindEvent(m),m);
LogStr(Buff);
if(pTargetBuffer[1]==3 && pTargetBuffer[3]==0 && pTargetBuffer[12]==0)
{
LogStr("SCO connection");
SCO_Handle=pTargetBuffer[4]+pTargetBuffer[5]*256;
}
}
LogStr(Dump(pTargetBuffer,L));
}
return L;
}
SERIAL_API ULONG COM_Write(
HANDLE pContext,
PUCHAR pSourceBytes,
int NumberOfBytes
)
{
LogStr("COM_Write");
if(SCO_Handle)
{
LogStr("sending SCO packet");
char Buffer[256];
Buffer[0]=SCO_Handle&255;
Buffer[1]=SCO_Handle/255;
Buffer[2]=240;
for(int i=0; i<240; i++)
Buffer[3+i]=(i&2)?127:0;
_COM_Write(
pContext,
(unsigned char*)"\x03",
1);
_COM_Write(
pContext,
(unsigned char*)Buffer,
240+3);
SCO_Handle=0;
}
if(NumberOfBytes>2)
{
char Buff[1024];
int m=pSourceBytes[1]*256+pSourceBytes[0];
sprintf(Buff,"%s - %04X",FindMessage(m),m);
LogStr(Buff);
}
LogStr(Dump(pSourceBytes,NumberOfBytes));
return _COM_Write(
pContext,
pSourceBytes,
NumberOfBytes);
}
SERIAL_API ULONG COM_Seek()
{
return -1;
}
Thanks for your help. The reason I am porting my Dll from Services.exe to Device.exe is because I need it to run continuosly and when running in Services.exe when the device suspends of course no CPU time. That is, I was hoping to implement the Dll as a driver and catch the PowerDown message and prevent it from happening.
I noticed that in the MSDN example the PowerDown method is void but in yours it returns Bool. To prevent the power down do I convert the method to return a false bool value? Can this functionality be done?
Regards Gerard
GerardRaciti said:
I noticed that in the MSDN example the PowerDown method is void but in yours it returns Bool.
Click to expand...
Click to collapse
Don't always trust MSDN regarding Windows CE. I've taken these prototypes from some of MS own drivers.
You can prevent device from sleeping from your program using this method:
http://msdn.microsoft.com/library/d.../html/ppc_programming_pocket_pc_2002_lfyy.asp
That was the method I used originally to tackle this problem but it consumed too much power leaving the screen in that dimmed state.
I had the understanding that if I implemented my Dll in a device driver the screen could go blank but the device would only go into "sleep" mode where drivers would still receive CPU time as long as they responded to the PowerDown function.
Do you know if this is possible or am I wasting my time?
I don't know. I never worked with power levels. But probably this is possible in driver with functions SetPowerRequirement and DevicePowerNotify. But this would work only if device supports D1 (low on) power mode. Otherwise I think you would not notice any difference with keeping the device always on and shutting down LCD+backlight.
Thanks again for your help.
I have managed to port my service into a device driver but am having trouble handling Power Management issues. It seems as though it is in my Dll attempting to prevent a device suspension which is crashing the device. If I dont attempt to prevent suspend mode or set power requirements the Dll is quite stable. If anyone has any experience with Device driver power management or can point me in the right direction it would be much appreciated.
Regards Gerard
you may try to ask in microsoft newsgroups like microsoft.public.windowsce.app.development or microsoft.public.windowsce.platbuilder or similar
For the program I posted here, I want to handle incoming calls before the default popup appears (to replace the ringtone).
Currently, my tool seems to be quick enough without lineSetAppPriority in most cases, but sadly not in all...
I was using the following code: (currently removed again, because it didn't work and even caused some troubles...)
Initialization:
Code:
if ( lineInitialize( &LineApp, theApp.m_hInstance, LineCallback,
theApp.m_pszAppName, &LineHandleCount ) == 0 )
{
LineHandles = new HLINE[LineHandleCount];
for(DWORD i = 0; i < LineHandleCount; i++)
{
if ( lineNegotiateAPIVersion( LineApp, i, 0x00010000, 0x00020000,
&ver, &extensionID ) == 0 )
{
rc = lineOpen( LineApp, i, &LineHandles[i], ver, 0, (DWORD)this,
LINECALLPRIVILEGE_MONITOR|LINECALLPRIVILEGE_OWNER,
LINEMEDIAMODE_INTERACTIVEVOICE, NULL );
if ( rc < 0 )
LineHandles[i] = NULL;
else
if ( LineHandleSignal == NULL )
LineHandleSignal = LineHandles[i];
}
}
HRESULT res = lineSetAppPriority( theApp.m_pszAppName,
LINEMEDIAMODE_INTERACTIVEVOICE,
NULL,
LINEREQUESTMODE_MAKECALL,
NULL, 1 );
}
Callback:
Code:
VOID FAR PASCAL LineCallback( DWORD hDevice,
DWORD dwMsg,
DWORD dwCallbackInstance,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3
)
{
if ( dwMsg == LINE_CALLSTATE )
{
LINECALLINFO *callInfo = (LINECALLINFO *)calloc(sizeof(LINECALLINFO)
+1024, 1);
callInfo->dwTotalSize = sizeof(LINECALLINFO)+1024;
lineGetCallInfo( (HCALL)hDevice, callInfo );
// different stuff...
HRESULT res;
// Remove from priority list, so lineHandoff will run the default
// call window
res = lineSetAppPriority( theApp.m_pszAppName,
LINEMEDIAMODE_INTERACTIVEVOICE, NULL,
LINEREQUESTMODE_MEDIACALL, NULL, 0 );
// Forward event to next instance (usually Windows' phone app)
lineHandoff( (HCALL)hDevice, NULL, callInfo->dwMediaMode );
// Set to top priority again
res = lineSetAppPriority( theApp.m_pszAppName,
LINEMEDIAMODE_INTERACTIVEVOICE, NULL,
LINEREQUESTMODE_MEDIACALL, NULL, 1 );
}
lineSetAppPriorty returns OK in all cases. But when a call comes in, the
default bubble applears simultaneously with the callback function. I
wanted it to be shown when I do the lineHandoff...
What am I doing wrong?
TIA,
Mirko
I used lineSetAppPriority too, with same result....
I think there is one way.....kill cprog
I am presently writing a RegEdit program to run on my PC and allow editing of the registry on the connected PPC. I have got to the point where I can read the entire registry and I am now implementing function to update the registry i.e. insert new key, delete key, add new Key Values etc...
The problem I have at the moment is trying to add a new value to an existing key. The function I have written so far to do this is as follows, but the call to CeRegSetValueEx(...) returns an error code 5!
Code:
//-----------------------------------------------------------------------------------
// Adds a new key value into the registry.
// // TO DO - add the data
int CRegEditDoc::AddNewKeyValue(HTREEITEM hParent, HKEY hRoot, LPTSTR lpszKey, LPTSTR lpszValueName, DWORD dwType)
{
USES_CONVERSION;
int nItem, rc;
HKEY hKey;
LPWSTR lpwszKey = T2W(lpszKey);
LPWSTR lpwszValueName = T2W(lpszValueName);
try
{
if (lstrlen (lpszKey))
{
if (m_rapi.CeRegOpenKeyEx (hRoot, lpwszKey, 0, 0, &hKey) != ERROR_SUCCESS)
{
return 0;
}
}
else
{
hKey = hRoot;
}
CString strValue = "my data";
LPWSTR lpwszData = T2W(strValue);
DWORD length = dim(lpwszData);
nItem = m_pRightView->GetListCtrl().GetItemCount();
if (m_rapi.CeRegSetValueEx(hKey, lpwszValueName, 0, dwType, (LPBYTE)lpwszData, length*2) != ERROR_SUCCESS) // last 2 lpData, szie in bytes of data.
{
HRESULT hResult = m_rapi.CeRapiGetError();
DWORD dwError = m_rapi.CeGetLastError();
return 0;
}
}
catch (CException* e)
{
TCHAR szCause[255];
e->GetErrorMessage(szCause, 255);
CString errorMsg = _T("Error in: CRegEditDoc::AddNewKeyValue: ");
errorMsg += szCause;
AfxMessageBox(errorMsg);
e->Delete();
}
return 1;
}
I would appreciate a little advise on the matter, as this is the first time I have used the RAPI.
Thanks.
Hi VZ800!
The error you're getting is 'access denied'. In WM5 many RAPI functions (including writing to registry) are blocked for security reasons. Your only choice is to use a dll with CeRapiInvoke functions, but it needs to be deployed through a special cab.
You can read about this on msdn.
By the way, the app you're writing already exists, and it has the same problem.
Good luck!
Thanks for the advice. Since my post I have found that my code works for the HKEY_LOCAL_MACHINE, "/Software".
I will investigate the issue you have pointed me to.
Actually, your code should work for the entire HKEY_CLASSES_ROOT as well. MS decided to block only certain 'sensitive' parts of the registry so they can not be corrupted from the outside by malicious software.
If you noticed, MS's own remote registry editor works through DLLs (a ton of them).
Any way, I skimped on words in my first post, since I was writing it on a bus, and while I love my Jamin, writing long text on it is not very enjoyable.
Let me elaborate on CeRapiInvoke:
It's a function you call on the PC side that receives a DLL name and a function name (in that DLL) as parameters and calls that function on the device. It also lets you transfer buffers of data to and from the called function.
It's a great way to communicate with a PPC device without using sockets. You can write the device side DLL to do what ever you wont (like access protected registry) and report back to the PC.
The only drawback is in WM5 this DLL has to be registered and have a 'system' file attribute set. That's why you have to deploy it by cab.
Like I said before it's all in the MSDN.
Hope this helps.
Thanks. I have read the articles (and printed them) about RAPI Restricted Mode Security etc... http://msdn.microsoft.com/library/d...5/html/wce51conRAPIRestrictedModeSecurity.asp and will write a DLL to go on the PPC which will be installed via CAB etc...
I updated the function to add a new value anyway. Rather than calling the RAPI functions for the registry CeRapi... I will call my own functions in my authorised DLL.
Code:
//-----------------------------------------------------------------------------------
// Adds a new key value into the registry.
//
int CRegEditDoc::AddNewKeyValue(HTREEITEM hParent, HKEY hRoot, LPTSTR lpszKey,
LPTSTR lpszValName, DWORD dwDType, LPBYTE lpData)
{
USES_CONVERSION;
HKEY hKey;
LPWSTR lpwszKey = T2W(lpszKey);
LPWSTR lpwszValName = T2W(lpszValName);
DWORD dwDSize = sizeof(lpData);
try
{
if (lstrlen(lpszKey))
{
if (m_rapi.CeRegOpenKeyEx (hRoot, lpwszKey, 0, 0, &hKey) != ERROR_SUCCESS)
{
return 0;
}
}
else
{
hKey = hRoot;
}
// Check if valuename already exists. Should never happen, but just in case.
if (m_rapi.CeRegQueryValueEx(hKey, lpwszValName, 0, &dwDType, NULL, &dwDSize) == ERROR_SUCCESS)
{
AfxMessageBox(_T("Value of this name already exists!"));
return 0;
}
if (m_rapi.CeRegSetValueEx(hKey, lpwszValName, 0, dwDType, lpData, dwDSize) != ERROR_SUCCESS)
{
HRESULT hResult = m_rapi.CeRapiGetError();
DWORD dwError = m_rapi.CeGetLastError();
AfxMessageBox(_T("Unable to create new value for this key!\nPlease check access rights."));
return 0;
}
}
catch (CException* e)
{
TCHAR szCause[255];
e->GetErrorMessage(szCause, 255);
CString errorMsg = _T("Error in: CRegEditDoc::AddNewKeyValue: ");
errorMsg += szCause;
AfxMessageBox(errorMsg);
e->Delete();
}
return 1;
}
A question on using the CeRapiInvoke function. Obviously my function that I will be invoking in my DLL will need to conform to the following footprint:
Code:
LPCWSTR, LPCWSTR, DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream**, DWORD
What I would like to know is this: If I want my function to be a wrapper to say the
Code:
CeRegQueryValueEx(HKEY, LPWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD)
function, how do I parse the function args? Please suggest how I would pack them into a BYTE* for the pInput parameter.
Actually, you got it a bit wrong:
Code:
FuncName(DWORD cbInput, BYTE *pInput, DWORD *pcbOutput, BYTE **ppOutput, IRAPIStream *ppIRAPIStream);
The prototype you specified is for the PC side (the first two strings are DLL name and function name);
I use the following parsing method:
Code:
BYTE* curInputPos = pInput;
memcpy((BYTE*)&hKey, curInputPos, sizeof(HKEY));
curInputPos += sizeof(HKEY);
memcpy((BYTE*)&dwIndex, curInputPos, sizeof(DWORD));
curInputPos += sizeof(DWORD);
memcpy((BYTE*)&Reserved, curInputPos, sizeof(DWORD));
curInputPos += sizeof(DWORD);
It works fine both ways.
Just don't forget to use LocalAlloc for inBuffer and LocalFree for outBuffer.
Thanks. I'll let you know how I get on.
So if I were to parse an HKEY and an LPTSTR accross I would do the following to put the data into a BYTE array:
Code:
DWORD dwIn, dwOut;
LPBYTE pInput;
PDWORD pOut;
dwIn = sizeof(HKEY) + (strlen(lpszKey)*sizeof(TCHAR));
pInput = (BYTE*)(LocalAlloc(LPTR, dwIn));
memcpy(pInput, (BYTE*)&hKey, sizeof(HKEY));
pInput += sizeof(HKEY);
memcpy(pInput, (BYTE*)&lpszKey, strlen(lpszKey)*sizeof(TCHAR));
// move pointer back to begining.
pInput -= sizeof(HKEY);
Basically, yes but with two reservations:
1) I recommend using a different pointer for the current position in buffer, to avoid errors.
2) you need to put the string length in the byte array before the string, otherwise you won't know it's length on the device side. Alternatively, you have to add 1 to the length so the 0 byte at the end gets packed and you can use strlen on the device.
Also keep in mined that unless you define the PC side project to work with UNICODE libraries, THCHAR will be defined as char, while on the device it's always WCHAR.
I really apreciate your help. I still can't get my DLL function to work I keep getting error 1064!
This is my code for the DLL named REditSvr.dll:
Code:
#include <windows.h>
#ifdef __cplusplus
extern "C"
{
#endif
__declspec (dllexport) INT RegEditDeleteValue (DWORD cbInput, BYTE* pInput, DWORD* pcbOutput, BYTE** ppOutput, PVOID reserved);
#ifdef __cplusplus
}
#endif
BOOL WINAPI DllMain (HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
return TRUE;
}
INT RegEditDeleteValue (DWORD cbInput, BYTE* pInput, DWORD* pcbOutput, BYTE** ppOutput, PVOID reserved)
{
INT rc = 0;
BYTE* curInputPos = pInput;
HKEY hKey;
DWORD dwLength;
// Copy args out of input buffer.
memcpy((BYTE*)&hKey, curInputPos, sizeof(HKEY));
curInputPos += sizeof(HKEY);
memcpy((BYTE*)&dwLength, curInputPos, sizeof(DWORD));
curInputPos += sizeof(DWORD);
// Allocate enough memory for local wchar.
LPWSTR lpszValueName = (WCHAR*)malloc(dwLength);
memcpy((BYTE*)&lpszValueName, curInputPos, sizeof(dwLength));
curInputPos += sizeof(dwLength);
// Do the registry delete.
rc = RegDeleteValue(hKey, lpszValueName);
// Allocate memory for the return buffer.
BYTE* pOutput = (BYTE*)LocalAlloc(LPTR, sizeof(long));
memcpy(pOutput, (BYTE*)rc, sizeof(long));
*ppOutput = pOutput;
*pcbOutput = sizeof(long);
// Free input buffer.
LocalFree(pInput);
// Free WCHAR
free(lpszValueName);
return GetLastError();
}
and this is the code in my PC application which invokes the above function (or I would hope it did):
Code:
//-----------------------------------------------------------------------------------
// Deletes the key value from the registry.
//
int CRegEditDoc::DeleteKeyValue(HKEY hRoot, LPCTSTR lpszKey, LPCTSTR lpszValName)
{
USES_CONVERSION;
HKEY hKey;
LPWSTR lpwszKey = T2W(lpszKey);
LPWSTR lpwszValName = T2W(lpszValName);
try
{
if (lstrlen(lpszKey))
{
if (m_rapi.CeRegOpenKeyEx (hRoot, lpwszKey, 0, 0, &hKey) != ERROR_SUCCESS)
{
return 0;
}
}
else
{
hKey = hRoot;
}
/* if (m_rapi.CeRegDeleteValue(hKey, lpwszValName) != ERROR_SUCCESS)
{
HRESULT hResult = m_rapi.CeRapiGetError();
DWORD dwError = m_rapi.CeGetLastError();
AfxMessageBox(_T("Unable to delete value for this key!\nPlease check access rights."));
return 0;
}
*/
// Testing remote registry value deletion.
DWORD dwIn, dwOut;
LPBYTE pInput, pCurInputPos;
PDWORD pOut;
DWORD dwLength = wcslen(lpwszValName)*sizeof(WCHAR);
dwIn = sizeof(HKEY) + dwLength;
pInput = (BYTE*)(LocalAlloc(LPTR, dwIn));
pCurInputPos = pInput;
memcpy(pCurInputPos, (BYTE*)&hKey, sizeof(HKEY));
pCurInputPos += sizeof(HKEY);
// Store the length of the string
memcpy(pCurInputPos, (BYTE*)&dwLength, sizeof(DWORD));
pCurInputPos += sizeof(DWORD);
memcpy(pCurInputPos, (BYTE*)&lpwszValName, dwLength);
HRESULT hr = m_rapi.CeRapiInvoke(L"REditSvr", L"RegEditDeleteValue", dwIn,
pInput, &dwOut, (PBYTE*)&pOut, NULL, 0);
HRESULT hResult = m_rapi.CeRapiGetError();
DWORD dwError = m_rapi.CeGetLastError();
LocalFree(pOut);
if (hKey != hRoot)
{
m_rapi.CeRegCloseKey(hKey);
}
}
catch (CException* e)
{
TCHAR szCause[255];
e->GetErrorMessage(szCause, 255);
CString errorMsg = _T("Error in: CRegEditDoc::DeleteKeyValue: ");
errorMsg += szCause;
AfxMessageBox(errorMsg);
e->Delete();
}
return 1;
}
The DLL has been deployed to the PPC \Windows folder by eVC4. My PPC runs WM5 (is this the problem, although I have written programs with eVC4 ok for it).
I would again appreciate your help/advice on why this isn't working. At present I have unlocked my PPC and I am able to edit any part of the registry etc...
Hi VZ800!
I noticed a couple of errors in your code (which you may have corrected yourself by now) but the biggest problem, I think is that you don't register the dll.
Here is the part you missed from MSDN:
(full link: http://msdn.microsoft.com/library/d...en-us/mobilesdk5/html/mob5lrfcerapiinvoke.asp)
To satisfy the requirements of the Remote Access Security Policy
1. Create a provisioning XML document that adds the new node "RAPI" to the metabase. This node must include the absolute path to the *.DLL file. For more information, see Metabase Settings. The following code example shows the contents of a typical provisioning XML file.
<wap-provisioningdoc>
<characteristic type="Metabase">
<characteristic type="RAPI\Program Files\Green Sky\recaller.dll\*">
<parm name="rw-access" value="3"/>
<parm name="access-role" value="152"/>
</characteristic>
</characteristic>
</wap-provisioningdoc>
2. Pass the file name of the provisioning XML document to the CAB wizard using the /postxml command line option. The CAB wizard will append the XML to the _setup.xml file it places in the CAB. For more information on creating CAB files, see CAB Wizard.
3. Set the System attribute on the *.DLL file.
Only the Manager security role provides the required permissions for modifying the metabase. The ideal way to get this security role is to have your application signed with a privileged certificate.
Note Since Pocket PC implements a one-tier security model, the CAB install process will automatically have the Manager security role.
Click to expand...
Click to collapse
Here's my advice:
Create a simple function that doesn't receive parameters, but pops up a message on the device. When you see that calling it works, try adding the rest of the code.
Hi
As I understand the DLL does not require code to self- register. Anyway, I can call the DLL function and did as you suggested and put a MessageBox in the function. This displayed fine. My code for the DLL is as follows now:
Code:
#include <windows.h>
#ifdef __cplusplus
extern "C"
{
#endif
__declspec (dllexport) INT RegEditDeleteValue (DWORD cbInput, BYTE* pInput, DWORD* pcbOutput, BYTE** ppOutput, PVOID reserved);
#ifdef __cplusplus
}
#endif
BOOL WINAPI DllMain (HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
return TRUE;
}
INT RegEditDeleteValue (DWORD cbInput, BYTE* pInput, DWORD* pcbOutput, BYTE** ppOutput, PVOID reserved)
{
DWORD rc = 0;
BYTE* curInputPos = pInput;
LPCWSTR lpszValueName;
HKEY hKey;
int len;
// Copy args out of input buffer.
memcpy((BYTE*)&hKey, curInputPos, sizeof(HKEY));
curInputPos += sizeof(HKEY);
// Size of value name string.
memcpy((BYTE*)&len, curInputPos, sizeof(int));
curInputPos += sizeof(int);
// Value name string.
memcpy((BYTE*)&lpszValueName, curInputPos, sizeof(len));
curInputPos += sizeof(len);
// Do the registry delete.
rc = RegDeleteValue(hKey, lpszValueName);
// Allocate memory for the return buffer.
*ppOutput = (BYTE*)LocalAlloc(LPTR, rc);
memcpy(*ppOutput, (BYTE*)&rc, sizeof(DWORD));
*pcbOutput = sizeof(DWORD);
// Free input buffer.
if (pInput)
LocalFree(pInput);
return GetLastError();
}
and this is the code from which I am calling it:
Code:
//-----------------------------------------------------------------------------------
// Deletes the key value from the registry.
//
int CRegEditDoc::DeleteKeyValue(HKEY hRoot, LPCTSTR lpszKey, LPCTSTR lpszValName)
{
USES_CONVERSION;
HKEY hKey;
LPWSTR lpwszKey = T2W(lpszKey);
LPCWSTR lpwszValName = T2W(lpszValName);
try
{
if (lstrlen(lpszKey))
{
if (m_rapi.CeRegOpenKeyEx (hRoot, lpwszKey, 0, 0, &hKey) != ERROR_SUCCESS)
{
return 0;
}
}
else
{
hKey = hRoot;
}
/* if (m_rapi.CeRegDeleteValue(hKey, lpwszValName) != ERROR_SUCCESS)
{
HRESULT hResult = m_rapi.CeRapiGetError();
DWORD dwError = m_rapi.CeGetLastError();
AfxMessageBox(_T("Unable to delete value for this key!\nPlease check access rights."));
return 0;
}
*/
// Testing remote registry value deletion.
DWORD dwIn, dwOut;
LPBYTE pInput, pCurInputPos;
PDWORD pOut, rc;
int len = wcslen(lpwszValName)*sizeof(WCHAR);
dwIn = sizeof(HKEY) + len;
pInput = (BYTE*)(LocalAlloc(LPTR, dwIn));
pCurInputPos = pInput;
// Store the hKey value in the output buffer.
memcpy(pCurInputPos, (BYTE*)&hKey, sizeof(HKEY));
pCurInputPos += sizeof(HKEY);
// Store the length of the string in the output buffer.
memcpy(pCurInputPos, (BYTE*)&len, sizeof(int));
pCurInputPos += sizeof(int);
// Store the value name string in the output buffer.
memcpy(pCurInputPos, (BYTE*)&lpwszValName, len);
HRESULT hr = m_rapi.CeRapiInvoke(L"REditSvr", L"RegEditDeleteValue", dwIn,
pInput, &dwOut, (PBYTE*)&pOut, NULL, 0);
// HRESULT hr = RapiFuncTest(dwIn, pInput, &dwOut, (PBYTE*)&pOut, NULL);
HRESULT hResult = m_rapi.CeRapiGetError();
DWORD dwError = m_rapi.CeGetLastError();
if (dwOut)
{
memcpy((BYTE*)&rc, pOut, sizeof(DWORD));
}
if (pOut)
{
LocalFree(pOut);
}
if (hKey != hRoot)
{
m_rapi.CeRegCloseKey(hKey);
}
}
catch (CException* e)
{
TCHAR szCause[255];
e->GetErrorMessage(szCause, 255);
CString errorMsg = _T("Error in: CRegEditDoc::DeleteKeyValue: ");
errorMsg += szCause;
AfxMessageBox(errorMsg);
e->Delete();
}
return 1;
}
As you can see in the DeleteKeyValue(...) function I called a test-function just to check that I was retrieving the data out of the pInput buffer ok, which I am.
I signed the DLL with the SDKSamplePrivDeveloper.pfx, added the /postxml via the /postxml switch in the cabwiz and successfully created a CAB file which installs the DLL into the \Windows folder on the PPC. The .inf file is as follows:
Code:
[CEStrings]
InstallDir=%CE2%
AppName="REditSvr"
[Strings]
CompanyName="AHartley"
[Version]
Signature="$Chicago$"
CESignature="$Windows CE$"
Provider=%CompanyName%
[SourceDisksNames.Arm]
1=,"arm files",,C:\eMDevelopment\PPCRegEdit\REditSvr\REL
[SourceDisksFiles.Arm]
REditSvr.dll=1
[Files.ARM]
REditSvr.dll
[DestinationDirs]
Files.Arm=,%InstallDir%
[DefaultInstall.Arm]
CopyFiles=Files.Arm
My PC side code invokes the DLL function return 0 as error code. But the error code returned in the ppOutput buffer is 0x00000057 Dec 87. Which equates to the error message "The parameter is incorrect."! Which must be a param of the RegDeleteValue(...) function, as if I comment this out I don't get any error return values!!
Any odeas?
This is all academic now as I won't be finishing the PPCRegEdit program coz of the Remote Registry Editor tool available in the eVC4 IDE, which I hadn't noticed before, duh. But I would like to know why the function isn't working as required.
You were writing this as a tool? :shock:
If you just asked, people would have told you about the existing reg edit and CeRegEdit witch works through RAPI directly.
Still, it is a nice exercise in coding which I done my self once (for other purposes)
Any way, your error is simple:
Code:
// Value name string.
memcpy((BYTE*)&lpszValueName, curInputPos, sizeof(len));
curInputPos += sizeof(len);
You are parsing it incorrectly.
This is how it should look:
Code:
// Value name string.
memcpy((BYTE*)lpszValueName, curInputPos, len);
curInputPos += len;
and on the PC side:
Code:
memcpy(pCurInputPos, (BYTE*)&lpwszValName, len);
should be:
Code:
memcpy(pCurInputPos, (BYTE*)lpwszValName, len);
once again, no offence but if you just read your code more carefully and use debug prints to check parameters, you won't need anyone's help.
Good luck in future projects.
(whoops, made an error my self while correcting another)
Yes, it is just an exercise.
Thanks for all your help. Sorry for the silly errors, I will try and take more care in future.
Hi All,
Is anyone familiar with the EDB notification mechanism? I have some code that has opened the appointments database to get change notifications, all well and good. The trouble is I am unable to delete the CENOTIFICATION structure, meaning I get a memory leak after every change.
if anyone has seen this or knows the solution, I'd be grateful.
Code:
CEOID apps_oid;
request= new CENOTIFYREQUEST; // or (CENOTIFYREQUEST *) LocalAlloc (LPTR,
// sizeof (CENOTIFYREQUEST));
if (request) {
request->dwSize = sizeof (CENOTIFYREQUEST);
request->hwnd = hwnd;
request->hHeap = NULL;
request->dwFlags = CEDB_EXNOTIFICATION;
request->dwParam = param;
database = CeOpenDatabaseInSession ( NULL,
&pim_guid,
&apps_oid,
L"Appointments Database",
0,
0, // or CEDB_AUTOINCREMENT,
request);
}
. . .
case WM_DBNOTIFICATION:
{
CENOTIFICATION * notification = (CENOTIFICATION *)lParam;
// Always returns FALSE
BOOL hr = CeFreeNotification(request, notification);
// Always returns 5 - access denied
DWORD dw = GetLastError();
}
break;
OK, so been trying to figure out what happens when you use SEUS.
It checks for internet connection by loading this URL:
Code:
http://emma.extranet.sonyericsson.com/ns/no-cache
I've figured out quite a bit.
Sony Ericsson has implemented something called Tampered Device Service.
This checks if the devices has been tampered with.
This service works from this server:
Code:
tds.sonyericsson.com
Then for the actual firmware download.
This is done by downloading 2 *.ser.gz which tells SEUS what Software customization to get and is sessions specific.
The customization ser.gz file looks something like this:
Code:
CDA=1233-7027_NjKhzOzTUsfXvPg40lyh6aTl.ser.gz
And it's downloaded from:
Code:
emma.extranet.sonyericsson.com
It's done via some sort of search mechanism on the server.
That looks like this:
Code:
ns/usdoe1/2/script/search/TAC8=35941903/CDA=1233-7027_By5JACZqd1R7JOpLu6qvwK8N.ser.gz
After that it's downloading the actual firmware files.
They are downloaded in bin format which I haven't been able to unpack yet.
They are also downloaded from the emma server and is named something like:
Code:
277795427_k9ABo3YVh+8klYUKwllGLDcJ.bin - ~14.3 MB
277835617_ZpJseUr9e09U5h2Cz81+5vcT.bin ~149 MB
Then it does a netbios call which has some sort of HEX code.
And then check the Internet connection again:
Code:
http://emma.extranet.sonyericsson.com/ns/no-cache
Now it starts up a service called:
Code:
/fq/ServiceClientDbServlet
This service runs from this server:
Code:
ma3.extranet.sonyericsson.com
This last part is done twice in a row.
Inside one of the *ser.gz files is a *.ser file which contains some code and instructions. Some parts is encrypted but most of the code is not.
See the complete code in post #2
I don't quite know what to do with all this info yet.
But hopefully something useful will come of this.
Just wanted to share a bit of my knowledge, hope it's useful for some of you here.
Code:
import com.sonyericsson.cs.ma.tess.api.ServiceException;
import com.sonyericsson.cs.ma.tess.api.ServiceRuntimeException;
import com.sonyericsson.cs.ma.tess.api.TessFile;
import com.sonyericsson.cs.ma.tess.api.UI;
import com.sonyericsson.cs.ma.tess.api.device.IdentificationResult;
import com.sonyericsson.cs.ma.tess.api.inject.InjectConfigValue;
import com.sonyericsson.cs.ma.tess.api.inject.InjectRef;
import com.sonyericsson.cs.ma.tess.api.inject.IncludeFor;
import com.sonyericsson.cs.ma.tess.api.inject.ServiceMethod;
import com.sonyericsson.cs.ma.tess.api.logging.Logging;
import com.sonyericsson.cs.ma.tess.api.protocols.DataArea;
import com.sonyericsson.cs.ma.tess.api.protocols.ProtocolFactory;
import com.sonyericsson.cs.ma.tess.api.protocols.VersionResponse;
import com.sonyericsson.cs.ma.tess.api.protocols.s1.S1Protocol;
import com.sonyericsson.cs.ma.tess.api.protocols.s1.S1Protocol.ShutdownMode;
import com.sonyericsson.cs.ma.tess.api.secs.SECSUnitData;
import com.sonyericsson.cs.ma.tess.api.secs.SECSUtil;
import com.sonyericsson.cs.ma.tess.api.service.ServiceResult;
import com.sonyericsson.cs.ma.tess.api.service.ServiceResultType;
import com.sonyericsson.cs.ma.tess.api.service.ServiceType;
import com.sonyericsson.cs.ma.tess.api.statistics.DiagnosticsUtil;
import com.sonyericsson.cs.ma.tess.api.statistics.StatisticsUtil;
import com.sonyericsson.cs.ma.tess.api.statistics.StatisticsUtil.SoftwareComponent;
import com.sonyericsson.cs.ma.tess.api.ta.TAUnit;
import com.sonyericsson.cs.ma.tess.api.util.StringUtil;
import com.sonyericsson.cs.ma.tess.api.x10.MarlinCertificateUpdate;
import com.sonyericsson.cs.ma.tess.api.zip.ZipFileUtil;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.w3c.dom.Document;
/**
* S1 QSD8250 eSheep platform Main Services implementation.
*
* Services in this logic implemented for use in COMMERCIAL services!
*
*/
public class S1QSD8250eSheepMainServicesLIVE
{
@InjectRef
private ProtocolFactory aProtocolFactory;
@InjectRef
private UI aUI;
@InjectRef
private Logging aLogger;
@InjectRef
private IdentificationResult aIdentifiers;
@InjectRef
private ZipFileUtil aZipFileUtil;
@InjectRef
private static DiagnosticsUtil aDiagnostics;
@InjectRef
private StatisticsUtil aStatistics;
@InjectRef
private SECSUtil aSECS;
@InjectRef
private StringUtil aStringUtil;
@InjectRef
private ClientEnvironment aClientEnvironment;
@InjectRef
private MarlinCertificateUpdate marlinCertUpdate;
// File references
// Loader reference
@InjectConfigValue("cLOADER")
private TessFile aLoader;
// App-SW reference - Exclude from Activation
@IncludeFor([ServiceType.CUSTOMIZE, ServiceType.SOFTWARE_UPDATE,
ServiceType.SOFTWARE_UPDATE_CONTENT_REFRESH])
@InjectConfigValue("cAPP_SW")
private TessFile aAppSW;
// FSP Reference - Exclude from Activation
@IncludeFor([ServiceType.CUSTOMIZE, ServiceType.SOFTWARE_UPDATE,
ServiceType.SOFTWARE_UPDATE_CONTENT_REFRESH])
@InjectConfigValue("cFSP")
private TessFile aFSP;
// miscTA units
// Startup/Shutdown flag used for indicating successful flash.
@InjectConfigValue("cTA_FLASH_STARTUP_SHUTDOWN_RESULT")
private String aStrTaFlashStartShutdownResult;
// Startup/Shutdown flag used for indicating successful flash.
@InjectConfigValue("cTA_EDREAM_FLASH_IN_PROGRESS")
private String aStrTaEDreamFlashStartShutdownResult;
// SIMlock data unit
@InjectConfigValue("cTA_SIMLOCK_DATA")
private String aStrTaSimlockData;
// Loose temp data unit
@InjectConfigValue("cTA_LOOSE_TEMP")
private String aStrTaLooseTemp;
// TA_APPLICATION_BUFFER_DATA_ARRAY[2]
@InjectConfigValue("cTA_APPLICATION_BUFFER_DATA_ARRAY2")
private String aStrTaApplicationBufferDataArray2;
// TA_APPLICATION_BUFFER_DATA_ARRAY[3]
@InjectConfigValue("cTA_APPLICATION_BUFFER_DATA_ARRAY3")
private String aStrTaApplicationBufferDataArray3;
// TA_MARLIN_DRM_KEY_UPDATE_FLAG
@InjectConfigValue("cTA_MARLIN_DRM_KEY_UPDATE_FLAG")
private String aStrTaMarlinDRMKeyUpdateFlag;
// Parameter names
@InjectConfigValue("cTA_APPLICATION_BUFFER_DATA_ARRAY0_NAME")
private String aTaApplicationBufferDataArray0Name;
@InjectConfigValue("cTA_APPLICATION_BUFFER_DATA_ARRAY1_NAME")
private String aTaApplicationBufferDataArray1Name;
@InjectConfigValue("cTA_APPLICATION_BUFFER_DATA_ARRAY2_NAME")
private String aTaApplicationBufferDataArray2Name;
@InjectConfigValue("cTA_APPLICATION_BUFFER_DATA_ARRAY3_NAME")
private String aTaApplicationBufferDataArray3Name;
@InjectConfigValue("cTA_SIMLOCK_DATA_NAME")
private String aTaSimlockDataName;
@InjectConfigValue("cTA_LOOSE_TEMP_NAME")
private String aTaLooseTempName;
@InjectConfigValue("cVERSION_RESPONSE")
private String aVersionResponseName;
// miscTA unit values
// Startup/Shutdown flag, cTA_FLASH_STARTUP_SHUTDOWN_RESULT, values
@InjectConfigValue("cTA_FLASH_STARTUP_SHUTDOWN_RESULT_ONGOING_VALUE")
private String aTaFlashStartupShutdownResultOngoingValue;
@InjectConfigValue("cTA_FLASH_STARTUP_SHUTDOWN_RESULT_FINISHED_VALUE")
private String aTaFlashStartupShutdownResultFinishedValue;
// Startup/Shutdown flag, cTA_EDREAM_FLASH_STARTUP_SHUTDOWN_RESULT, values
@InjectConfigValue("cTA_EDREAM_FLASH_FLASH_IN_PROGRESS_ONGOING")
private String aTaEDreamFlashStartupShutdownResultOngoingValue;
@InjectConfigValue("cTA_EDREAM_FLASH_FLASH_IN_PROGRESS_COMPLETED")
private String aTaEDreamFlashStartupShutdownResultFinishedValue;
// Update.xml values
// File name
private static String UPDATE_XML_FILE_NAME = "update.xml";
// NOERASE tag value
private static String UPDATE_XML_NOERASE_TAG = "NOERASE";
// SIMLOCK tag value
private static String UPDATE_XML_SIMLOCK_TAG = "SIMLOCK";
// PRESERVECACHE tag value
private static String UPDATE_XML_PRESERVECACHE_TAG = "PRESERVECACHE";
// UI Progress texts
@InjectConfigValue("cSEND_DATA")
private String aSendDataText;
@InjectConfigValue("cSEND_DATA_DONE")
private String aSendDataDoneText;
@InjectConfigValue("cSERVICE_FINALIZING")
private String aServiceFinalizingText;
@InjectConfigValue("cSERVICE_FINALIZING_DONE")
private String aServiceFinalizingDoneText;
@InjectConfigValue("cSERVICE_INITIALIZATION")
private String aServiceInitializationText;
@InjectConfigValue("cSERVICE_INITIALIZATION_DONE")
private String aServiceInitializationDoneText;
/**
* ACTIVATION
*
*/
@ServiceMethod(ServiceType.ACTIVATION)
public ServiceResult activation() throws ServiceException
{
boolean vDoActivation = true;
showInitServiceText();
try
{
S1Protocol vS1 = aProtocolFactory.getProtocol(S1Protocol.class);
int vTaSimlockData = Integer.parseInt(aStrTaSimlockData);
int vTaLooseTemp = Integer.parseInt(aStrTaLooseTemp);
int vTaApplicationBufferDataArray2 =
Integer.parseInt(aStrTaApplicationBufferDataArray2);
int vTaApplicationBufferDataArray3 =
Integer.parseInt(aStrTaApplicationBufferDataArray3);
// Check if activation is needed?
// Send loader
vS1.sendFile(aLoader);
vS1.openDataArea(DataArea.MISC_TA);
// Read the SIMlock data from TA_SIMLOCK_DATA
byte[] vSIMlockData = vS1.readDataArea(vTaSimlockData);
if (vSIMlockData != null && vSIMlockData.length >= 20)
{
// Check 20 first bytes (if set to 0)
for (int vI = 0; vI < 20; vI++)
{
if (vSIMlockData[vI] != 0)
{
vDoActivation = false;
break;
}
}
}
else
{
aLogger
.error("Could not determine if activation is needed. Not possible to read enough data.");
throw new ServiceRuntimeException("Error when activating phone.");
}
// Do activation?
if (vDoActivation)
{
// Verify that the dongle is present
aSECS.ensureDongleReady();
String vIMEI = aIdentifiers.getIMEI();
SECSUnitData[] vInputData = getS1SIMLockSignatureInputData(vS1);
SECSUnitData[] vOutputData =
vS1.getS1SIMLockSignature(vInputData, vIMEI);
if (vOutputData != null && vOutputData.length > 6)
{
byte[] vEmpty = new byte[1];
vEmpty[0] = 0x00;
vS1.writeToDataArea(vTaApplicationBufferDataArray2, vEmpty);
vS1.writeToDataArea(
vTaApplicationBufferDataArray3,
vOutputData[3].getUnitData());
vS1
.writeToDataArea(vTaSimlockData, vOutputData[4]
.getUnitData());
vS1.writeToDataArea(vTaLooseTemp, vOutputData[5].getUnitData());
}
else
{
aLogger.error("Not enough data in response from SECS server.");
throw new ServiceRuntimeException(
"Error occured when communicating with server.");
}
}
else
{
aUI
.showText("ACTIVATION NOT NEEDED! This unit has been "
+ "activated already. The service is exiting without execution.");
}
showFinalizingText();
vS1.closeDataArea();
vS1.shutdownDevice(ShutdownMode.DISCONNECT);
}
catch (ServiceException pEx)
{
aLogger.error("Exception when executing ACTIVATION service.", pEx);
throw pEx;
}
return ServiceResult.SUCCESSFUL;
}
/**
* CUSTOMIZE
*
*/
@ServiceMethod(ServiceType.CUSTOMIZE)
public ServiceResult customize() throws ServiceException
{
showInitServiceText();
ServiceResult vServiceResult =
new ServiceResult(
ServiceResultType.SUCCESSFUL,
"Customize EXECUTED! ACTIVATION NEEDED!",
null);
try
{
S1Protocol vS1 = aProtocolFactory.getProtocol(S1Protocol.class);
int vTaSimlockData = Integer.parseInt(aStrTaSimlockData);
int vTaLooseTemp = Integer.parseInt(aStrTaLooseTemp);
showSendingDataText();
// Send loader
vS1.sendFile(aLoader);
vS1.openDataArea(DataArea.MISC_TA);
readDID(vS1);
updateMartinKey(vS1);
setFlashStartupShutdownFlagOngoing(vS1);
// Send App-SW
sendFile(vS1, aAppSW);
// Send FSP
if ("false".equalsIgnoreCase(aFSP.getProperty("SIMLockCustomized"))
&& "true".equalsIgnoreCase(aIdentifiers
.getIdentifier("SIMLockReusable")))
{
// quick-customize
String[] vExcludeTags = new String[1];
vExcludeTags[0] = UPDATE_XML_SIMLOCK_TAG;
String[] vFilesToExcludeFromFSP = parseFile(aFSP, vExcludeTags);
// Send FSP
sendZipFile(vS1, aFSP, vFilesToExcludeFromFSP);
vServiceResult =
new ServiceResult(
ServiceResultType.SUCCESSFUL,
"Quick Customize EXECUTED! NO ACTIVATION NEEDED!",
null);
}
else
{
// customize
// Tamper the simlock data
tamperSimlockData(vS1);
// Set the simlock data unit id to loose temp
aFSP.modifyData(vTaSimlockData, vTaLooseTemp);
sendFile(vS1, aFSP);
}
setFlashStartupShutdownFlagFinished(vS1);
showSendingDataTextDone();
showFinalizingText();
vS1.closeDataArea();
vS1.shutdownDevice(ShutdownMode.DISCONNECT);
storeSoftwareAfterStatistics();
}
catch (ServiceException pEx)
{
aLogger.error("Exception when executing CUSTOMIZE service.", pEx);
throw pEx;
}
return vServiceResult;
}
/**
* SOFTWARE UPDATE
*
*/
@ServiceMethod(ServiceType.SOFTWARE_UPDATE)
public ServiceResult softwareUpdate() throws ServiceException
{
showInitServiceText();
try
{
S1Protocol vS1 = aProtocolFactory.getProtocol(S1Protocol.class);
showSendingDataText();
// Send loader
vS1.sendFile(aLoader);
vS1.openDataArea(DataArea.MISC_TA);
readDID(vS1);
updateMartinKey(vS1);
// Search the APP-SW zip file for xml file and metadata. Exclude user
// data
String[] vExcludeTags = new String[1];
vExcludeTags[0] = UPDATE_XML_NOERASE_TAG;
String[] vFilesToExcludeFromAPPSW = parseFile(aAppSW, vExcludeTags);
// Search the FSP zip file for xml file and metadata. Exclude user data
// and simlock if existing
vExcludeTags = new String[2];
vExcludeTags[0] = UPDATE_XML_NOERASE_TAG;
vExcludeTags[1] = UPDATE_XML_SIMLOCK_TAG;
String[] vFilesToExcludeFromFSP = parseFile(aFSP, vExcludeTags);
setFlashStartupShutdownFlagOngoing(vS1);
// Send App-SW
// Anything to exclude?
if (vFilesToExcludeFromAPPSW != null
&& vFilesToExcludeFromAPPSW.length > 0)
{
sendZipFile(vS1, aAppSW, vFilesToExcludeFromAPPSW);
}
else
{
sendFile(vS1, aAppSW);
}
// Send FSP
sendZipFile(vS1, aFSP, vFilesToExcludeFromFSP);
setFlashStartupShutdownFlagFinished(vS1);
showSendingDataTextDone();
showFinalizingText();
vS1.closeDataArea();
vS1.shutdownDevice(ShutdownMode.DISCONNECT);
storeSoftwareAfterStatistics();
}
catch (ServiceException pEx)
{
aLogger
.error("Exception when executing SOFTWARE UPDATE service.", pEx);
throw pEx;
}
return ServiceResult.SUCCESSFUL;
}
/**
* SOFTWARE UPDATE CONTENT REFRESH
*
*/
@ServiceMethod(ServiceType.SOFTWARE_UPDATE_CONTENT_REFRESH)
public ServiceResult softwareUpdateContentRefresh() throws ServiceException
{
showInitServiceText();
try
{
S1Protocol vS1 = aProtocolFactory.getProtocol(S1Protocol.class);
showSendingDataText();
// Send loader
vS1.sendFile(aLoader);
vS1.openDataArea(DataArea.MISC_TA);
readDID(vS1);
updateMartinKey(vS1);
// Search the FSP zip file for xml file and metadata. Exclude
// simlock if existing
String[] vExcludeTags = new String[0];
aLogger.debug("isSwapEnabled is: "
+ aClientEnvironment.isSwapEnabled());
// Check the client environment.
if (!aClientEnvironment.isSwapEnabled())
{
aLogger.debug("Cache partition will be preserved.");
vExcludeTags = new String[1];
vExcludeTags[0] = UPDATE_XML_PRESERVECACHE_TAG;
}
// Temporarily catch the exception
String[] vFilesToExcludeFromAPPSW = parseFile(aAppSW, vExcludeTags);
vExcludeTags = new String[1];
vExcludeTags[0] = UPDATE_XML_SIMLOCK_TAG;
String[] vFilesToExcludeFromFSP = parseFile(aFSP, vExcludeTags);
setFlashStartupShutdownFlagOngoing(vS1);
// Anything to exclude?
if (vFilesToExcludeFromAPPSW != null
&& vFilesToExcludeFromAPPSW.length > 0)
{
sendZipFile(vS1, aAppSW, vFilesToExcludeFromAPPSW);
}
else
{
sendFile(vS1, aAppSW);
}
// Send FSP
sendZipFile(vS1, aFSP, vFilesToExcludeFromFSP);
setFlashStartupShutdownFlagFinished(vS1);
showSendingDataTextDone();
showFinalizingText();
vS1.closeDataArea();
vS1.shutdownDevice(ShutdownMode.DISCONNECT);
storeSoftwareAfterStatistics();
}
catch (ServiceException pEx)
{
aLogger
.error(
"Exception when executing SOFTWARE UPDATE CONTENT REFRESH service.",
pEx);
throw pEx;
}
return ServiceResult.SUCCESSFUL;
}
/**
* Private help method to get DID data from device, if available.
*
*/
private void readDID(S1Protocol pS1)
{
byte[] vEmptyUnit = new byte[0];
List<TAUnit> vUnits = new ArrayList<TAUnit>();
aLogger.debug("Reading diagnostic data.");
final int vLastUnit = 10009;
final int vFirstUnit = 10000;
for (int vUnit = vFirstUnit; vUnit <= vLastUnit; vUnit++)
{
try
{
byte[] vData = pS1.readDataArea(vUnit);
if (vData != null && vData.length > 0)
{
pS1.writeToDataArea(vUnit, vEmptyUnit);
vUnits.add(new TAUnit(vUnit, vData));
}
}
catch (ServiceException vServiceException)
{
}
}
if (vUnits.size() > 0)
{
byte[] vDiagnosticData;
try
{
aLogger.debug("Diagnostic data found, sending diagnostic data.");
vDiagnosticData = aDiagnostics.createDiagnosticData(vUnits);
aDiagnostics.storeDiagnostic(aIdentifiers.getIMEI(), aIdentifiers
.getApplicationSoftwareID(), aIdentifiers
.getApplicationSoftwareRev(), vDiagnosticData, "06");
}
catch (ServiceException pEx)
{
}
}
}
/**
* Private help method to tamper the simlock data.
*
*/
private void tamperSimlockData(S1Protocol pS1) throws ServiceException
{
int vTaSimlockData = Integer.parseInt(aStrTaSimlockData);
// Read the SIMlock data from TA_SIMLOCK_DATA
byte[] vSIMlockData = pS1.readDataArea(vTaSimlockData);
if (vSIMlockData != null && vSIMlockData.length > 0)
{
// Tamper 20 first bytes (set to 0)
// Make sure enough data is read
if (vSIMlockData.length >= 20)
{
for (int vI = 0; vI < 20; vI++)
{
vSIMlockData[vI] = 0;
}
}
else
{
throw new ServiceRuntimeException(
"Data read, but not enough to tamper.");
}
// Write back the tampered SIMlock data to TA_SIMLOCK_DATA
pS1.writeToDataArea(vTaSimlockData, vSIMlockData);
}
else
{
throw new ServiceRuntimeException("Could not read data.");
}
}
/**
* Private help method to get S1 SIMlock signature input data from device.
*
*/
private SECSUnitData[] getS1SIMLockSignatureInputData(S1Protocol pS1)
throws ServiceException
{
SECSUnitData[] vSECSUnitData = new SECSUnitData[7];
int vTaSimlockData = Integer.parseInt(aStrTaSimlockData);
int vTaLooseTemp = Integer.parseInt(aStrTaLooseTemp);
int vTaApplicationBufferDataArray3 =
Integer.parseInt(aStrTaApplicationBufferDataArray3);
byte[] vEmpty = new byte[1];
vEmpty[0] = 0x00;
vSECSUnitData[0] =
new SECSUnitData(aTaApplicationBufferDataArray0Name, vEmpty);
vSECSUnitData[1] =
new SECSUnitData(aTaApplicationBufferDataArray1Name, vEmpty);
vSECSUnitData[2] =
new SECSUnitData(aTaApplicationBufferDataArray2Name, vEmpty);
byte[] vInputUnitData = pS1.readDataArea(vTaApplicationBufferDataArray3);
vSECSUnitData[3] =
new SECSUnitData(aTaApplicationBufferDataArray3Name, vInputUnitData);
vInputUnitData = pS1.readDataArea(vTaSimlockData);
vSECSUnitData[4] = new SECSUnitData(aTaSimlockDataName, vInputUnitData);
vInputUnitData = pS1.readDataArea(vTaLooseTemp);
vSECSUnitData[5] = new SECSUnitData(aTaLooseTempName, vInputUnitData);
VersionResponse vVersionResponse = pS1.getVersionResponse();
byte[] vVersionResponseArray =
vVersionResponse.getVersionResponseAsBytes();
vInputUnitData = vVersionResponseArray;
vSECSUnitData[6] = new SECSUnitData(aVersionResponseName, vInputUnitData);
return vSECSUnitData;
}
/**
* Parses the specified file for a xml metadata file and the parses the xml
* file for the tags defined. Tag values are then returned as a string array.
*
*/
private String[] parseFile(TessFile pFile, String[] pTags)
throws ServiceException
{
ArrayList<String> vResult = new ArrayList<String>();
Document vUpdateXML =
aZipFileUtil.getXMLFile(pFile, UPDATE_XML_FILE_NAME);
if (vUpdateXML != null)
{
if (pTags != null)
{
for (String vTag : pTags)
{
String[] vFilesFound =
aZipFileUtil.getXMLTextContentByTagName(vUpdateXML, vTag);
if (vFilesFound != null && vFilesFound.length > 0)
{
aLogger.debug("Found files to exclude from "
+ pFile.getFileName()
+ " from tag "
+ vTag
+ " in "
+ UPDATE_XML_FILE_NAME
+ ":");
for (String vFileName : vFilesFound)
{
aLogger.debug(vFileName);
}
vResult.addAll(Arrays.asList(vFilesFound));
}
}
}
}
else
{
aLogger.debug("No " + UPDATE_XML_FILE_NAME + " found");
// throw new
throw new ServiceRuntimeException("Could not find a "
+ UPDATE_XML_FILE_NAME
+ " in the zip file, abort.");
}
return vResult.toArray(new String[vResult.size()]);
}
private void updateMartinKey(S1Protocol pS1) throws ServiceException
{
int vTaMarlinDRMKeyUpdateFlag =
Integer.parseInt(aStrTaMarlinDRMKeyUpdateFlag);
byte[] vFlagValue = null;
pS1.openDataArea(DataArea.MISC_TA);
// check the flag
try
{
vFlagValue = pS1.readDataArea(vTaMarlinDRMKeyUpdateFlag);
if (vFlagValue != null
&& aStringUtil
.convertByteArrayToString(vFlagValue)
.equalsIgnoreCase("01"))
{
// updated already
return;
}
}
catch (ServiceException vServiceException)
{
// exception indicates no update has been done
}
// check if update is available for this unit
if (marlinCertUpdate.isNewCertificateAvailable())
{
// update the cert
InputStream vTAFileInputStream =
marlinCertUpdate.getCertificateTAInputStream();
pS1.sendTAFileFromStream(vTAFileInputStream);
aLogger.debug("Marlin key updated.");
}
// set the flag as updated
pS1.writeToDataArea(vTaMarlinDRMKeyUpdateFlag, aStringUtil
.convertStringToByteArray("0x01"));
return;
}
/**
* Private help method to set the flash ongoing flag to ongoing.
*
* @throws ServiceException
*
*/
private void setFlashStartupShutdownFlagOngoing(S1Protocol pS1)
throws ServiceException
{
int vTaFlashStartupShutdownResult =
Integer.parseInt(aStrTaFlashStartShutdownResult);
int vTaEDreamFlashStartupShutdownResult =
Integer.parseInt(aStrTaEDreamFlashStartShutdownResult);
// Set the TA_FLASH_STARTUP_SHUTDOWN_RESULT (2227) flag to 0xA0000000 to
// indicate
// flash ongoing
pS1
.writeToDataArea(
vTaFlashStartupShutdownResult,
aStringUtil
.convertStringToByteArray(aTaFlashStartupShutdownResultOngoingValue));
// Set the 10100 flag specific for eDream
// Set the TA_EDREAM_FLASH_STARTUP_SHUTDOWN_RESULT (10100) flag to 0x01 to
// indicate
// flash ongoing
pS1
.writeToDataArea(
vTaEDreamFlashStartupShutdownResult,
aStringUtil
.convertStringToByteArray(aTaEDreamFlashStartupShutdownResultOngoingValue));
}
/**
* Private help method to set the flash ongoing flag to finished.
*
* @throws ServiceException
*
*/
private void setFlashStartupShutdownFlagFinished(S1Protocol pS1)
throws ServiceException
{
int vTaFlashStartupShutdownResult =
Integer.parseInt(aStrTaFlashStartShutdownResult);
int vTaEDreamFlashStartupShutdownResult =
Integer.parseInt(aStrTaEDreamFlashStartShutdownResult);
// Set the TA_FLASH_STARTUP_SHUTDOWN_RESULT (2227) flag to 0xAA000000 to
// indicate
// flash finished
pS1
.writeToDataArea(
vTaFlashStartupShutdownResult,
aStringUtil
.convertStringToByteArray(aTaFlashStartupShutdownResultFinishedValue));
// Set the 10100 flag specific for eDream
// Set the TA_EDREAM_FLASH_STARTUP_SHUTDOWN_RESULT (10100) flag to 0x00 to
// indicate flash finished
pS1
.writeToDataArea(
vTaEDreamFlashStartupShutdownResult,
aStringUtil
.convertStringToByteArray(aTaEDreamFlashStartupShutdownResultFinishedValue));
}
/**
* Private help method to store software and CDF ids and versions.
*
*/
private void storeSoftwareAfterStatistics()
{
String vAPPSWId = aAppSW.getProperty("Id");
String vAPPSWVer = aAppSW.getVersion();
String vCDFId = aFSP.getProperty("CDFId");
String vCDFVer = aFSP.getProperty("CDFVer");
if (vAPPSWId != null)
{
aStatistics.storeSoftwareAfter(
SoftwareComponent.SW1,
vAPPSWId,
vAPPSWVer);
}
if (vCDFId != null)
{
aStatistics.storeCustomizationAfter(vCDFId, vCDFVer);
}
}
private void sendZipFile(
S1Protocol pS1,
TessFile pFile,
String[] pFilesToExclude) throws ServiceException
{
aLogger.debug("Sending "
+ pFile.getFileName()
+ ", "
+ pFile.getVersion());
pS1.sendZipFile(pFile, pFilesToExclude);
}
private void sendFile(S1Protocol pS1, TessFile pFile)
throws ServiceException
{
aLogger.debug("Sending "
+ pFile.getFileName()
+ ", "
+ pFile.getVersion());
pS1.sendFile(pFile);
}
/**
* Private help method to display start sending data text.
*
*/
private void showSendingDataText()
{
aUI.showText(aSendDataText);
}
/**
* Private help method to display start sending data done text.
*
*/
private void showSendingDataTextDone()
{
aUI.showText(aSendDataDoneText);
}
/**
* Private help method to display start up and initialization text.
*
*/
private void showInitServiceText()
{
aUI.showText(aServiceInitializationText);
aUI.showText(aServiceInitializationDoneText);
aUI.showText("");
}
/**
* Private help method to display please wait text.
*
*/
private void showFinalizingText()
{
aUI.showText("");
aUI.showText(aServiceFinalizingText);
aUI.showText(aServiceFinalizingDoneText);
}
}
Reserved for future use.
wow seems u done some packet sniffing...
may be u should contact Bin4ry regarding this... he is involved in FreeXperia Project for Arc/Play...
i am sure he can shed some more light on this matter...
Figured out the *.bin files is the actual files that also goes in the blob_fs folder:
Code:
%programfiles%\Sony Ericsson\Update Service\db\
So they are decryptable using the known method.
Tampered Device Service does in fact check for Root and custom software.
Don't know if this will have an effect in the updating process from SEUS.
So, it's a bad news huh. Keep looking. Thanks for the info.
Sent from my X10i using XDA App
Confirmed that devices that has been rooted and modified in software will not be eligible for 2.3.3 update. You will have to flash back a stock unrooted firmware before updating to 2.3.3
Of course. SE said that in their blog. Better backup all data in SD Card and format it too. I don't think the SEUS' intelligent enough to check out that the SD Card contains CyanogenMod folder as busybox and xRecovery
EDIT: I tried to find the update 2.1 package in my computer after repaired my phone for several times and I can't find it. It's of course that it's deleted as soon as the update completed.
I believe SEUS works like the Flash Tool and Pay-Per-Update service through fastgsm.com and davince.
Flash Tool requires you to provide the firmware and place the sin files in the correct location.
Pay service requires a fee to install the correct sin files/firmware.
SEUS requires a CDA to determine which sin files/firmware to install.
I beg that the FlashTool works like SEUS cause without SEUS and other update services, where is FlashTool come from?
But what if SEUS change its method? Well, i still want to update and we will see how it goes.
Sent from my X10i using XDA App
Whatever method they choose, they can't close the door behind them. They need the access too. Flash Tool can be updated.
Nor would google allow that. JMHO
Yes, FT can be updated but it's development is kinda dead as of now, and we don't even have its source codes, so the other developers can't update it. Unless if Androxyde and Bin4ry want to work on FT again.
Hzu said:
Yes, FT can be updated but it's development is kinda dead as of now, and we don't even have its source codes, so the other developers can't update it. Unless if Androxyde and Bin4ry want to work on FT again.
Click to expand...
Click to collapse
Why are the devs acting like this is an issue? The Flash Tool already works on the ARC, so what are you worried about?
Work on Arc no mean it can work on X10, just like Arc has bootloader unlocked but no mean X10 can when update to 2.3.3
silveraero said:
Work on Arc no mean it can work on X10, just like Arc has bootloader unlocked but no mean X10 can when update to 2.3.3
Click to expand...
Click to collapse
You totally missed the point. The bootloader or root has NEVER mattered. When the NEVER has happened, then start your *****ing.
agentJBM said:
Why are the devs acting like this is an issue? The Flash Tool already works on the ARC, so what are you worried about?
Click to expand...
Click to collapse
What I mean is that IF SE changed their flashing method for the GB firmware and FT won't work for those who upgraded their X10 to GB. But another user has said that they won't since it requires them to start all over again.
Who knows, we're not the one who are developing the firmwares and we all should stop making assumptions(but some people aren't making assumptions, they are so sure they are right).
Hzu said:
What I mean is that IF SE changed their flashing method for the GB firmware and FT won't work for those who upgraded their X10 to GB. But another user has said that they won't since it requires them to start all over again.
Who knows, we're not the one who are developing the firmwares and we all should stop making assumptions(but some people aren't making assumptions, they are so sure they are right).
Click to expand...
Click to collapse
I am not pretending to know. However, you are failing to acknowledge that the Flash Tool is a modification of Update Service. The same method is used. Quit acting like this is nuclear science.
I told you, what IF they CHANGE the flashing method, then SEUS will also be updated with the new method.
Why am I repeating this anyway? Silly me.