您的位置:首页 > 其它

设备名与链接名的转换

2016-04-10 01:17 302 查看
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;
}


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);
}


只能用于R0 MF实现的:
#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[i]!=L'\0')
{

if (wszNTName[i] == L'\0')
{
break;
}
if (wszNTName[i] == L'\\')
{
ulSepNum++;
}
if (ulSepNum == 3)
{
wszNTName[i] = 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[i] == 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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: