This function can be used as a general-purpose mechanism to remotely execute a routine on a remote Microsoft® Windows® CE-based device.
HRESULT CeRapiInvoke( LPCWSTR pDllPath, LPCWSTR pFunctionName, DWORD cbInput, BYTE * pInput, DWORD * pcbOutput, BYTE ** ppOutput, IRAPIStream ** ppIRAPIStream, DWORD dwReserved );
[in] Pointer to a string buffer containing the name of a DLL that is on the Microsoft® Windows® CE-based device and that contains the function identified in pFunctionName.
[in] Pointer to a string buffer containing the name of the function that RAPI should call on the Windows CE-based device.
[in] Number of bytes in the input buffer *pInput.
[in] Pointer to a buffer containing the input data.
[out] Pointer to a variable that is set to the number of bytes in the output buffer ppOutput when the function returns.
[out] Pointer to a variable that is set to the location of the output buffer upon return.
[in, out] The ppIRAPIStream parameter specifies block mode or stream mode. Select block mode by supplying the value NULL. Select stream mode by supplying a valid pointer to a variable of type IRAPIStream; this IRAPIStream interface can be used for a direct transfer of data. If ppIRAPIStream is not NULL, the pFunctionName parameter on the Windows CE-based device will be passed a pointer to the IRAPIStream interface.
If RAPI services on the Windows CE-based device successfully locate and call the client function, then in Block Mode the return value is that which is returned on the Windows CE-based device by the called function. In Stream Mode, the return value is S_OK. If the function was not called successfully, or an exception occurred during its execution, an error code is returned.
The CeGetLastError function can be used to get the error code, which takes the value set by pFunctionName, including the following values:
The LoadLibrary pDllPath call failed on the device.
The GetProcAddress of pFunctionName call on the device failed.
An exception occurred during execution of pFunctionName.
CeRapiInvoke loads the device-side DLL named in pDllPath, then calls the RAPI extension named in pFunctionName. It is the responsibility of the RAPI extension to release the IRAPIStream object (that is, to call pIRAPIStream->Release();).
An application should allocate memory for the pInput parameter with the LocalAlloc function. The caller is responsible for freeing pInput. The system allocates memory for the ppOutput parameter. When the application is completed with the buffer, it should free the memory with the LocalFree function.
The CeRapiInvoke function operates in either block mode or stream mode. In block mode, the caller passes the data in a single buffer as an input parameter and receives the response in a single buffer as an output parameter. This is a synchronous call, thus all input or output data must be present in memory at the time of the call. In stream mode, the CeRapiInvoke function returns a pointer to an IStream type interface that can be used to exchange arbitrary sized data in any order and direction. In this mode, the caller can still pass data in a single buffer as an input parameter, but from that point on all data should be exchanged by means of the stream. Thus the data can be read, written, and stored in chunks. Streaming is significantly faster than block mode.
The ppIRAPIStream parameter specifies block mode or stream mode. Select block mode by supplying the value NULL. Select stream mode by supplying a valid pointer to a variable of type IRAPIStream; this IRAPIStream interface can be used for a direct transfer of data. If ppIRAPIStream is not NULL, the pFunctionName parameter on the Windows CE device will be passed a pointer to the IRAPIStream interface.
The IRAPIStream ** definition is based on IStream and has been expanded by two new methods to allow the setting of timeouts. These methods, IRAPIStream::SetRapiStat and IRAPIStream::GetRapiStat, are modeled ** after the IStream::Stat method.
The IRAPIStream object does not guarantee the reception of data by the device. It is up to your application to implement application-level ACK. The device application should send an acknowledgement code after it has succeeded in reading all of the data from the stream. After the desktop application has written to the stream, it should wait until it receives the acknowledgement code from the device application before it releases the stream.
Note In previous releases, this method could be used to obtain a handle to objects on the remote device that could be used by other RAPI method calls, such as CeWriteRecordProps. Starting with Windows® CE version 5.01, RAPI method calls will fail if a handle retrieved by this method is used. Database and registry key handles should be obtained by using the CeOpenDatabaseEx and CeRegOpenKeyEx RAPI methods.
As of Windows Mobile Version 5.0, the Remote Access Security Policy on Smartphone and Pocket PC is set to Restricted by default. These devices are considered "Locked," which prevents you from using CeRapiInvoke to invoke device-side DLLs — unless you take extra steps to satisfy the requirements of the Remote Access Security Policy. For more information on RAPI security, see Security for Windows Mobile-based Devices.
Note Although still locked, CeRapiInvoke is permitted on the non-phone version of Pocket PC.
CeRapiInvoke gives elevated privileges to any DLL that can be invoked on the mobile device.
RAPI security policies are set in the project.reg configuration file.
Follow this procedure if you successfully used CeRapiInvoke in the past, and it now fails under the Windows Mobile 5.0 Remote Access Security Policy.
To satisfy the requirements of the Remote Access Security Policy
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"/> <!-- 152 maps to "CARRIER_TPS | USER_AUTH | MANAGER" --> </characteristic> </characteristic> </wap-provisioningdoc>
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.
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.
Pocket PC: Pocket PC 2002 and later
Smartphone: Smartphone 2002 and later
OS Versions: Windows CE 3.0 and later
Send Feedback on this topic to the authors