C#读取硬盘物理序列号-非管理员权限

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace SCBLL.Comm
{
    [StructLayout(LayoutKind.Sequential)]
    internal struct STORAGE_PROPERTY_QUERY
    {
        public uint PropertyId;
        public uint QueryType;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
        public byte[] AdditionalParameters;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    internal struct STORAGE_DEVICE_DESCRIPTOR
    {
        public uint Version;
        public uint size;
        public byte DeviceType;
        public byte DeviceTypeModifier;
        public byte RemovableMedia;
        public byte CommandQueueing;
        public uint VendorIdOffset;
        public uint ProductIdOffset;
        public uint ProductRevisionOffset;
        public uint SerialNumberOffset;
        public uint BusType;
        public uint RawPropertiesLength;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1000)]
        public byte[] RawDeviceProperties;
    }

    public class HardDisk
    {

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern int CloseHandle(IntPtr hObject);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr CreateFile(
            string lpFileName,
            uint dwDesiredAccess,
            uint dwShareMode,
            IntPtr lpSecurityAttributes,
            uint dwCreationDisposition,
            uint dwFlagsAndAttributes,
            IntPtr hTemplateFile);

        [DllImport("Kernel32.dll")]
        static extern int DeviceIoControl(
            IntPtr hDevice,
            uint dwIoControlCode,
            ref STORAGE_PROPERTY_QUERY lpInBuffer,
            uint nInBufferSize,
            ref STORAGE_DEVICE_DESCRIPTOR lpOutBuffer,
            uint nOutBufferSize,
            ref uint lpBytesReturned,
            [Out] IntPtr lpOverlapped);

        //const uint DFP_GET_VERSION = 0x00074080;
        //const uint DFP_SEND_DRIVE_COMMAND = 0x0007c084;
        //const uint DFP_RECEIVE_DRIVE_DATA = 0x0007c088;

        //const uint GENERIC_READ = 0x80000000;
        //const uint GENERIC_WRITE = 0x40000000;
        const uint FILE_SHARE_READ = 0x00000001;
        const uint FILE_SHARE_WRITE = 0x00000002;
        //const uint Create_NEW = 1;
        const uint OPEN_EXISTING = 3;

        const uint FILE_DEVICE_MASS_STORAGE = 0x0000002d;
        const uint IOCTL_STORAGE_BASE = FILE_DEVICE_MASS_STORAGE;
        const uint FILE_DEVICE_CONTROLLER = 0x00000004;
        const uint IOCTL_SCSI_BASE = FILE_DEVICE_CONTROLLER;
        const uint METHOD_BUFFERED = 0;
        const uint FILE_ANY_ACCESS = 0;

        private static uint CTL_CODE(uint DeviceType, uint Function,
                                     uint Method, uint Access)
        {
            return ((DeviceType << 16) | (Access << 14) |
                    (Function << 2) | Method);
        }

        private static uint IOCTL_STORAGE_QUERY_PROPERTY = CTL_CODE(
                IOCTL_STORAGE_BASE, 0x500,
                METHOD_BUFFERED, FILE_ANY_ACCESS); // From winioctl.h

        public static string GetSerialNo(byte driveIndex)
        {
            switch (Environment.OSVersion.Platform)
            {
                case PlatformID.Win32Windows:
                    throw new NotSupportedException("不支持Win9x.");
                case PlatformID.Win32NT:
                    return GetHddInfoNT(driveIndex);
                case PlatformID.Win32S:
                    throw new NotSupportedException("不支持Win32s.");
                case PlatformID.WinCE:
                    throw new NotSupportedException("不支持WinCE.");
                default:
                    throw new NotSupportedException("不知道的操作系统.");
            }
        }

        private static string GetHddInfoNT(byte driveIndex)
        {
            uint bytesReturned = 0;

            IntPtr hDevice = CreateFile(
                string.Format(@"\\.\PhysicalDrive{0}", driveIndex),
                0,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                IntPtr.Zero,
                OPEN_EXISTING,
                0,
                IntPtr.Zero);
            if (hDevice == IntPtr.Zero)
            {
                throw new Exception("CreateFile faild.");
            }
            STORAGE_PROPERTY_QUERY query = new STORAGE_PROPERTY_QUERY();
            query.PropertyId = 0;
            query.QueryType = 0;
            STORAGE_DEVICE_DESCRIPTOR device = new STORAGE_DEVICE_DESCRIPTOR();

            if (0 == DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
                                                 ref query, (uint)Marshal.SizeOf(query),
                                                 ref device, (uint)Marshal.SizeOf(device),
                                                 ref bytesReturned,
                                                 IntPtr.Zero))
            {
                CloseHandle(hDevice);
                throw new Exception(string.Format("Drive {0} error.", driveIndex));
            }

            CloseHandle(hDevice);

            string SerialNumber = null;
            if (device.SerialNumberOffset > 0)
            {
                int n = 0;
                while (device.RawDeviceProperties[device.SerialNumberOffset - 35 + n++] != 0) ;
                byte[] buf = new byte[n];
                Array.Copy(device.RawDeviceProperties, device.SerialNumberOffset - 36, buf, 0, n);
                SerialNumber = Encoding.ASCII.GetString(buf).Trim();
            }

            return SerialNumber;
        }

    }

}
 

你可能感兴趣的:(C#)