织梦CMS - 轻松建站从此开始!

罗索

Windows mobile/WinCE RAPI教程

落鹤生 发布于 2010-07-01 20:47 点击:次 
Windows CE中有了RAPI以后,PC应用程序就能远程管理Windows CE设备。导出函数将处理文件系统、注册表和数据库以及用于查询系统配置的函数。大多数RAPI是 Windows CE API函数中的副本,只有少数的函数扩展了API。
TAG:

1.RAPI概述

Windows CE中有了RAPI以后,PC应用程序就能远程管理Windows CE设备。导出函数将处理文件系统、注册表和数据库以及用于查 询系统配置的函数。大多数RAPI是 Windows CE API函数中的副本,只有少数的函数扩展了API。

RAPI函数被列在 Windows CE API 参考中,但是将有PC应用程序来调用而不是由 Widows CE应用程序调用。在函数的名称都有前缀Ce来与他们的Window CE的副本进行区分;例如:Windows CE中的函数 GetStoreInformation将在该函数的RAPI版本中称为 CeGetStoreInformation。在Windows CE应用程序将不会调用RAPI函数。

2.初始化RAPI

调用RAPI函数之前,你必须调用函数 CeRapiInit或CeRapiInitEx来初始化 RAPI库。这两个函数的区别在于CeRapiInit会阻塞(等待与Windows CE设备连接成功),而 CeRapiInitEx不会等待连接成功。

这两个函数的原形。
  1. HRESULT CeRapiIni(void); 
  2. HRESULT CeRapiInitEx(RAPIINIT *pRapiInit); 
  3. typedef struct _RAPIINIT  
  4.     DWORD cbSize; 
  5.     HANDLE heRapiInit; 
  6.     STDAPI hrRapiInit; 
  7. } RAPIINIT; 
在调用CeRapiInitEx之前,必须填写cbSize字段。
3.结束RAPI会话

结束所有必要的RAPI调用时,你应该调用 下面这个函数来进行清除:

HRESULT CeRapiUninit(void);

这个函数很好地关闭与远程设备地RAPI通 信。如果RAPI会话没有被初始化

CeRapiUninit将返回 E_FAIL

4.预定义的RAPI函数

RAPI服务包括很多预定义的RAPI函 数,这些在连接时,PC端复制 Windows CE函数。因此,正如GetStoreInformation将把对象存储哭得大小和空间返回到 Windows CE程序,CeGetStoreInformation将把关于连接的Windows CE设备的相同信息返回到基于PC的应用程序。

4.1 RAPI系统信息函数< /span>

大多数函数都是Windows CE函数的 副本,除了CeGetPassWord和 CeRapiInvoke

系统信息函数

函数

描述

CeGetSystemInfo
返回当前系统信息
CeGetSystemMetrics
获取Windows元素的尺寸和系统设置< /span>
CeGetVersionEx
获取当前运行的操作系统版本的扩展信息
CeGetSystemPowerStatusEx
获取电池状态
CeGlobalMemoryStatus
获取系统物理内存和虚拟内存信息
CeGetStoreInformation
获取存储器信息并填入STORE_INFORMATION结构
4.2 RAPI文件和目录管理函数

下面的列表显示的是RAPI文件管理函数, 这个列表说明几乎所有可用于 Windows CE应用程序的文件函数都可以用于基于PC的程序。< /span>

函数

描述

CeCopyFile
复制文件
CeCreateDirectory
创建目录
CeCreateFile
创建,打开文件、管道、通讯资源、磁盘设备或者控制台。返回一个句柄用来访问对象。
CeDeleteFile
删除文件
CeFindAllFiles
从指定的Windows CE目录中获取所有文件和目录的信息,并且复制到一个包含CE_FIND_DATA结构的数组中
CeFindFirstFile
在目录中查找匹配给定文件名的一个文件
CeFindClose

