{ Prog->VolCmd - Command-line tools for viewing volumes. Shell command: VOL [subcommand] Subcommands: list - List all volumes (device, size, FS) info - Show volume details @author(Aaron Hance ) } unit app.volcmd; interface procedure init(); implementation uses core.ds.lists, memory.heap, driver.storage.mgr, driver.storage.types, core.strings, io.stdio, debug.tracer, driver.storage.vol.mgr; var g_out : POutBuf; { ---------- helpers ---------- } function wnd : uint32; begin wnd := 0; end; function str2int(s : pchar) : uint32; begin str2int := stringToInt(s); end; { Check whether a string contains only digit characters } function isNumeric(s : pchar) : boolean; var i : uint32; len : uint32; begin isNumeric := false; len := stringSize(s); if len = 0 then exit; for i := 0 to len - 1 do begin if (s[i] < '0') or (s[i] > '9') then exit; end; isNumeric := true; end; procedure print(s : pchar); begin io.stdio.bufWriteStr(g_out, s); end; procedure println(s : pchar); begin io.stdio.bufWriteStrLn(g_out, s); end; procedure printint(v : uint32); begin io.stdio.bufWriteInt(g_out, integer(v)); end; procedure printhex(v : uint32); begin io.stdio.bufWriteHex(g_out, v); end; { Print a byte count in human-readable form: B, KB, MB or GB } procedure printsize(bytes : uint32); begin if bytes >= 1073741824 then begin printint(bytes div 1073741824); print(' GB'); end else if bytes >= 1048576 then begin printint(bytes div 1048576); print(' MB'); end else if bytes >= 1024 then begin printint(bytes div 1024); print(' KB'); end else begin printint(bytes); print(' B'); end; end; { ---------- VOL LIST ---------- } procedure cmd_list(); var i : uint32; count : uint32; vol : PStorage_Volume; begin count := driver.storage.vol.mgr.get_volume_count(); if count = 0 then begin println('No volumes registered.'); exit; end; println('IDX DEVICE SIZE FS'); println('--- ------ ---- --'); for i := 0 to count - 1 do begin vol := driver.storage.vol.mgr.get_volume(i); if vol = nil then continue; print(' '); printint(i); print(' '); { Device info } if vol^.device <> nil then begin printint(vol^.device^.id); print(' ('); print(driver.storage.mgr.controller_type_2_string(vol^.device^.controller)); print(')'); end else print('?'); print(' '); { Size } printsize(vol^.sectorCount * vol^.sectorSize); print(' '); { Filesystem } if vol^.filesystem <> nil then print(vol^.filesystem^.sName) else print('none'); println(''); end; end; { ---------- VOL INFO ---------- } procedure cmd_info(params : PParamList); var idx : uint32; vol : PStorage_Volume; begin if paramCount(params) < 2 then begin println('Usage: VOL info '); exit; end; if not isNumeric(getParam(1, params)) then begin println('Error: volume index must be a number.'); exit; end; idx := str2int(getParam(1, params)); vol := driver.storage.vol.mgr.get_volume(idx); if vol = nil then begin print('Error: volume '); printint(idx); print(' not found ('); printint(driver.storage.vol.mgr.get_volume_count()); println(' volumes registered).'); exit; end; print('Sector Start: '); printint(vol^.sectorStart); println(''); print('Sector Count: '); printint(vol^.sectorCount); println(''); print('Sector Size: '); printint(vol^.sectorSize); println(' bytes'); print('Size: '); printsize(vol^.sectorCount * vol^.sectorSize); println(''); print('Free: '); if (vol^.lifecycleFlags and STORAGE_VOLUME_FLAG_FREE_UNKNOWN) <> 0 then println('Unknown') else begin printsize(vol^.freeSectors * vol^.sectorSize); println(''); end; print('Boot Drive: '); if vol^.isBootDrive then println('yes') else println('no'); print('Filesystem: '); if vol^.filesystem <> nil then println(vol^.filesystem^.sName) else println('none'); print('Device: '); if vol^.device <> nil then begin printint(vol^.device^.id); print(' ('); print(driver.storage.mgr.controller_type_2_string(vol^.device^.controller)); println(')'); end else println('none'); end; { ---------- Main dispatcher ---------- } procedure command_vol(params : PParamList; stdin_buf, stdout_buf, stderr_buf: POutBuf); var subcmd : pchar; begin g_out := stdout_buf; push_trace('VolCmd.command_vol'); if paramCount(params) = 0 then begin println('Usage: VOL '); exit; end; subcmd := getParam(0, params); if stringEquals(subcmd, 'list') then begin cmd_list(); exit; end; if stringEquals(subcmd, 'info') then begin cmd_info(params); exit; end; print('Unknown subcommand: '); println(subcmd); end; { ---------- Init ---------- } procedure init(); begin io.stdio.registerCommand('VOL', @command_vol, 'Volume information & management.'); end; end.