您的位置:首页 > 其它

使用Native API查询Windows硬盘分区系统设备名称

2016-02-01 10:29 507 查看


标签:
windowsapiattributeswinapistringobject

2012-09-08 21:12
1932人阅读 评论(0)
收藏
举报



分类:
Win应用(24)




作者同类文章X

版权声明:本文为博主原创文章,未经博主允许不得转载。

[cpp]
view plain
copy
print?

#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>
// 定义函数返回值
typedef ULONG NTSTATUS;
// 宽字节字符串结构定义

typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

// 对象属性定义

typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
UNICODE_STRING *ObjectName;
ULONG Attributes;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

// 基本信息定义

typedef struct _DIRECTORY_BASIC_INFORMATION {
UNICODE_STRING ObjectName;
UNICODE_STRING ObjectTypeName;
} DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION;

// 返回值或状态类型定义
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define DIRECTORY_QUERY (0x0001)
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
#define STATUS_MORE_ENTRIES ((NTSTATUS)0x00000105L)
#define STATUS_NO_MORE_ENTRIES ((NTSTATUS)0x8000001AL)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
#define SYMBOLIC_LINK_QUERY (0x0001)
#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)
// 初始化对象属性宏定义
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES );\
(p)->RootDirectory = r;\
(p)->Attributes = a;\
(p)->ObjectName = n;\
(p)->SecurityDescriptor = s;\
(p)->SecurityQualityOfService = NULL;\
}

// 字符串初始化
typedef VOID (CALLBACK* RTLINITUNICODESTRING)(PUNICODE_STRING, PCWSTR);
RTLINITUNICODESTRING RtlInitUnicodeString;
// 字符串比较
typedef
BOOLEAN
(WINAPI *RTLEQUALUNICODESTRING)(
const UNICODE_STRING *String1,
const UNICODE_STRING *String2,
BOOLEAN CaseInSensitive
);
RTLEQUALUNICODESTRING RtlEqualUnicodeString;
// 打开对象
typedef NTSTATUS (WINAPI *ZWOPENDIRECTORYOBJECT)(
OUT PHANDLE DirectoryHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
ZWOPENDIRECTORYOBJECT ZwOpenDirectoryObject;
// 查询对象
typedef
NTSTATUS
(WINAPI *ZWQUERYDIRECTORYOBJECT)(
IN HANDLE DirectoryHandle,
OUT PVOID Buffer,
IN ULONG BufferLength,
IN BOOLEAN ReturnSingleEntry,
IN BOOLEAN RestartScan,
IN OUT PULONG Context,
OUT PULONG ReturnLength OPTIONAL
);
ZWQUERYDIRECTORYOBJECT ZwQueryDirectoryObject;
// 打开符号链接对象
typedef
NTSTATUS
(WINAPI *ZWOPENSYMBOLICKLINKOBJECT)(
OUT PHANDLE SymbolicLinkHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
ZWOPENSYMBOLICKLINKOBJECT ZwOpenSymbolicLinkObject;
// 查询符号链接对象
typedef
NTSTATUS
(WINAPI *ZWQUERYSYMBOLICKLINKOBJECT)(
IN HANDLE SymbolicLinkHandle,
IN OUT PUNICODE_STRING TargetName,
OUT PULONG ReturnLength OPTIONAL
);
ZWQUERYSYMBOLICKLINKOBJECT ZwQuerySymbolicLinkObject;
// 关闭已经打开的对象
typedef
NTSTATUS
(WINAPI *ZWCLOSE)(
IN HANDLE Handle
);
ZWCLOSE ZwClose;

#define InitObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}

#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009AL) // ntsubauth


HMODULE hNtdll = NULL;

BOOL LoadNtdllModule(void)
{
hNtdll = LoadLibrary(_T("ntdll.dll" ));
if ( NULL == hNtdll ) {
_tprintf(_T("[%s]--Load ntdll.dll failed(%ld).\r\n"), __FUNCTION__, GetLastError());
return FALSE;
}
return TRUE;
}

void FreeNtdllModule(void)
{
if (hNtdll) {
FreeLibrary(hNtdll);
}
}

BOOL InitNtdllAPI(void)
{
RtlInitUnicodeString = (RTLINITUNICODESTRING)GetProcAddress( hNtdll, "RtlInitUnicodeString");
RtlEqualUnicodeString = (RTLEQUALUNICODESTRING)GetProcAddress( hNtdll, "RtlEqualUnicodeString");
ZwOpenDirectoryObject = (ZWOPENDIRECTORYOBJECT)GetProcAddress( hNtdll, "ZwOpenDirectoryObject");
ZwQueryDirectoryObject = (ZWQUERYDIRECTORYOBJECT)GetProcAddress( hNtdll, "ZwQueryDirectoryObject");
ZwOpenSymbolicLinkObject = (ZWOPENSYMBOLICKLINKOBJECT)GetProcAddress( hNtdll, "ZwOpenSymbolicLinkObject");
ZwQuerySymbolicLinkObject = (ZWQUERYSYMBOLICKLINKOBJECT)GetProcAddress( hNtdll, "ZwQuerySymbolicLinkObject");
ZwClose = (ZWCLOSE)GetProcAddress( hNtdll, "ZwClose");

if (!RtlInitUnicodeString
|| !RtlEqualUnicodeString
|| !ZwOpenDirectoryObject
|| !ZwQueryDirectoryObject
|| !ZwOpenSymbolicLinkObject
|| !ZwQuerySymbolicLinkObject
|| !ZwClose){
return FALSE;
}
return TRUE;
}

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

InitObjectAttributes(&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 = (PWSTR)GlobalAlloc(GPTR, LinkTarget->MaximumLength);
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)) {
GlobalFree(LinkTarget->Buffer);
}

return status;
}

