以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 Dot NET,C#,ASP,VB 』  (http://bbs.xml.org.cn/list.asp?boardid=43)
----  用C#访问硬盘物理扇区和逻辑扇区的方法  (http://bbs.xml.org.cn/dispbbs.asp?boardid=43&rootid=&id=125322)


--  作者:卷积内核
--  发布时间:7/23/2012 9:45:00 AM

--  用C#访问硬盘物理扇区和逻辑扇区的方法

int __fastcall C_BA580_PATH::GetUsbDevice(AnsiString* strUsbDriverName)
{
  char lpBuffer[MAX_DRIVER_STRING_LENGHT];
  char*lpSingleDevice;

  DWORD nBufferLength = MAX_DRIVER_STRING_LENGHT;
  DWORD dwSignleDeviceBufferIndex =0, dwDeviceNum =0;

  lpSingleDevice = (char*)malloc(sizeof(char)* MAX_DRIVER_STRING_LENGHT);
  if(lpSingleDevice == NULL)
  {
  ShowMessage("系统分配内存错误");
  return 0;
  }
  memset(lpSingleDevice,0x0,MAX_DRIVER_STRING_LENGHT);
  memset(lpBuffer,0x0,MAX_DRIVER_STRING_LENGHT);

  nBufferLength = GetLogicalDriveStrings(nBufferLength,lpBuffer); //列举盘符

  for(DWORD i =0; i< nBufferLength; i++)
  {
  if(lpBuffer[i] != 0x00) //分离各个离盘符
  {
  lpSingleDevice[dwSignleDeviceBufferIndex] = lpBuffer[i];
  dwSignleDeviceBufferIndex++;
  continue;
  }
  lpSingleDevice[dwSignleDeviceBufferIndex] = 0x0;
  dwSignleDeviceBufferIndex = 0;
  if(*lpSingleDevice == 'A') //A盘 不需要
  continue;
  if(GetDriveType(lpSingleDevice) == DRIVE_REMOVABLE) //获取移动磁盘
  {
  strUsbDriverName[dwDeviceNum] = lpSingleDevice ;
  dwDeviceNum++;
  }

  }
  free(lpSingleDevice);
  return dwDeviceNum;
}

2.获取PID,UID,序列号信息

int CUSBPortDlg::GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)
{
  HDEVINFO hDevInfoSet; //设备信息集句柄;
  SP_DEVICE_INTERFACE_DATA ifdata;
  PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;
  int nCount;
  BOOL bResult;
LPGUID UsbClassGuid;
CHANGER_PRODUCT_DATA ProductBuffer;
unsigned long BytesReturned;
  
UsbClassGuid = (LPGUID)malloc(sizeof(GUID));
UsbClassGuid->Data1 = 0xa5dcbf10L;
UsbClassGuid->Data2 = 0x6530;
UsbClassGuid->Data3 = 0x11d2;
UsbClassGuid->Data4[0] = 0x90;
UsbClassGuid->Data4[1] = 0x1F;
UsbClassGuid->Data4[2] = 0x00;
UsbClassGuid->Data4[3] = 0xC0;
UsbClassGuid->Data4[4] = 0x4F;
UsbClassGuid->Data4[5] = 0xB9;
UsbClassGuid->Data4[6] = 0x51;
UsbClassGuid->Data4[7] = 0xED;  

  // 取得一个该GUID相关的设备信息集句柄
  hDevInfoSet = SetupDiGetClassDevs(UsbClassGuid, // class GUID
  NULL, // 无关键字
  NULL, // 不指定父窗口句柄
  DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备
  
  // 失败...
  if (hDevInfoSet == INVALID_HANDLE_VALUE)
  {
  return 0;
  }
  
  // 申请设备接口数据空间
  pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);
  
  pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  
  nCount = 0;
  bResult = TRUE;
  
  // 设备序号=0,1,2... 逐一测试设备接口,到失败为止
  while (bResult)
  {
  ifdata.cbSize = sizeof(ifdata);
   
  // 枚举符合该GUID的设备接口
  bResult = ::SetupDiEnumDeviceInterfaces(
  hDevInfoSet, // 设备信息集句柄
  NULL, // 不需额外的设备描述
  UsbClassGuid, // GUID
  (ULONG)nCount, // 设备信息集里的设备序号
  &ifdata); // 设备接口信息
   
  if (bResult)
  {
  // 取得该设备接口的细节(设备路径)
  bResult = SetupDiGetInterfaceDeviceDetail(
  hDevInfoSet, // 设备信息集句柄
  &ifdata, // 设备接口信息
  pDetail, // 设备接口细节(设备路径)
  INTERFACE_DETAIL_SIZE, // 输出缓冲区大小
  NULL, // 不需计算输出缓冲区大小(直接用设定值)
  NULL); // 不需额外的设备描述
  if (bResult)
  {
  // 复制设备路径到输出缓冲区
  ::strcpy(pszDevicePath[nCount], pDetail->DevicePath);
  // 调整计数值
  nCount++;
  }
  }
  }
  // 释放设备接口数据空间
  ::GlobalFree(pDetail);
  // 关闭设备信息集句柄
  ::SetupDiDestroyDeviceInfoList(hDevInfoSet);
  return nCount;
}


