如何获得短名的长名?

c:\\Progam\\a~1\\b~1\hi~1.txt
C:
C:\\Program 与 a~1c:\\Program\\ax
C:\\program\\ax与b~1c:\\program\\ax\by
C:\\program\\ax\\by与hi~1.txt C:\\program\\ax\\by\\hiz.txt


ZwQueryDirectoryFile(hDirHandle,NULL, 0, 0, &Iosb, Buffer,
		1024,
		FileBothDirectoryInformation,
		TRUE,
		&ustrShortName, //传回与 ustrShortName Match的项
		TRUE);



在cmd中 dir /x  查看短名


代码实现:

#include <ntifs.h>
#include <ntstrsafe.h>
#include <ntddk.h>
#include <windef.h>

BOOL IsRootDirecotry(WCHAR * wszDir)
{
	SIZE_T length = wcslen(wszDir);
	
	// c:
	if((length == 2) && (wszDir[1] == L':'))
		return TRUE;
	//\\??\\c:
	if((length == 6) && 
		(_wcsnicmp(wszDir, L"\\??\\", 4) == 0) &&
		(wszDir[5] == L':'))
		return TRUE;
	//\\DosDevices\\c:
	if((length == 14) && 
		(_wcsnicmp(wszDir, L"\\DosDevices\\", 12) == 0) &&
		(wszDir[13] == L':'))
		return TRUE;
	//\\Device\\HarddiskVolume1
	if((length == 23) &&
		(_wcsnicmp(wszDir, L"\\Device\\HarddiskVolume", 22) == 0))
		return TRUE;
	
	
	return FALSE;
}


BOOL IsDirectorySep(WCHAR ch) 
{
    return (ch == L'\\' || ch == L'/');
}

//C:\\Program\\123456~1
//wszRootdir为:c:\\Program
//wszShortName为:123456~1

BOOL QueryDirectoryForLongName(
					  WCHAR * wszRootDir, 
					  WCHAR * wszShortName, 
					  WCHAR *wszLongName, 
					  ULONG ulSize)
{
	UNICODE_STRING				ustrRootDir		= {0};
	UNICODE_STRING				ustrShortName	= {0};
	UNICODE_STRING				ustrLongName	= {0};
	OBJECT_ATTRIBUTES			oa				= {0};
	IO_STATUS_BLOCK				Iosb			= {0};
	NTSTATUS					ntStatus		= 0;
	HANDLE						hDirHandle		= 0;
	BYTE						*Buffer			= NULL;
	WCHAR						*wszRoot		= NULL;
	PFILE_BOTH_DIR_INFORMATION	pInfo			= NULL;

	RtlZeroMemory(&Iosb, sizeof(IO_STATUS_BLOCK));
	Iosb.Status = STATUS_NO_SUCH_FILE;

	wszRoot = ExAllocatePoolWithTag(PagedPool,
								  MAX_PATH * sizeof(WCHAR),
								  'L2S');
	if(wszRoot == NULL)
	{
		return FALSE;
	}

	RtlZeroMemory(wszRoot, MAX_PATH * sizeof(WCHAR));

	wcsncpy(wszRoot, wszRootDir, MAX_PATH);

	RtlInitUnicodeString(&ustrRootDir, wszRoot);
	RtlInitUnicodeString(&ustrShortName, wszShortName);

	if(IsRootDirecotry(wszRoot))
		RtlAppendUnicodeToString(&ustrRootDir, L"\\");

	InitializeObjectAttributes(&oa,
							   &ustrRootDir,
							   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
							   0, 
							   0);  
	
	ntStatus = ZwCreateFile(&hDirHandle,
							GENERIC_READ | SYNCHRONIZE,
							&oa,
							&Iosb,
							0, 
							FILE_ATTRIBUTE_DIRECTORY, 
							FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 
							FILE_OPEN, 
							FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT , 
							0,
							0);

	if (!NT_SUCCESS(ntStatus)) 
	{ 
		ExFreePool(wszRoot);
		return FALSE;
	}

	ExFreePool(wszRoot);

	Buffer = ExAllocatePoolWithTag(PagedPool,
						  1024,
						  'L2S');
	if(Buffer == NULL)
	{
		ZwClose(hDirHandle);
		return FALSE;
	}

	RtlZeroMemory(Buffer, 1024);

	ntStatus = ZwQueryDirectoryFile(hDirHandle,
								NULL,
								0,
								0,
								&Iosb,
								Buffer,
								1024,
								FileBothDirectoryInformation,
								TRUE,
								&ustrShortName, //传回与 ustrShortName Match的项
								TRUE);

	if (!NT_SUCCESS(ntStatus)) 
	{
		ExFreePool(Buffer);
		ZwClose(hDirHandle);
		return FALSE;
	}

	ZwClose(hDirHandle);

	pInfo = (PFILE_BOTH_DIR_INFORMATION) Buffer;
	
	if(pInfo->FileNameLength == 0)
	{
		ExFreePool(Buffer);
		return FALSE;
	}

	ustrShortName.Length  = (USHORT)pInfo->FileNameLength;
	ustrShortName.MaximumLength = (USHORT)pInfo->FileNameLength;
	ustrShortName.Buffer = pInfo->FileName;	//长名

	if(ulSize < ustrShortName.Length)
	{	
		ExFreePool(Buffer);
		return FALSE;
	}

	ustrLongName.Length = 0;
	ustrLongName.MaximumLength = (USHORT)ulSize;
	ustrLongName.Buffer = wszLongName;

	RtlCopyUnicodeString(&ustrLongName, &ustrShortName);
	ExFreePool(Buffer);
	return TRUE;
}