BOOL QueryHardiskVolume(UINT nDiskNo, UINT nPartNo, LPTSTR lpszTargetPath, DWORD dwLength)
{
NTSTATUS status;
UNICODE_STRING szSymbolicLink;
UNICODE_STRING szDeviceName;
WCHAR *lpszSymbolicLink;
CHAR *_lpszTargetPath;
BOOL bRet = FALSE;
lpszSymbolicLink = (PWSTR)GlobalAlloc(GPTR, MAX_PATH * sizeof(WCHAR));
if (!lpszSymbolicLink){
return FALSE;
}
wsprintfW(lpszSymbolicLink, L"\\Device\\Harddisk%u\\Partition%u", nDiskNo, nPartNo);

//RtlInitUnicodeString(&szSymbolicLink, L"\\??\\C:");
//RtlInitUnicodeString(&szSymbolicLink, L"\\??\\Harddisk0Partition1");
//RtlInitUnicodeString(&szSymbolicLink, L"\\Device\\Harddisk0\\Partition1");
RtlInitUnicodeString(&szSymbolicLink, lpszSymbolicLink);

status = QuerySymbolicLink(&szSymbolicLink, &szDeviceName);
if (STATUS_SUCCESS == status){
_tprintf(_T("[%S] => [%S]\n"), szSymbolicLink.Buffer, szDeviceName.Buffer);
if (szDeviceName.Length <= dwLength) {
#ifndef _UNICODE
_lpszTargetPath = WideCharToAnsi(szDeviceName.Buffer);
if (_lpszTargetPath){
//CopyMemory(lpszTargetPath, _lpszTargetPath, lstrlenA(_lpszTargetPath));
lstrcpyA(lpszTargetPath, _lpszTargetPath);
bRet = TRUE;
delete [] _lpszTargetPath;
}
#else
CopyMemory(lpszTargetPath, szDeviceName.Buffer, szDeviceName.Length)
#endif
}
GlobalFree(szDeviceName.Buffer);
}
GlobalFree(lpszSymbolicLink);
return bRet;
}

#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>
// 定义函数返回值
typedef ULONG NTSTATUS;
// 宽字节字符串结构定义

