掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
容量について (ID:17251)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
9x系でファイルシステムがFAT32の場合、 GetDiskFreeSpaceは間違った値を返すので処理をわける必要があります。 9x系 FAT32クラスタサイズ取得方法は下記のようにします。 const CARRY_FLAG = $00000001; VWIN32_DIOC_DOS_DRIVEINFO = 6; type // DIOCレジスタ構造体 TDIOC_REGISTERS = record reg_EBX : DWORD; reg_EDX : DWORD; reg_ECX : DWORD; reg_EAX : DWORD; reg_EDI : DWORD; reg_ESI : DWORD; reg_Flags: DWORD; end; // ----------------------------------------------------------------- // 9x系 FAT32クラスタサイズ取得関数 ※取得失敗時は -1 を返す // Drive ドライブ番号 1 が A ドライブ,2 が B ドライブと続きます。 // ----------------------------------------------------------------- function GetClusterSizeFAT32(Drive: Byte): Integer; type // FAT32 拡張DPB(Device Parameter Block)構造体 TExtDPB = packed record dpb_drive : Byte; dpb_unit : Byte; dpb_sector_size : Word; // セクタサイズ dpb_cluster_mask : Byte; // クラスタ当りのセクタ数 - 1 dpb_cluster_shift : Byte; dpb_first_fat : Word; dpb_fat_count : Byte; dpb_root_entries : Word; dpb_first_sector : Word; dpb_max_cluster : Word; dpb_fat_size : Word; dpb_dir_sector : Word; dpb_reserved2 : DWORD; dpb_media : Byte; dpb_first_access : Byte; dpb_reserved3 : DWORD; dpb_next_free : Word; dpb_free_cnt : Word; extdpb_free_cnt_hi : Word; extdpb_flags : Word; extdpb_FSInfoSec : Word; extdpb_BkUpBootSec : Word; extdpb_first_sector: DWORD; extdpb_max_cluster : DWORD; extdpb_fat_size : DWORD; extdpb_root_clus : DWORD; extdpb_next_free : DWORD; end; // Int 21h Function 7302hの戻り値を格納する構造体 TDPBResult = packed record wSize: Word; DPB : TExtDPB; end; var Reg : TDIOC_REGISTERS; DPBResult : TDPBResult; hDevice : THandle; bResult : Boolean; BytesReturned: DWORD; begin Result:= -1; FillChar(DPBResult, SizeOf(TDPBResult), 0); FillChar(Reg, SizeOf(TDIOC_REGISTERS), 0); Reg.reg_EDX := Drive; // 対象のドライブ番号をDLレジスタに読込 Reg.reg_EAX := $7302; // Int 21h Function 7302h: Get_ExtDPB(FAT32) Reg.reg_EDI := DWORD(@DPBResult); // 戻り値を受け取る構造体のアドレス。 DeviceIoControlによって、ES:DIに分割される Reg.reg_ECX := SizeOf(TDPBResult); // 戻り値を受け取る構造体のサイズ Reg.reg_Flags:= CARRY_FLAG; // エラーを仮定したキャリーフラグ // 仮想ドライバ Vwin32を開く hDevice:= CreateFile('\\.\vwin32', 0, 0, nil, 0, FILE_FLAG_DELETE_ON_CLOSE, 0); if (hDevice <> INVALID_HANDLE_VALUE) then begin // Int 21h Function 7302hの呼出 try bResult:= DeviceIoControl( hDevice, VWIN32_DIOC_DOS_DRIVEINFO, @Reg, SizeOf(TDIOCRegisters), @Reg, SizeOf(TDIOCRegisters), BytesReturned, nil ); finally CloseHandle(hDevice); end; // reg_FlagsのLSBはcarry flagであり、エラーならセットされる if bResult and (Reg.reg_Flags and CARRY_FLAG = 0) then with DPBResult.DPB do Result:= (dpb_cluster_mask + 1) * dpb_sector_size; end; end; この他にも setupapi.dll の API関数を使った方法もあります。 使用関数は SetupCreateDiskSpaceList SetupDestroyDiskSpaceList SetupAddToDiskSpaceList SetupQuerySpaceRequiredOnDrive です。 こちらはクラスタギャップを考慮したディスクサイズを返してくれます。 よかったら調べてみて下さい。
←解決時は質問者本人がここをチェックしてください。
更新する
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.