目前一点思路也没有所以希望大家给个方向,C#要通过什么手段对磁盘扇区进行读写.还是需要借助其他方法?因为从前没有做过所以请大家说的详细点,然后我好去百度查资料.谢谢

解决方案 »

  1.   

    C#语言没有这方面的支持。去找DDK文档看存储驱动的指令码吧。
      

  2.   

    如果驱动和分区已经确认
    你可以使用
    CreateFileA 看看
    http://blog.csdn.net/zgke/archive/2008/09/26/2981855.aspx
    可能对你有帮助
      

  3.   

    你可以是试试调用C++写的DLL文件,或者通过调用WIN32API来获取逻辑磁盘的详细信息。。
      

  4.   

    主要是为了挣分,楼主看着给!C++如下:
    #include<setupapi.h>
    #include<stdio.h>
    #include<objbase.h>
    #ifndef__BORLANDC__
    #pragmacomment(lib,"setupapi.lib")
    #endif
    charg_strCrnVerify[]=
    {
      0xBB,0xB6,0xD3,0xAD,0xB9,0xE2,0xC1,0xD9,0x20,0x43,
      0x2B,0x2B,0x42,0x75,0x69,0x6C,0x64,0x65,0x72,0xD1,
      0xD0,0xBE,0xBF,0x20,0x2D,0x20,0x68,0x74,0x74,0x70,
      0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x63,0x63,0x72,
      0x75,0x6E,0x2E,0x63,0x6F,0x6D
    };
    voidCrnReplaceString(LPSTRlpBuf,charc1,charc2)
    {
      intnLen=strlen(lpBuf);
      LPSTRlpTemp=newchar[nLen];
      memset(lpTemp,0,nLen);
      intj=0;
      for(inti=0;i<nLen;i++)
      {
        if(lpBuf[i]==c1)
        {
          if(c2!=0x00)
          {
            lpTemp[j]=c2;
            j++;
          }
        }
        else
        {
          lpTemp[j]=lpBuf[i];
          j++;
        }
      }
      //
      memset(lpBuf,0,nLen);
      strncpy(lpBuf,lpTemp,nLen);
      delete[]lpTemp;
    }
    //获取指定盘符的序列号(针对USB优盘有效)
    //charcDiskID:指定盘符,如'L'
    //LPSTRlpPID:序列号存放的缓冲,如charszPID[32]
    //byccrun(老妖)[email protected]
    boolCrnGetUSBDiskID(charcDiskID,LPSTRlpPID)
    {
      charszDrv[4];
      sprintf(szDrv,"%c:\",cDiskID);
      if(GetDriveType(szDrv)!=DRIVE_REMOVABLE)
      {
        MessageBox(0,"指定的盘不是有效的优盘.",
            "错误",MB_OK|MB_ICONWARNING);
        returnfalse;
      }
      charlpRegPath[512]={0};
      charlpRegValue[256]={0};
      sprintf(lpRegPath,"SYSTEM\MountedDevices");
      sprintf(lpRegValue,"\DosDevices\%c:",cDiskID);
      //
      DWORDdwDataSize(0);
      DWORDdwRegType(REG_BINARY);
      LPBYTElpRegBinData(NULL);
      LPSTRlpUSBKeyData(NULL);
      //查询注册表中映射驱动器的设备信息
      HKEYhKey;
      longlRet=::RegOpenKeyEx(
          HKEY_LOCAL_MACHINE,//rootkey
          lpRegPath,//要访问的键的位置
          0,    //
          KEY_READ, //以查询的方式访问注册表
          &hKey);  //hKEY保存此函数所打开的键的句柄
      if(lRet!=ERROR_SUCCESS)
        returnfalse;
      else
      {
        lRet=::RegQueryValueEx(hKey,//所打开的键的句柄
            lpRegValue,  //要查询的键值名
            NULL,
            &dwRegType,  //查询数据的类型
            lpRegBinData, //保存所查询的数据
            &dwDataSize); //预设置的数据长度
        if(lRet!=ERROR_SUCCESS)
        {
          ::RegCloseKey(hKey);
          returnfalse;
        }
        else
        {
          lpRegBinData=newBYTE[dwDataSize];
          lpUSBKeyData=newchar[dwDataSize];
          memset(lpUSBKeyData,0,dwDataSize);
          lRet=::RegQueryValueEx(hKey,
              lpRegValue,
              NULL,
              &dwRegType,
              lpRegBinData,
              &dwDataSize);
          if(lRet!=ERROR_SUCCESS)
          {
    // 本文转自 C++Builder 研究 - http://www.ccrun.com/article.asp?i=1021&d=fgp83l
            delete[]lpRegBinData;
            delete[]lpUSBKeyData;
            ::RegCloseKey(hKey);
            returnfalse;
          }
        }
      }
      ::RegCloseKey(hKey);
      //过滤二进制串中的无用信息(将0x0字符去除)
      intj=0;
      for(DWORDi=0;i<dwDataSize;i++)
      {
        if(lpRegBinData[i]!=0x0)
        {
          lpUSBKeyData[j]=lpRegBinData[i];
          j++;
        }
      }
      delete[]lpRegBinData;
      //I'msorry:YoucanremoveunderlineinyourCode.
      MessageBox(0,g_strCrnVerify,"CrnGetUSBDiskID",0);
      //I'msorry:Onlyfor[ZhuanTieBuLiuMing].--#
      // 截取lpUSBKeyData中的有用信息,例:7&100a16f&0
      // ??STORAGE#RemovableMedia#7&100a16f&0&RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}
      // 63 63 72 75 6E 2E 63 6F 6D
      LPSTRlpPos1=strstr(lpUSBKeyData,"#RemovableMedia#")+16;
      LPSTRlpPos2=strstr(lpUSBKeyData,"RM");
      strncpy(lpUSBKeyData,lpPos1,int(lpPos2)-int(lpPos1));
      lpUSBKeyData[int(lpPos2)-int(lpPos1)-1]=0x0;
      strcpy(lpUSBKeyData,strupr(lpUSBKeyData));
      //DiskDevice(磁盘设备)的GUID
      GUIDguidUSB;
      CLSIDFromString(L"{53f56307-b6bf-11d0-94f2-00a0c91efb8b}",&guidUSB);
      //
      HDEVINFOhUSB=SetupDiGetClassDevs(
          &guidUSB,NULL,0,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
      if(hUSB==INVALID_HANDLE_VALUE)
      {
        delete[]lpUSBKeyData;
        returnfalse;
      }
      //
      intnDevIndex=0;
      boolbSuccess;
      SP_DEVINFO_DATADevData;
      SP_DEVICE_INTERFACE_DATADevIntData;
      PSP_DEVICE_INTERFACE_DETAIL_DATAlpDevIntDetailData;
      DWORDdwBytesReturned;
      //遍历磁盘设备
      do
      {
        DevIntData.cbSize=sizeof(SP_DEVICE_INTERFACE_DATA);
        bSuccess=SetupDiEnumDeviceInterfaces(hUSB,NULL,&guidUSB,
            nDevIndex,&DevIntData)>0;
        if(bSuccess)
        {
          //获取接口详细信息
          DevData.cbSize=sizeof(SP_DEVINFO_DATA);
          dwBytesReturned=0;
          SetupDiGetDeviceInterfaceDetailA(hUSB,&DevIntData,
              NULL,0,&dwBytesReturned,&DevData);
          if(dwBytesReturned!=0&&GetLastError()==ERROR_INSUFFICIENT_BUFFER)
          {
            lpDevIntDetailData=(PSP_DEVICE_INTERFACE_DETAIL_DATA)
                GlobalAlloc(GMEM_FIXED,dwBytesReturned);
            lpDevIntDetailData->cbSize=
                sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
            if(SetupDiGetDeviceInterfaceDetailA(hUSB,&DevIntData,
                lpDevIntDetailData,dwBytesReturned,&dwBytesReturned,&DevData))
            {
              //取得设备接口详细信息并根据转化后的路径在注册表中查询
              LPSTRlpPathTemp=newchar[strlen(lpDevIntDetailData->DevicePath)+256];
              strcpy(lpRegPath,"SYSTEM\CurrentControlSet\Enum\");
              strcpy(lpPathTemp,lpDevIntDetailData->DevicePath);
              lpPos1=LPSTR(int(lpPathTemp)+4);
              lpPos2=LPSTR(int(strstr(lpPathTemp,"{"))-1);
              strncpy(lpPathTemp,lpPos1,int(lpPos2)-int(lpPos1));
              lpPathTemp[int(lpPos2)-int(lpPos1)]=0x0;
              CrnReplaceString(lpPathTemp,'#','\');
              strcat(lpRegPath,lpPathTemp);
              //
              if(RegOpenKeyEx(
                  HKEY_LOCAL_MACHINE,
                  lpRegPath,
                  0,
                  KEY_READ,
                  &hKey)==ERROR_SUCCESS)
              {
                dwRegType=REG_SZ;
                LPSTRlpRegSzData=NULL;
                dwDataSize=0;
                lRet=::RegQueryValueEx(hKey,
                    "ParentIdPrefix",
                    NULL,
                    &dwRegType,
                    (LPBYTE)lpRegSzData,
                    &dwDataSize);
                if(lRet==ERROR_SUCCESS)
                {
                  lpRegSzData=newchar[dwDataSize];
                  lRet=::RegQueryValueEx(hKey,
                      "ParentIdPrefix",
                      NULL,
                      &dwRegType,
                      (LPBYTE)lpRegSzData,
                      &dwDataSize);
                  if(lRet==ERROR_SUCCESS)
                  {
                    strcpy(lpRegSzData,strupr(lpRegSzData));
                    if(!strcmp(lpUSBKeyData,lpRegSzData))
                    {
                      //经比对,找到要查询的磁盘设备
                      strcpy(lpPathTemp,LPSTR(int(strstr(
                        lpDevIntDetailData->DevicePath,"#"))+1));
                      lpPos1=LPSTR(int(strstr(lpPathTemp,"#"))+1);
                      lpPos2=LPSTR(int(strstr(lpPathTemp,"#{")));
                      strncpy(lpPathTemp,lpPos1,int(lpPos2)-int(lpPos1));
                      lpPathTemp[int(lpPos2)-int(lpPos1)]=0x0;
                      //获取最终的磁盘序列号
                      CrnReplaceString(lpPathTemp,'&',0x00);
                      if(lpPID)
                        strncpy(lpPID,strupr(lpPathTemp),32);
                      //
                      delete[]lpRegSzData;
                      delete[]lpPathTemp;
                      GlobalFree(lpDevIntDetailData);
                      ::RegCloseKey(hKey);
                      break;
                    }
                  }
                  delete[]lpRegSzData;
                }
                ::RegCloseKey(hKey);
              }
              delete[]lpPathTemp;
              nDevIndex++;
            }
            GlobalFree(lpDevIntDetailData);
          }
        }
      }while(bSuccess);
      SetupDiDestroyDeviceInfoList(hUSB);
      delete[]lpUSBKeyData;
      returntrue;
    }
    //---------------------------------------------------------------------------
    void__fastcallTForm1::Button1Click(TObject*Sender)
    {
      charlpPID[32];
      if(CrnGetUSBDiskID('L',lpPID))
        ShowMessage(lpPID);
    }
      

  5.   

    第二中利用C++ DDK开发
    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;
    }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();
            }    
        }
    }