看流星社区

 找回密码
 注册账号
查看: 1730|回复: 0

设备名与链接名的转换

[复制链接]

该用户从未签到

发表于 2017-6-1 13:33:42 | 显示全部楼层 |阅读模式
MyQueryDosDeviceW从ReactOS的源码里拷贝的
兼容R0/R3
DWORD
WINAPI
MyQueryDosDeviceW(
                                  LPCWSTR lpDeviceName,
                                  LPWSTR lpTargetPath,
                                  DWORD ucchMax
                                  )
{
        POBJECT_DIRECTORY_INFORMATION DirInfo;
        OBJECT_ATTRIBUTES ObjectAttributes;
        UNICODE_STRING UnicodeString;
        HANDLE DirectoryHandle;
        HANDLE DeviceHandle;
        ULONG ReturnLength;
        ULONG NameLength;
        ULONG Length;
        ULONG Context;
        BOOLEAN RestartScan;
        NTSTATUS Status;
        UCHAR Buffer[512];
        PWSTR Ptr;

        /* Open the '\??' directory */
        RtlInitUnicodeString (&UnicodeString,
                L"\\??");
        InitializeObjectAttributes (&ObjectAttributes,
                &UnicodeString,
                OBJ_CASE_INSENSITIVE,
                NULL,
                NULL);
        Status = NtOpenDirectoryObject (&DirectoryHandle,
                DIRECTORY_QUERY,
                &ObjectAttributes);
        if (!NT_SUCCESS (Status))
        {
                return 0;
        }

        Length = 0;

        if (lpDeviceName != NULL)
        {
                /* Open the lpDeviceName link object */
                RtlInitUnicodeString (&UnicodeString,
                        (PWSTR)lpDeviceName);
                InitializeObjectAttributes (&ObjectAttributes,
                        &UnicodeString,
                        OBJ_CASE_INSENSITIVE,
                        DirectoryHandle,
                        NULL);
                Status = NtOpenSymbolicLinkObject (&DeviceHandle,
                        GENERIC_READ,
                        &ObjectAttributes);
                if (!NT_SUCCESS (Status))
                {
                        pfnNtClose (DirectoryHandle);
                        return 0;
                }

                /* Query link target */
                UnicodeString.Length = 0;
                UnicodeString.MaximumLength = (USHORT)ucchMax * sizeof(WCHAR);
                UnicodeString.Buffer = lpTargetPath;

                ReturnLength = 0;
                Status = NtQuerySymbolicLinkObject (DeviceHandle,
                        &UnicodeString,
                        &ReturnLength);
                pfnNtClose (DeviceHandle);
                pfnNtClose (DirectoryHandle);
                if (!NT_SUCCESS (Status))
                {
                        return 0;
                }

                Length = UnicodeString.Length / sizeof(WCHAR);
                if (Length < ucchMax)
                {
                        /* Append null-charcter */
                        lpTargetPath[Length] = UNICODE_NULL;
                        Length++;
                }
                else
                {
                        return 0;
                }
        }
        else
        {
                RestartScan = TRUE;
                Context = 0;
                Ptr = lpTargetPath;
                DirInfo = (POBJECT_DIRECTORY_INFORMATION)Buffer;

                while (TRUE)
                {
                        Status = NtQueryDirectoryObject (DirectoryHandle,
                                Buffer,
                                sizeof (Buffer),
                                TRUE,
                                RestartScan,
                                &Context,
                                &ReturnLength);
                        if (!NT_SUCCESS(Status))
                        {
                                if (Status == STATUS_NO_MORE_ENTRIES)
                                {
                                        /* Terminate the buffer */
                                        *Ptr = UNICODE_NULL;
                                        Length++;

                                        Status = STATUS_SUCCESS;
                                }
                                else
                                {
                                        Length = 0;
                                }
                                break;
                        }

                        if (!wcscmp (DirInfo->TypeName.Buffer, L"SymbolicLink"))
                        {
                                NameLength = DirInfo->Name.Length / sizeof(WCHAR);
                                if (Length + NameLength + 1 >= ucchMax)
                                {
                                        Length = 0;
                                        break;
                                }

                                memcpy (Ptr,
                                        DirInfo->Name.Buffer,
                                        DirInfo->Name.Length);
                                Ptr += NameLength;
                                Length += NameLength;
                                *Ptr = UNICODE_NULL;
                                Ptr++;
                                Length++;
                        }

                        RestartScan = FALSE;
                }

                pfnNtClose (DirectoryHandle);
        }

        return Length;
}[/code]
TA实现的:
BOOLEAN NtPathToDosPathW(WCHAR *FullNtPath, WCHAR *FullDosPath)
{
        WCHAR DosDevice[4]= {0};       //dos设备名最大长度为4
        WCHAR NtPath[64]= {0};       //nt设备名最大长度为64
        WCHAR *RetStr=NULL;
        size_t NtPathLen=0;
        if (!FullNtPath || !FullDosPath)
        {
                return FALSE;
        }
        for(short i=65; i<26+65; i++)
        {
                DosDevice[0]=i;
                DosDevice[1]=L':';
                if(QueryDosDeviceW(DosDevice,NtPath,64))
                {
                        if (NtPath)
                        {
                                NtPathLen=wcslen(NtPath);
                                if (!wcsnicmp(NtPath,FullNtPath,NtPathLen))
                                {
                                        wcscpy(FullDosPath,DosDevice);
                                        wcscat(FullDosPath,FullNtPath+NtPathLen);
                                        return TRUE;
                                }
                        }
                }
        }
        return FALSE;
}

