C++ - GetFinalPathNameByHandleW が 2000 でも使いたい

C++ - GetFinalPathNameByHandleW が XP でも使いたい - Qiita
これ見て、 Windows 2000に移植しようと思ったんだけど…。

|。・ω・)。o ( あれ?GetVolumeInformationByHandleW ってXPにもなくね? )

って訳で、Windows 2000に実装するために1から作ってみることに


まず、テスト用のコード

int _tmain(int argc, _TCHAR* argv[])
{
    wchar_t result[640];
    wchar_t     fn[640]=L"c:\\winnt\notepad.exe";
    if(argc >=2)
        lstrcpyW(fn,argv[1]);
    HANDLE hFile = CreateFileW(
        fn,
         FILE_READ_ATTRIBUTES, /* desired access */
        0, /* share mode */
        NULL, /* security attributes */
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
            FILE_FLAG_OPEN_REPARSE_POINT,
        NULL);

    _tsetlocale(LC_ALL, _T(""));
    GetFinalPathNameByHandle3(hFile,result,640,VOLUME_NAME_DOS);
    wprintf(L"VOLUME_NAME_DOS: %s\n",result);
    GetFinalPathNameByHandle3(hFile,result,640,VOLUME_NAME_NT);
    wprintf(L"VOLUME_NAME_NT: %s\n",result);
    GetFinalPathNameByHandle3(hFile,result,640,VOLUME_NAME_NONE);
    wprintf(L"VOLUME_NAME_NONE: %ws\n",result);

    CloseHandle(hFile);
    return 0;
}

Windows 2000向けのコード
Flag は VOLUME_NAME_DOS/ VOLUME_NAME_NT/ VOLUME_NAME_NONE の3つに対応

__declspec(dllexport) DWORD WINAPI GetFinalPathNameByHandle3(
  HANDLE hFile,
   LPTSTR lpszFilePath,
    DWORD  cchFilePath,
    DWORD  dwFlags
  ){
    DWORD result = 0;
    HINSTANCE hDll=GetModuleHandleA("ntdll.dll");
    FARPROC GP2 = GetProcAddress(hDll,"NtQueryObject");
    BYTE  u8_Buffer[2000];
    UNICODE_STRING *u = (UNICODE_STRING*)u8_Buffer;
    DWORD eee;
    if (hFile == (HANDLE)INVALID_HANDLE){
                   SetLastError(ERROR_INVALID_PARAMETER);
                   return 0;
    }
    //NtQueryObject(hFile,FileDirectoryInformation,u8_Buffer,2000,&eee)
        _asm{
            lea eax,eee
            push eax
            push 2000
            lea eax,u8_Buffer
            push eax
            push FileDirectoryInformation
            push hFile
            call GP2
    
        }
        if(dwFlags == VOLUME_NAME_NT) {

            result = lstrlenW(u->Buffer);
               if(cchFilePath>= result){
                    lstrcpyW(lpszFilePath,u->Buffer);
                    return result;
               } else {
                   SetLastError(ERROR_NOT_ENOUGH_MEMORY);
                   return 0;
               }
        
        
        }

        // Translate path with device name to drive letters.
        wchar_t szTemp[640]={0};

        if(dwFlags == VOLUME_NAME_DOS||dwFlags ==VOLUME_NAME_NONE) {
        if (GetLogicalDriveStrings(640-1, szTemp))
        {
            wchar_t *p=szTemp;
            wchar_t  lpVolumeNameBuffer[640];
            DWORD vsn=0;

            do{
                p[2]=0;
                QueryDosDeviceW(p,lpVolumeNameBuffer,640);
                int l = lstrlenW(lpVolumeNameBuffer);
                if(!memcmp(lpVolumeNameBuffer,u->Buffer,l*2)){
                    result = lstrlenW(u->Buffer+l);
                    if(dwFlags == VOLUME_NAME_DOS)
                        result +=2;
                    if(cchFilePath>= result){
                        if(dwFlags == VOLUME_NAME_DOS){
                            lstrcpyW(lpszFilePath,p);
                            lstrcatW(lpszFilePath,u->Buffer+l);
                        } else {
                            lstrcpyW(lpszFilePath,u->Buffer+l);
                        }
                        return result;
                    } else {
                        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
                       return 0;
                    }
                }
                p+=4;
            }while(*p);
// Network対応
                lstrcpyW(lpVolumeNameBuffer,L"\\Device\\Mup");
                int l = lstrlenW(lpVolumeNameBuffer);
                if(!memcmp(lpVolumeNameBuffer,u->Buffer,l*2)){
                    result = lstrlenW(u->Buffer+l);
                    if(dwFlags == VOLUME_NAME_DOS)
                        result +=7
;
                    if(cchFilePath>= result){
                        if(dwFlags == VOLUME_NAME_DOS){
                            lstrcpyW(lpszFilePath,L"\\\\?\\UNC");
                            lstrcatW(lpszFilePath,u->Buffer+l);
                        } else {
                            lstrcpyW(lpszFilePath,u->Buffer+l);
                        }
                        return result;
                    } else {
                        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
                       return 0;
                    }
                }

                lstrcpyW(lpVolumeNameBuffer,L"\\Device\\LanmanRedirector");
                l = lstrlenW(lpVolumeNameBuffer);
                if(!memcmp(lpVolumeNameBuffer,u->Buffer,l*2)){
                    result = lstrlenW(u->Buffer+l);
                    if(dwFlags == VOLUME_NAME_DOS)
                        result +=7
;
                    if(cchFilePath>= result){
                        if(dwFlags == VOLUME_NAME_DOS){
                            lstrcpyW(lpszFilePath,L"\\\\?\\UNC");
                            lstrcatW(lpszFilePath,u->Buffer+l);
                        } else {
                            lstrcpyW(lpszFilePath,u->Buffer+l);
                        }
                        return result;
                    } else {
                        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
                       return 0;
                    }
                }
        }
    }
    SetLastError(ERROR_INVALID_PARAMETER);
      return 0;
}