BOOL QueryLongName(WCHAR * wszFullPath, WCHAR * wszLongName, ULONG size)
{
	BOOL		rtn				= FALSE;
	WCHAR *		pchStart		= wszFullPath;
	WCHAR *		pchEnd			= NULL;
	WCHAR *		wszShortName	= NULL;
	
	//c:\\Program\\Files1~1-->获得Files1~1的长名
	while(*pchStart)
	{
		if(IsDirectorySep(*pchStart))
			pchEnd = pchStart;
		
		pchStart++;
	}
	//wszFullPath=c:\\Program
	//pchEnd = Files~1
	
	if(pchEnd)
	{
		*pchEnd++ = L'\0';
		//c:\\Program\\Files1~1
		//wszFullPath:c:\\Program
		//pchEnd:Files1~1
		wszShortName = pchEnd;
		rtn = QueryDirectoryForLongName(wszFullPath, wszShortName, wszLongName, size);
		*(--pchEnd) = L'\\';
		//wszFullPath=c:\\Program\\Files1~1
	}
	return rtn;
}

//先把根目录拷贝到目标目录中,剩下的找到下一级目录是否含有~,如果有,则开始转化。
//如:c:\\Progam\\a~1\\b~1\hi~1.txt
//pchStart指向目录中前一个\\,pchEnd扫描并指向目录的下一个\\,其中如果发现了~,则是短名,需要转换。
//传c:\\Program\\a~1-->c:\\Progam\\ax
//传c:\\Program\\ax\\b~1-->c:\\Program\\ax\\by
//传c:\\Program\\ax\by\\hi~1.txt-->c:\\Program\\ax\by\\hiz.txt
BOOL ConverShortToLongName(WCHAR *wszLongName, WCHAR *wszShortName, ULONG size)
{
	WCHAR			*szResult		= NULL;
	WCHAR			*pchResult		= NULL;
	WCHAR			*pchStart		= wszShortName;
	INT				Offset			= 0;
  
	szResult = ExAllocatePoolWithTag(PagedPool,
						  sizeof(WCHAR) * (MAX_PATH * 2 + 1),
						  'L2S');

	if(szResult == NULL)
	{
		return FALSE;
	}
	
	RtlZeroMemory(szResult, sizeof(WCHAR) * (MAX_PATH * 2 + 1));
	pchResult = szResult;


	//C:\\x\\-->\\??\\c:
	if (pchStart[0] && pchStart[1] == L':') 
	{
		*pchResult++ = L'\\';
		*pchResult++ = L'?';
		*pchResult++ = L'?';
		*pchResult++ = L'\\';
		*pchResult++ = *pchStart++;
		*pchResult++ = *pchStart++;
		Offset = 4;
	}
	//\\DosDevices\\c:\\xx-->\\??\\c:
	else if (_wcsnicmp(pchStart, L"\\DosDevices\\", 12) == 0)
	{
		RtlStringCbCopyW(pchResult, sizeof(WCHAR) * (MAX_PATH * 2 + 1), L"\\??\\");
		pchResult += 4;
		pchStart += 12;
		while (*pchStart && !IsDirectorySep(*pchStart))
			*pchResult++ = *pchStart++;
		Offset = 4;
	}
	//\\Device\\HarddiskVolume1\\xx-->\\Device\\HarddiskVolume1
	else if (_wcsnicmp(pchStart, L"\\Device\\HardDiskVolume", 22) == 0)
	{
		RtlStringCbCopyW(pchResult, sizeof(WCHAR) * (MAX_PATH * 2 + 1),L"\\Device\\HardDiskVolume");
		pchResult += 22;
		pchStart += 22;
		while (*pchStart && !IsDirectorySep(*pchStart))
			*pchResult++ = *pchStart++;
	}
	//\\??\\c:\\xx-->\\??\\c:
	else if (_wcsnicmp(pchStart, L"\\??\\", 4) == 0)
	{
		RtlStringCbCopyW(pchResult, sizeof(WCHAR) * (MAX_PATH * 2 + 1), L"\\??\\");
		pchResult += 4;
		pchStart += 4;

		while (*pchStart && !IsDirectorySep(*pchStart))
			*pchResult++ = *pchStart++;
	}
	else
	{
		ExFreePool(szResult);
		return FALSE;
	}

	while (IsDirectorySep(*pchStart)) 
	{
		BOOL			bShortName			= FALSE;
		WCHAR			*pchEnd				= NULL;
		WCHAR			*pchReplacePos		= NULL;

		*pchResult++ = *pchStart++;

		pchEnd = pchStart;
		pchReplacePos = pchResult;

		while (*pchEnd && !IsDirectorySep(*pchEnd))
		{
			if(*pchEnd == L'~')
			{
				bShortName = TRUE;
			}

			*pchResult++ = *pchEnd++;
		}

		*pchResult = L'\0';
  
		if(bShortName)
		{
			WCHAR  * szLong = NULL;
			
			szLong = ExAllocatePoolWithTag(PagedPool,
						  sizeof(WCHAR) * MAX_PATH,
						  'L2S');
			if(szLong)
			{
				RtlZeroMemory(szLong,  sizeof(WCHAR) * MAX_PATH);

				if(QueryLongName(szResult, szLong, sizeof(WCHAR) * MAX_PATH))
				{
					RtlStringCbCopyW(pchReplacePos, sizeof(WCHAR) * (MAX_PATH * 2 + 1), szLong);
					pchResult = pchReplacePos + wcslen(pchReplacePos);
				}

				ExFreePool(szLong);
			}
		}

		pchStart = pchEnd;
	}

	wcsncpy(wszLongName, szResult + Offset, size/sizeof(WCHAR));
	ExFreePool(szResult);
	return TRUE;
}

BOOL IsShortNamePath(WCHAR * wszFileName)
{
	WCHAR *p = wszFileName;

	while(*p != L'\0')
	{
		if(*p == L'~')
		{
			return TRUE;
		}
		p++;
	}
	
	return FALSE;
}

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

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
	//dir /x看短名
	WCHAR	wszShortName[MAX_PATH] =L"\\??\\C:\\PROGRA~1\\COMMON~1\\MICROS~1\\VC\\1.txt";
	WCHAR	wszLongName[MAX_PATH] = {0};

	if(ConverShortToLongName(wszLongName, wszShortName, sizeof(wszLongName)))
	{
		DbgPrint("%ws\n", wszLongName);
	}

	pDriverObject->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值