2006 年 10 月 22 日 23 時 51 分

ドライブを割り当てる


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


ドライブの割り当ては、2 種類あった。
ローカルパスとネットワークボリューム。
利用者から見てみれば両者は同じような物だが、
プログラム的に考えると、全く別のものだ。

ローカルパスの割り当ては、
ドライブ(MS-DOS デバイス)に対して、
別のデバイスパスへリンクを定義する作業となり、
DefineDosDevice API を使う。

ネットワークボリュームの割り当ては、
まず、ファイル共有を提供しているサーバに接続し、
そして、その接続をローカルドライブにマッピングする。
これは、LAN Manager 系の NetUseAdd API か、
Windows 系の、WNetAddConnection API を使う。

では、これらをまとめた関数を作ってみよう。
カテゴリは、DriveMap とし、
作成関数を DriveMapCreate と命名する。

========== drivemap.h ==========

/* インクルードガード */
#ifndef drivemap_h_included
#define drivemap_h_included

#include <windows.h>
#include <ole2.h>

/* プロトタイプ定義 */
HRESULT DriveMapCreate(const wchar_t *driveName,
        const wchar_t *target);

#endif /* !drivemap_h_included */

========== end of folderlink.h ==========

関数では、Z: などのドライブ名と、
C:\TEMP、\\server\share などのパスを受け取り、
パスに応じて自動的に API を切り替えるようにしよう。

NetUseAdd と WNetAddConnection は歴史が違うだけで、
どちらを使っても構わない。
まあ、WNetAddConnection の方が簡単なのでこっちにする。

========== drivemap.c ==========

#define UNICODE
#define STRICT
#define WIN32_LEAN_AND_MEAN

#include "drivemap.h"

/* wcsncmp */
#include <string.h>

/* WNetAddConnection */
#include <winnetwk.h>

HRESULT DriveMapCreate(const wchar_t *driveName,
        const wchar_t *target) {

    /* 先頭が \\ で始まるなら */
    if (wcsncmp(target, L"\\\\", 2)) {

        /* UNC パス */
        return HRESULT_FROM_WIN32(
                WNetAddConnection(target, NULL, driveName));

    } else {

        /* ローカルパス */
        if (!DefineDosDevice(0, driveName, target))
                return HRESULT_FROM_WIN32(GetLastError());
        return S_OK;

    }

}

========== end of drivemap.c ==========

API が強力なので、拍子抜けするくらい簡単である。
WNetAddConnection も DefineDosDevice も、
パラメータを渡すだけで全てやってくれる。

さて、ネットワーク共有にアクセスする場合は、
通常ユーザ認証を行う必要がある。

WNetAddConnection は、古い API であるため、
Windows 95 のようなパスワードだけの認証が可能だ。
ここでユーザ名を指定することはできない。

今回は、ユーザ認証を行うつもりはないので、
パスワードの部分(第 2 引数)に NULL を指定している。

API で認証情報を指定しなかった場合、
最初にパススルー認証を試すことになっている。
この場合、現在のユーザとパスワードが使われる。

例えば、ドメインに所属しない Windows XP が 2 台あり、
双方に同じパスワードの同じユーザ名を登録しておく。

片方に上記ユーザでログオンして使用しており、
もう一方でファイル共有を開始しているとすると、
ログオンユーザは、確認なしにもう一方にアクセスできる。
これが、パススルー認証という機能だ。

上で作った関数の場合は、パススルーのみをサポートする。
利用者と異なるユーザ名やパスワードを入力させる場合は、
NetUseAdd や、WNetAddConnection2 等を使う必要がある。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.