关闭指定的查找句柄,CeFindFirstFile和CeFindNextFile 函数用这个句柄查找文件

CeFindNextFile
从上一次访问的CeFindFirstFile继续查找文件
CeGetFileAttributes
返回指定文件或目录的属性
CeGetFileSize
获取指定文件的字节大小
CeGetFileTime
获取文件创建日期时间,最后访问日期时间和最后修改日期时间< /span>
CeMoveFile
移动(重命名)一个文件或者目录
CeReadFile
从文件指针处读取文件数据
CeWriteFile
从文件指针处写入文件数据
表内有一个新函数CeFindAllFiles,它对Windows CE 应用程序不可用。
原型:
BOOL CeFindAllFiles (LPCWSTR szPath, DWORD dwFlags,LPDWORD lpdwFoundCount,LPLPCE_FIND_DATA ppFindDataArray);

设计CeFindAllFiles 是为了增强性能,只需调用它一次就能返回给定目录的所有文件,而不需要使用 CeFindFirstFile和CeFindNextFile来重复RAPI的调用。

具体参数参考SDK…

4.3 RAPI 数据库函数

下面的列表中显示的是RAPI数据库函数。 这些函数模拟了在Windows CE中找到的扩展数据库API

数据库函数
CeCreateDatabase 
CeOpenDatabaseEx 
CeCreateDatabaseEx 
CeReadRecordProps 
CeDeleteDatabase 
CeReadRecordPropsEx 
CeDeleteDatabaseEx 
CeSeekDatabase 
CeDeleteRecord 
CeSetDatabaseInfo 
CeFindFirstDatabase 
CeSetDatabaseInfoEx 
CeFindFirstDatabaseEx 
CeWriteRecordProps 
CeFindNextDatabase 
CeMountDBVol 
CeFindNextDatabaseEx 
CeUnmountDBVol 
CeOidGetInfo 
CeEnumDBVolumes 
CeOidGetInfoEx 
CeFindAllDatabases 
CeOpenDatabase 
 

几乎所有的数据库函数都有 Windows CE副本。唯一的例外的是新函数CeCreateDatabase

像CeFindAllFiles一样,设计这个函数也是为了增强性能。
函数原型:
BOOL CeFindAllDatabases (DWORD dwDbaseType, WORD wFlags,LPWORD cFindData,LPLPCEDB_FIND_DATA ppFindData);
具体参数参考SDK…
RAPI注册表管理函数

这些函数与它们的Windows CE副本 的工作方式一样,但是,要记住所有的字符串都是Unicode格式。

4.4 其 他的API函数< /span>

可以说Windows CE上的功能,通过 RAPI都能实现,我在这里不可能不一一列举了。

电量显示函数
STDAPI_(BOOL) CeGetSystemPowerStatusEx
(
  PSYSTEM_POWER_STATUS_EX pstatus
  BOOL fUpdate 
);
创建进程,就是可以打开CE上的应用程序
CeCreateProcess
窗体管理函数
窗体管理函数
CeGetWindow 
CeGetWindowText 
CeGetWindowLong 
CeGetClassName 
5.Pget例子程序

编写RAPI应用程序需要加 RAPI.h 和 RAPI.lib

在EVC4.0下设置方法:

[Tools]\[Options]\[Directories]进 行设置他们的目录。< /span>

在VSS2005下的设置方法:< /span>

[Tools]\[Options]\[Projects and Solutions][VC++ Directories ]

下面时.h文件lib的存放目录。< /span>

C:\Program Files\Windows CE Tools\wce420\POCKET PC 2003\Activesync\Inc
C:\Program Files\Windows CE Tools\wce420\POCKET PC 2003\Activesync\Lib
C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0 Pocket PC SDK\Activesync\Inc
C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0 Pocket PC SDK\Activesync\Lib
这个程序是SDK的例子代码
具体路径
PPC2003  和 WM5 PPC
C:\Program Files\Windows CE Tools\wce420\POCKET PC 2003\Samples\Win32\Rapi\Pget
C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0 Pocket PC SDK\Samples\CPP\Win32\Rapi\Pget
WM5 SP
C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0 Smartphone SDK\Samples\CPP\Win32\Rapi\Pget

