我個人一直覺得這不是一個合理的設計。比如就我們的設備而言,雖然正式的產品不支持ActiveSync,但是由於有些第三方driver只能通過ActiveSync安裝,所以有的時候還不能不用。麻煩在於我們的設備只能作USB host,不能作USB device,USB連接不能用;Serial port也只有一個,已經被用作debug輸出,也不能用。這種情況下,要支持ActiveSync只能用Ethernet連接。
這篇文章要介紹的是在serial和USB連接都不能用的情況下,如何直接建立Ethernet連接。這個問題其實等價於如何在設備和主機之間建立一個合法的partnership。有了partnership,設備和主機以後就可以直接通訊了。從實現上來看,partnership是一些存在設備端和主機端的註冊表配置,設備端和主機端程序利用這些配置信息進行認證和同步。以下是建立partnership的一些步驟:
1,在設備端創建註冊表。其中PName爲你要連接的主機名,PId可以自己指定一個,和別人的不衝突就行,比如可以通過網卡的MAC地址算出一個來。
"PCur"=dword:00000001
"Connectoid"="Network Connection"
"AutoDisc"=dword:00000000
[HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows CE ServicesPartnersP1]
"PName"="sting"
"PId"=dword:67454d7f
[HKEY_LOCAL_MACHINEWindows CE ServicesSynchronizationObjectsFile]
"Store"="cefobj.dll"
2,在主機端配置註冊表。主機端partnership的大致註冊表配置在網上可以找到,比如這兒就有一份。當然那些不能直接拿來用,還必須修改一些設備特定的設置。經過簡單的研究,我發現ActiveSync的主機端程序在TCP端口5679上監聽,設備端發起Ethernet連接請求時會把這些設置信息在一個packet裏發過來。主機端則根據這些信息對設備進行認證,通過後建立連接。packet格式經分析如下:
DWORD unused; // +00
DWORD dwPacketSize; // +04, =sizeof(packet)+4
DWORD cbSize; // +08, 0x00000024
union {
DWORD dwOSVersion; // +0c
struct {
BYTE bMajorVer;
BYTE bMinorVer;
WORD wBuildNumber;
};
};
DWORD dwProcessorType; // +10,
DWORD dwFlags; // +14
DWORD PId1; // +18
DWORD PId2; // +1c
DWORD dwOffsetDevName; // +20, 0x00000024
DWORD dwOffsetDevType; // +24
DWORD dwOffsetOemInfo; // +28
// WCHAR pDevName[];
// WCHAR pDevType[];
// WCHAR pOemInfo[];
};
有了這個packet的數據,我們就可以在主機端建立partnership了。首先要在主機端手工建立一個Data Folder,比如我的主機名爲sting,設備名爲MoonNight,則Data Folder爲:
C:/Documents and Settings/sting/Application Data/Microsoft/ActiveSync/Profiles/MoonNight
要配置的註冊表大約有這麼幾項:
$PARTNERID$ =PId1
$DISPLAY_NAME$ = pSyncPacket+sizeof(SyncPacket)+dwOffsetDevName)
$DEVICE_TYPE$ = pSyncPacket+sizeof(SyncPacket)+dwOffsetDevType)
$OEM_INFO$ = pSyncPacket+sizeof(SyncPacket)+dwOffsetOemInfo)
$PROCESSOR_TYPE$=dwProcessorType
$PARTNER_PROFILE_PATH$=Data Folder路徑
"ConnectTypesAllowed"=dword:00000004
[HKEY_CURRENT_USER/Software/Microsoft/Windows CE Services/Partners/$PARTNERID$]
"Schedule Option"=dword:00000000
"DisplayName"="$DISPLAY_NAME$"
"DeviceType"="$DEVICE_TYPE$"
"Description"=""
"DataFolder"="$PARTNER_PROFILE_PATH$"
"Processor"=""
"ProcessorType"=dword:$PROCESSOR_TYPE$
"OemInfo"="$OEM_INFO$"
"TotalSize"=dword:00000000
"Version"=dword:038c0a04
"Capabilities"=dword:00000110
"ServerMajor"=dword:00000000
"ServerMinor"=dword:00000000
"PimsInstalled"=dword:00000000
這種方法也有一些侷限性。一個是ActiveSync在4.0版本以後就不再支持Ethernet連接了,因此要用這種方法只能裝ActiveSync 3.7或3.8。還有一個,如果你打了Windows CE 5.0的2005 Q2 patch,Ethernet也不能正常工作。原因是這個patch改了一些ActiveSycn的bug的同時又導入了一個愚蠢的bug-repllog.exe在調用socket API前沒有用WSAStartup進行初始化!真是令人FT。微軟的同志們看到這篇文章的趕緊叫你們的WinCE Team改BUG啊。
鑑於ActiveSync現在已經不再直接支持Ethernet,這個問題比較理想的解決方案其實是利用虛擬串口-在設備端和主機端各虛擬出一個串口,ActiveSync程序連接到虛擬串口,虛擬串口再通過網絡和另外一端進行通信。PC上的虛擬串口轉Ethernet的軟件很多,這兒就有一個免費的。CE上的虛擬串口轉Ethernet的免費軟件我沒找到,不想花錢的話可能需要自己寫一個。