Programming Field - プログラミング Tips

ファイル名の比較と長いファイル名

ファイル名を比較するには、絶対パスに直し、「ロングファイル名」か「ショートファイル名」に揃えて比較しないと、同じファイルを指しているのに間違った結果を得ることがあります。

Windows 95 では、GetLongPathNameが存在しませんが、DOS関数でint割り込み21Hの7160H関数(マイナーコード2H)を使うと取得できます。

以下にGetLongPathNameの代わりとなる関数例を書きましたが、dos.hが無いと使えません。SELECTOROF、OFFSETOFについては、Win16の特殊ポインタの話にもある程度書いています。

int割り込みを使わない代替関数はこちら

#include <dos.h>

#define SELECTOROF(lp)       HIWORD(lp)
#define OFFSETOF(lp)         LOWORD(lp)

DWORD WINAPI MyGetLongPathName(LPCSTR lpszShortPath, LPSTR lpszLongPath, DWORD cchBuffer)
{
    REGPACK regs;
    LPSTR lp;

    lp = (LPSTR) malloc(sizeof(CHAR) * MAX_PATH);

    *lp = 0;

    regs.w.ax = 0x7160;
    regs.h.cl = 2;                         // Get Long Path Name
    regs.h.ch = 0x80;                      // 0: Without SUBST, 0x80: With SUBST
    regs.w.ds = SELECTOROF(lpszShortPath); // seg lpszShortPath
    regs.w.si = OFFSETOF(lpszShortPath);   // offset lpszShortPath
    regs.w.es = SELECTOROF(lp);            // seg lp
    regs.w.di = OFFSETOF(lp);              // offset lp
    intr(0x21, &regs);
    if ((regs.w.flags & 0x01) || !*lp)     // 0x01: CF
    {
        free(lp);
        if (!lpszLongPath || !cchBuffer)
            return (DORD) strlen(lpszShortPath);
        strncpy(lpszLongPath, lpszShortPath, (size_t) cchBuffer);
        return cchBuffer;
    }

    if (!lpszLongPath || !cchBuffer)
    {
        cchBuffer = (DWORD) strlen(lp);
        free(lp);
        return cchBuffer;
    }

    strncpy(lpszLongPath, lp, (size_t) cchBuffer);
    free(lp);
    return cchBuffer;
}

最終更新日: 2007/05/23