使用Native API查询Windows硬盘分区系统物理设备号

来源:互联网 发布:pipe函数 linux 编辑:程序博客网 时间:2024/04/29 04:45
#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;// 字符串比较typedefBOOLEAN(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;// 查询对象typedefNTSTATUS(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;// 打开符号链接对象typedefNTSTATUS(WINAPI *ZWOPENSYMBOLICKLINKOBJECT)(OUT PHANDLE SymbolicLinkHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes);ZWOPENSYMBOLICKLINKOBJECT ZwOpenSymbolicLinkObject;// 查询符号链接对象typedefNTSTATUS(WINAPI *ZWQUERYSYMBOLICKLINKOBJECT)(IN HANDLE SymbolicLinkHandle,IN OUT PUNICODE_STRING TargetName,OUT PULONG ReturnLength OPTIONAL);ZWQUERYSYMBOLICKLINKOBJECT ZwQuerySymbolicLinkObject;// 关闭已经打开的对象typedefNTSTATUS(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)     // ntsubauthHMODULE 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;}#elseCopyMemory(lpszTargetPath, szDeviceName.Buffer, szDeviceName.Length)#endif}GlobalFree(szDeviceName.Buffer);}GlobalFree(lpszSymbolicLink);return bRet;}



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

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


0 0
原创粉丝点击