C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: USBフラッシュメモリのサイズを取得したい


(過去ログ 59 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■33615 / inTopicNo.1)  USBフラッシュメモリのサイズを取得したい
  
□投稿者/ DELI (1回)-(2009/03/05(Thu) 14:15:06)

分類:[.NET 全般] 

環境:
  VisualStudio2008
  .NetFramework3.5SP1


ストレージの物理サイズを取得する必要が有ったので、WMIクラスから情報を取得したのですが、
USBフラッシュメモリだと実際のサイズより小さいサイズがとれてきました。
何が駄目なのか、どうやれば物理サイズをとれるのかが分かる人がいらっしゃいましたら教示を
お願いします。

FullSpeed対応の32MUSBフラッシュメモリを刺した状態で以下のコードを実行すると

  Console.WriteLine("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
  ManagementClass mc = new ManagementClass("Win32_DiskDrive");
  ManagementObjectCollection moc = mc.GetInstances();
  foreach (ManagementObject mo in moc)
  {
      Console.WriteLine("-------------------------------------------------");
      foreach (PropertyData property in mo.Properties)
      {
          Console.WriteLine("{0} = {1}", property.Name, property.Value);
      }
  }
  Console.WriteLine("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");


こういう結果が得られた(必要無いと思った行は消してます)

-------------------------------------------------
Caption = BUFFALO ClipDrive USB Device
CreationClassName = Win32_DiskDrive
Description = ディスク ドライブ
DeviceID = \\.\PHYSICALDRIVE1
InterfaceType = USB
Name = \\.\PHYSICALDRIVE1
Size = 24675840
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

「Size = 24675840」って明らかにサイズが違う。
試しに論理ドライブのサイズを取ると「32493568」がとれてきた。それっぽい値。
物理ドライブのサイズが論理ドライブのサイズより小さい理由も分かりません。

Win32_DiskDriveのSizeって物理的なサイズじゃない???でも、内蔵HDDはそれっぽい値なんですが。

引用返信 編集キー/
■33657 / inTopicNo.2)  Re[1]: USBフラッシュメモリのサイズを取得したい
□投稿者/ オショウ (105回)-(2009/03/06(Fri) 06:13:27)
> ストレージの物理サイズを取得する必要が有ったので、WMIクラスから情報を取得したのですが、
> USBフラッシュメモリだと実際のサイズより小さいサイズがとれてきました。
> 何が駄目なのか、どうやれば物理サイズをとれるのかが分かる人がいらっしゃいましたら教示を
> お願いします。

  http://dobon.net/vb/dotnet/file/freespace.html

  ここの記事の内容をお試し下さい。

以上。
引用返信 編集キー/
■33662 / inTopicNo.3)  Re[2]: USBフラッシュメモリのサイズを取得したい
□投稿者/ DELI (6回)-(2009/03/06(Fri) 12:51:59)
No33657 (オショウ さん) に返信

>   http://dobon.net/vb/dotnet/file/freespace.html
>
>   ここの記事の内容をお試し下さい。

リンク先の記事に書かれているのは論理ドライブのサイズですよね。
既に書いていますが、そちらは、それっぽい値がとれます。
今回欲しいのはUSBフラッシュメモリ全体のサイズなので、パーティションで切った後のサイズでは不足です。
引用返信 編集キー/
■33690 / inTopicNo.4)  Re[3]: USBフラッシュメモリのサイズを取得したい
□投稿者/ オショウ (106回)-(2009/03/06(Fri) 23:26:54)
アンフォーマット時のサイズは厳密には取れません。
何らかのフォーマットを行うことでサイズが確定します。

フォーマットの種類を考慮しませんが、こんなのは如何?

  http://oshiete1.goo.ne.jp/qa2784627.html

  こんなのもあるけど・・・

  http://www.dinop.com/vc/diskinfo2.html

C++/CLIでマネージドから呼ぶようにしてみましたが、一応
それらしい値は取れますね!

以上。参考まで
引用返信 編集キー/
■33693 / inTopicNo.5)  Re[4]: USBフラッシュメモリのサイズを取得したい
□投稿者/ dogatana (43回)-(2009/03/07(Sat) 09:58:58)
No33690 (オショウ さん) に返信
> アンフォーマット時のサイズは厳密には取れません。
> 何らかのフォーマットを行うことでサイズが確定します。

Win32APIであればDeviceIoControlでIOCTL_DISK_GET_DRIVE_GEOMETRY_EXを使えます。

これで得られたDISK_GEOMETRY_EX構造体のDiskSizeメンバに物理ドライブのサイズが
入ります。このメンバ以外にDISK_GEOMETRY構造体があり、中にCHSの情報があります
が、それらで計算しても正しいサイズが得られませんので、要注意。

