使用Native API查询Windows硬盘分区系统设备名称
2012-09-08 21:12
597 查看
#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; }
测试: 获取系统第一块物理硬盘第一分区设备名称
TCHAR szDeviceName[MAX_PATH]; if (LoadNtdllModule()) { if(InitNtdllAPI()){ QueryHardiskVolume(0, 1, szDeviceName, MAX_PATH); } FreeNtdllModule(); }
相关文章推荐
- 使用Native API查询Windows硬盘分区系统设备名称
- U盘在MAC系统下格式化后在windows上显示设备,无法正常使用
- Windows 到 Linux 之旅: 第 6 部分. 使用分区和文件系统
- Windows系统使用WMIC的获取硬盘ID的问题
- C/C++获取Windows系统CPU和内存及硬盘使用情况
- 使用系统光盘对硬盘进行分区及操作系统的安装
- 怎么在Linux系统下使用NTFS的U盘或者是分区以及移动硬盘-使用工具NTFS-3G
- 研究Linux系统硬盘分区,并与Windows比较(未完,优先级问题没弄明白)
- 软件项目或者产品有时候会用到本机网卡的物理MAC地址、IP地址、硬盘序列号加上使用软体名称和地址进行安全加密验证,例如结合MAC地址进行登录验证等等,当然这种项目一般在局域网内运行,能相对提高系统的安全性
- python使用WMI检测windows系统信息、硬盘信息、网卡信息的方法
- python使用WMI检测windows系统信息、硬盘信息、网卡信息的方法
- UEFI+GPT模式下的Windows系统中分区结构和默认分区大小及硬盘整数分区研究
- ubuntu和windows双系统,安装启动引导器的设备应该选择默认的整块硬盘
- windows 2003 server系统硬盘分区调整技巧
- Linux下使用blkid命令查询设备及文件系统信息的方法
- Windows 到 Linux 之旅—第 6 部分. 使用分区和文件系统
- 使用NTFS-3G在redhat 系统下挂载NTFS格式硬盘分区
- 专题:Windows 到 Linux 之旅:第 6 部分. 使用分区和文件系统
- 在vmware中使用实际物理硬盘分区,那么在虚拟系统启动后,该分区将被锁定,直到虚拟系统关机。
- 怎样将一个windows硬盘重新分区,格式化,并挂载到linux系统内