For mounted drives with drive letters, call Win32 ShellApi function SHGetSpecialFolderLocation(0, CSIDL_DRIVES, Drives). Declare local variable Drives: PItemIdList. This is in unit named ShellAPI in delphi. Hopefully a similar unit exists in FreePascal.
For unmounted drives, you will have to enumerate the device drivers by the device driver class of GUID_DEVINTERFACE_DISK somehow.  The SetupAPI of windows should be able to help you.
You can get SetupAPI.pas from the JEDI JCL or JEDI API projects.
procedure GetListFromSetupApi(aStrings: TStrings);
var
  iDev: Integer;
  RegDataType: Cardinal;
  reqSize:DWORD;
  prop:Cardinal;
  pszData:PByte;
  hinfo:   HDEVINFO;
  bResult: BOOL;
  devinfo: SP_DEVINFO_DATA;
  dwRequiredSize,dwPropertyRegDataType,dwAllocSz:Cardinal;
begin
  LoadSetupApi;
  if not Assigned(SetupDiGetClassDevs) then
    Exit;
  hinfo := SetupDiGetClassDevs(@GUID_DEVINTERFACE_DISK, nil, HWND(nil),
                               DIGCF_DEVICEINTERFACE or DIGCF_PRESENT or DIGCF_PROFILE);
  devinfo.ClassGuid.D1 := 0;
  devinfo.ClassGuid.D2 := 0;
  devinfo.ClassGuid.D3 := 0;
  devinfo.cbSize := SizeOf(SP_DEVINFO_DATA);
  iDev := 0;
   while SetupDiEnumDeviceInfo(hinfo, iDev, devinfo) do
    begin
    dwRequiredSize := 0;
    prop := SPDRP_PHYSICAL_DEVICE_OBJECT_NAME;
    // results on my computer:
    // \Device\Ide\IAAStorageDevice-1
    // \Device\Ide\IAAStorageDevice-2
    // \Device\0000008a                 (this one is a usb disk, use SPDRP_ENUMERATOR_NAME, returns USBSTOR)
//   prop := SPDRP_ENUMERATOR_NAME; // results: IDE, USBSTOR, or other bus type.
//   prop := SPDRP_LOCATION_INFORMATION; // a number like 1,2,3.
    { SPDRP_DRIVER - driver guid }
    { Get Size of property }
     SetupDiGetDeviceRegistryProperty
                (hinfo,
                devinfo,
                prop,
                dwPropertyRegDataType,
                nil,
                0,
                dwRequiredSize);   { dwRequiredSize should be around 88 after this point, in unicode delphi }
     if dwRequiredSize>0 then begin
        dwAllocSz := dwRequiredSize+4;
        pszData := AllocMem(dwAllocSz);
        bResult := SetupDiGetDeviceRegistryProperty
                (hinfo,
                devinfo,
                prop,
                dwPropertyRegDataType,
                pszData,
                dwAllocSz,
                dwRequiredSize);
        aStrings.Add(IntToStr(aStrings.Count)+': '+PChar(pszData));
        FreeMem(pszData);
    end;
    inc(iDev);
  end;
  SetupDiDestroyDeviceInfoList(hinfo);
end;
A complete working DELPHI example including the above code and the appropriate JEDI API units is here.  You can adapt it to free pascal and lazarus pretty easily.