2012-04-25 13 views
3

プロジェクトでは、NTFSパーティション上のすべての空き/使用済みクラスタの一覧を取得します。 これは$ Bitmapファイルをダンプして内容を解析する必要があります。

ウェブ上にはAPIや例はほとんどありませんが、動作していないようです。 $ Bitmapファイルをどこかにコピーする簡単な方法/コードサンプルがありますか?

唯一の方法はFSCTL_GET_VOLUME_BITMAPですか?理想的には私はC#でそれをやりたいと思います。

+1

そして、ここでは、私はFSCTL_GET_VOLUME_BITMAP' *は... *私はあなたがファイルシステムは完全にアイドル状態でない限り、あなたはビットマップを取得する第二は、それが古くなっていることを実現を願ってい – Gabe

+1

簡単な方法でした 'と思いました。 .. – MJZ

+0

@MJZしかしファイルを読むことはパーティションを_not_アイドルにします。パーティションはマウント解除する必要があります。 –

答えて

1

$Bitmapを直接読むのではなく、簡単なルートに行き、IOCTLを使用してください。もちろん、誰かがあなたのためにそれをしたならば、自分で行う必要はありません。

http://blogs.msdn.com/b/jeffrey_wall/archive/2004/09/13/229137.aspx

クラス全体がコードの300行以上あるので、私はそれをすべて掲載しませんが、ここではその機能があります:それは、MSDNブロガーが既にあなたのためのちょっといいラッパーを書いたことが判明します

/// <summary> 
    /// Get cluster usage for a device 
    /// </summary> 
    /// <param name="DeviceName">use "c:"</param> 
    /// <returns>a bitarray for each cluster</returns> 
    static public BitArray GetVolumeMap(string DeviceName) 
    { 
     IntPtr pAlloc = IntPtr.Zero; 
     IntPtr hDevice = IntPtr.Zero; 

     try 
     { 
      hDevice = OpenVolume(DeviceName); 

      Int64 i64 = 0; 

      GCHandle handle = GCHandle.Alloc(i64, GCHandleType.Pinned); 
      IntPtr p = handle.AddrOfPinnedObject(); 

      // alloc off more than enough for my machine 
      // 64 megs == 67108864 bytes == 536870912 bits == cluster count 
      // NTFS 4k clusters == 2147483648 k of storage == 2097152 megs == 2048 gig disk storage 
      uint q = 1024 * 1024 * 64; // 1024 bytes == 1k * 1024 == 1 meg * 64 == 64 megs 

      uint size = 0; 
      pAlloc = Marshal.AllocHGlobal((int)q); 
      IntPtr pDest = pAlloc; 

      bool fResult = DeviceIoControl(
       hDevice, 
       FSConstants.FSCTL_GET_VOLUME_BITMAP, 
       p, 
       (uint)Marshal.SizeOf(i64), 
       pDest, 
       q, 
       ref size, 
       IntPtr.Zero); 

      if (!fResult) 
      { 
       throw new Exception(Marshal.GetLastWin32Error().ToString()); 
      } 
      handle.Free(); 

      /* 
      object returned was... 
     typedef struct 
     { 
     LARGE_INTEGER StartingLcn; 
     LARGE_INTEGER BitmapSize; 
     BYTE Buffer[1]; 
     } VOLUME_BITMAP_BUFFER, *PVOLUME_BITMAP_BUFFER; 
      */ 
      Int64 StartingLcn = (Int64)Marshal.PtrToStructure(pDest, typeof(Int64)); 

      Debug.Assert(StartingLcn == 0); 

      pDest = (IntPtr)((Int64)pDest + 8); 
      Int64 BitmapSize = (Int64)Marshal.PtrToStructure(pDest, typeof(Int64)); 

      Int32 byteSize = (int)(BitmapSize/8); 
      byteSize++; // round up - even with no remainder 

      IntPtr BitmapBegin = (IntPtr)((Int64)pDest + 8); 

      byte[] byteArr = new byte[byteSize]; 

      Marshal.Copy(BitmapBegin, byteArr, 0, (Int32)byteSize); 

      BitArray retVal = new BitArray(byteArr); 
      retVal.Length = (int)BitmapSize; // truncate to exact cluster count 
      return retVal; 
     } 
     finally 
     { 
      CloseHandle(hDevice); 
      hDevice = IntPtr.Zero; 

      Marshal.FreeHGlobal(pAlloc); 
      pAlloc = IntPtr.Zero; 
     } 
    } 
+0

ここにコードを追加できますか? –

+0

@Cole:何をするコード? – Gabe

+0

リンクからの@Gabeコードなので、境界線 "リンクのみの回答"ではありません。しかし、コードブロックの大きさを見て、決して気にしないでください。 –

1

NFI.EXEあるすべてのNTFSパーティションの項目を列挙することができ、「OEMサポートツール」の一部(にするために使用):ボリュームビットマップを取得します。 $ Bitmapの内容をダンプすることもできます。

enter image description here

関連する問題