BOOLEAN DosPathToNtPathW(WCHAR *FullDosPath, WCHAR *FullNtPath)
{
        WCHAR DosDevice[4]= {0};       //dos设备名最大长度为4
        WCHAR NtPath[64]= {0};       //nt设备名最大长度为64
        WCHAR *RetStr=NULL;
        size_t NtPathLen=0;
        if (!FullNtPath || !FullDosPath)
        {
                return FALSE;
        }
        DosDevice[0]=FullDosPath[0];
        DosDevice[1]=L':';
        if(QueryDosDeviceW(DosDevice,NtPath,64))
        {
                if (NtPath)
                {
                        wcscpy(FullNtPath,NtPath);
                        wcscat(FullNtPath,FullDosPath+2);
                        return TRUE;
                }
        }
        return FALSE;
}

BOOLEAN NtPathToDosPathA(CHAR *FullNtPath, CHAR *FullDosPath)
{
        CHAR DosDevice[4]= {0};       //dos设备名最大长度为4
        CHAR NtPath[64]= {0};       //nt设备名最大长度为64
        CHAR *RetStr=NULL;
        size_t NtPathLen=0;
        if (!FullNtPath || !FullDosPath)
        {
                return FALSE;
        }
        for(short i=65; i<26+65; i++)
        {
                DosDevice[0]=i;
                DosDevice[1]=L':';
                if(QueryDosDeviceA(DosDevice,NtPath,64))
                {
                        if (NtPath)
                        {
                                NtPathLen=strlen(NtPath);
                                if (!strnicmp(NtPath,FullNtPath,NtPathLen))
                                {
                                        strcpy(FullDosPath,DosDevice);
                                        strcat(FullDosPath,FullNtPath+NtPathLen);
                                        return TRUE;
                                }
                        }
                }
        }
        return FALSE;
}

BOOLEAN DosPathToNtPathA(CHAR *FullDosPath, CHAR *FullNtPath)
{
        CHAR DosDevice[4]= {0};       //dos设备名最大长度为4
        CHAR NtPath[64]= {0};       //nt设备名最大长度为64
        CHAR *RetStr=NULL;
        size_t NtPathLen=0;
        if (!FullNtPath || !FullDosPath)
        {
                return FALSE;
        }
        DosDevice[0]=FullDosPath[0];
        DosDevice[1]=L':';
        if(QueryDosDeviceA(DosDevice,NtPath,64))
        {
                if (NtPath)
                {
                        strcpy(FullNtPath,NtPath);
                        strcat(FullNtPath,FullDosPath+2);
                        return TRUE;
                }
        }
        return FALSE;
}

void test()
{
        WCHAR dspW1[]=L"c:\\windows\\system32\\config\\sam",dspW2[500]={0};
        WCHAR ntpW[500]= {0};
        DosPathToNtPathW(dspW1,ntpW);
        printf("%S\n",ntpW);
        NtPathToDosPathW(ntpW,dspW2);
        printf("%S\n",dspW2);
        //
        CHAR dspA1[]="c:\\windows\\system32\\config\\sam",dspA2[500]={0};
        CHAR ntpA[500]= {0};
        DosPathToNtPathA(dspA1,ntpA);
        printf("%s\n",ntpA);
        NtPathToDosPathA(ntpA,dspA2);
        printf("%s\n",dspA2);
}[/code]


只能用于R0MF实现的:
#include <ntddk.h>
#include <windef.h>
#include <ntstrsafe.h>

//输入\\??\\c:-->\\device\\\harddiskvolume1
//LinkTarget.Buffer注意要释放

