Archive: PPC-registry on Windows Mobile 5.0 fails


PPC-registry on Windows Mobile 5.0 fails
Got everything up and running, including a fab. installation routine - works a treat on CE 2003 but fails on Mobile 5.0. At first I thought the issue was the WM5 security model, but that is not so 'cos another part of my app. can happily manipulate the PPC registry over RAPI.

My code with debug:
${PPC-registry::CeRapiInitEx} $R0
MessageBox MB_OK "PPC-registry::CeRapiInit$\n$\n\Errorlevel: [$R0]"
${PPC-registry::Read} "HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory" "Folder" $R0 $R1
MessageBox MB_OK 'PPC-registry::Read$\n$\n\$$R0 "string" =[$R0]$\n\$$R1 "type" =[$R1]$\n'

Fails at the Read function:
Unhandled exception at 0x2501499b in IfapMobileSetup.exe: 0xC0000005: Access violation writing location 0x10049000.

I have read the comments from tbednarz (Sep 2002), but setting /NOUNLOAD changes nothing!

Any inspirational thoughts most warmly welcomed!!!

Peter


1. Is this happens with PPC-registry::CeRapiInit
2. Is this happens with other functions (like PPC-registry::Write)?


1. PPC-registry::CeRapiInit seems to be exactly as good (or bad?) as PPC-registry::CeRapiInitEx.
2. PPC-registry::Write fails just like Read... you can test this using your own example code. I have tested against both iPAQ rx1950 and the HTC PU10 = T.Mobile MDA Pro, both fail the same.
Sorry to be the bearer of bad news...


... you can test this using your own example code.
I can't test it.

Have no idea. Maybe update rapi.lib from Windows Mobile 5.0 SDK, but I haven't it.

[edit]Seams that is security problem.[/edit]

http://nickcheng.com/wiki/doku.php?i...ation_security
http://channel9.msdn.com/wiki/defaul...r.MigrationFAQ (Why can't I use RAPI with my Windows Mobile device?)

I'll see what I can do. How can I contact you?


Found something. MSDN:

Microsoft Windows CE 5.0 Trusted APIs
...
The secure registry architecture in Windows CE allows only trusted applications that you have identified to modify keys and values in protected portions of the registry.

Because most of the registry is unprotected, original equipment manufacturers must place all-important registry information in one of the protected keys.
Note All applications have read-only access to all registry keys and values.

In Windows CE, the following registry root keys and their subkeys are protected from untrusted applications:
HKEY_LOCAL_MACHINE\Comm
HKEY_LOCAL_MACHINE\Drivers
HKEY_LOCAL_MACHINE\HARDWARE
HKEY_LOCAL_MACHINE\Init
HKEY_LOCAL_MACHINE\Services
HKEY_LOCAL_MACHINE\SYSTEM
HKEY_LOCAL_MACHINE\WDMDrivers


Untrusted applications are also not allowed to modify protected data. They receive the ERROR_ACCESS_DENIED return value if they attempt to use the following registry functions:
RegSetValueEx
RegCreateKeyEx
RegDeleteKey
RegDeleteValue

My email: beedell@ifap.de


Peter Beedell as you see MSDN remark answer on question. If your application not trusted, you can only read from registry, and can't read from:
HKEY_LOCAL_MACHINE\Comm
HKEY_LOCAL_MACHINE\Drivers
HKEY_LOCAL_MACHINE\HARDWARE
HKEY_LOCAL_MACHINE\Init
HKEY_LOCAL_MACHINE\Services
HKEY_LOCAL_MACHINE\SYSTEM
HKEY_LOCAL_MACHINE\WDMDrivers


This can not explain why your PPC-RegistryTest fails - here you are writing to HKEY_LOCAL_MACHINE\SOFTWARE\NSIS.
Even if this were the case, can we expect the application to fail with a memory exception?
I have another instance (C++) using RAPI which works just fine...!


Can you provide some code from this instance?


Do you mean you want me to give your your own test code?


I have another instance (C++) using RAPI which works just fine...!
I understand it that you have some program written on C++ that uses RAPI. And if you have sources, I can view it.

Woops, its Delphi code..!
procedure TMainForm.TransferFeatureToPocket(AFeature: integer);
var
ri: TRapiInit;
hRes: HRESULT;
dwRet: DWORD;

h_Key: HKey;
ph_Key: PHKey;
res, cri: longint;
k_exist: LPDWORD;
// k_exist: PDWORD;
pFeature: Pointer;
begin
TraceFunction('MainForm.TransferFeatureP Start', false);
StatusBar.Panels[0].Text := 'Connecting ...';
StatusBar.Refresh;
ri.cbSize := sizeof(ri);
hRes := CeRapiInitEx(ri);
dwRet := WaitForSingleObject(ri.heRapiInit, 5000);

