Hi,
I have 2 HTC Tornado (T-Mobile SDA) smartphone and Visual Studio 2005. I want to connect them over a GSM data connection. For this risen, I write a little class "myTAPI".
If I use the "LINEMEDIAMODE_INTERACTIVEVOICE" media mode, I can dial and answer speech calls. But if I change the mode to "LINEMEDIAMODE_DATAMODEM", something go wrong. If call the second smartphone with my application, I see for a half second 2 arrows in the right left corner. "lineGetLineDevStatus" returns one active call, for the moment. But I can't get the call over "lineGetMessage" . So I have no hCall Handle.
If I call to PSTN, my phone ring. If I answer by hand, I hear a modem tone.
Program calling phone
Code:
TAPIDev.getMessage();
TAPIDev.getMessage();
TAPIDev.getMessage();
TAPIDev.dial(CString("01716597462"), LINEMEDIAMODE_DATAMODEM);//01716597462
TAPIDev.getMessage();
TAPIDev.getMessage();
TAPIDev.getMessage();
TAPIDev.getMessage();
//TAPIDev.openSerial();
TAPIDev.getStatus();
TAPIDev.getMessage();
TAPIDev.getStatus();
Sleep(5000);
Program waiting phone
Code:
for(i = 0; i < 60; ++i){
TAPIDev.getStatus();
TAPIDev.getMessage();
}
Can someone help me?
Or have someone sample code, that works on tornado.
My sourcecode:
- mytapi: my TAPI class
- open: open the connection
- dial: dial an number
- getMessage: lineGetMessage and answer if possible a call
- getStatus: lineGetLineDevStatus - output for debugging
Thanks
Thomas
answering a GSM datacall not work
Hi,
I implement the same program ( connecting two gsm phones over a gsm data channel) with RIL instance of TAPI. But I have the same problem. The calling smartphone works, but den second smartphone not answer. I only see 2 small arrows in the right left corner for a second.
In an other forum, I read, I have to kill "cprog.exe" but the result is the same.
It down work!
Have somebody a idea?
my code for the calling phone
Code:
HRESULT result;
DWORD dwNotificationClasses = 0xFF0000;
HRIL g_hRIL = 0;
DWORD pdwVersion;
result = RIL_Initialize(1, ResultCallback, NotifyCallback, dwNotificationClasses, g_dwParam, &g_hRIL);
TRACE(TEXT("RIL_Initialize: 0x%0X \n"), result);
result = RIL_GetDriverVersion(
g_hRIL, // @parm handle to RIL instance returned by <f RIL_Initialize>
&pdwVersion // @parm pointer to version. HIWORD is major version, LOWORD is minor version
);
TRACE(TEXT("RIL_GetDriverVersion 0x%0X \n"), pdwVersion);
result = RIL_Dial(
g_hRIL,
"123",
RIL_CALLTYPE_DATA, // @parm type of the call to establish (<def RIL_CALLTYPE_> constant)
RIL_DIALOPT_NONE // @parm dialing options (any combination of <def RIL_DIALOPT_> constants)
);
TRACE(TEXT("RIL_Dial: %d\n"), result);
Sleep(30000);
result = RIL_Hangup(
g_hRIL // @parm handle to RIL instance returned by <f RIL_Initialize>
);
TRACE(TEXT("RIL_Hangup: 0x%0X \n"), result);
Sleep(20000);
result = RIL_Deinitialize(g_hRIL);
TRACE(TEXT("RIL_Deinitialize: 0x%0X \n"), result);
my code for the answering phone:
Code:
HRESULT result;
DWORD dwNotificationClasses = 0xFF0000;
HRIL g_hRIL = 0;
DWORD pdwVersion;
result = RIL_Initialize(1, ResultCallback, NotifyCallback, dwNotificationClasses, g_dwParam, &g_hRIL);
TRACE(TEXT("RIL_Initialize: 0x%0X \n"), result);
result = RIL_GetDriverVersion(
g_hRIL, // @parm handle to RIL instance returned by <f RIL_Initialize>
&pdwVersion // @parm pointer to version. HIWORD is major version, LOWORD is minor version
);
TRACE(TEXT("RIL_GetDriverVersion 0x%0X \n"), pdwVersion);
Sleep(20000);
result = RIL_Answer( g_hRIL );
TRACE(TEXT("RIL_Answer: 0x%0X \n"), result);
Sleep(20000);
result = RIL_Deinitialize(g_hRIL);
TRACE(TEXT("RIL_Deinitialize: 0x%0X \n"), result);
my output for the calling phone:
Load module: myRIL.exe
Load module: shellres.dll
Load module: shutil.dll
Load module: commctrl.dll
Load module: aygshell.dll
Load module: tshres.dll.0407.mui
Load module: tshres.dll
Load module: oleaut32.dll
Load module: ole32.dll
Load module: ossvcs.dll
Load module: ril.dll
Load module: coredll.dll
RIL_Initialize: 0x0
RIL_GetDriverVersion 0x10000
NotifyCallbackRIL_Dial: 468
notify: dwCode=0x800002 lpData=303BFE88, cbData=4
NotifyCallbacknotify: dwCode=0x400005 lpData=303BFD90, cbData=32
NotifyCallbacknotify: dwCode=0x400005 lpData=303BFD90, cbData=32
NotifyCallbacknotify: dwCode=0x400005 lpData=303BFD90, cbData=32
NotifyCallbacknotify: dwCode=0x400005 lpData=303BFD90, cbData=32
NotifyCallbacknotify: dwCode=0x400005 lpData=303BFD90, cbData=32
ResultCallbackresult: dwCode=5, hrCmdID=468 lpData=00000000, cbData=0
NotifyCallbacknotify: dwCode=0x400005 lpData=303BFD90, cbData=32
NotifyCallbacknotify: dwCode=0x400005 lpData=303BFD90, cbData=32
RIL_Hangup: 0x1D5
NotifyCallbacknotify: dwCode=0x10005 lpData=00000000, cbData=0
ResultCallbackresult: dwCode=1, hrCmdID=469 lpData=00000000, cbData=0
The thread 0x2d266852 has exited with code 0 (0x0).
RIL_Deinitialize: 0x0
Load module: t9ime.dll
Click to expand...
Click to collapse
my output for the answering phone:
Load module: myRIL.exe
Load module: shellres.dll
Load module: shutil.dll
Load module: commctrl.dll
Load module: aygshell.dll
Load module: tshres.dll.0407.mui
Load module: tshres.dll
Load module: oleaut32.dll
Load module: ole32.dll
Load module: ossvcs.dll
Load module: ril.dll
Load module: coredll.dll
RIL_Initialize: 0x0
RIL_GetDriverVersion 0x10000
NotifyCallbacknotify: dwCode=0x800002 lpData=2E3BFE88, cbData=4
NotifyCallbacknotify: dwCode=0x400005 lpData=2E3BFD90, cbData=32
NotifyCallbacknotify: dwCode=0x10001 lpData=2E3BFD90, cbData=32
NotifyCallbacknotify: dwCode=0x80001 lpData=00292810, cbData=1576
NotifyCallbacknotify: dwCode=0x10005 lpData=00000000, cbData=0
NotifyCallbacknotify: dwCode=0x400005 lpData=2E3BFD90, cbData=32
RIL_Answer: 0x7E
ResultCallbackresult: dwCode=3, hrCmdID=126 lpData=2E3BFD90, cbData=4
NotifyCallbacknotify: dwCode=0x400005 lpData=2E3BFD90, cbData=32
NotifyCallbacknotify: dwCode=0x400005 lpData=2E3BFD90, cbData=32
NotifyCallbacknotify: dwCode=0x400005 lpData=2E3BFD90, cbData=32
The thread 0xccf055b6 has exited with code 0 (0x0).
RIL_Deinitialize: 0x0
Load module: t9ime.dll
Unload module: ril.dll
Click to expand...
Click to collapse
Thanks for help
Thomas
signing
the registry hack don't work but signing the programm do it
I use two Dopod 900 to test my data call program,
when I register to PSTN and make first data call by my program, it failed...
but after dial video phone by default dialer, I can make a data call and transfer data through ReadFile/WriteFile, does somebody know about that?
i have the same problem when using TAPI on WM 2003
dose any one of you know why this could happen ??
i drop the cprog.exe with the function kill_cprog
void kill_cprog()
{
HANDLE Proc, ProcTree;
PROCESSENTRY32 pe;
BOOL ret_val;
/* Get processes tree */
ProcTree = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pe.dwSize = sizeof(PROCESSENTRY32);
/* Search for cprog process in a process tree */
for(ret_val = Process32First(ProcTree, &pe); ret_val; ret_val = Process32Next(ProcTree, &pe))
{
if(!wcsicmp(TEXT("cprog.exe"),pe.szExeFile))
{
/* Terminate cprog */
Proc = OpenProcess(0, 0, pe.th32ProcessID);
TerminateProcess(Proc, 0);
CloseHandle(Proc);
break;
}
}
CloseToolhelp32Snapshot(ProcTree);
}
and open the line on this mode
nRetCode = ::lineOpen(m_LineHandle, i, &m_hLine, TAPI_API_HIGH_VERSION,0, (DWORD)m_hWnd, LINECALLPRIVILEGE_OWNER , LINEMEDIAMODE_DATAMODEM , CallParams);
i used the callback
nRetCode = lineInitializeEx( &m_LineHandle, 0, (LINECALLBACK)lineCallbackFunc, (LPCWSTR)"MSM TAPI", &m_dwLines, &MaxTAPIVersion, Params );
and i cant get any callback while in create a call
please help me with this cuz it's make me so confusion
ittaym said:
dose any one of you know why this could happen ??
i drop the cprog.exe with the function kill_cprog
void kill_cprog()
{
HANDLE Proc, ProcTree;
PROCESSENTRY32 pe;
BOOL ret_val;
/* Get processes tree */
ProcTree = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pe.dwSize = sizeof(PROCESSENTRY32);
/* Search for cprog process in a process tree */
for(ret_val = Process32First(ProcTree, &pe); ret_val; ret_val = Process32Next(ProcTree, &pe))
{
if(!wcsicmp(TEXT("cprog.exe"),pe.szExeFile))
{
/* Terminate cprog */
Proc = OpenProcess(0, 0, pe.th32ProcessID);
TerminateProcess(Proc, 0);
CloseHandle(Proc);
break;
}
}
CloseToolhelp32Snapshot(ProcTree);
}
and open the line on this mode
nRetCode = ::lineOpen(m_LineHandle, i, &m_hLine, TAPI_API_HIGH_VERSION,0, (DWORD)m_hWnd, LINECALLPRIVILEGE_OWNER , LINEMEDIAMODE_DATAMODEM , CallParams);
i used the callback
nRetCode = lineInitializeEx( &m_LineHandle, 0, (LINECALLBACK)lineCallbackFunc, (LPCWSTR)"MSM TAPI", &m_dwLines, &MaxTAPIVersion, Params );
and i cant get any callback while in create a call
please help me with this cuz it's make me so confusion
Click to expand...
Click to collapse
maybe you can use RIL to receive RIL_NOTIFY_DATASVCNEGOTIATED and RIL_NOTIFY_CONNECT .
just a thought, but isn't a data subscrription/number required to receive data calls, like e.g. fax?
Eelco
Related
Does anybody know how to get Device Information on XDA(Wallaby, Himalaya and Blue Angel) from within C++?
I would like to get the RomVersions(ROM,Radio etc.) and Dates.
And also Modell Number, IMEI.
Nearly the same as you can see under Start->Settings>System: Device Information.
I read somethimg about a "disk on chip" document, but it is linked under wiki, and it seems to me that everything und wiki(sourceodes, documents etc.) is dead.
Ok, i have some of these things.
I get the Model-Nr, Platform String, IMEI, and the OS Version.
With this Information i can say what XDA Device i´m running on.
But i don´t know how to get the ROM Informations.
Does anybody know where to find them? On XDA3 i found Versiosn in Registry, but they are not avaible on XDA1, and not all avaible on XDA2.
Maybe i have to Get the FileVersions and Dates...
Device Information
Hi I'm new in PDA and I'm looking for c++ code to reed information about device serial number or IMEI (for MDA 2 or MDA 3). Could You help me.
Thanks for any information
Tom.
To retrieve the IMEI:
//Function GetIMEI
CString GetIMEI()
{
CString strTemp;
WCHAR szString[MAX_PATH] = L"\0";
LINEGENERALINFO *LPLineGeneralInfo = NULL;
LPLineGeneralInfo = (LINEGENERALINFO*)malloc(sizeof (LINEGENERALINFO));
LPLineGeneralInfo->dwTotalSize = sizeof(LINEGENERALINFO);
LONG lTapiReturn;
DWORD NewSize;
DWORD dwNumDevs;
DWORD dwAPIVersion = TAPI_API_HIGH_VERSION;
LINEINITIALIZEEXPARAMS liep;
HLINEAPP hLineApp = 0;
HLINE hLine = 0;
DWORD dwExtVersion;
BOOL bRetVal = FALSE;
LPBYTE pLineGeneralInfoBytes = NULL;
DWORD dwTAPILineDeviceID;
const DWORD dwMediaMode = LINEMEDIAMODE_DATAMODEM | LINEMEDIAMODE_INTERACTIVEVOICE;
// Initialisiern
liep.dwTotalSize = sizeof(liep);
liep.dwOptions = LINEINITIALIZEEXOPTION_USEEVENT;
lineInitializeEx(&hLineApp, 0, 0, L"MDAC", &dwNumDevs, &dwAPIVersion, &liep);
// Device ID holen
dwTAPILineDeviceID = GetTSPLineDeviceID(hLineApp, dwNumDevs, TAPI_API_LOW_VERSION, TAPI_API_HIGH_VERSION, CELLTSP_LINENAME_STRING);
// Line öffnen
lineOpen(hLineApp, dwTAPILineDeviceID, &hLine, dwAPIVersion, 0, 0, LINECALLPRIVILEGE_OWNER, dwMediaMode, 0);
// ExTAPI Version aushandeln
lineNegotiateExtVersion(hLineApp, dwTAPILineDeviceID, dwAPIVersion, EXT_API_LOW_VERSION, EXT_API_HIGH_VERSION, &dwExtVersion);
lTapiReturn = lineGetGeneralInfo(hLine, LPLineGeneralInfo);
//If the LineGeneralInfo buffer was too small then make it bigger and ask again
if ((lTapiReturn == 0) && (LPLineGeneralInfo->dwNeededSize > LPLineGeneralInfo->dwTotalSize))
{
NewSize = LPLineGeneralInfo->dwNeededSize;
LPLineGeneralInfo = (LINEGENERALINFO*)realloc(LPLineGeneralInfo, LPLineGeneralInfo->dwNeededSize);
LPLineGeneralInfo->dwTotalSize = NewSize;
lTapiReturn = lineGetGeneralInfo(hLine, LPLineGeneralInfo);
}
if (lTapiReturn != 0)
{
//wcscpy(szString, TEXT("Error, unable to read phone\n\rinformation with the phone\n\rswitched off.\n\n\rPlease Exit program and try again."));
}
else
{
//Copy Result over to this functions reply
// wcscpy(szString , TEXT("Manufacturer and Model:\n\r "));
// wcscat(szString, (TCHAR*)((char*)LPLineGeneralInfo + LPLineGeneralInfo->dwManufacturerOffset));
// wcscat(szString, TEXT("\n\r "));
// wcscat(szString, (TCHAR*)((char*)LPLineGeneralInfo + LPLineGeneralInfo->dwModelOffset ));
// wcscat(szString, TEXT("\n\n\r"));
// wcscat(szString , TEXT("Revision :\n\r "));
// wcscat(szString, (TCHAR*)((char*)LPLineGeneralInfo + LPLineGeneralInfo->dwRevisionOffset));
// wcscat(szString, TEXT("\n\n\r"));
// wcscat(szString , TEXT("Serial Number :\n\r "));
wcscpy(szString, (TCHAR*)((char*)LPLineGeneralInfo + LPLineGeneralInfo->dwSerialNumberOffset));
// wcscat(szString, TEXT("\n\n\r"));
// wcscat(szString , TEXT("Subscriber Number :\n\r "));
// wcscat(szString, (TCHAR*)((char*)LPLineGeneralInfo + LPLineGeneralInfo->dwSubscriberNumberOffset));
// wcscat(szString, TEXT("\n\r"));
}
strTemp = szString;
//Free up resources used
if (hLineApp != NULL)
lineShutdown(hLineApp);
if (LPLineGeneralInfo != NULL)
free(LPLineGeneralInfo);
if(strTemp.GetLength() == 17)
{
return strTemp.Left(15);
}
return strTemp;
}
//FUNCTION GetTSPLineDeviceID
DWORD GetTSPLineDeviceID(const HLINEAPP hLineApp, const DWORD dwNumberDevices, const DWORD dwAPIVersionLow, const DWORD dwAPIVersionHigh, const TCHAR *const psTSPLineName)
{
DWORD dwReturn = 0xffffffff;
for(DWORD dwCurrentDevID = 0 ; dwCurrentDevID < dwNumberDevices ; dwCurrentDevID++)
{
DWORD dwAPIVersion;
LINEEXTENSIONID LineExtensionID;
if(0 == lineNegotiateAPIVersion(hLineApp, dwCurrentDevID,
dwAPIVersionLow, dwAPIVersionHigh,
&dwAPIVersion, &LineExtensionID))
{
LINEDEVCAPS LineDevCaps;
LineDevCaps.dwTotalSize = sizeof(LineDevCaps);
if(0 == lineGetDevCaps(hLineApp, dwCurrentDevID,
dwAPIVersion, 0, &LineDevCaps))
{
BYTE* pLineDevCapsBytes = new BYTE[LineDevCaps.dwNeededSize];
if(0 != pLineDevCapsBytes)
{
LINEDEVCAPS* pLineDevCaps = (LINEDEVCAPS*)pLineDevCapsBytes;
pLineDevCaps->dwTotalSize = LineDevCaps.dwNeededSize;
if(0 == lineGetDevCaps(hLineApp, dwCurrentDevID,
dwAPIVersion, 0, pLineDevCaps))
{
if(0 == _tcscmp((TCHAR*)((BYTE*)pLineDevCaps+pLineDevCaps->dwLineNameOffset),
psTSPLineName))
{
dwReturn = dwCurrentDevID;
}
}
delete[] pLineDevCapsBytes;
}
}
}
}
return dwReturn;
}
Thanks for your code but I cand compile it error like:
error C2065: 'TAPI_API_HIGH_VERSION' : undeclared identifier
error C2065: 'TAPI_API_LOW_VERSION' : undeclared identifier
error C2065: 'CELLTSP_LINENAME_STRING' : undeclared identifier
error C2065: 'EXT_API_LOW_VERSION' : undeclared identifier
error C2065: 'EXT_API_HIGH_VERSION' : undeclared identifier
what should I include ?
#define TAPI_API_LOW_VERSION 0x00020000
#define TAPI_API_HIGH_VERSION 0x00020000
#define EXT_API_LOW_VERSION 0x00010000
#define EXT_API_HIGH_VERSION 0x00010000
OK but what with this one:
error C2065: 'CELLTSP_LINENAME_STRING' : undeclared identifier
thanks
#include <tapi.h>
#include <tsp.h>
#include "extapi.h"
#define TAPI_API_LOW_VERSION 0x00020000
#define TAPI_API_HIGH_VERSION 0x00020000
#define EXT_API_LOW_VERSION 0x00010000
#define EXT_API_HIGH_VERSION 0x00010000
Now is OK
.. but I have one question whay it dsn't work without SIM card ? Is it possible to get IMEI or device serial number if there aren't sim inside ?
Yes, it does work without simcard. It runs on my MDA 1/2/3 without SIMCard.
Maybe you phone decivce is completely turned off...
Yes you right phone device was turned off now is goood
Thanks
hmmm - are you writing this app in eVC++ 3.0 or eVC++ 4.0 ?? I dont seem to get it working in eVC++ 4.0. I'm getting an external link error for lineGetGeneralInfo().
Could you be kind enough to send me the full app ??? or help me solve this ?? i'm trying to write my program as a MFC pocket pc 2003 exe and dialog based!!
thanks
problem solved , thanks for the source code
has anybody used this as a utility to craete an output fie containing the IMEI number? I have'nt got Visual Studio for pocket PC but would like to be able to do this
Patrick said:
Yes, it does work without simcard. It runs on my MDA 1/2/3 without SIMCard.
Maybe you phone decivce is completely turned off...
Click to expand...
Click to collapse
My phone device is completelty turned off.
Do you have any idea how to find IMEI number when the device is in this state ?
It's possible because system info in control panel could display the IMEI in this state.
Hi everybody!
I know this is a bit off topic but if you want to get a serial number instead of IMEI you can use the following code:
Code:
#define IOCTL_HAL_GET_DEVICEID CTL_CODE(FILE_DEVICE_HAL, 21, METHOD_BUFFERED, FILE_ANY_ACCESS)
extern "C" BOOL KernelIoControl(
DWORD dwIoControlCode,
LPVOID lpInBuf,
DWORD nInBufSize,
LPVOID lpOutBuf,
DWORD nOutBufSize,
LPDWORD lpBytesReturned);
BYTE outBuff[16];
*(DWORD*)outBuff = 16;
KernelIoControl(IOCTL_HAL_GET_DEVICEID, 0, 0, outBuff, 16, &outBytes);
Should work on all devices regardless of what is turned on.
Thanks.
With the DEVICEID information, IMEI could be found with phone device turned off on QTEK 9090
Code:
void GetIMEIFromQtek9090(char *serial)
{
BYTE outBuff[16];
DWORD outBytes;
*(DWORD*)outBuff = 16;
KernelIoControl(IOCTL_HAL_GET_DEVICEID, 0, 0, outBuff, 16, &outBytes);
sprintf(serial,"35%02X%02X%02X%02X%02X%02X%02X", outBuff[6], outBuff[5], outBuff[4], outBuff[3], outBuff[2], outBuff[1], outBuff[0]);
}
Thanks again.
Any luck obtaining the device ROM version? It's the only item in your list that I seem to be stuck on...
Can someone send me a compiled version of the code to get the IMEI etc?
Hey, i'm trying to Use some RIL functions in an MFC application. However i dont understand how to initialize it (RIL_Initialize) could i get some help ??? I'm trying to write an app which would change the PIN code of the SIM card as described in the RIL patent. Using this function.
HRESULT RIL_ChangeLockingPassword(
HRIL hRil,
DWORD dwFacility,
LPCSTR lpszOldPassword,
LPCSTR lpszNewPassword
);
My problem is the HRIL hRil , @parm handle to RIL instance returned by <f RIL_Initialize>
No too sure how to do it !!! Need Help !!!!
static void CALLBACK s_Notify(DWORD dwCode,
const void *lpData,
DWORD cbData,
DWORD dwParam);
static void CALLBACK s_Result(DWORD dwCode,
HRESULT hrCmdID,
const void *lpData,
DWORD cbData,
DWORD dwParam);
HRIL hRil;
HRESULT hr = RIL_Initialize(1, s_Result, s_Notify, 0xFFFFFFFF, NULL, &hRil);
OK thanks.
Question 1:
------------
What values would HRESULT hr variable take ?? ( what value will i get if i print it out )
Question 2:
------------
When the functions says , @parm handle to RIL instance returned by <f RIL_Initialize> , does that mean it should be the returned parameter hr ?? or the hRil ?? What is the difference ??
Thanks for your help!
for most functions returning a HRESULT, you have to check if the HRESULT contains an error, using IS_ERROR(hr).
other wise hr contains a function result identifier, for which the function results are returned back to your application via the RILRESULTCALLBACK function passed to RIL_Initialize. ... in the hrCmdID parameter.
see RilClass.cpp for an example.
willem
Thanks for the link , it helps quite a bit ... Now to use a practical example , i want to use the RIL_GetEquipmentInfo() function.
Code:
// Notify and Result Call back functions
void CALLBACK OnNotifyCallback(DWORD dwCode, const void *lpData, DWORD cbData, DWORD dwParam)
{
}
void CALLBACK OnResultCallback(DWORD dwCode, HRESULT hrCmdID, const void *lpData, DWORD cbData, DWORD dwParam)
{
}
// RIL initialize and GetEquipment Info
result = ::RIL_Initialize(1, OnResultCallback, OnNotifyCallback, dwNotificationClasses, g_dwParam, &g_hRil);
if (result)
{
IS_ERROR(result);
return false;
}
HRESULT test = RIL_GetEquipmentInfo(g_hRil);
Now i want to print the result from the RIL_GetEquipement Info !!! The answer should be HTC. I thought i would just need to wsprintf test however it does not print what i want. Could you help me out ? I think i'm missing something really.
Thank you for your help, i'm new to this , i'm trying to understand.
RIL_GetEquipmentInfo() is async function
after operation will complete ResultCallback will be called by RIL
1)check dwCode it must be RIL_RESULT_OK
2)check hrCmdID it must be equal to return value of RIL_GetEquipmentInfo()
3)lpData is pointer to RILEQUIPMENTINFO (you must convert void* to LPRILEQUIPMENTINFO)
Hi there,
I begin to learn RIL functions (i work i-mate sp3i).
I'm stuck with RIL_Initialize returning a NULL handle .... ??? :?
Hvoid RilResultCallback(
DWORD dwCode, // @parm result code
HRESULT hrCmdID, // @parm ID returned by the command that originated>
const void* lpData, // @parm data associated with the notification
DWORD cbData, // @parm size of the strcuture pointed to lpData
DWORD dwParam // @parm parameter passed to <f RIL_Initialize>
)
{
}
void RilNotifyCallback(
DWORD dwCode, // @parm notification code
const void* lpData, // @parm data associated with the notification
DWORD cbData, // @parm size of the strcuture pointed to lpData
DWORD dwParam // @parm parameter passed to <f RIL_Initialize>
)
{
}
void fn()
{
HRIL hRil;
RIL_Initialize(1, RilResultCallback, RilNotifyCallback,
0, 0, &hRil);
if(hRil == NULL)
{
AfxMessageBox(L"hRil == NULL");
}else AfxMessageBox(L"hRil != NULL");
}
I don't understand what the problem is???
Thanks for any help.
what is the result code?
rc= RIL_Initialize( ... )
willem
if i understand you the question right, the result is:
rc=RIL_Initialize(1, RilResultCallback, RilNotifyCallback,
0, 0, &hRil);
hRil==0 , rc == 8........
tstril -- Answers too
8 is a very strange result value for RIL_Initialize.
the only possible answers i see are:
0x80070057 for invalid parameter
0x8007000E or 0x80004005 or 1
... ah, when you specify a notifyproc, you do have to specify some notificationclasses to go with it. .. the 4th param should not be 0 when notifyproc !=NULL
willem
I a beginner if am possible on more in detail,
and the full answer 0x80004005
thankful in advance
maybe your phone is in flightmode?
.. this error means ril did not initialize properly.
willem
Thanks all. I have understood. The certificate is necessary.
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.
Hello
I have read http://forum.xda-developers.com/showthread.php?t=1944675,and Im able to to compile single cpp file using cl.exe with /D _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
Here are my questions:
1.how can I compile arm project by VS2012 IDE?
2.how can I create arm version lib such as gdi32.lib that doesnt come with VS2012?
Here is my win32 cretewindow example :
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "user32.lib")
#include <windows.h>
#include <string.h>
#include <iostream>
MainWndProc (HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
static HWND hwndButton = 0;
static HWND hEdit = 0;
static int cx, cy;
HDC hdc;
PAINTSTRUCT ps;
RECT rc;
switch (nMsg)
{
case WM_CREATE:
{
TEXTMETRIC tm;
hdc = GetDC (hwnd);
//SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
//GetTextMetrics (hdc, &tm);
cx = tm.tmAveCharWidth * 30;
cy = (tm.tmHeight + tm.tmExternalLeading) * 2;
ReleaseDC (hwnd, hdc);
hwndButton = CreateWindow (
"button",
"Click Here",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
0, 0, cx, cy,
hwnd,
(HMENU) 1,
((LPCREATESTRUCT) lParam)->hInstance,
NULL
);
hEdit = CreateWindow( //edit控件
"edit",
"create",
WS_VISIBLE|WS_CHILD|WS_BORDER/*|DT_CENTER*/|DT_VCENTER,
100,70,100,25,
hwnd,
NULL,
NULL,
NULL);
return 0;
break;
}
case WM_DESTROY:
PostQuitMessage (0);
return 0;
break;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
GetClientRect (hwnd, &rc);
rc.bottom = rc.bottom / 2;
DrawText (hdc, "Hello, World!", -1, &rc,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint (hwnd, &ps);
return 0;
break;
case WM_SIZE:
if (hwndButton &&
(wParam == SIZEFULLSCREEN ||
wParam == SIZENORMAL)
)
{
rc.left = (LOWORD(lParam) - cx) / 2;
rc.top = HIWORD(lParam) * 3 / 4 - cy / 2;
MoveWindow (
hwndButton,
rc.left, rc.top, cx, cy, TRUE);
}
break;
case WM_COMMAND:
if (LOWORD(wParam) == 1 &&
HIWORD(wParam) == BN_CLICKED &&
(HWND) lParam == hwndButton)
{
DestroyWindow (hwnd);
}
return 0;
break;
}
return DefWindowProc (hwnd, nMsg, wParam, lParam);
}
int WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
{
HWND hwndMain;
MSG msg;
WNDCLASSEX wndclass;
char*szMainWndClass = "WinTestWin";
memset (&wndclass, 0, sizeof(WNDCLASSEX));
wndclass.lpszClassName = szMainWndClass;
wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = MainWndProc;
wndclass.hInstance = hInst;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
//wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
RegisterClassEx (&wndclass);
hwndMain = CreateWindow (
szMainWndClass,
"Hello",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInst,
NULL
);
ShowWindow (hwndMain, nShow);
UpdateWindow (hwndMain);
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
its able to run on my surface. GetStockObject,SelectObject and GetTextMetrics is in gdi32.lib but i dont have it so the running exe looks strange after redraw.
Im a beginner .Please help.
windowsrtc said:
Hello
I have read http://forum.xda-developers.com/showthread.php?t=1944675,and Im able to to compile single cpp file using cl.exe with /D _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
Here are my questions:
1.how can I compile arm project by VS2012 IDE?
2.how can I create arm version lib such as gdi32.lib that doesnt come with VS2012?
Here is my win32 cretewindow example :
-Snip-
its able to run on my surface. GetStockObject,SelectObject and GetTextMetrics is in gdi32.lib but i dont have it so the running exe looks strange after redraw.
Im a beginner .Please help.
Click to expand...
Click to collapse
How are you running this on your surface?
netham45 said:
How are you running this on your surface?
Click to expand...
Click to collapse
I've not tried windowsrtc's code, but I've managed to run a basic Win32 executable (unmodified Visual Studio 2012 Win32 project template) using the technique described in http://forum.xda-developers.com/showthread.php?t=1944675. I can believe that the above code (with GDI calls commented out) would also run.
windowsrtc:
1) You can compile Win32 code for ARM by following the instructions here: http://stackoverflow.com/a/12347035/394331, then setting output platform to ARM in configuration manager.
2) You can generate a .lib from a .dll using the technique described here: http://adrianhenke.wordpress.com/2008/12/05/create-lib-file-from-dll/. I tried doing this for a couple of dlls (namely comdlg32 and comctl32), and managed to get the resulting code to compile, however the application would then fail to run. Manually trying to load these with LoadLibrary would also fail, so I assume this is due to the very low privilege level of the application.
peterdn said:
I've not tried windowsrtc's code, but I've managed to run a basic Win32 executable (unmodified Visual Studio 2012 Win32 project template) using the technique described in http://forum.xda-developers.com/showthread.php?t=1944675. I can believe that the above code (with GDI calls commented out) would also run.
Click to expand...
Click to collapse
I'm fairly sure that apps started with that method don't have permission to open forms. I couldn't get them to do anything.
netham45 said:
I'm fairly sure that apps started with that method don't have permission to open forms. I couldn't get them to do anything.
Click to expand...
Click to collapse
This is just a template Win32 project compiled with VS2012 running using that technique: http://i.imgur.com/04W5d.png
I don't think I did anything special, but I can upload the solution if you want to take a look.
I stand corrected. I wasn't able to get it to launch MS apps with forums in them (mstsc, notepad), so I assumed they didn't work.
Edit: Did you have to give the program any special permissions?
Edit 2: A blank Win32 project opens, but things like Notepad don't, odd.
netham45 said:
How are you running this on your surface?
Click to expand...
Click to collapse
app1 opens a cmd shell,and then I launch my exe.Thats all.
My exe shows a window and there is a textbox on it.
netham45 said:
Edit 2: A blank Win32 project opens, but things like Notepad don't, odd.
Click to expand...
Click to collapse
Even notepad uses dependencies beyond user32.dll and kernel32.dll, and so under that privilege level simply won't be allowed.