| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879 | unit IEDriveInfo;{================================================================== Component TDriveInfo  /  Version 2.6  / January 2000 ====================================================    Description:    ============    Central drive management class. Provides information about all    installed drives, for example wether drive is valid, disk is inserted    displayname or volume size.    Author:    =======    (c) Ingo Eckel 1999    Sodener Weg 38    65812 Bad Soden    Germany    For detailed documentation and history see the documentation in TDriveInfo.htm.{==================================================================}{Required compiler options:}{$A+,B-,X+,H+,P+}{$WARN SYMBOL_PLATFORM OFF}interfaceuses  Windows, Registry, SysUtils, Classes, ComCtrls, ShellApi, ShlObj, CommCtrl, Forms,  BaseUtils, System.Generics.Collections, Vcl.Graphics;const  {Flags used by TDriveInfo.ReadDriveStatus and TDriveView.RefreshRootNodes:}  dsValid = 0;        {checks only whether drive is still valid}  dsImageIndex = 1;   {Fetch imageindex, if not allready fetched}  dsSize = 2;         {Fetch disk size and serialnumber}  dsDisplayName = 4;  {Fetch drives displayname}  dsAll = dsImageIndex or dsSize or dsDisplayName;  FirstDrive          = 'A';  SystemDrive         = 'C';  LastDrive           = 'Z';  FirstSpecialFolder  = CSIDL_DESKTOP;  LastSpecialFolder   = CSIDL_PRINTHOOD;type  TDriveInfoRec = class    PIDL        : PItemIDList; {Fully qualyfied PIDL}    Init        : Boolean;     {Drivestatus was updated once}    Valid       : Boolean;     {Drivestatus is valid}    ValidButHiddenByDrivePolicy: Boolean;    DriveReady  : Boolean;     {Drive is ready}    DriveType   : Integer;     {DRIVE_REMOVABLE, DRIVE_FIXED, DRIVE_CDROM, DRIVE_RAMDISK, DRIVE_REMOTE}    DisplayName : string;      {Windows displayname}    PrettyName  : string;      {Prettyfied displayname}    DriveSerial : DWORD;       {Serial number of the drive}    Size        : Int64;       {Drivesize}    ImageIndex  : Integer;     {Drive imageIndex}  end;  TRealDrive = char;  TSpecialFolder = FirstSpecialFolder..LastSpecialFolder;  PSpecialFolderRec = ^TSpecialFolderRec;  TSpecialFolderRec = record    Valid: Boolean;    Location: string;    DisplayName: string;    ImageIndex: Integer;    PIDL: PItemIDList;  end;  TDriveInfo = class(TObject)  private    FData: TObjectDictionary<string, TDriveInfoRec>;    FNoDrives: DWORD;    FNoViewOnDrive: DWORD;    FDesktop: IShellFolder;    FFolders: array[TSpecialFolder] of TSpecialFolderRec;    FHonorDrivePolicy: Integer;    FUseABDrives: Boolean;    FLoaded: Boolean;    function GetFolder(Folder: TSpecialFolder): PSpecialFolderRec;    procedure ReadDriveBasicStatus(Drive: string);    procedure ResetDrive(Drive: string);    procedure SetHonorDrivePolicy(Value: Integer);    function GetFirstFixedDrive: Char;    procedure Load;    function AddDrive(Drive: string): TDriveInfoRec;    function GetDriveBitMask(Drive: string): Integer;    function DoAnyValidPath(DriveType: Integer; CanBeHidden: Boolean; var Path: string): Boolean;    function ReadDriveMask(Reg: TRegistry; ValueName: string): DWORD;  public    function Get(Drive: string): TDriveInfoRec;    property SpecialFolder[Folder: TSpecialFolder]: PSpecialFolderRec read GetFolder;    procedure NeedData;    function AnyValidPath: string;    function GetDriveKey(Path: string): string;    function GetDriveRoot(Drive: string): string;    function IsRealDrive(Drive: string): Boolean;    function IsFixedDrive(Drive: string): Boolean;    function GetImageIndex(Drive: string): Integer;    function GetSimpleName(Drive: string): string;    function GetDisplayName(Drive: string): string;    function GetPrettyName(Drive: string): string;    function ReadDriveStatus(Drive: string; Flags: Integer): Boolean;    procedure OverrideDrivePolicy(Drive: string);    property HonorDrivePolicy: Integer read FHonorDrivePolicy write SetHonorDrivePolicy;    property FirstFixedDrive: Char read GetFirstFixedDrive;    property UseABDrives: Boolean read FUseABDrives write FUseABDrives;    constructor Create;    destructor Destroy; override;  end;function GetShellFileName(const Name: string): string; overload;function GetShellFileName(PIDL: PItemIDList): string; overload;function GetNetWorkName(Drive: string): string;function GetNetWorkConnected(Drive: string): Boolean;function IsRootPath(Path: string): Boolean;function GetThumbnail(Path: string; Size: TSize): TBitmap;{Central drive information object instance of TDriveInfo}var  DriveInfo : TDriveInfo;resourceString  ErrorInvalidDrive = '%s is a invalid drive letter.';implementationuses  Math, PIDL, OperationWithTimeout, PasTools, CompThread;type  PRGBQuadArray = ^TRGBQuadArray;    // From graphics.pas  TRGBQuadArray = array[Byte] of TRGBQuad;  // From graphics.pasvar  ThreadLock: TRTLCriticalSection;  ReadyDrives: string;type  TDriveInfoThread = class(TCompThread)  public    constructor Create(Drives: string);  protected    procedure Execute; override;  private    FDrives: string;  end;constructor TDriveInfoThread.Create(Drives: string);begin  inherited Create(True);  FDrives := Drives;  FreeOnTerminate := True;  Resume;end;procedure TDriveInfoThread.Execute;var  I: Integer;  FreeSpace, Size: Int64;  DriveRoot: string;  Drive: Char;begin  if Length(FDrives) = 1 then  begin    Drive := FDrives[1];    DriveRoot := DriveInfo.GetDriveRoot(Drive);    if GetDiskFreeSpaceEx(PChar(DriveRoot), FreeSpace, Size, nil) then    begin      EnterCriticalSection(ThreadLock);      ReadyDrives := ReadyDrives + Drive;      LeaveCriticalSection(ThreadLock);    end;  end    else  begin    for I := 1 to Length(FDrives) do    begin      TDriveInfoThread.Create(FDrives[I]);      Sleep(100);    end;  end;end;constructor TDriveInfo.Create;begin  inherited;  FHonorDrivePolicy := 1;  FUseABDrives := True;  FLoaded := False;  FData := TObjectDictionary<string, TDriveInfoRec>.Create([doOwnsValues]);end; {TDriveInfo.Create}destructor TDriveInfo.Destroy;begin  FData.Free;  inherited;end; {TDriveInfo.Destroy}procedure TDriveInfo.NeedData;var  I: Integer;  Drive: Char;begin  if not FLoaded then  begin    Load;    FLoaded := True;  end;  EnterCriticalSection(ThreadLock);  try    for I := 1 to Length(ReadyDrives) do    begin      Drive := ReadyDrives[I];      Assert(FData.ContainsKey(Drive));      FData[Drive].DriveReady := True;    end;    ReadyDrives := '';  finally    LeaveCriticalSection(ThreadLock);  end;end;function TDriveInfo.DoAnyValidPath(DriveType: Integer; CanBeHidden: Boolean; var Path: string): Boolean;var  Drive: TRealDrive;  DriveInfoRec: TDriveInfoRec;begin  for Drive := SystemDrive to LastDrive do  begin    DriveInfoRec := Get(Drive);    if (DriveInfoRec.Valid or        (CanBeHidden and DriveInfoRec.ValidButHiddenByDrivePolicy)) and       (DriveInfoRec.DriveType = DriveType) and       DirectoryExists(ApiPath(GetDriveRoot(Drive))) then    begin      Result := True;      Path := GetDriveRoot(Drive);      Exit;    end;  end;  Result := False;end;function TDriveInfo.AnyValidPath: string;begin  if (not DoAnyValidPath(DRIVE_FIXED, False, Result)) and     (not DoAnyValidPath(DRIVE_FIXED, True, Result)) and     (not DoAnyValidPath(DRIVE_REMOTE, False, Result)) then  begin    raise Exception.Create(SNoValidPath);  end;end;function TDriveInfo.IsRealDrive(Drive: string): Boolean;begin  Result := (Length(Drive) = 1);  Assert((not Result) or ((Drive[1] >= FirstDrive) and (Drive[1] <= LastDrive)));end;function TDriveInfo.IsFixedDrive(Drive: string): Boolean;begin  Result := True;  if IsRealDrive(Drive) and (Drive[1] < FirstFixedDrive) then Result := False;end;function TDriveInfo.GetDriveKey(Path: string): string;begin  Result := ExtractFileDrive(Path);  if (Length(Result) = 2) and (Result[2] = DriveDelim) then  begin    Result := Upcase(Result[1]);  end    else  if IsUncPath(Path) then  begin    Result := LowerCase(Result);  end    else  begin    raise EConvertError.Create(Format(ErrorInvalidDrive, [Path]))  end;end;function TDriveInfo.GetDriveRoot(Drive: string): string;begin  if IsRealDrive(Drive) then  begin    Result := Drive + ':\'  end    else  begin    Assert(IsUncPath(Drive));    Result := IncludeTrailingBackslash(Drive);  end;end;function TDriveInfo.GetFolder(Folder: TSpecialFolder): PSpecialFolderRec;var  FileInfo: TShFileInfo;  Path: PChar;  Flags: Word;begin  NeedData;  Assert((Folder >= Low(FFolders)) and (Folder <= High(FFolders)));  with FFolders[Folder] do  begin    if not Valid then    begin      SpecialFolderLocation(Folder, Location, PIDL);      if Assigned(PIDL) then      begin        Path := PChar(PIDL);        Flags := SHGFI_PIDL;      end        else      begin        Path := PChar(Location);        Flags := 0;      end;      SHGetFileInfo(Path, 0, FileInfo, SizeOf(FileInfo),        SHGFI_DISPLAYNAME or SHGFI_SYSICONINDEX or SHGFI_SMALLICON or Flags);      ImageIndex := FileInfo.iIcon;      DisplayName := FileInfo.szDisplayName;      Valid := True;    end;  end;  Result := @FFolders[Folder];end;procedure TDriveInfo.SetHonorDrivePolicy(Value: Integer);var  Drive: TRealDrive;begin  if HonorDrivePolicy <> Value then  begin    FHonorDrivePolicy := Value;    if FLoaded then    begin      for Drive := FirstDrive to LastDrive do      begin        ReadDriveBasicStatus(Drive);      end;    end;  end;end;function TDriveInfo.GetFirstFixedDrive: Char;begin  if UseABDrives then Result := FirstDrive    else Result := SystemDrive;end;function TDriveInfo.GetDriveBitMask(Drive: string): Integer;begin  Assert(IsRealDrive(Drive));  Result := (1 shl (Ord(Drive[1]) - Ord('A')));end;procedure TDriveInfo.ReadDriveBasicStatus(Drive: string);var  ValidDriveType: Boolean;  InaccessibleByDrivePolicy, HiddenByDrivePolicy: Boolean;  DriveBitMask: Integer;begin  Assert(FData.ContainsKey(Drive));  with FData[Drive] do  begin    DriveType := Windows.GetDriveType(PChar(GetDriveRoot(Drive)));    DriveBitMask := GetDriveBitMask(Drive);    InaccessibleByDrivePolicy :=      IsRealDrive(Drive) and ((HonorDrivePolicy and 2) <> 0) and ((DriveBitMask and FNoViewOnDrive) <> 0);    HiddenByDrivePolicy :=      IsRealDrive(Drive) and ((HonorDrivePolicy and 1) <> 0) and ((DriveBitMask and FNoDrives) <> 0);    ValidDriveType :=      (DriveType in [DRIVE_REMOVABLE, DRIVE_FIXED, DRIVE_CDROM, DRIVE_RAMDISK, DRIVE_REMOTE]) and      (not InaccessibleByDrivePolicy);    ValidButHiddenByDrivePolicy := ValidDriveType and HiddenByDrivePolicy;    Valid := ValidDriveType and (not HiddenByDrivePolicy);  end;end;procedure TDriveInfo.ResetDrive(Drive: string);begin  with FData[Drive] do  begin    DriveReady := False;    DisplayName := '';    PrettyName := '';    DriveSerial := 0;    Size := -1;    ImageIndex := 0;  end;end;function TDriveInfo.ReadDriveMask(Reg: TRegistry; ValueName: string): DWORD;var  DataInfo: TRegDataInfo;begin  Result := 0;  if Reg.GetDataInfo(ValueName, DataInfo) then  begin    if (DataInfo.RegData = rdBinary) and (DataInfo.DataSize >= SizeOf(Result)) then    begin      Reg.ReadBinaryData(ValueName, Result, SizeOf(Result));    end      else    if DataInfo.RegData = rdInteger then    begin      Result := Reg.ReadInteger(ValueName);    end;  end;end;procedure TDriveInfo.Load;var  Drive: TRealDrive;  Reg: TRegistry;  Folder: TSpecialFolder;  Drives: string;begin  AppLog('Loading drives');  Reg := TRegistry.Create;  FNoDrives := 0;  FNoViewOnDrive := 0;  try    if Reg.OpenKeyReadOnly('Software\Microsoft\Windows\CurrentVersion\Policies\Explorer') then    begin      FNoDrives := ReadDriveMask(Reg, 'NoDrives');      FNoViewOnDrive := ReadDriveMask(Reg, 'NoViewOnDrive');    end;  finally    Reg.Free;  end;  AppLog(Format('NoDrives mask: %d', [Integer(FNoDrives)]));  AppLog(Format('NoViewOnDrive mask: %d', [Integer(FNoViewOnDrive)]));  FDesktop := nil;  Drives := EmptyStr;  for Drive := FirstDrive to LastDrive do  begin    if AddDrive(Drive).Valid then      Drives := Drives + Drive;  end;  if Length(Drives) > 0 then  begin    AppLog(Format('Drives found: %s', [Drives]));    TDriveInfoThread.Create(Drives);  end;  for Folder := Low(FFolders) to High(FFolders) do    FFolders[Folder].Valid := False;end;function TDriveInfo.AddDrive(Drive: string): TDriveInfoRec;begin  Result := TDriveInfoRec.Create;  FData.Add(Drive, Result);  ResetDrive(Drive);  ReadDriveBasicStatus(Drive);end;function TDriveInfo.GetImageIndex(Drive: string): Integer;begin  NeedData;  Result := 0;  if Get(Drive).Valid then  begin    if Get(Drive).ImageIndex = 0 then      ReadDriveStatus(Drive, dsImageIndex);    Result := Get(Drive).ImageIndex;  end;end; {TDriveInfo.GetImageIndex}function TDriveInfo.GetDisplayName(Drive: string): string;begin  if Get(Drive).Valid then  begin    if Length(Get(Drive).DisplayName) = 0 then      ReadDriveStatus(Drive, dsDisplayName);    Result := Get(Drive).DisplayName;  end    else  begin    Result := GetSimpleName(Drive);  end;end; {TDriveInfo.GetDisplayname}function TDriveInfo.GetPrettyName(Drive: string): string;begin  if Get(Drive).Valid then  begin    if Length(Get(Drive).PrettyName) = 0 then      ReadDriveStatus(Drive, dsDisplayName);    Result := Get(Drive).PrettyName;  end    else  begin    Result := GetSimpleName(Drive);  end;end; {TDriveInfo.GetPrettyName}function TDriveInfo.GetSimpleName(Drive: string): string;begin  Result := Drive;  if IsRealDrive(Result) then Result := Result + ':';end;function TDriveInfo.Get(Drive: string): TDriveInfoRec;begin  NeedData;  // We might want to wait for ReadyDrives to beempty before returning  // (or even better do that only in DriveReady getter)  if not FData.TryGetValue(Drive, Result) then  begin    Assert(IsUncPath(Drive));    Result := AddDrive(Drive);  end;end; {TDriveInfo.GetData}function TDriveInfo.ReadDriveStatus(Drive: string; Flags: Integer): Boolean;var  ErrorMode: Word;  FileInfo: TShFileInfo;  DriveRoot: string;  DriveID: string;  CPos: Integer;  Eaten: ULONG;  ShAttr: ULONG;  MaxFileNameLength: DWORD;  FileSystemFlags: DWORD;  FreeSpace: Int64;  SimpleName: string;  DriveInfoRec: TDriveInfoRec;  S: string;begin  // Among other, this makes sure the pending drive-ready status from the background thread are collected,  // before we overwrite it with fresh status here.  NeedData;  if not Assigned(FDesktop) then    SHGetDesktopFolder(FDesktop);  DriveRoot := GetDriveRoot(Drive);  // When this method is called, the entry always exists already  Assert(FData.ContainsKey(Drive));  DriveInfoRec := FData[Drive];  with DriveInfoRec do  begin    Init := True;    ReadDriveBasicStatus(Drive);    if Valid then    begin      if (not Assigned(PIDL)) and IsFixedDrive(Drive) then      begin        ShAttr := 0;        if DriveType = DRIVE_REMOTE then        begin          ShellFolderParseDisplayNameWithTimeout(            FDesktop, Application.Handle, nil, PChar(DriveRoot), Eaten, PIDL, ShAttr, 2 * MSecsPerSec);        end          else        begin          FDesktop.ParseDisplayName(Application.Handle, nil, PChar(DriveRoot), Eaten, PIDL, ShAttr);        end;      end;      {Read driveStatus:}      if (Flags and dsSize) <> 0 then      begin        { turn off critical errors }        ErrorMode := SetErrorMode(SEM_FailCriticalErrors or SEM_NOOPENFILEERRORBOX);        try          DriveReady := GetDiskFreeSpaceEx(PChar(DriveRoot), FreeSpace, Size, nil);          if DriveReady then          begin            {Access the physical drive:}            if GetVolumeInformation(PChar(DriveRoot), nil, 0,                 @DriveSerial, MaxFileNameLength, FileSystemFlags,                 nil, 0) then            begin            end              else            begin              DriveSerial := 0;            end;          end            else          begin            DriveSerial := 0;          end;        finally          { restore old error mode }          SetErrorMode(ErrorMode);        end;      end;      {DisplayName:}      if (Flags and dsDisplayName) <> 0 then      begin        {Fetch drives displayname:}        SimpleName := GetSimpleName(Drive);        if Assigned(PIDL) then DisplayName := GetShellFileName(PIDL)          else        begin          // typical reason we do not have PIDL is that it took too long to          // call ParseDisplayName, in what case calling SHGetFileInfo with          // path (instead of PIDL) will take long too, avoiding that and using          // fallback          DisplayName := '(' + SimpleName + ')';        end;        if DriveType <> DRIVE_REMOTE then        begin          PrettyName := SimpleName + ' ' + DisplayName;          S := ' (' + SimpleName + ')';          CPos := Pos(S, PrettyName);          if CPos > 0 then            Delete(PrettyName, CPos, Length(S));        end          else        if IsRealDrive(Drive) then        begin          DriveID := GetNetWorkName(Drive);          PrettyName := Format('%s %s (%s)', [SimpleName, ExtractFileName(DriveID), ExtractFileDir(DriveID)]);        end          else        begin          Assert(IsUncPath(DriveRoot));          PrettyName := SimpleName;        end;      end;      {ImageIndex:}      if (Flags and dsImageIndex) <> 0 then      begin        if Assigned(PIDL) then        begin          SHGetFileInfo(PChar(PIDL), 0, FileInfo, SizeOf(FileInfo), SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_PIDL)        end          else        begin          SHGetFileInfo(PChar(DriveRoot), 0, FileInfo, SizeOf(FileInfo), SHGFI_SYSICONINDEX or SHGFI_SMALLICON);        end;        ImageIndex := FileInfo.iIcon;      end;    end      else    begin      if Assigned(PIDL) then        FreePIDL(PIDL);      ResetDrive(Drive);    end;    Result := Valid and DriveReady;  end;end; {TDriveInfo.ReadDriveStatus}procedure TDriveInfo.OverrideDrivePolicy(Drive: string);var  Mask: DWORD;begin  Assert(FData.ContainsKey(Drive));  Assert(FData[Drive].ValidButHiddenByDrivePolicy);  Mask := (not GetDriveBitMask(Drive));  FNoDrives := FNoDrives and Mask;  ReadDriveBasicStatus(Drive);  Assert(FData[Drive].Valid);end;function GetShellFileName(const Name: string): string;var  SFI: TSHFileInfo;  E: Integer;begin  E := SetErrorMode(SEM_FAILCRITICALERRORS);  try    if SHGetFileInfo(PChar(Name), 0, SFI, SizeOf(TSHFileInfo), SHGFI_DISPLAYNAME) <> 0 then      Result := SFI.szDisplayName;  finally    SetErrorMode(E);  end;end; {GetShellFileName}function GetShellFileName(PIDL: PItemIDList): string;var  SFI: TSHFileInfo;  E: Integer;begin  E := SetErrorMode(SEM_FAILCRITICALERRORS);  try    if SHGetFileInfo(PChar(PIDL), 0, SFI, SizeOf(TSHFileInfo), SHGFI_PIDL or SHGFI_DISPLAYNAME) <> 0 then      Result := SFI.szDisplayName;  finally    SetErrorMode(E);  end;end; {GetShellFileName}function GetNetWorkName(Drive: string): string;var  Path: string;  P: array[0..MAX_PATH] of Char;  MaxLen : DWORD;begin  Path := ExcludeTrailingBackslash(DriveInfo.GetDriveRoot(Drive));  MaxLen := MAX_PATH;  if WNetGetConnection(PChar(Path), P, MaxLen) = NO_ERROR then    Result := P  else    Result := '';end; {GetNetWorkName}type  LPBYTE = ^BYTE;  LMSTR = LPWSTR;  NET_API_STATUS = DWORD;  _USE_INFO_1 = record    ui1_local: LMSTR;    ui1_remote: LMSTR;    ui1_password: LMSTR;    ui1_status: DWORD;    ui1_asg_type: DWORD;    ui1_refcount: DWORD;    ui1_usecount: DWORD;  end;  USE_INFO_1 = _USE_INFO_1;  PUSE_INFO_1 = ^USE_INFO_1;  LPVOID = Pointer;const  USE_OK       = 0;  USE_PAUSED   = 1;  USE_SESSLOST = 2;  USE_DISCONN  = 2;  USE_NETERR   = 3;  USE_CONN     = 4;  USE_RECONN   = 5;function NetUseGetInfo(UncServerName: LMSTR; UseName: LMSTR; Level: DWORD; var BufPtr: LPBYTE): NET_API_STATUS; stdcall; external 'netapi32.dll';function NetApiBufferFree(Buffer: Pointer): DWORD; stdcall; external 'netapi32.dll';function GetNetWorkConnected(Drive: string): Boolean;var  BufPtr: LPBYTE;  NetResult: Integer;  ServerName: string;  PServerName: PChar;  Name: string;  P: Integer;begin  Name := '';  PServerName := nil;  if DriveInfo.IsRealDrive(Drive) then  begin    Name := Drive + ':';  end    else  if IsUncPath(Drive) then  begin    Name := Copy(Drive, 3, Length(Drive) - 2);    P := Pos('\', Name);    if P > 0 then    begin      ServerName := Copy(Name, P + 1, Length(Name) - P);      PServerName := PChar(ServerName);      SetLength(Name, P - 1);    end      else    begin      Assert(False);    end;  end    else  begin    Assert(False);  end;  if Name = '' then  begin    Result := False;  end    else  begin    NetResult := NetUseGetInfo(PServerName, PChar(Name), 1, BufPtr);    if NetResult = 0 then    begin      Result := (PUSE_INFO_1(BufPtr)^.ui1_status = USE_OK);      NetApiBufferFree(LPVOID(BufPtr));    end      else    begin      // NetUseGetInfo works for DFS shares only, hence when it fails      // we suppose different share type and fallback to "connected"      Result := True;    end;  end;end;function IsRootPath(Path: string): Boolean;begin  Result := SameText(ExcludeTrailingBackslash(ExtractFileDrive(Path)), ExcludeTrailingBackslash(Path));end;function GetThumbnail(Path: string; Size: TSize): TBitmap;var  ImageFactory: IShellItemImageFactory;  X, Y: Integer;  Row: PRGBQuadArray;  Pixel: PRGBQuad;  Alpha: Byte;  Handle: HBITMAP;begin  Result := nil;  SHCreateItemFromParsingName(PChar(Path), nil, IShellItemImageFactory, ImageFactory);  if Assigned(ImageFactory) then  begin    if Succeeded(ImageFactory.GetImage(Size, SIIGBF_RESIZETOFIT, Handle)) then    begin      Result := TBitmap.Create;      try        Result.Handle := Handle;        Result.PixelFormat := pf32bit;        for Y := 0 to Result.Height - 1 do        begin          Row  := Result.ScanLine[Y];          for X := 0 to Result.Width - 1 do          begin            Pixel := @Row[X];            Alpha := Pixel.rgbReserved;            Pixel.rgbBlue := (Pixel.rgbBlue * Alpha) div 255;            Pixel.rgbGreen := (Pixel.rgbGreen * Alpha) div 255;            Pixel.rgbRed := (Pixel.rgbRed * Alpha) div 255;          end;        end;      except        Result.Free;        raise;      end;    end;    ImageFactory := nil; // Redundant?  end;end;initialization  InitializeCriticalSection(ThreadLock);  if not Assigned(DriveInfo) then    DriveInfo := TDriveInfo.Create;finalization  if Assigned(DriveInfo) then  begin    DriveInfo.Free;    DriveInfo := nil;  end;  DeleteCriticalSection(ThreadLock);end.
 |