お世話になっております。よろしくお願いします。
環境は VC++ 2008 on WinXP SP3 です。
NT パス名、例えば \Device\HarddiskVolume1\... を C:\... に変換する方法をご教示い
ただけませんでしょうか。
ローカルドライブ下にあるパスについては、GetLogicalDriveStrings でドライブ名の一
覧を取得し、QueryDosDevice でドライブ名を NT デバイス形式に変換し、前方一致で確
認すればよいかと思っております。
が、ネットワークドライブや、ドライブレターが割り当てられていない UNC パスについ
てはどうすればよろしいのでしょうか?
ローカルドライブの場合、例えば C: について QueryDosDevice で問い合わせれば
\Device\HarddiskVolume1 という文字列のみが返ってくるため、前方一致で判別できま
す。
しかし、例えば、N: が \\Server\Path にマップされている場合、ネットワークドライブ
内にあるファイルの NT パスは \Device\LanmanRedirector\Server\Path なのですが、
N: に対して QueryDosDevice を実行すると \Device\LanmanRedirector\;N:謎の数字
\Server\Path のような文字列が返ってきてしまい、前方一致できません。
また、当然ではありますが、QueryDosDevice に UNC を渡しても、対応する NT パスは取
得できません。
NT パスが \Device\LanmanRedirector\Server\Path となっていれば、それは
\\Server\Path を指すのだと解釈してしまうのも、ドライバか何かの実装が異なれば、
LanmanRedirector 以外の名前がありそうで怖いです。
RtlNtPathNameToDosPathName という関数もありますが、Undocumented なので、できれば
使いたくありません。
統一的な方法である必要はありません。
NT パスから、ターゲットがローカルファイルなのかネットワークファイルなのか判別で
きるならば、それぞれに固有の方法でも構いません。
(マウントポイントの場合にどうなるかは調べる必要がありそうです)
ご存知の方がいらっしゃいましたら、どうかよろしくお願いいたします。
なお、ブログの方にも同じ内容を投稿しておりますが、これは備忘録としてであり、マル
チポストの意図はありません。
GetLogicalDriveStrings()ではなく、GetLogicalDrives()を使ってドライブの一覧を取得し、
QueryDosDevice()の結果で前方一致するのはいかがでしょう?
またはGetDriveType()でもネットワークドライブかどうかは判断できると思います。
GetLogicalDriveStrings でできるというのは試さずに書いてしまいましたが、
GetLogicalDriveStrings は C:\ のように末尾に \ がついたものを返すので、そのまま
では QueryDosDevice に渡せそうに無いですね。
そういう意味では GetLogicalDrives を使うべきですね。
ただ、そこから先には進めません。
すみません、質問を勘違いしていましたm(_ _)m
「\Device\HarddiskVolume1」は、デバイス名マッピングですよね?
質問の中の「NTパス」の意図が分からないのですが、
たとえばRtlDosPathNameToNtPathName()で、C:\WINDOWS\などを渡すと、
\??\C:\WINDOWS\などと返ってくると思います。
NTパスというのは、このことでしょうか?
また、UNCはどのような文字列をどのように変換したいのでしょうか?
またしても見当違いだったら申し訳ないです(--;
用語が不正確で申し訳ありません。
> 質問の中の「NTパス」の意図が分からないのですが、
CMSK さんのおっしゃる「デバイスマッピング」のことです。
C:\Windows に対しては \Device\HarddiskVolume1\Windows になります。
> UNCはどのような文字列をどのように変換したいのでしょうか?
\Device\LanmanRedirector\Server\Path のようなものを \\Server\Path にしたいので
す。
それにあたっては、この書式が変わらないということが Microsoft によって公言されて
いれば良いのですが、ドライバの実装等によって LanmanRedirector 以外の名前になり得
る場合は、単純に文字列置換するわけには行きません。
SMBだけじゃなく、WebDAV等も対応しなくはならないのですよね。
ローカルファイルかネットワーク上のファイルかを判断するのであれば、
一番手っ取り早いのは、フィルタドライバで処理することではないでしょうか?
> SMBだけじゃなく、WebDAV等も対応しなくはならないのですよね。
うーん…
ここで書いてない内情を言うと、Windows ファイル共有だけ対応できればいいかなぁ、と
思うのですが、技術的興味としては全部対応にしたいですね。
> フィルタドライバで処理することではないでしょうか?
そこまではちょっと…
ユーザーモードで変換する方法は無いものでしょうか?
何かあるんじゃないかと思ってはいるのですが。
UNCが無ければどうにかなるのですが・・。
すみません、私の知識ではユーザモードでは手詰まりです。
お役に立てずに申し訳ないですm(_ _)m