read_link()

シンボリックリンクのターゲットパスを取得する関数read_link()を実装しました。
symlink.cpp
リパースポイントの仕様を調べるのに時間がかかって、実装が中途半端です。
現状、Windows 2000/XPのジャンクションのみで、VistaシンボリックリンクPOSIX用実装はまだです。


filesystem_errorにパスを渡すためにエラー処理が煩雑になっています。

HAMIGAKI_FILESYSTEM_DECL
boost::filesystem::path read_link(const boost::filesystem::path& p)
{
    nt_file f(p);

    // コンストラクタは例外を投げないので明示的にチェック
    // (nt_fileクラスは別用途にも使うため)
    if (!f.is_valid())
    {
        throw boost::filesystem::filesystem_error(
            "hamigaki::filesystem::read_link", p, f.native_error());
    }

    boost::filesystem::path tp;
    // get_reparse_point()も例外を投げない
    // (関数側ではパスpを取得できないため)
    if (!f.get_reparse_point(tp))
    {
        if (int ec = f.native_error())
        {
            throw boost::filesystem::filesystem_error(
                "hamigaki::filesystem::read_link", p, ec);
        }
        else
        {
            throw boost::filesystem::filesystem_error(
                "hamigaki::filesystem::read_link",
                "invalid reparse point data");
        }
    }
    return tp;
}

素直に例外を投げ直した方がいいかもしれません。