欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

NT路径,DOS路径和Device路径互相转换

程序员文章站 2023-04-05 20:58:39
项目中遇到的比较奇葩的问题,从网上找到一份源码,https://blog.csdn.net/qq125096885/article/details/70766206 稍微整理了下,VS可以直接编译 ......

项目中遇到的比较奇葩的问题,从网上找到一份源码,https://blog.csdn.net/qq125096885/article/details/70766206

稍微整理了下,vs可以直接编译

#include "stdafx.h"
#include <windows.h>
#include <iostream>


#define nt_success(status) (((ntstatus)(status)) >= 0)

#define status_unsuccessful              ((ntstatus)0xc0000001l)

#define status_success                   ((ntstatus)0x00000000l)    // ntsubauth

#define status_name_too_long             ((ntstatus)0xc0000106l)

//删除指针
#define safedeletepoint(pdata) { if(pdata){delete pdata;pdata=null;} }

//删除数组
#define safedeletearraysize(pdata) { if(pdata){delete []pdata;pdata=null;} }

typedef struct _unicode_string {
    ushort length;
    ushort maximumlength;
    pwch   buffer;
} unicode_string;

typedef unicode_string *punicode_string;

typedef struct _rtl_buffer {
    pwchar    buffer;
    pwchar    staticbuffer;
    size_t    size;
    size_t    staticsize;
    size_t    reservedforallocatedsize; // for future doubling
    pvoid     reservedforimalloc; // for future pluggable growth
} rtl_buffer, *prtl_buffer;

typedef struct _rtl_unicode_string_buffer {
    unicode_string string;
    rtl_buffer     bytebuffer;
    wchar          minimumstaticbufferforterminalnul[sizeof(wchar)];
} rtl_unicode_string_buffer, *prtl_unicode_string_buffer;


//dos路径转换nt路径    c:\\windows\\system32\\drivers    -- \\??\\c:\\windows\\system32\\drivers
ntstatus dospathtontpath(wchar_t* pdospath, punicode_string pntpath)
{
    //定义变量
    ntstatus status = status_unsuccessful;
    typedef boolean(__stdcall *fnrtldospathnametontpathname_u)(pcwstr dosfilename, punicode_string ntfilename, pwstr *filepart, pvoid reserved);
    static fnrtldospathnametontpathname_u rtldospathnametontpathname_u = (fnrtldospathnametontpathname_u)getprocaddress(getmodulehandle(l"ntdll.dll"), "rtldospathnametontpathname_u");

    //参数效验
    if (isbadreadptr(pdospath, 1) != 0)return null;
    if (rtldospathnametontpathname_u == null)return null;

    if (rtldospathnametontpathname_u(pdospath, pntpath, null, null))
    {
        status = status_success;
    }
    return status;
}

//nt路径转换dos路径    \\??\\c:\\windows\\system32\\drivers    -- c:\\windows\\system32\\drivers
ntstatus ntpathtodospath(punicode_string pntpath, wchar_t* pszdospath)
{
    //定义变量
    ntstatus status = status_unsuccessful;
    rtl_unicode_string_buffer dospath = { 0 };
    wchar_t* bytedospathbuffer = null;
    wchar_t* bytentpathbuffer = null;


    typedef ntstatus(__stdcall *fnrtlntpathnametodospathname)(ulong flags, prtl_unicode_string_buffer path, pulong disposition, pwstr* filepart);
    static fnrtlntpathnametodospathname rtlntpathnametodospathname = (fnrtlntpathnametodospathname)getprocaddress(getmodulehandle(l"ntdll.dll"), "rtlntpathnametodospathname");

    //参数效验
    if (isbadreadptr(pntpath, 1) != 0)return status;
    if (isbadwriteptr(pszdospath, 1) != 0)return status;
    if (rtlntpathnametodospathname == null)return status;

    bytedospathbuffer = (wchar_t*)new char[pntpath->length + sizeof(wchar_t)];
    bytentpathbuffer = (wchar_t*)new char[pntpath->length + sizeof(wchar_t)];
    if (bytedospathbuffer == null || bytentpathbuffer == null) return status;

    rtlzeromemory(bytedospathbuffer, pntpath->length + sizeof(wchar_t));
    rtlzeromemory(bytentpathbuffer, pntpath->length + sizeof(wchar_t));
    rtlcopymemory(bytedospathbuffer, pntpath->buffer, pntpath->length);
    rtlcopymemory(bytentpathbuffer, pntpath->buffer, pntpath->length);

    dospath.bytebuffer.buffer = bytedospathbuffer;
    dospath.bytebuffer.staticbuffer = bytentpathbuffer;
    dospath.string.buffer = pntpath->buffer;
    dospath.string.length = pntpath->length;
    dospath.string.maximumlength = pntpath->length;
    dospath.bytebuffer.size = pntpath->length;
    dospath.bytebuffer.staticsize = pntpath->length;


    status = rtlntpathnametodospathname(0, &dospath, null, null);
    if (nt_success(status))
    {
        if (_wcsnicmp(pntpath->buffer, bytedospathbuffer, pntpath->length) == 0)
        {
            status = status_unsuccessful;
        }
        else
        {
            rtlcopymemory(pszdospath, bytedospathbuffer, wcslen(bytedospathbuffer) * sizeof(wchar_t));
        }
    }
    else
    {
        //wprintf(l"getlasterror=%i\n", prtlntstatustodoserror(status));
        status = status_unsuccessful;
    }


    safedeletearraysize(bytedospathbuffer);
    safedeletearraysize(bytentpathbuffer);
    return status;
}