typedef struct _UNICODE_STRING {
	USHORT  Length;
	USHORT  MaximumLength;
	PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

// 对象属性定义

typedef struct _OBJECT_ATTRIBUTES {
	ULONG Length;
	HANDLE RootDirectory;
	UNICODE_STRING *ObjectName;
	ULONG Attributes;
	PSECURITY_DESCRIPTOR SecurityDescriptor;
	PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

// 基本信息定义

typedef struct _DIRECTORY_BASIC_INFORMATION {
	UNICODE_STRING ObjectName;
	UNICODE_STRING ObjectTypeName;
} DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION;

// 返回值或状态类型定义
#define OBJ_CASE_INSENSITIVE      0x00000040L
#define DIRECTORY_QUERY           (0x0001)
#define STATUS_SUCCESS            ((NTSTATUS)0x00000000L) // ntsubauth
#define STATUS_MORE_ENTRIES       ((NTSTATUS)0x00000105L)
#define STATUS_NO_MORE_ENTRIES    ((NTSTATUS)0x8000001AL)
#define STATUS_BUFFER_TOO_SMALL   ((NTSTATUS)0xC0000023L)
#define SYMBOLIC_LINK_QUERY       (0x0001)
#define SYMBOLIC_LINK_ALL_ACCESS  (STANDARD_RIGHTS_REQUIRED | 0x1)
// 初始化对象属性宏定义
#define InitializeObjectAttributes( p, n, a, r, s ) { \
	(p)->Length = sizeof( OBJECT_ATTRIBUTES );\
	(p)->RootDirectory = r;\
	(p)->Attributes = a;\
	(p)->ObjectName = n;\
	(p)->SecurityDescriptor = s;\
	(p)->SecurityQualityOfService = NULL;\
}

// 字符串初始化
typedef VOID (CALLBACK* RTLINITUNICODESTRING)(PUNICODE_STRING, PCWSTR);
RTLINITUNICODESTRING RtlInitUnicodeString;
// 字符串比较
typedef
	BOOLEAN
	(WINAPI *RTLEQUALUNICODESTRING)(
	const UNICODE_STRING *String1,
	const UNICODE_STRING *String2,
	BOOLEAN CaseInSensitive
	);
RTLEQUALUNICODESTRING RtlEqualUnicodeString;
// 打开对象
typedef NTSTATUS (WINAPI *ZWOPENDIRECTORYOBJECT)(
	OUT PHANDLE DirectoryHandle,
	IN ACCESS_MASK DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes
	);
ZWOPENDIRECTORYOBJECT ZwOpenDirectoryObject;
// 查询对象
typedef
	NTSTATUS
	(WINAPI *ZWQUERYDIRECTORYOBJECT)(
	IN HANDLE DirectoryHandle,
	OUT PVOID Buffer,
	IN ULONG BufferLength,
	IN BOOLEAN ReturnSingleEntry,
	IN BOOLEAN RestartScan,
	IN OUT PULONG Context,
	OUT PULONG ReturnLength OPTIONAL
	);
ZWQUERYDIRECTORYOBJECT ZwQueryDirectoryObject;
// 打开符号链接对象
typedef
	NTSTATUS
	(WINAPI *ZWOPENSYMBOLICKLINKOBJECT)(
	OUT PHANDLE SymbolicLinkHandle,
	IN ACCESS_MASK DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes
	);
ZWOPENSYMBOLICKLINKOBJECT ZwOpenSymbolicLinkObject;
// 查询符号链接对象
typedef
	NTSTATUS
	(WINAPI *ZWQUERYSYMBOLICKLINKOBJECT)(
	IN HANDLE SymbolicLinkHandle,
	IN OUT PUNICODE_STRING TargetName,
	OUT PULONG ReturnLength OPTIONAL
	);
ZWQUERYSYMBOLICKLINKOBJECT ZwQuerySymbolicLinkObject;
// 关闭已经打开的对象
typedef
	NTSTATUS
	(WINAPI *ZWCLOSE)(
	IN HANDLE Handle
	);
ZWCLOSE ZwClose;

#define InitObjectAttributes( p, n, a, r, s ) { \
	(p)->Length = sizeof( OBJECT_ATTRIBUTES );          \
	(p)->RootDirectory = r;                             \
	(p)->Attributes = a;                                \
	(p)->ObjectName = n;                                \
	(p)->SecurityDescriptor = s;                        \
	(p)->SecurityQualityOfService = NULL;               \
}

#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_INSUFFICIENT_RESOURCES    ((NTSTATUS)0xC000009AL)     // ntsubauth

HMODULE hNtdll = NULL;

BOOL LoadNtdllModule(void)
{
	hNtdll = LoadLibrary(_T("ntdll.dll" ));
	if ( NULL == hNtdll ) {
		_tprintf(_T("[%s]--Load ntdll.dll failed(%ld).\r\n"), __FUNCTION__, GetLastError());
		return FALSE;
	}
	return TRUE;
}

void FreeNtdllModule(void)
{
	if (hNtdll) {
		FreeLibrary(hNtdll);
	}
}

