Entering Passive Mode

カテゴリ 'C++, C' の記事
< 1 2 3 4 5 6 >

リパースデータバッファの構造

構造

リパースタグなどの特殊なデータにアクセスする場合、
デバイスドライバに対して制御コードを送り、
データ構造を直接扱う必要がある。

Windows には、DeviceIoControl という API があり、
これを使うことで、デバイスドライバの制御が可能である。

リパースポイントの情報を得るためには、
対象のディレクトリハンドルに対して、
FSCTL_GET_REPARSE_POINT という制御コードを送る。
そうすれば、その結果としてリパースポイントの情報が、
リパースデータバッファと呼ばれる構造で返却される。

リパースポイント

NTFS のボリュームマウントポイントは、
ディレクトリに設定することができ、
リンクの処理は NTFS によって行われる。

そのため、一度設定したマウントポイントは、
OS を再起動しても維持されている。
また、ディスクを異なる PC に持っていっても、
リンク先のボリュームが存在すれば利用できる。

こんなことが可能なのは、リンク先に関する情報が、
ディスク自身に保存されているからである。

ボリュームマウントポイントの作成

ボリュームマウントポイントの API も充実している。
ボリュームを、ドライブやパスに割り当てるには、
SetVolumeMountPoint API を使うだけでできる。

    BOOL SetVolumeMountPoint(
        LPCSTR lpszVolumeMountPoint,
        LPCSTR lpszVolumeName
    );

lpszVolumeMountPoint には、割り当てるドライブの
ルートディレクトリや、マウント先ディレクトリを指定する。
例えば、「R:\」や「D:\mnt\cdrom\」などとなる。
どちらの場合でも、パスの最後には \ 記号が必要だ。

ボリュームマウントポイント

ボリュームマウントポイント

Windows 2000 以降は、管理ツール「ディスクの管理」の、
「ドライブ文字とパスの変更」メニューより、
ボリュームに割り当てるドライブ名を変更可能だ。

この画面では、ドライブの追加や削除ができる。
ボリュームには、ドライブを割り当てるのは任意であるが、
割り当てる場合は最大 1 つのドライブ名しか指定できない。

どうしても複数のドライブ名を割り当てたい場合は、
割り当てたドライブのルートディレクトリに対して
subst することで仮想ドライブを作ることが可能である。

ディスクの管理とボリューム識別子

Windows 2000 以降の NT 系では、
ディスクの管理機能が強化され、
ディスク構成の変更に非常に強くなっている。

ハードディスクのパーティションや、
CD-ROM ドライブ、外付けドライブなどは、
ボリューム、又はディスクボリュームと呼ばれているが、
従来はドライブ名によってこれを識別した。

Windows 2000 では、ドライブ名の代わりに、
ボリュームを一意に識別できる GUID を持っている。
この識別子はボリューム識別子と呼ばれる。

NTFS のハードリンク

NTFS のハードリンクは、UNIX 系のそれと同じ機能である。
複数のファイル名が、同じファイルデータを指す状態だ。
それぞれのファイル名には主従関係は存在せず、
共通のデータを持つ以外、通常のファイルと変わらない。

リンクというのは、ファイルシステム内の概念であり、
NTFS ではファイル名とデータ(全ストリーム)の関係を指す。

通常のファイルは、1 つのデータに対して、
1 つのファイル名がリンクしているが、
ハードリンクされたファイルの場合、1 つのデータに対して、
複数のファイル名がリンクしているということだ。

ファイルシステムの能力

今まで色々なリンク機能を見てきたが、
これらはシェルやカーネル(サブシステム)の能力であった。

ショートカットやフォルダリンクは、
シェルを使わない場合は利用できない。
ドライブのマッピング機能は、
プログラムからも利用することはできるが、
ドライブへの割り当てしかできず、制約もある。

このトピックの一番最初では、
UNIX ファイルシステムのリンク機能について書いた。

ドライブを割り当てる

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

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

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

ディレクトリのドライブ割り当て

ディレクトリ ドライブ割り当て

GUI ではネットワークドライブの割り当てしか使えないが、
Windows には SUBST という CUI プログラムが存在し、
これを使えば任意のドライブの任意のディレクトリを
ドライブに割り当てることができる。

これも、MS-DOS の時代からある古いコマンドだ。
例えば、以下のようにすると、自分のユーザプロファイルを
H ドライブに割り当てることができる。

    > subst p: "C:\Documents and Settings\alex"

ネットワークドライブの割り当て

ネットワーク ドライブ割り当て

今まで説明してきたのは、シェルの機能であった。
何度も書いているが、シェルの機能は利用者のためにある。
一般のプログラムがシェルの機能を使うためには、
意識して複雑なプログラムコードを書く必要がある。

では、一般のプログラムが何も意識せずに、
利用できるリンク機能はないのだろうか。

実は、MS-DOS の時代からある代表的な機能がある。
それは、ネットワークドライブの割り当て機能だ。

< 1 2 3 4 5 6 >
このページのトップへ戻る
© 2008 Project Loafer/Project Fireball and all blog writers. Powered by Nucleus CMS