这个程序是从小机器上复制文件到PC的控制 台应用程序。< /span>

代码部分就不具体写出了。只说明一下流程< /span>

复制文件的命令是;
Pget  <CE源文件>   <PC目的文件>
1. CeRapiInit()进行初始化。
2. CeFindFirstFile()来判断CE端是否存在该文件。< /span>
3. CeCreateFile()来打开CE端的文件。
4. CreateFile()来创建PC端的复制到的文件。< /span>
5. CeReadFile()把CE的文件读到缓存区里。< /span>
6. WriteFile()把缓存区里的数据保存到PC端。< /span>
7. CeCloseHandle()和CloseHandle()关闭CE和PC上的文件句柄。< /span>

8. 最 后调用CeRapiUninit(); 进行清楚。< /span>

下面的这张截图就是把CE端的 “\battery.png” 复制到 PC上的“c:\test.png”文件中。

6.自定义RAPI函数

无论RAPI接口支持多少函数,总会出现一 些应用程序需要的但RAPI接口没有提供的函数。RAPI为 PC提供一种方法去调用 Windows CE上的用户定义的函数。< /span>

你可以使用两种方法来调用用户定义的函数。 一种是“阻塞模式”,另一种是“流模式”< /span>

下面这段是它的英文介绍。
You can invoke a user-defined RAPI function in one of two ways. The first way is called block mode. In block mode, you make a call to the RAPI remote invocation function, the function makes the call to a specified function in a specified DLL, the DLL function does its thing and returns, and the RAPI function then returns to the calling PC program with the output. The second method is called stream mode. In this mode, the RAPI call to the function returns immediately, but a connection is maintained between the calling PC application and the Windows CE DLL–based function. This method allows information to be fed back to the PC on an ongoing basis.

6.1 使 用RAPI调用自定义函数。< /span>

CeRapiInvoke将 允许我们调用远程设备中的任何API函数!不过不是直接调用,仍然需要对远程API 进行一些“包装”。

CeRapiInvoke的 原型如下:

STDAPI_( HRESULT ) CeRapiInvoke(
    LPCWSTR pDllPath,                      //  包含API的Dll文件完整路径
    LPCWSTR pFunctionName,         //  要调用的函数名
    DWORD cbInput,                           //  函数输入缓冲区大小
    BYTE * pInput,                               //  函数输入缓冲区指针
    DWORD * pcbOutput,                  //  函数输出缓冲区大小
    BYTE ** ppOutput,                       //  函数输出缓冲区指针
    IRAPIStream ** ppIRAPIStream,  //  指定使用阻塞模式或流模式
    DWORD dwReserved);                //  保留

下面这段英文是它的详细介绍
The first parameter to CeRapiInvoke is the name of the DLL on the Windows CE device that contains the function you want to call. The name must be in Unicode but can include a path. If no path is specified, the DLL is assumed to be in the \windows directory on the device. The second parameter is the name of the function to be called. The function name must be in Unicode and is case specific.
The next two parameters, cbInput and pInput, should be set to the buffer containing the data and the size of that data to be sent to the Windows CE–based function. The input buffer should be allocated in the local heap of the application. When you call CeRapiInvoke, this buffer will be freed by the function. The pcbOutput and ppOutput parameters are both pointers—the first a pointer to a DWORD that receives the size of the data returned and the second a pointer to a PBYTE variable that receives the pointer to the buffer containing the data returned by the Windows CE function. The buffer returned by CeRapiInvoke is allocated by the function in your local heap. You&apos;re responsible for freeing this buffer.

6.2 编 写RAPI服务器函数(CE端的DLL中的函数)