BOOL InitNtdllAPI(void)
{
	RtlInitUnicodeString      = (RTLINITUNICODESTRING)GetProcAddress( hNtdll, "RtlInitUnicodeString");
	RtlEqualUnicodeString     = (RTLEQUALUNICODESTRING)GetProcAddress( hNtdll, "RtlEqualUnicodeString");
	ZwOpenDirectoryObject     = (ZWOPENDIRECTORYOBJECT)GetProcAddress( hNtdll, "ZwOpenDirectoryObject");
	ZwQueryDirectoryObject    = (ZWQUERYDIRECTORYOBJECT)GetProcAddress( hNtdll, "ZwQueryDirectoryObject");
	ZwOpenSymbolicLinkObject  = (ZWOPENSYMBOLICKLINKOBJECT)GetProcAddress( hNtdll, "ZwOpenSymbolicLinkObject");
	ZwQuerySymbolicLinkObject = (ZWQUERYSYMBOLICKLINKOBJECT)GetProcAddress( hNtdll, "ZwQuerySymbolicLinkObject");
	ZwClose                   = (ZWCLOSE)GetProcAddress( hNtdll, "ZwClose");

	if (!RtlInitUnicodeString
		|| !RtlEqualUnicodeString
		|| !ZwOpenDirectoryObject
		|| !ZwQueryDirectoryObject
		|| !ZwOpenSymbolicLinkObject
		|| !ZwQuerySymbolicLinkObject
		|| !ZwClose){
		return FALSE;
	}
	return TRUE;
}

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

	InitObjectAttributes(&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 = (PWSTR)GlobalAlloc(GPTR, LinkTarget->MaximumLength);
	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)) {
		GlobalFree(LinkTarget->Buffer);
	}

	return status;
}

BOOL QueryHardiskVolume(UINT nDiskNo, UINT nPartNo, LPTSTR lpszTargetPath, DWORD dwLength)
{
	NTSTATUS status;
	UNICODE_STRING szSymbolicLink;
	UNICODE_STRING szDeviceName;
	WCHAR *lpszSymbolicLink;
	CHAR *_lpszTargetPath;
	BOOL bRet = FALSE;
	lpszSymbolicLink = (PWSTR)GlobalAlloc(GPTR, MAX_PATH * sizeof(WCHAR));
	if (!lpszSymbolicLink){
		return FALSE;
	}
	wsprintfW(lpszSymbolicLink, L"\\Device\\Harddisk%u\\Partition%u", nDiskNo, nPartNo);

	//RtlInitUnicodeString(&szSymbolicLink, L"\\??\\C:");
	//RtlInitUnicodeString(&szSymbolicLink, L"\\??\\Harddisk0Partition1");
	//RtlInitUnicodeString(&szSymbolicLink, L"\\Device\\Harddisk0\\Partition1");
	RtlInitUnicodeString(&szSymbolicLink, lpszSymbolicLink);

	status = QuerySymbolicLink(&szSymbolicLink, &szDeviceName);
	if (STATUS_SUCCESS == status){
		_tprintf(_T("[%S] => [%S]\n"), szSymbolicLink.Buffer, szDeviceName.Buffer);
		if (szDeviceName.Length <= dwLength) {
#ifndef _UNICODE
			_lpszTargetPath = WideCharToAnsi(szDeviceName.Buffer);			
			if (_lpszTargetPath){
				//CopyMemory(lpszTargetPath, _lpszTargetPath, lstrlenA(_lpszTargetPath));
				lstrcpyA(lpszTargetPath, _lpszTargetPath);
				bRet = TRUE;
				delete [] _lpszTargetPath;
			}
#else
			CopyMemory(lpszTargetPath, szDeviceName.Buffer, szDeviceName.Length)
#endif
		}
		GlobalFree(szDeviceName.Buffer);
	}
	GlobalFree(lpszSymbolicLink);
	return bRet;
}


测试: 获取系统第一块物理硬盘第一分区设备名称

[cpp]
view plain
copy
print?

TCHAR szDeviceName[MAX_PATH];
if (LoadNtdllModule()) {
if(InitNtdllAPI()){
QueryHardiskVolume(0, 1, szDeviceName, MAX_PATH);
}
FreeNtdllModule();
}

TCHAR szDeviceName[MAX_PATH];
    if (LoadNtdllModule()) {
        if(InitNtdllAPI()){
            QueryHardiskVolume(0, 1, szDeviceName, MAX_PATH);             
        }
        FreeNtdllModule();
    }


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