if ((dwRet <> WAIT_OBJECT_0) or (SUCCEEDED(ri.hrRapiInit) = FALSE)) then
begin
// Could not initialize Rapi
TraceFunction('MainForm.TransferFeatureP CRU', false);
CeRapiUninit;
TraceFunction('MainForm.TransferFeatureP - Pocket PC not connected!', false);
StatusBar.Panels[0].Text := 'Pocket PC not connected!';
end
else
begin
TraceFunction('MainForm.TransferFeatureP - Registering ...', false);
StatusBar.Panels[0].Text := 'Registering ...';
StatusBar.Refresh;
cri := CeRapiInitEx(ri);
if cri <> 0 then
begin
StatusBar.Panels[0].Text := 'Error!';
TraceFunction('MainForm.TransferFeatureP - Error!', false);
end
else
begin
try
TraceFunction('MainForm.TransferFeatureP - CeRegCreateKeyEx Start', false);
res := CeRegCreateKeyEx(
HKEY_CURRENT_USER,
'Software\ifap GmbH\praxisCENTER mobile',
0,
'ActivateCode',
0,
0,
nil,
@h_Key,
k_exist);
TraceFunction('MainForm.TransferFeatureP - CeRegCreateKeyEx End', false);

if res <> 0 then
begin
StatusBar.Panels[0].Text := 'Key not found!';
TraceFunction('MainForm.TransferFeatureP - Key not found!', false);
end;

pFeature := @AFeature;
TraceFunction('MainForm.TransferFeatureP CeRegSetValueEx Start', false);
res := CeRegSetValueEx(h_Key, 'ActivateCode', 0, REG_DWORD, pFeature, SizeOf(AFeature));
TraceFunction('MainForm.TransferFeatureP CeRegSetValueEx End', false);

if res <> 0 then
begin
StatusBar.Panels[0].Text := 'Program not activated properly!';
TraceFunction('MainForm.TransferFeatureP - Program not activated properly!', false);
end;

if hres = ERROR_SUCCESS then
res := res;
StatusBar.Panels[0].Text := '';

TraceFunction('MainForm.TransferFeatureP - CeRegCloseKey start', false);
CeRegCloseKey(HKEY_CURRENT_USER);
TraceFunction('MainForm.TransferFeatureP - CeRegCloseKey end', false);
except

end;
end;
end;

TraceFunction('MainForm.TransferFeatureP End', false);
end;


I do have C++ code that uses RAPI to copy a file to a WM5 device (i.e. nothing to do with the registry) - here it is just for fun ;-)

void CRencherRAPI::InitializeSettings()
{
LPTSTR pPath = new TCHAR[MAX_PATH + 10];
GetSystemDirectory(pPath, MAX_PATH);
CString str(pPath);
str += "\\rapi.dll";
hInst = LoadLibrary(str);
if (hInst)
{
CeRapiInit = (FARPROC) GetProcAddress(hInst, "CeRapiInit");
CeRapiUninit = (FARPROC) GetProcAddress(hInst, "CeRapiUninit");
CeCreateFile = (pfnFunc0)GetProcAddress(hInst, "CeCreateFile");
CeWriteFile = (pfnFunc1)GetProcAddress(hInst, "CeWriteFile");
CeCloseHandle = (pfnFunc2)GetProcAddress(hInst, "CeCloseHandle");
CeFindFirstFile = (pfnFunc3)GetProcAddress(hInst, "CeFindFirstFile");
CeGetFileSize = (pfnFunc4)GetProcAddress(hInst, "CeGetFileSize");
CeReadFile = (pfnFunc5)GetProcAddress(hInst, "CeReadFile");
CeFindNextFile = (pfnFunc6)GetProcAddress(hInst, "CeFindNextFile");
CeCreateDirectory = (pfnFunc7)GetProcAddress(hInst, "CeCreateDirectory");
CeCreateProcess = (pfnFunc8)GetProcAddress(hInst, "CeCreateProcess");
CeGetSystemInfo = (pfnFunc9)GetProcAddress(hInst, "CeGetSystemInfo");
m_bRapiLoaded = true;
}
else
{
FreeLibrary(hInst);
MessageBox(m_hWnd, "Rapi.dll konnte nicht geladen werden.", "Info", MB_OK);
}
}

#define BUFFER_SIZE 10240

