ページ

ラベル WifiSwitcher の投稿を表示しています。 すべての投稿を表示
ラベル WifiSwitcher の投稿を表示しています。 すべての投稿を表示

2008-03-05

WifiSwitcher更新

WifiSwitcherを更新しました。
 
先日のアイコン表示方法の変更に加えて、プログラム起動時の無線LANの状態確認と「有効なAPのみ表示する」オプションを追加しています。
 
 
あと、レジストリに設定を保存するときに不要なキーを作っていた問題を(こっそり)修正しました。
動作には影響ありませんが HKCU\Software\tauchi.net\WifiSwitcher以下の余分なキーは必要ありません。
コードのコピペばかりしていると変な失敗をしてしまいますね。
 

2008-03-03

アイコンのサイズ

「Windows Mobileプログラミング徹底理解」一通り読み終わりました。
これまで全く知らなかったような事も載っていて大変参考になります。
 
とりあえず知らなかった事の1つ目が、本の冒頭で触れられている「DPIとアイコンサイズ」の箇所(31ページ)の「画面の物理サイズが変わっても文字やアイコンが同じ大きさで表示される」という部分。
WifiSwitcherをエミューレタで動かすと妙に大きい画面になるなぁと思っていたのですが、ZERO3とエミュレータでは小さいアイコンのサイズが違っていたのですね。
 
 
アイコンのサイズを32×32と決め打ちしていたのがよくなかったようです。
g_hImageList = ImageList_Create(32, 32, ILC_COLOR24 |ILC_MASK, 5, 0);
ImageList_ReplaceIcon(g_hImageList, -1, LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_SIGNAL_0)));
ImageList_ReplaceIcon(g_hImageList, -1, LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_SIGNAL_1)));
ImageList_ReplaceIcon(g_hImageList, -1, LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_SIGNAL_2)));
ImageList_ReplaceIcon(g_hImageList, -1, LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_SIGNAL_3)));
ImageList_ReplaceIcon(g_hImageList, -1, LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_SIGNAL_4)));
 
まず、アイコンのサイズをGetSystemMetrics()で取得しました。
小さいアイコンのサイズは SM_CXSMICON, SM_CYSMICONで取得できるようです。
iCx = GetSystemMetrics(SM_CXSMICON);
iCy = GetSystemMetrics(SM_CYSMICON);
g_hImageList = ImageList_Create(iCx, iCy, ILC_COLOR24 |ILC_MASK, 5, 0);
 
次にアイコンの読み込みですが LoadIcon()だと通常サイズのアイコンしか読み込めないみたいなので、LoadImage()に先ほど取得したアイコンのサイズを指定して読み込みました。
そのままだと ImageList_ReplaceIcon()に渡せないので無理やりHICONにキャストしています(本当にこんなのでいいのか不安ですが...)。
ImageList_ReplaceIcon(g_hImageList, -1, (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_SIGNAL_0), IMAGE_ICON, iCx, iCy, LR_DEFAULTCOLOR));
ImageList_ReplaceIcon(g_hImageList, -1, (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_SIGNAL_1), IMAGE_ICON, iCx, iCy, LR_DEFAULTCOLOR));
ImageList_ReplaceIcon(g_hImageList, -1, (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_SIGNAL_2), IMAGE_ICON, iCx, iCy, LR_DEFAULTCOLOR));
ImageList_ReplaceIcon(g_hImageList, -1, (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_SIGNAL_3), IMAGE_ICON, iCx, iCy, LR_DEFAULTCOLOR));
ImageList_ReplaceIcon(g_hImageList, -1, (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_SIGNAL_4), IMAGE_ICON, iCx, iCy, LR_DEFAULTCOLOR));
 
これでエミュレータでもまともに表示されるようになりました。
 
 
エミュレータで動かすために余計なリソースを持つのは無駄かな...とも思うのですが、少しずつでもまともなプログラムにしていった方がいいですよね。
 

2008-01-12

WifiSwitcher更新

