Bài viết này hướng dẫn cách sử dụng RAPI (Remote Application Programming Interface) để giao tiếp giữa máy tính Windows và thiết bị Windows CE. RAPI cung cấp các hàm API cho phép truy cập và điều khiển thiết bị di động từ máy tính để bàn.
Để triển khai, chúng ta cần sử dụng thư viện rapi.dll và khai báo các cấu trúc cần thiết. Trong ví dụ này, đường dẫn thư viện động là: C:/WINDOWS/system32/rapi.dll. Thay vì sử dụng file header rapi.h, chúng ta sẽ tự định nghĩa các cấu trúc cần thiết như RAPIINIT và sử dụng GetProcAddress() để tải các hàm từ DLL.
- Khởi tạo RAPI
BOOL CRemoteDevice::InitializeRAPI()
{
TCHAR szDllPath[MAX_PATH + 10];
GetSystemDirectory(szDllPath, MAX_PATH);
CString strFullPath(szDllPath);
strFullPath += _T("\\Rapi.dll");
HMODULE hModule = LoadLibrary(strFullPath);
if(hModule != NULL)
{
pfnCeRapiInitEx = (RAPI_INIT_EX)GetProcAddress(hModule, "CeRapiInitEx");
pfnCeRapiUninit = (RAPI_UNINIT)GetProcAddress(hModule, "CeRapiUninit");
pfnCeCreateFile = (CE_CREATE_FILE)GetProcAddress(hModule, "CeCreateFile");
pfnCeWriteFile = (CE_WRITE_FILE)GetProcAddress(hModule, "CeWriteFile");
pfnCeCloseHandle = (CE_CLOSE_HANDLE)GetProcAddress(hModule, "CeCloseHandle");
pfnCeFindFirstFile = (CE_FIND_FIRST)GetProcAddress(hModule, "CeFindFirstFile");
pfnCeGetFileSize = (CE_GET_FILE_SIZE)GetProcAddress(hModule, "CeGetFileSize");
pfnCeReadFile = (CE_READ_FILE)GetProcAddress(hModule, "CeReadFile");
pfnCeFindNextFile = (CE_FIND_NEXT)GetProcAddress(hModule, "CeFindNextFile");
pfnCeCreateDirectory = (CE_CREATE_DIR)GetProcAddress(hModule, "CeCreateDirectory");
pfnCeCreateProcess = (CE_CREATE_PROC)GetProcAddress(hModule, "CeCreateProcess");
pfnCeGetSystemInfo = (CE_GET_SYS_INFO)GetProcAddress(hModule, "CeGetSystemInfo");
return TRUE;
}
return FALSE;
}
- Thiết lập kết nối với thiết bị
BOOL CRemoteDevice::EstablishConnection()
{
RAPIINIT initStructure;
DWORD dwWaitStatus = 0;
HRESULT hrResult = S_FALSE;
if(m_bInitialized == FALSE)
{
initStructure.cbSize = sizeof(RAPIINIT);
initStructure.hrRapiInit = S_FALSE;
initStructure.heRapiInit = NULL;
hrResult = pfnCeRapiInitEx(&initStructure);
dwWaitStatus = WaitForSingleObject(initStructure.heRapiInit, 3000);
if(hrResult == S_OK && initStructure.hrRapiInit == S_OK &&
dwWaitStatus != WAIT_TIMEOUT)
{
m_bInitialized = TRUE;
return TRUE;
}
return FALSE;
}
return TRUE;
}
- Truyền file từ PC sang thiết bị
BOOL CRemoteDevice::UploadFileToDevice(CString strPCPath, CString strDevicePath)
{
CFile fileSource;
HANDLE hDestFile;
BYTE pBuffer[CHUNK_SIZE];
DWORD dwBytesWritten = 0;
long lFileSize = 0;
long lChunks = 0;
long lRemainder = 0;
long lIndex = 0;
if(!fileSource.Open(strPCPath, CFile::modeRead | CFile::typeBinary))
{
return FALSE;
}
lFileSize = fileSource.GetLength();
lChunks = lFileSize / CHUNK_SIZE;
lRemainder = lFileSize % CHUNK_SIZE;
BSTR bstrDevicePath = strDevicePath.AllocSysString();
SysFreeString(bstrDevicePath);
hDestFile = pfnCeCreateFile(bstrDevicePath,
GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hDestFile == INVALID_HANDLE_VALUE)
{
fileSource.Close();
return FALSE;
}
for(lIndex = 0; lIndex < lChunks; lIndex++)
{
memset(pBuffer, 0, CHUNK_SIZE);
if(fileSource.Read(pBuffer, CHUNK_SIZE) > 0)
{
pfnCeWriteFile(hDestFile, pBuffer, CHUNK_SIZE, &dwBytesWritten, NULL);
}
}
memset(pBuffer, 0, CHUNK_SIZE);
if(fileSource.Read(pBuffer, lRemainder) > 0)
{
pfnCeWriteFile(hDestFile, pBuffer, lRemainder, &dwBytesWritten, NULL);
}
pfnCeCloseHandle(hDestFile);
fileSource.Close();
pfnCeRapiUninit();
return TRUE;
}