--  作者:卷积内核
--  发布时间:7/23/2012 9:46:00 AM

--  
C#利用
Zgke.DriverLoader T = new Zgke.DriverLoader("C:");
byte[] Temp = T.ReadSector(0);
MessageBox.Show(T.GetString(Temp));

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using System.Windows.Forms;
namespace Zgke
{
  /// <summary>
  /// 2008-09-26
  /// 磁盘扇区
  /// </summary>
  public class DriverLoader
  {
  private const uint GENERIC_READ = 0x80000000;
  private const uint GENERIC_WRITE = 0x40000000;

  private const uint FILE_SHARE_READ = 0x00000001;
  private const uint FILE_SHARE_WRITE = 0x00000002;

  private const uint OPEN_EXISTING = 3;   

  [DllImport("kernel32.dll", SetLastError = true)]
  private static extern SafeFileHandle CreateFileA(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
   
    
  private System.IO.FileStream _DirverStream;
  private long _SectorLength = 0;   
  private SafeFileHandle _DirverHandle;

  /// <summary>
  /// 扇区数
  /// </summary>
  public long SectorLength { get { return _SectorLength; } }
  
  /// <summary>
  /// 获取磁盘扇区信息
  /// </summary>
  /// <param name="DirverName">G:</param>
  public DriverLoader(string DirverName)
  {
  if (DirverName == null && DirverName.Trim().Length == 0) return;
  _DirverHandle = CreateFileA("\\\\.\\" + DirverName.Trim(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

  _DirverStream = new System.IO.FileStream(_DirverHandle, System.IO.FileAccess.ReadWrite);

  GetSectorCount();
  }
  /// <summary>
  /// 扇区显示转换
  /// </summary>
  /// <param name="SectorBytes">扇区 长度512</param>
  /// <returns>EB 52 90 ......55 AA</returns>
  public string GetString(byte[] SectorBytes)
  {
  if (SectorBytes.Length != 512) return "";
  StringBuilder ReturnText = new StringBuilder();

  int RowCount = 0;
  for (int i = 0; i != 512; i++)
  {
  ReturnText.Append(SectorBytes[i].ToString("X02") + " ");

  if (RowCount == 15)
  {
  ReturnText.Append("\r\n");
  RowCount = -1;
  }

  RowCount++;
  }

  return ReturnText.ToString();

  }   
  /// <summary>
  /// 获取扇区数
  /// </summary>
  private void GetSectorCount()
  {
  if (_DirverStream == null) return;
  _DirverStream.Position = 0;

  byte[] ReturnByte = new byte[512];
  _DirverStream.Read(ReturnByte, 0, 512); //获取第1扇区
    
  if (ReturnByte[0] == 0xEB && ReturnByte[1] == 0x58) //DOS的好象都是32位
  {
  _SectorLength = (long)BitConverter.ToInt32(new byte[] { ReturnByte[32], ReturnByte[33], ReturnByte[34], ReturnByte[35] }, 0);
  }
  if (ReturnByte[0] == 0xEB && ReturnByte[1] == 0x52) //NTFS好象是64位
  {
  _SectorLength = BitConverter.ToInt64(new byte[] { ReturnByte[40], ReturnByte[41], ReturnByte[42], ReturnByte[43], ReturnByte[44], ReturnByte[45], ReturnByte[46], ReturnByte[47] }, 0);
  }

  }   
    
  /// <summary>
  /// 读一个扇区
  /// </summary>
  /// <param name="SectorIndex">扇区号</param>
  /// <returns>如果扇区数字大于分区信息的扇区数 返回NULL</returns>
  public byte[] ReadSector(long SectorIndex)
  {   
  if (SectorIndex > _SectorLength) return null;
  _DirverStream.Position = SectorIndex * 512;   
  byte[] ReturnByte = new byte[512];
  _DirverStream.Read(ReturnByte, 0, 512); //获取扇区
  return ReturnByte;
  }
  /// <summary>
  /// 写入数据
  /// </summary>
  /// <param name="SectorBytes">扇区 长度512</param>
  /// <param name="SectorIndex">扇区位置</param>
  public void WritSector(byte[] SectorBytes, long SectorIndex)
  {
  if (SectorBytes.Length != 512) return;
  if (SectorIndex > _SectorLength) return;
  _DirverStream.Position = SectorIndex * 512;
  _DirverStream.Write(SectorBytes, 0, 512); //写入扇区  
  }
  /// <summary>
  /// 关闭
  /// </summary>
  public void Close()
  {
  _DirverStream.Close();
  }   
  }
}


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
46.875ms