NTSTATUS QuerySymbolicLink(
                        IN PUNICODE_STRING SymbolicLinkName,
                        OUT PUNICODE_STRING LinkTarget
                        )                                 
{
        OBJECT_ATTRIBUTES        oa                = {0};
        NTSTATUS                        status        = 0;
        HANDLE                                handle        = NULL;

        InitializeObjectAttributes(
                                                        &oa,
                                                        SymbolicLinkName,
                                                        OBJ_CASE_INSENSITIVE,
                                                        0,
                                                        0);

        status = ZwOpenSymbolicLinkObject(&handle, GENERIC_READ, &oa);
        if (!NT_SUCCESS(status))
        {
                return status;
        }

        LinkTarget->MaximumLength = MAX_PATH*sizeof(WCHAR);
        LinkTarget->Length = 0;
        LinkTarget->Buffer = ExAllocatePoolWithTag(PagedPool, LinkTarget->MaximumLength,'SOD');
        if (!LinkTarget->Buffer)
        {
                ZwClose(handle);
                return STATUS_INSUFFICIENT_RESOURCES;
        }

        RtlZeroMemory(LinkTarget->Buffer, LinkTarget->MaximumLength);

        status = ZwQuerySymbolicLinkObject(handle, LinkTarget, NULL);
        ZwClose(handle);

        if (!NT_SUCCESS(status))
        {
                ExFreePool(LinkTarget->Buffer);
        }

        return status;
}

//输入\\Device\\harddiskvolume1
//输出C:
//DosName.Buffer的内存记得释放

NTSTATUS
MyRtlVolumeDeviceToDosName(
                                                IN PUNICODE_STRING DeviceName,
                                                OUT PUNICODE_STRING DosName
                                                )

/*++

Routine Description:

This routine returns a valid DOS path for the given device object.
This caller of this routine must call ExFreePool on DosName->Buffer
when it is no longer needed.

Arguments:

VolumeDeviceObject - Supplies the volume device object.
DosName - Returns the DOS name for the volume
Return Value:

NTSTATUS

--*/

{
        NTSTATUS                                status                                        = 0;
        UNICODE_STRING                        driveLetterName                        = {0};
        WCHAR                                        driveLetterNameBuf[128] = {0};
        WCHAR                                        c                                                = L'\0';
        WCHAR                                        DriLetter[3]                        = {0};
        UNICODE_STRING                        linkTarget                                = {0};

        for (c = L'A'; c <= L'Z'; c++)
        {
                RtlInitEmptyUnicodeString(&driveLetterName,driveLetterNameBuf,sizeof(driveLetterNameBuf));
                RtlAppendUnicodeToString(&driveLetterName, L"\\??\\");
                DriLetter[0] = c;
                DriLetter[1] = L':';
                DriLetter[2] = 0;
                RtlAppendUnicodeToString(&driveLetterName,DriLetter);

                status = QuerySymbolicLink(&driveLetterName, &linkTarget);
                if (!NT_SUCCESS(status))
                {
                        continue;
                }

                if (RtlEqualUnicodeString(&linkTarget, DeviceName, TRUE))
                {
                        ExFreePool(linkTarget.Buffer);
                        break;
                }

                ExFreePool(linkTarget.Buffer);
        }

        if (c <= L'Z')
        {
                DosName->Buffer = ExAllocatePoolWithTag(PagedPool, 3*sizeof(WCHAR), 'SOD');
                if (!DosName->Buffer)
                {
                        return STATUS_INSUFFICIENT_RESOURCES;
                }

                DosName->MaximumLength = 6;
                DosName->Length   = 4;
                *DosName->Buffer  = c;
                *(DosName->Buffer+ 1) = ':';
                *(DosName->Buffer+ 2) = 0;

                return STATUS_SUCCESS;
        }

        return status;
}

//c:\\windows\\hi.txt<--\\device\\harddiskvolume1\\windows\\hi.txt
BOOL NTAPI GetNTLinkName(WCHAR *wszNTName, WCHAR *wszFileName)
{
        UNICODE_STRING                ustrFileName = {0};
        UNICODE_STRING                ustrDosName = {0};
        UNICODE_STRING                ustrDeviceName = {0};

        WCHAR                                *pPath = NULL;
        ULONG                                i = 0;
        ULONG                                ulSepNum = 0;


        if (wszFileName == NULL ||
                wszNTName == NULL ||
                _wcsnicmp(wszNTName, L"\\device\\harddiskvolume", wcslen(L"\\device\\harddiskvolume"))!=0)
        {
                return FALSE;
        }

        ustrFileName.Buffer = wszFileName;
        ustrFileName.Length = 0;
        ustrFileName.MaximumLength = sizeof(WCHAR)*MAX_PATH;

        while(wszNTName!=L'\0')
        {

                if (wszNTName == L'\0')
                {
                        break;
                }
                if (wszNTName == L'\\')
                {
                        ulSepNum++;
                }
                if (ulSepNum == 3)
                {
                        wszNTName = UNICODE_NULL;
                        pPath = &wszNTName[i+1];
                        break;
                }
                i++;
        }

        if (pPath == NULL)
        {
                return FALSE;
        }

        RtlInitUnicodeString(&ustrDeviceName, wszNTName);

        if (!NT_SUCCESS(MyRtlVolumeDeviceToDosName(&ustrDeviceName, &ustrDosName)))
        {
                return FALSE;
        }

        RtlCopyUnicodeString(&ustrFileName, &ustrDosName);
        RtlAppendUnicodeToString(&ustrFileName, L"\\");
        RtlAppendUnicodeToString(&ustrFileName, pPath);

        ExFreePool(ustrDosName.Buffer);

        return TRUE;
}