物理ドライブなので、フォーマットには関係なく、たとえMBRが壊れてても問題なく
読めます。

問題は.NETから呼べるかですが、.NET知らないのでさっぱり分かりません。^^


引用返信 編集キー/
■33695 / inTopicNo.6)  Re[5]: USBフラッシュメモリのサイズを取得したい
□投稿者/ オショウ (108回)-(2009/03/07(Sat) 12:08:58)
> 問題は.NETから呼べるかですが、.NET知らないのでさっぱり分かりません。^^

  わざわざVBやC#にしなくても、C++/CLIで書けばマネージドなので
  そのクラスをVBやC#から呼べます。

  どうしてもVBやC#のみで・・・と言うのであれば

  http://forum.softpedia.com/lofiversion/index.php/t15647.html

  各種宣言は・・・

  http://www.pinvoke.net/index.aspx

  ここで検索して拾えます。

  参考までに

※ C++のヘッダーファイルに既に各種宣言が為されていますので、
  わざわざVBやC#で置き換えたかなりの量の宣言部分を再定義する
  のは労力の無駄かと・・・

  因みに、C++/CLIで書いた実行部分のソースコードのみなら・・・

static void MarshalString( String ^ s, std::wstring& os ){

using namespace Runtime::InteropServices;
const wchar_t* chars = (const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();

os = chars;

Marshal::FreeHGlobal(IntPtr((void*)chars));

}


ULONGLONG DiskSize::GetDiskSize(int DrvNo){

String^ DriveName;
std::wstring devicename;

using namespace Text;
DriveName = String::Format ("\\\\.\\PhysicalDrive{0}",DrvNo);

MarshalString(DriveName, devicename);

HANDLE hDevice;

hDevice = CreateFile(devicename.c_str(), GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if(!hDevice){
return 0;
}

DISK_GEOMETRY geo;
BOOL res;
DWORD res_bytes;

res = DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geo, sizeof(geo), &res_bytes, NULL);
if(!res){
CloseHandle(hDevice);
return 0;
}

ULONGLONG totalsize;

totalsize = geo.SectorsPerTrack * geo.BytesPerSector * geo.TracksPerCylinder;
totalsize = (totalsize * geo.Cylinders.QuadPart);

CloseHandle(hDevice);

return totalsize;

}

以上。
引用返信 編集キー/
■33870 / inTopicNo.7)  Re[5]: USBフラッシュメモリのサイズを取得したい
□投稿者/ DELI (16回)-(2009/03/12(Thu) 12:05:02)
2009/03/12(Thu) 12:05:56 編集(投稿者)

すみません。動作確認のための時間をなかなかとれなかったので、返答が遅くなりました。

No33693 (dogatana さん) に返信
> ■No33690 (オショウ さん) に返信
>>アンフォーマット時のサイズは厳密には取れません。
>>何らかのフォーマットを行うことでサイズが確定します。
>
> Win32APIであればDeviceIoControlでIOCTL_DISK_GET_DRIVE_GEOMETRY_EXを使えます。
>
> これで得られたDISK_GEOMETRY_EX構造体のDiskSizeメンバに物理ドライブのサイズが
> 入ります。このメンバ以外にDISK_GEOMETRY構造体があり、中にCHSの情報があります
> が、それらで計算しても正しいサイズが得られませんので、要注意。

C++/CLIで書いて動作を確認すると、期待する値が帰って来ました。
非常に助かりました。ありがとう御座います。

[ついでに]
おっしゃられるとおり、DISK_GEOMETRY構造体のシリンダ数やセクタ数から計算しても、
期待する値にはなりません。オショウさんの貼ってくれたコードでは、私が初めに書いた
サイズの[24675840]がとれてきました。
ということは、WMIのDiskDriveのSizeはDISK_GEOMETRY構造体の値から計算で求められて
いるという事でしょうね。
となると、気になるのはWMIにディスクサイズは入ってないかって事ですが、ざっとクラスを
眺めても見つかりません。諦めろって事かな。
せっかくC#でプログラムを書いているので、手軽に情報をとれれば嬉しいのですが、諦めます。
(取得が可能で有るという事と手軽であるという事は大きく違う・・・・)

あと、計算で求めたものと違うサイズなのは何でだろう。
HDDの内周と外周のセクタ数の差?でも、USBフラッシュメモリには関係無い気がする。
まさか、どうせ信頼出来ない値だからと言うことで適当に設定されてるとかwww
※知っている人が居たらヒントだけでも教えてくれると有り難いです

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -