设备名与链接名的转换
2016-04-10 01:17
302 查看
MyQueryDosDeviceW从ReactOS的源码里拷贝的
兼容R0/R3
TA实现的:
只能用于R0 MF实现的:
兼容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; }
相关文章推荐
- 写在前面
- 我的开发之路正式开启
- MongoDB在Windows32bit(linux)下配置成自动开启的服务器注意事项
- iOS之蓝牙开发
- 线段树
- salesforce 零基础开发入门学习(十三)salesforce中JSON的使用
- 使用stringstream对象简化类型转换
- 一场BC的台前幕后
- 《Linux内核设计与实现》第八周读书笔记——第四章 进程调度
- 使用eclipse编译ns3
- hbase 异常解决
- 内部排序算法相关优化及总结(二)
- Android性能优化-内存泄露的检查与处理
- MySQL多实例配置
- 八皇后求解方法(递归求解)
- 用struts2框架中iframe对应的jsp页面的不到action的值
- StudyJams-第02课_线性布局(LinearLayout)、相对布局(RelativeLayout)、填充(padding)、边距(margin)
- 【ios开发学习】常见问题积累
- 跨站脚本攻击(XSS)——常见网站攻击手段原理与防御
- swift 汉字转拼音