2009年12月16日 星期三

如何在Windows Mobile 6上使用cmd.exe

1. 下載"WindowsMobilePowerToys.msi", 可以在 Microsoft Download Center中找到.
http://www.microsoft.com/downloads/details.aspx?familyid=74473FD6-1DCC-47AA-AB28-6A2B006EDFE9&displaylang=en

2. 安裝WindowsMobilePowerToys.msi在PC上.

3. 在PC上的路徑下
C:\Program Files\Windows Mobile Developer Power Toys\PPC_Command_Shell\arm
可以看到3個檔案, 1)cmd.exe, 2)console.dll, 3)shell.exe

4. 將console.dll copy 到Device的\Windows下

5. copy cmd.exe, shell.exe到Device你想要的目錄下
P.S. Shell.exe似乎不一定需要

6. 設Registry:
[HKEY_LOCAL_MACHINE\Drivers\Console]
"OutputTo"=dword:0
P.S. 如果是在PocketPC2003不需要設此Registry

7. 執行cmd.exe即可
P.S. 原先WindowsMobilePowerToys是提供給PocketPC2003,所以畫面很小

2009年9月8日 星期二

查詢連線狀態

1. 利用ConnMgrQueryDetailedStatus查詢所有連線
char szBuf[4096]; //一次給4096比較充足,就不需要qurey2次
DWORD dwSize = 0;
CONNMGR_CONNECTION_DETAILED_STATUS *pDetailStatus = (CONNMGR_CONNECTION_DETAILED_STATUS*) szBuf;
HRESULT hRet = S_FALSE;
int idx = 0;
dwSize = sizeof(szBuf);
hRet = ConnMgrQueryDetailedStatus(pDetailStatus, &dwSize);
if(S_OK != hRet)
{
_tprintf( _T("\n Fail to query detailed status"));
return;
}
while( TRUE )
{
TCHAR wszDestGUID[18] = {0};
unsigned char szGUID[8] = {0};
memcpy(szGUID, pDetailStatus->guidDestNet.Data4, 8);
int nDigit[16];
memset(nDigit, 0, sizeof(int) * 16);
int j = 0;

這裡是因為我當初要去抓GUID,GUID有4個data,第4個data是byte, 4個bit一個數字,16進位的數字.
pDetailStatus->guidDestNet--每一組連線都有一組GUID值,連線相關資訊亦會儲存在
HKEY_LOCAL_MACHINE\Comm\ConnMgr\Providers\{EF097F4C-DC4B-4c98-8FF6-AEF805DC0E8E}\{XXXXX......}之下.
取得目前連線中的GUID,可以反推回去,取得連線中的proxy值,ConnMgrQueryDetailedStatus無法取得proxy,但連線至網際網路時,若有proxy必須設定proxy.

for(int i = 0; i < 8; i++)
{
int nDigit1, nTemp;
nDigit1 = szGUID[i] >> 4;
nTemp = nDigit1 << 4;
int nDigit2 = szGUID[i] - nTemp;
nDigit[j] = nDigit2; nDigit[j+1] = nDigit1; j = j + 2;
}
for(int n = 1; n < 16; n = n + 2)
{
TCHAR szTemp[1];
wsprintf(szTemp, _T("%X"), nDigit[n]);
wcscat(wszDestGUID, szTemp);
wsprintf(szTemp, _T("%X"), nDigit[n-1]);
wcscat(wszDestGUID, szTemp);
if(n == 3)
wcscat(wszDestGUID, _T("-"));
}
TCHAR szTemp[MAX_PATH];
wsprintf(m_wszDestGUID, _T("%02X-%02X-%02X-%s"), pDetailStatus->guidDestNet.Data1, pDetailStatus->guidDestNet.Data2, pDetailStatus->guidDestNet.Data3, wszDestGUID);
wcscpy(m_wszCurrConnectKey, TEXT("Comm\\ConnMgr\\Providers\\{EF097F4C-DC4B-4c98-8FF6-AEF805DC0E8E}\\"));
wcscpy(szTemp, _T("HTTP-{"));
wcscat(szTemp, m_wszDestGUID);
wcscat(szTemp, _T("}"));
wcscat(m_wszCurrConnectKey, szTemp);
}
if(NULL == pDetailStatus->pNext)
break;
pDetailStatus =pDetailStatus->pNext;
}

利用ConnMgrQueryDetailedStatus,可以查詢到所有連線, 若是想知道目前連線中的,則利用pDetailStatus->dwConnectionStatus == CONNMGR_STATUS_CONNECTED,再去細看其它各項資訊.

2. 利用Registry查詢連線資訊
DWORD dwType = 0 , dwSize = 0;
HKEY hKey;
int nCount = 0;

HKEY_LOCAL_MACHINE\System\State\Connections\Cellular ->the state of current cellular connections

if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("System\\State\\Connections\\Cellular"), 0, 0, &hKey))
{
dwSize = sizeof(DWORD);
RegQueryValueEx(hKey, _T("Count"), NULL, &dwType, (LPBYTE)&nCount, &dwSize);
}

"Count"-Number of cellular connections that are currently connected.
上述利用ConnMgrQueryDetailedStatus去查詢,pDetailStatus->dwConnectionStatus == CONNMGR_STATUS_CONNECTED,是用來查詢目前連線中相關資訊,此部份包含ActiveSync連線.