//\\device\\harddiskvolume1\x86.sys    c:\x86.sys    
bool devicedospathtontpath(wchar_t* pszdospath, wchar_t* pszntpath)
{
    static tchar    szdrivestr[max_path] = { 0 };
    static tchar    szdevname[max_path] = { 0 };
    tchar            szdrive[3];
    int             cchdevname;
    int             i;

    //检查参数  
    if (isbadreadptr(pszdospath, 1) != 0)return false;
    if (isbadwriteptr(pszntpath, 1) != 0)return false;


    //获取本地磁盘字符串  
    zeromemory(szdrivestr, arraysize(szdrivestr));
    zeromemory(szdevname, arraysize(szdevname));
    if (getlogicaldrivestrings(sizeof(szdrivestr), szdrivestr))
    {
        for (i = 0; szdrivestr[i]; i += 4)
        {
            if (!lstrcmpi(&(szdrivestr[i]), _t("a:\\")) || !lstrcmpi(&(szdrivestr[i]), _t("b:\\")))
                continue;

            szdrive[0] = szdrivestr[i];
            szdrive[1] = szdrivestr[i + 1];
            szdrive[2] = '\0';
            if (!querydosdevice(szdrive, szdevname, max_path))//查询 dos 设备名  
                return false;

            cchdevname = lstrlen(szdevname);
            if (_tcsnicmp(pszdospath, szdevname, cchdevname) == 0)//命中  
            {
                lstrcpy(pszntpath, szdrive);//复制驱动器  
                lstrcat(pszntpath, pszdospath + cchdevname);//复制路径  

                return true;
            }
        }
    }

    lstrcpy(pszntpath, pszdospath);

    return false;
}

ntstatus rtlinitunicodestring(out punicode_string destinationstring, in pcwstr sourcestring)
{

#define argument_present(argumentpointer)    (\
    (char *)((ulong_ptr)(argumentpointer)) != (char *)(null) )

    size_t length;
    destinationstring->length = 0;
    destinationstring->maximumlength = 0;
    destinationstring->buffer = (pwstr)sourcestring;
    if (argument_present(sourcestring))
    {
        length = wcslen(sourcestring);

        // we are actually limited to 32765 characters since we want to store a meaningful
        // maximumlength also.
        if (length > (unicode_string_max_chars - 1)) {
            return status_name_too_long;
        }

        length *= sizeof(wchar);

        destinationstring->length = (ushort)length;
        destinationstring->maximumlength = (ushort)(length + sizeof(wchar));
    }

    return status_success;
}


int main()
{
    ntstatus status;
    wchar_t szwindowsdirectory[max_path] = { 0 };
    wchar_t dospathbuffer[max_path] = { 0 };
    wchar_t szntpath[max_path] = { 0 };
    unicode_string strbuff = { 0 };
    std::wstring dospath = l"c:\\windows\\system32\\drivers";
    std::wstring devicepath = l"\\device\\harddiskvolume4\\123.txt";
    punicode_string pntpath = new unicode_string;

    getwindowsdirectory(szwindowsdirectory, arraysize(szwindowsdirectory));

    status = dospathtontpath((wchar_t*)dospath.c_str(), pntpath);
    if (nt_success(status))
    {
        status = ntpathtodospath(pntpath, dospathbuffer);
        safedeletepoint(pntpath);
    }

    devicedospathtontpath((wchar_t*)devicepath.c_str(), szntpath);
    rtlinitunicodestring(&strbuff, szntpath);

    getchar();
    return 0;

    system("pause");
    return 0;
}