void CRencherRAPI::CopyFiletoWinCE(CString strFileNamePC, CString strFileNamePPC)
{
if (m_bRapiLoaded = false)
{
return;
}
CFile oldFile;
char cTemp[BUFFER_SIZE];
int n = BUFFER_SIZE;
DWORD nbytes;
CString s;
long iTotBytes = 0;
long iPercent = 0;

m_bAbborted = FALSE;

oldFile.Open(strFileNamePC, CFile::modeRead |CFile::typeBinary);
long iLen = oldFile.GetLength();
long iMaxLen = iLen;
if (m_pProgressbar != NULL)
{
m_pProgressbar->SetRange(0, 100);
}

iLen = iLen / BUFFER_SIZE;
BSTR bstr = strFileNamePPC.AllocSysString();

CeRapiInit();
HANDLE h;


h = CeCreateFile(bstr, GENERIC_READ , 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (h != INVALID_HANDLE_VALUE)
{
if (MessageBox(m_hWnd, "Datei ist bereits auf Windows CE Gerät vorhanden, möchten Sie sie überschreiben?", "Info", MB_YESNO) == IDNO )
{
return;
}
CeCloseHandle(h);
}

h = CeCreateFile(bstr, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

long iProgressDividor = iMaxLen / 100L;

while(oldFile.Read(&cTemp, BUFFER_SIZE) >= 1)
{
CeWriteFile(h, &cTemp, (DWORD)n, &nbytes, NULL);
iTotBytes = iTotBytes + (long)nbytes;
if (m_pProgressbar != NULL)
{
iPercent = (iTotBytes / iProgressDividor) + 1L;
m_pProgressbar->SetPos(iPercent);
if (m_bAbborted)
{
break;
}
}
}
SysFreeString(bstr);
CeCloseHandle(h);
oldFile.Close();
CeRapiUninit();
}

CString CRencherRAPI::GetCStringFromFile(CString strFileName)
{
if (m_bRapiLoaded = false)
{
return "";
}

CString strOut;
LPSTR pText = NULL;
int iLen;
CFile f;
if (f.Open(strFileName, CFile::modeReadWrite))
{
iLen = f.GetLength();
pText = new char[iLen + 1];
f.Read(pText, iLen);
pText[iLen] = '\0';
CString str(pText);
strOut = str;
delete pText;
f.Close();
}
else
{
strOut = "Error";
}
return strOut;
}


Peter check your e-mail


I cant seem to reply directly....
Ihre Nachricht hat einige oder alle Empfänger nicht erreicht.

Betreff: AW: PPC-registry
Gesendet am: 23.03.2006 12:46

Folgende Empfänger konnten nicht erreicht werden:

***1040;***1083;***1077;***1082;***1089;***1072;***1085;***1076;***1088; ***1064;***1077;***1085;***1075;***1072;***1083;***1100;***1094; am 23.03.2006 12:46
Fehler bei der SMTP-Kommunikation mit dem E-Mail-Server des Empfängers. Wenden Sie sich an Ihren Systemadministrator.
<IFAP-DC1.ifap.local #5.5.0 smtp;550 Access from ip address 62.154.249.106 blocked. Visit http://win.mail*****cgi-bin/support_bl?ip=62.154.249.106>

So here is my response...

Hi Mr. um, er, sorry, do you have a nickname I could use?
Yes, the RegistryTest.nsi runs happily on my CE 2003 devices, but fails on anything other than the RAPI initialisation {PPC-registry::CeRapiInitEx}.
This fails even if I ensure the first action after the init is a read of a key that defiantly exists:
${PPC-registry::Read} "HKEY_CURRENT_USER\SOFTWARE\ifap GmbH\praxisCENTER mobile" "ActivateCode" $R0 $R1

Best regards,

Peter Beedell.
-----Ursprüngliche Nachricht-----
Von: ***1040;***1083;***1077;***1082;***1089;***1072;***1085;***1076;***1088; ***1064;***1077;***1085;***1075;***1072;***1083;***1100;***1094; [mailto:shengalts@mail.ru]
Gesendet: Donnerstag, 23. März 2006 12:25
An: Peter Beedell
Betreff: PPC-registry

I'll check the code you posted little later. Peter then you run PPC-RegistryTest.nsi "Basic registry functions" it fails then calls PPC-registry::Read?


That should read: "but fails on anything other than the RAPI initialisation on WM5 devices."


Can you test the attachment. It try to read "HKEY_CURRENT_USER\SOFTWARE\ifap GmbH\praxisCENTER mobile" "ActivateCode"


Running this Test.exe results in a small window, titled "Fehler" (German for failure), a small square (non-printable character?) and the OK button - nothing else.

The behaviour is identical on both CE 2003 and Windows Mobile 5.0 devices.


titled "Fehler"
Don't mind it. How about next test?

The results are identical to the last test in all respects!
Just one observation, when the process 'ends' it leaves a task running that must be killed in the task manager.


What the real value of the ActivateCode and what type is it?

Just one observation, when the process 'ends' it leaves a task running that must be killed in the task manager.
Forgot CeRapiUninit()

Any integer value and the type is a REG_DWORD


Peter can we talk now in ICQ? My: 345166905


---


Hi Aleksander,
I have tried the latest version and it fails at the PPC-registry::Read with "*lpcbData=65536". Clicking the MessageBox away it is followed by another with "MakeNSISWPlacement" before the system crashes!
I wait for your response!
Cheers, Peter.


Maybe this one?


Identical behaviour in all aspects! Sorry!
Peter.


Peter can you sign on ICQ?


How about this?


I have tested this as well - no change...
I am trying to contact you by ICQ


---