2009年8月21日 星期五

如何建立連線

一、建立GPRS連線
1. AttemptConnect
BOOL bAvailable = FALSE;

HANDLE hConn = NULL;
CONNMGR_CONNECTIONINFO ci = { 0 };
ci.cbSize = sizeof(ci);
ci.dwParams = CONNMGR_PARAM_GUIDDESTNET CONNMGR_PARAM_MAXCONNLATENCY;
ci.dwFlags = CONNMGR_FLAG_PROXY_HTTP CONNMGR_FLAG_PROXY_WAP CONNMGR_FLAG_PROXY_SOCKS4 CONNMGR_FLAG_PROXY_SOCKS5;
ci.ulMaxConnLatency = 4000; // 4 second
ci.bDisabled = TRUE;
ci.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;
ci.guidDestNet = GetNetworkGuid();
if (SUCCEEDED(hr = ConnMgrEstablishConnection(&ci, &hConn)))
{
DWORD dwResult = WaitForSingleObject(hConn, 400);
switch (dwResult)
{
case WAIT_OBJECT_0:
{
DWORD dwStatus;
if( SUCCEEDED(ConnMgrConnectionStatus(hConn, &dwStatus)) && ( (dwStatus == CONNMGR_STATUS_CONNECTED) (dwStatus == CONNMGR_STATUS_CONNECTIONDISABLED) ))
{
hr = S_OK;
CheckForRequiredProxy(hConn);
}
else
{
hr = S_FALSE;
}
break;
}
case WAIT_TIMEOUT:
hr = E_FAIL;
break;
}
ConnMgrReleaseConnection(hConn, FALSE);
}

2. QueryProxy
BOOL bHasProxy = FALSE;
HKEY hKey;
DWORD dwSize = 0, dwType = 0;

wcscpy(m_wszCurrConnectKey, TEXT("Comm\\ConnMgr\\Providers\\{EF097F4C-DC4B-4c98-8FF6-AEF805DC0E8E}\\"));
目前連線相關設定值都會設在HKEY_LOCAL_MACHINE下\Comm\ConnMgr\Providers\{EF097F4C-DC4B-4c98-8FF6-AEF805DC0E8E}
HKEY_LOCAL_MACHINE下\Comm\ConnMgr\Providers\下有許多組GUID, EF097F4C-DC4B-4c98-8FF6-AEF805DC0E8E是指目前連線那一組


if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, m_wszCurrConnectKey, 0, 0, &hKey))
//Proxy

抓出目前連線的proxy設定值

dwSize = MAX_LOADSTRING * sizeof(TCHAR);
wmemset(m_wszProxy, 0, sizeof(m_wszProxy));
if(RegQueryValueEx(hKey, _T("Proxy"), NULL, &dwType, (LPBYTE)m_wszProxy, &dwSize) == ERROR_SUCCESS)
{
if((wcscmp(m_wszProxy, _T("")) != 0) && (wcscmp(m_wszProxy, _T("new-inet:1159")) != 0))
bHasProxy = TRUE;
}
else
{
RETAILMSG(TRUE, (_T("RegQueryValueEx m_wszProxy is fail")));
}
RegCloseKey(hKey);
}

3.SetProxyToInternet

連線至internet時,若有proxy則須多設proxy至registry,利用InternetSetOption可以將proxy值自動設定到registry,若沒有設定或設定錯誤,在InternetOpenUrl會return error.

INTERNET_PER_CONN_OPTION_LIST List;
INTERNET_PER_CONN_OPTION Option[1];
unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);

Option[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
Option[0].Value.pszValue = m_wszProxy;

List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
List.pszConnection = NULL;
List.dwOptionCount = 1;
List.dwOptionError = 0;
List.pOptions = Option;

if(!InternetSetOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, nSize))
RETAILMSG(TRUE, (_T("InternetSetOption set INTERNET_OPTION_PER_CONNECTION_OPTION failed! (%d)\n"), GetLastError()));

二、 連線至網際網路
if(!g_bHasProxy)
hOpen = InternetOpen (TEXT("ceHttp"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
else
hOpen = InternetOpen (TEXT("ceHttp"), INTERNET_OPEN_TYPE_PROXY, g_wszProxy, g_wszProxy, 0);

有無proxy的設定值必須不同,此proxy的值是查詢registry所得.

hRequest = InternetOpenUrl (hOpen, lpszServer, NULL,0,
INTERNET_FLAG_EXISTING_CONNECT, 0);
HttpSendRequest (hRequest, NULL, 0, NULL, 0);
hAppend = CreateFile (XTRAFILE_PATH, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
dwPos = SetFilePointer (hAppend, 0, NULL, FILE_END);

char szBuffTemp[MAX_FILE_READ_WIN_MOBILE];
int i=0;
int iTotalBytesRecvd=0;
while (InternetReadFile(hRequest, (LPVOID)szBuffTemp, 4096, &dwSize))
{
if(dwSize ==0)
break;
WriteFile (hAppend, szBuffTemp,dwSize,&dwBytesWritten, NULL);
iTotalBytesRecvd=iTotalBytesRecvd+dwSize;// To do: store file content somewhere:

}
CloseHandle (hAppend);
InternetCloseHandle (hOpen);
InternetCloseHandle (hRequest);