こそこそと修正していた WifiSwitcherを v0.2として公開します。
(と言ってもソースと ReadMe付けただけですが...)  
v0.1からの変更点として、11b/11gの表示と WEP/WPA等の暗号・認証方式の表示が追加されています。
また、RSSI表示は直感的でないとのご意見もありましたので、信号強度をアイコン表示するようにしてみました。(RSSIとの対応はNSDNの記述に従っています)
 
 
ただ、ソフトの名前にもなっているアクセスポイントの切り替えは あまり進歩していません。
いっそ名前も変えて切り替え機能は無かった事にしてしまってもいいかもしれませんね(笑。
 

2008-01-06

11bか11gか

去年から引っ張っているネタとしてWifiInfoや WifiSwitcherで11b, 11gの種別を判定したいという宿題があります。
 
アクセスポイントの検索結果として取得できるNDIS_WLAN_BSSID_EXには NetworkTypeInUseというメンバがありますが、アドエスの場合は常に Ndis802_11OFDM24(11g)を返してくれるので役に立ちません。
 
でも正月に帰省先でボーっとテレビを観ていたとき、ふと SupportedRatesメンバの内容で判断できるのでは?と思いつきました。
SupportedRatesメンバには使用できる伝送レートがセットされているとの事。
11bで使用できる伝送レートは 1Mbps, 2Mbps, 5.5Mbps, 11Mbpsの 4種類。
11gはそれに加えて、9, 18, 36, 54, 6, 12, 24, 48Mbpsの合計12種類が使用できます。
SupportedRatesメンバに正しく値がセットされていれば、何種類の伝送レートが登録されているかを数えることで 11b, 11gの判定ができそうです。
INT iSupportedRatesCount = 0;

for (INT i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
    if (0 == ndisBssid.SupportedRates[i]) {
        break;
    }
    iSupportedRatesCount ++;
}
switch (iSupportedRatesCount) {
    case 4:
        // 11b
        break;
    case 8:
        // 11aは 8種類(だった...と思う)
        break;
    case 12:
        // 11g
        break;
    default:
        // その他?
        break;
}
 
WifiSwitcherに組み込んでみるとこんな感じ。
 
 
とりあえず正しく判定できているようです。
 
ただ この方法で取得できるのはアクセスポイントや自分自身のNICがサポートしている伝送レートなので、WifiInfoに組み込んで「現在のネットワーク種別」を取得することはできなさそうです。
やはり NetworkTypeInUseメンバに正しい値をセットして欲しいですよね。
 

2007-12-20

WifiSwitcher更新...途中

ここ数日、アドエス ソフトスレで WifiFoFumが話題にのぼっていました。
動いている証拠のスクリーンショットをアップして下さっている方もいたのですが、やはり自分の環境では動いてくれません。
 
個人的にはあまり無線APを検索したいという需要は無いのですが、同じように WifiFoFumが動かないという方が WifiSwitcherの名前を挙げてくれていたので ちょっとだけ修正をはじめてみました。
 
とりあえず、定期的(10秒間隔)でAPを検索するように変更しました。
検索間隔、検索時のRSSIしきい値の(微妙な)設定画面を追加しました。
 
 
ただ、今日はどうも風邪でもひいてしまったようで 頭がまわりません。
とりあえずの作りかけ版をアップしておきます。
  • up0856.zip
  • up0860.zip
    (12/21追記)
    一部修正版をアップしました。
まだまだ設定を保存できなかったり APを切り替えた時にLEDが消えたり(?) 表示が狂ったりしますが、後日修正しますので WifiFoFumが動かない同志の方は気長にお待ちください。
 

2007-11-04

無線LANの接続先切り替え

先日 没にした無線LANの接続先切り替えツールですが、 自分の環境で WifiFoFumがうまく動かなかったので続きを作り始めました。
まだまだあやしい動作をしますが、W-ZERO3.org Uploaderにアップしておきます。
 
ところが、いざ作り始めてみると思ったように切り替えすることができずに苦労しています。
問題点も山積みです。
  • 未登録のアクセスポイントを見つけた状態(標準の接続先選択ダイアログが表示された状態)で接続先を切り替えることができない。
  • アドホックモードへの切り替えに失敗することがあるような気がする。
 
.NETが必要ないという事以外は全ての点において WifiFoFumが上ですので、 WifiFoFumがちゃんと動いている人には全く必要のないアプリですね。
むしろ WifiFoFumがすぐに終了してしまう問題の解決方法をご存じの方はこっそり教えてください。
 

2007-10-31

没ネタ

ここ数日 ListViewの使い方で悩んでいたのですが、なんとなく使い方がわかってきました。
 
で、ようやく動いた画面がこれ。
 
 
最初は SDKのサンプルを眺めていたのですが 結構高尚な事をしていてなかなか全体が把握できず、 最後には定番の(?)猫でもわかるプログラミングのお世話になりました。
 
SDKのヘルプもこのくらい噛み砕いてくれるとありがたいのですが...。
 
ともかく表示まではできたので続きを...と思っていたのですが、これってどう見ても WifiFoFumのパクリ(笑
しかもレーダーチャートなし
 
もうちょっと別の方向性を考えないといけませんね。
 

2007-10-24

アクセスポイントの一覧を取得してみる

OID_802_11_BSSID_LISTを使って無線アクセスポイントの一覧を取得してみました。
 
ポイントは、先に OID_802_11_BSSID_LIST_SCANを呼ぶ必要があることと、OID_802_11_BSSID_LIST_SCANの呼び出しが終わってもアクセスポイントの一覧は更新されていないことがあるという事でしょうか。
別の解説では 6秒とか書かれてますが、そんなに待てませんよね...
 
あと、2つめ以降の BSSIDを取得しようとして pNdisBssidList->Bssid[i]と書いてしばらく悩んでいました。 (Cは不慣れなので...)
 
DWORD                           dwBytesReturned = 0,
                                dwError;
UCHAR                           ucQueryBuffer[1024]; // サイズは適当...
PNDISUIO_QUERY_OID              pNdisQueryOid;
PNDISUIO_SET_OID                pNdisSetOid;
PNDIS_802_11_BSSID_LIST_EX      pNdisBssidList;
PNDIS_WLAN_BSSID_EX             pNdisBssid;


// BSSIDの一覧を更新
ZeroMemory(ucQueryBuffer, 1024);
pNdisSetOid                     = (PNDISUIO_SET_OID)&ucQueryBuffer[0];
pNdisSetOid->Oid                = OID_802_11_BSSID_LIST_SCAN;
pNdisSetOid->ptcDeviceName      = WLAN_DEVICE_NAME;

if (!DeviceIoControl(
        g_hNdis                         ,
        IOCTL_NDISUIO_SET_OID_VALUE     ,
        (LPVOID)&ucQueryBuffer[0]       ,
        sizeof(ucQueryBuffer)           ,
        (LPVOID)&ucQueryBuffer[0]       ,
        sizeof(ucQueryBuffer)           ,
        &dwBytesReturned                ,
        NULL
)) {
    dwError = GetLastError();
}

// 一応 待ってみる
Sleep(6000);

// BSSIDの一覧を取得
ZeroMemory(ucQueryBuffer, 1024);
pNdisQueryOid                   = (PNDISUIO_QUERY_OID)&ucQueryBuffer[0];
pNdisQueryOid->Oid              = OID_802_11_BSSID_LIST;
pNdisQueryOid->ptcDeviceName    = WLAN_DEVICE_NAME;


if (DeviceIoControl(
        g_hNdis                         ,
        IOCTL_NDISUIO_QUERY_OID_VALUE   ,
        (LPVOID)&ucQueryBuffer[0]       ,
        sizeof(ucQueryBuffer)           ,
        (LPVOID)&ucQueryBuffer[0]       ,
        sizeof(ucQueryBuffer)           ,
        &dwBytesReturned                ,
        NULL
)) {
    pNdisBssidList = (PNDIS_802_11_BSSID_LIST_EX)pNdisQueryOid->Data;
    pNdisBssid = &(pNdisBssidList->Bssid[0]);
    for (int i = 0; i < pNdisBssidList->NumberOfItems; i++) {
        if (pNdisBssid->Length) {
            // 有効なデータ
        }
        // 次のBSSID
        pNdisBssid = (PNDIS_WLAN_BSSID_EX)(((PBYTE)pNdisBssid) + pNdisBssid->Length );
    }
} else {
    dwError = GetLastError();
}
 
これでインフラストラクチャモード、アドホックモード問わずにアクセスポイントの一覧を取得できるようになりました。
 
ついでに NDIS_WLAN_BSSID_EXの NetworkTypeInUseメンバを見ると Ndis802_11OFDM24(802.11g)が返ってきていました。
すぐにでも WifiInfoに組み込もうと思ったのですが、試してみると 11bのアクセスポイントに対しても Ndis802_11OFDM24が返ってきています。
 
こんなところでオチをつけなくてもいいのに...。
 
ちょっと残念ですが、少なくともアクセスポイントの一覧は取得できたので良しとしましょう。