Search code examples
delphiwmidelphi-10.3-rio

Why does MSFT_PhysicalDisk always returns disk Size = 0?


I need to get some info about the physical disks using WMI MSFT_PhysicalDisk class.

It has all I need, but returned disk Size is always zero... Why is this happening ? Am I doing something wrong or it normal this behavior ?

I use this code:

program WMI_PhysicalDisk;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Winapi.ActiveX,
  System.Win.ComObj,
  System.Variants;

function VarToInt(const AVariant: Variant): INT64;// integer;
begin Result := StrToIntDef(Trim(VarToStr(AVariant)), 0); end;

procedure GetMSFT_PhysicalDiskInfo;
const
  WbemUser =''; WbemPassword =''; WbemComputer ='localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject : OLEVariant;
  oEnum : IEnumvariant;
  iValue : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\Microsoft\Windows\Storage', WbemUser, WbemPassword);
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM MSFT_PhysicalDisk','WQL',wbemFlagForwardOnly);
  oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
    Writeln(Format('DeviceId %s',[VarToStr(FWbemObject.DeviceId)]));                      // String
    Writeln(Format('LogicalSectorSize %d',[VarToInt(FWbemObject.LogicalSectorSize)]));    // Uint64
    Writeln(Format('MediaType %d',[VarToInt(FWbemObject.MediaType)]));                    // Uint16
    Writeln(Format('Model %s',[VarToStr(FWbemObject.Model)]));                            // String
    Writeln(Format('PhysicalSectorSize %d',[VarToInt(FWbemObject.PhysicalSectorSize)]));  // Uint64
    Writeln(Format('Size %d',[VarToInt(FWbemObject.Size)]));                              // Uint64
    Writeln('-----------------------------------------------------');
    FWbemObject:=Unassigned;
  end;
end;
begin
 try
    CoInitialize(nil);
    try
      GetMSFT_PhysicalDiskInfo;
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
end.

And I get... :

DeviceId 1
LogicalSectorSize 512
MediaType 3
Model WDC WD10SPZX-22Z10T0
PhysicalSectorSize 4096
Size 0
-------------------------------------------------------------------
DeviceId 0
LogicalSectorSize 512
MediaType 4
Model KBG40ZNS256G NVMe TOSHIBA 256GB
PhysicalSectorSize 4096
Size 0
-------------------------------------------------------------------
DeviceId 2
LogicalSectorSize 512
MediaType 3
Model ST1000LM024 HN-M101MBB
PhysicalSectorSize 4096
Size 0
-------------------------------------------------------------------

Solution

  • You have one little problem in your VarToInt function. it should use StrToInt64Def.

    the corrected function will looks like this :

    function VarToInt(const AVariant: Variant): INT64;// integer;
    begin Result := StrToInt64Def(Trim(VarToStr(AVariant)), 0); end;