BOOL QueryVolumeName(WCHAR ch, WCHAR * name, USHORT size)
{
        WCHAR szVolume[7] = L"\\??\\C:";
        UNICODE_STRING LinkName;
        UNICODE_STRING VolName;
        UNICODE_STRING ustrTarget;
        NTSTATUS ntStatus = 0;
       
        RtlInitUnicodeString(&LinkName, szVolume);
       
        szVolume[4] = ch;

        ustrTarget.Buffer = name;
        ustrTarget.Length = 0;
        ustrTarget.MaximumLength = size;
       
        ntStatus = QuerySymbolicLink(&LinkName, &VolName);
        if (NT_SUCCESS(ntStatus))
        {
                RtlCopyUnicodeString(&ustrTarget, &VolName);
                ExFreePool(VolName.Buffer);
        }
        return NT_SUCCESS(ntStatus);
       
}

//\\??\\c:\\windows\\hi.txt-->\\device\\harddiskvolume1\\windows\\hi.txt

BOOL NTAPI GetNtDeviceName(WCHAR * filename, WCHAR * ntname)
{
        UNICODE_STRING uVolName = {0,0,0};
        WCHAR volName[MAX_PATH] = L"";
        WCHAR tmpName[MAX_PATH] = L"";
        WCHAR chVol = L'\0';
        WCHAR * pPath = NULL;
        int i = 0;
       

        RtlStringCbCopyW(tmpName, MAX_PATH * sizeof(WCHAR), filename);
       
        for(i = 1; i < MAX_PATH - 1; i++)
        {
                if(tmpName == L':')
                {
                        pPath = &tmpName[(i + 1) % MAX_PATH];
                        chVol = tmpName[i - 1];
                        break;
                }
        }
       
        if(pPath == NULL)
        {
                return FALSE;
        }
       
        if(chVol == L'?')
        {
                uVolName.Length = 0;
                uVolName.MaximumLength = MAX_PATH * sizeof(WCHAR);
                uVolName.Buffer = ntname;
                RtlAppendUnicodeToString(&uVolName, L"\\Device\\HarddiskVolume?");
                RtlAppendUnicodeToString(&uVolName, pPath);
                return TRUE;
        }
        else if(QueryVolumeName(chVol, volName, MAX_PATH * sizeof(WCHAR)))
        {
                uVolName.Length = 0;
                uVolName.MaximumLength = MAX_PATH * sizeof(WCHAR);
                uVolName.Buffer = ntname;
                RtlAppendUnicodeToString(&uVolName, volName);
                RtlAppendUnicodeToString(&uVolName, pPath);
                return TRUE;
        }
       
        return FALSE;
}

VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
        DbgPrint("Goodbye!\n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
        UNICODE_STRING                ustrDeviceName                        = {0};
        UNICODE_STRING                ustrLinkName                        = {0};
        WCHAR                                *wszDeviceName                        = L"\\Device\\harddiskvolume1";
        NTSTATUS                        ntStatus                                = 0;
        WCHAR                        DeviceName[MAX_PATH]                = L"\\Device\\harddiskvolume1\\windows\\hi.txt";
        WCHAR                        FileName[MAX_PATH]                = {0};
        WCHAR                        szDeviceName[MAX_PATH]  = {0};

        RtlInitUnicodeString(&ustrDeviceName, wszDeviceName);

        ntStatus = MyRtlVolumeDeviceToDosName(&ustrDeviceName, &ustrLinkName);
        if (NT_SUCCESS(ntStatus))
        {
               
                DbgPrint("linkname:%wZ\n", &ustrLinkName);
                if (ustrLinkName.Buffer)
                {
                        ExFreePool(ustrLinkName.Buffer);
                }
        }
        if (GetNTLinkName(DeviceName, FileName))
        {
                DbgPrint("FileName:%ws\n", FileName);
                GetNtDeviceName(FileName, szDeviceName);
                DbgPrint("szDeviceName:%ws", szDeviceName);
        }

        pDriverObject->DriverUnload = DriverUnload;
       
        return STATUS_SUCCESS;

}
[/code]
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 18:16

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表