テスト結果

C:\>GetVol.exe c:\WINNT\notepad
.exe
VOLUME_NAME_DOS: C:\WINNT\notepad.exe
VOLUME_NAME_NT: \Device\HarddiskVolume1\WINNT\notepad.exe
VOLUME_NAME_NONE: \WINNT\notepad.exe

C:\>GetVol.exe GetVol.exe
VOLUME_NAME_DOS: C:\Documents and Settings\Administrator\デスクトップ\GetVol.exe
VOLUME_NAME_NT: \Device\HarddiskVolume1\Documents and Settings\Administrator\デスクトップ\GetVol.exe
VOLUME_NAME_NONE: \Documents and Settings\Administrator\デスクトップ\GetVol.exe

・ω・ いいんじゃないかな?
後は、もうちょっと整理やバッファーのチェック処理を追加して実装するよ

なんでこんなもの実装するかって?

[Python-Dev] GetFinalPathNameByHandleW - what is the minimum windows version python-3.5 will support ?

In essence: yes.
Python's support for Windows is outlined in PEP 11:
https://www.python.org/dev/peps/pep-0011/#microsoft-windows
which establishes that Python drops support for a Windows platform when
Microsoft does. WinXP (somewhat noisily) finished support last year:
http://windows.microsoft.com/en-gb/windows/end-support-help
while Server 2003 -- more quietly; I had to go and look -- came out of
extended support this month:
https://support.microsoft.com/en-us/lifecycle?p1=3198
Since Python 3.5 will come out after both of those platforms have
finished support, there's no guarantee that it will run without error on
those systems.
Obviously, all earlier releases of Python -- including the long-term-supported 2.7 should continue to work. Any otherwise undocumented failure to work on older platforms should be raised as a bug.

Python はマイクロソフトがサポートを切った時に同じようにすると決定しています。
WindowsXPの鬱陶しいサポートが去年やっと終わりました

|。・ω・) 。o (これは、XPを超えるチャンス!)

というわけですよ

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です