Using Delphi to find special drives

I am trying to write a small program in Delphi 2007 to access files from a portable USB drive whenever it is connected to a Windows 7 machine. However, this drive does not appear as the standard drive letter. It appears in the "Portable Devices" section in Windows Explorer. I wrote the following code to list all the elements in the Computer section:

Procedure TfrmMain.ComputerChanged(Var Msg: TMessage);
Var
  Enum: IEnumIDList;
  Fetched: Longword;
  Item: PItemIDList;
  Path: String;
  Computer: IShellFolder;
  StrRet: TSTRRET;
Begin
  Status('Computer changed...  Checking folders.');
  fDesktop.BindToObject(fCompPidl, Nil, IID_IShellFolder, Computer);
  If Assigned(Computer) And
     (Computer.EnumObjects(Self.Handle, SHCONTF_FOLDERS, Enum) = NOERROR) Then
  Begin
    While (Enum.Next(1, Item, Fetched) = NOERROR) Do
    Begin
      FillChar(StrRet, SizeOf(StrRet), #0);
      Computer.GetDisplayNameOf(Item, SHGDN_FORADDRESSBAR or SHGDN_NORMAL, StrRet);
      Path := StrRetToStr(StrRet, Item);
      Status(Path);
    End;
  End;
End;

(note: the Status procedure simply displays a message in TMemo.)

This is called whenever my application is notified of a change by the Windows shell subsystem. It lists all local drives and network drives, but nothing more (iCloud Photos drive is also missing).

Does anyone know how I can access the files on these virtual disks?

+4
2

COM . , CoInitializeEx, , .

, , . CoInitializeEx/CoUninitialize COINIT_MULTITHREADED, - , .

program ListMyComputer;

{$APPTYPE CONSOLE}

uses
  ComObj, ShlObj, ShellApi, ShLwApi, ActiveX, Windows, SysUtils;

var
  Enum: IEnumIDList;
  Fetched: Longword;
  CompPidl, Item: PItemIDList;
  Path: PWideChar;
  Desktop, Computer: IShellFolder;
  StrRet: TSTRRET;
begin
  CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
  try
    WriteLn('Computer changed...  Checking folders.');
    SHGetDesktopFolder(Desktop);
    SHGetFolderLocation(0, CSIDL_DRIVES, 0, 0, CompPidl);
    Desktop.BindToObject(CompPidl, Nil, IID_IShellFolder, Computer);
    CoTaskMemFree(CompPidl);
    If Assigned(Computer) And
       (Computer.EnumObjects(0, SHCONTF_FOLDERS, Enum) = NOERROR) Then
    Begin
      While (Enum.Next(1, Item, Fetched) = NOERROR) Do
      Begin
        FillChar(StrRet, SizeOf(StrRet), #0);
        Computer.GetDisplayNameOf(Item, SHGDN_FORADDRESSBAR or SHGDN_NORMAL, StrRet);
        StrRetToStr(@StrRet, Item, Path);
        WriteLn(Path);
        CoTaskMemFree(Path);
      End;
    End;
    WriteLn('Enumeration complete');
    ReadLn;
  finally
    CoUninitialize
  end;
end.
+4

@SertacAkyuz Windows Portable Device API, Exchange, . , , ( ) : http://pastebin.com/0hSWv5pE

+2

Source: https://habr.com/ru/post/1542700/


All Articles