你不能调用 Windows CE DLL 中的所有函数。函数结构必须符合下面的函数原型

STDAPI INT FuncName (DWORD cbInput, BYTE *pInput, DWORD *pcbOutput,
                     BYTE **ppOutput, IRAPIStream *pIRAPIStream);
这些参数与CeRapiInvoke非常匹配。

6.3 阻 塞模式的例子代码< /span>

CE端 的DLL程序。

RapiServ.c

 

  1. //=================================================================== 
  2. #include <windows.h>                 // For all that Windows stuff 
  3.     
  4. // The following ensures that the function will be exported from the DLL 
  5. // and that any C++ compilers used won&apos;t mangle the name. 
  6. #ifdef __cplusplus 
  7. extern "C" { 
  8. #endif 
  9. __declspec (dllexportINT RAPIGetDiskSize (DWORDBYTE *, DWORD *, 
  10.                                             BYTE **, PVOID); 
  11. #ifdef __cplusplus 
  12. #endif 
  13. //=================================================================== 
  14. // DllMain - DLL initialization entry point 
  15. BOOL WINAPI DllMain (HANDLE hinstDLL, DWORD dwReason, 
  16.                      LPVOID lpvReserved) { 
  17.     return TRUE; 
  18. //=================================================================== 
  19. // RAPIGetDiskSize - Returns the disk size and free space.  Called from 
  20. // PC application using RAPI. 
  21. // 
  22. INT RAPIGetDiskSize (DWORD cbInput, BYTE *pInput, DWORD *pcbOutput, 
  23.                      BYTE **ppOutput, PVOID reserved) { 
  24.     PDWORD pdwLocal; 
  25.     LPTSTR pPtr; 
  26.     DWORD i; 
  27.     int rc = 0; 
  28.     ULARGE_INTEGER lnFree, lnTotal; 
  29.     
  30.     *pcbOutput = 0;            // Zero output bytes for now. 
  31. if (!pInput) return –1;    // Make sure there is an input buffer. 
  32.     // 判断是否已零结束的字符串 
  33.     pPtr = (LPTSTR)pInput; 
  34.     for (i = 0; i < cbInput / 2; i++) 
  35.         if (!*pPtr++) 
  36.             break
  37.     // 如果是非零结束或字符串长度等于零返回-2 
  38. if ((i >= cbInput / 2) || (i == 0))  
  39.         LocalFree (pInput); 
  40.         return -2; 
  41.     } 
  42.     
  43.     // 调用GetDiskFreeSpaceEx函数 
  44.     if (GetDiskFreeSpaceEx ((LPTSTR)pInput, NULL, &lnTotal, &lnFree)) { 
  45.     
  46.         // Allocate memory for the return buffer. 
  47.         pdwLocal = (PDWORD) LocalAlloc (LPTR, 2 * sizeof (DWORD)); 
  48.         if (pdwLocal) { 
  49.             // Copy data from function to output buffer. 
  50.             pdwLocal[0] = lnTotal.LowPart; 
  51.             pdwLocal[1] = lnFree.LowPart; 
  52.             // Specify size and buffer. 
  53.             *pcbOutput = 2 * sizeof (DWORD); 
  54.             *ppOutput = (PBYTE)pdwLocal; 
  55.         } else 
  56.             rc = GetLastError(); 
  57.     } else 
  58.         rc = GetLastError(); 
  59.     // The function is responsible for freeing the input buffer. 
  60.     LocalFree (pInput); 
  61.     return rc; 
  62. __declspec (dllexportINT RAPIGetDiskSize(… 

告诉链接程序已导出的山数,这样 外部模块就可以直接调 用这个函数。

  RAPIGetDiskSize的输入缓冲区被用来将目录名称传递到DLL,而输出缓冲区将返回传递的目录的总的磁盘空间和自由空间。输入和输出缓冲区的格式完全由 你决定,然而,输入缓冲区应使用 LocalAlloc来分配,这样RAPI库可以在它使用完后释放它。

   在PC端,调用堵塞模式RAPI服务器函数应像下 面这样。

 

  1. // MyCeGetDiskFreeSpaceEx - Homegrown implementation of a RAPI 
  2. // GetDiskFreeSpace function
  3. BOOL MyCeGetDiskFreeSpaceEx (LPWSTR pszDir, PDWORD pdwTotal, 
  4. PDWORD pdwFree) { 
  5.     HRESULT hr; 
  6.     DWORD dwIn, dwOut; 
  7.     LPBYTE pInput; 
  8.     LPWSTR pPtr; 
  9.     PDWORD pOut; 
  10.     BOOL bRC = FALSE; 
  11.     
  12.     // Get length of Unicode string. 
  13.     for (dwIn = 2, pPtr = pszDir; *pPtr++; dwIn+=2); 
  14.     // Allocate buffer for input. 
  15.     pInput = LocalAlloc (LPTR, dwIn); 
  16.     if (!pInput) 
  17.         return FALSE; 
  18.     // Copy directory name into input buffer. 
  19.     memcpy (pInput, pszDir, dwIn); 
  20.     
  21.     // Call function on Windows CE device. 
  22.     hr = CeRapiInvoke (L"RapiServ", L"RAPIGetDiskSize", dwIn, 
  23.                        pInput, &dwOut, (PBYTE *)&pOut, NULL, 0); 
  24.     
  25.     // If successful, return total and free values. 
  26.     if (hr == 0) { 
  27.         *pdwTotal = pOut[0]; 
  28.         *pdwFree = pOut[1]; 
  29.         bRC = TRUE; 
  30.     } 
  31.     LocalFree (pOut); 
  32.     return bRC; 

这个函数封装拉对CeRapiInvoke的调用,这样该调用看起来就像另一个 Windows CE RAPI调用。当函数返回时,由返回代码指出调用的 成功或失败。CeRapiInvoke将释放传递给它的输入缓冲区。然后从输入缓冲区复制这些数据,并且那个缓冲区将用LocalFree()来释放。

6.4 流模式

流模式RAPI调用与阻塞模式不同,在流模式中,初始化RAPI调用将创建PC应用程序与Windows  CE设备上的服务器程序之间的链接。当在流模式中调用CeRapiInvoke时,这个函数将立即返回。你此时使用IRAPIStream接口来与服务器 DLL通信。你可以使用一个指针访问这个接口,该指针由CeRapiInvoke调用在由ppIRAPIStream指向的变量中返回。

Following is a call to CeRapiInvoke that establishes a stream connection and then writes and reads back 10 bytes from the remote server DLL.

 

  1. DWORD dwIn, dwOut, cbBytes; 
  2. IRAPIStream *pIRAPIStream; 
  3. BYTE bBuff[BUFF_SIZE]; 
  4. PBYTE pOut; 
  5. HRESULT hr; 
  6.     
  7. // RAPI call 
  8. hr = CeRapiInvoke (L"ServDLL", L"RAPIRmtFunc", dwIn, bBuff, 
  9.                    &dwOut, &pOut, &pIRAPIStream, 0); 
  10. if (hr == S_OK)  
  11.     // Write 10 bytes. 
  12.     pIRAPIStream->Write (bBuff, 10, &cbBytes); 
  13.     // Read data from server. 
  14.     pIRAPIStream->Read (bBuff, 10, &cbBytes); 
  15. pIRAPIStream->Release (); 
When establishing a stream connection, you can still use the input buffer to pass initial data down to the remote server.
From then on, you should use the Read and Write methods of IRAPIStream to communicate with the server. 
When you&apos;re finished with the IRAPIStream interface, you must call Release to release the interface.
(jinhaijian)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201007/9763.html]
本文出处:CSDN博客 作者:jinhaijian
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容