Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Оболочка Shell-информация о дисках.


Автор: tricky 22.4.2005, 13:05
Как мне удалось выяснить Win2k/XP получает информацию о дисках, а
именно меня интересует тип диска (CD-ROM, жесткий и т.п.) из функций
библиотеки shell32.dll, а не функцией GetDriveTypeA. У меня такое
ощущение, что инфа о типах диска получается на старте Win2k/WinXP
запоминается и затем в процессе работы винды больше не обновляется.
Т.е. нажатие F5 не приводит к обновлению инфы о типах диска. Эти
сведения я получил след.образом: внедрился в адресное простанство
explorer перехватил функцию SHGetFileInfo, которая возвращает инфу о
типах диска разместил там код windows.beep(500, 100), это означало что должен
был происходить писк в случая обновления инфы о типе диска. Писк я так
и не услышал (перехват выполнен на 100% в этом сомнения нет).

Вопрос: Как заставить обновляться инфу о типах диска в explorer'e во время работы
Win2k/XP

Автор: Rouse_ 24.4.2005, 23:40
Ну это очень глупый способ. Перехватил ты что? Что-то но никак не АПИ функцию, которая вполне возможно подгрузилась динамически, а не через IAT. Ну а типы диска определить достаточно просто, не спускаясь на второе кольцо:

Код

procedure TForm1.Button1Click(Sender: TObject);
const
  NameSize = 4;
  VolumeCount = 26;
  TotalSize = NameSize * VolumeCount;
  Report = 'Volume: %s %s';
var
  Buff, Volume: String;
  I, Count: Integer;
begin
  SetLength(Buff, TotalSize);
  Count := GetLogicalDriveStrings(TotalSize, @Buff[1]) div NameSize;
  if Count = 0 then
    Memo1.Lines.Add(SysErrorMessage(GetLastError))
  else
    for I := 0 to Count - 1 do
    begin
      Volume := PChar(@Buff[(I * NameSize) + 1]);
      case GetDriveType(PChar(Volume)) of
        DRIVE_UNKNOWN: Memo1.Lines.Add(Format(Report, [Volume,
          'The drive type cannot be determined.']));
        DRIVE_NO_ROOT_DIR: Memo1.Lines.Add(Format(Report, [Volume,
          'The root path is invalid. For example, no volume is mounted at the path.']));
        DRIVE_REMOVABLE: Memo1.Lines.Add(Format(Report, [Volume,
          'The disk can be removed from the drive.']));
        DRIVE_FIXED: Memo1.Lines.Add(Format(Report, [Volume,
          'The disk cannot be removed from the drive.']));
        DRIVE_REMOTE: Memo1.Lines.Add(Format(Report, [Volume,
          'The drive is a remote (network) drive.']));
        DRIVE_CDROM: Memo1.Lines.Add(Format(Report, [Volume,
          'The drive is a CD-ROM drive.']));
        DRIVE_RAMDISK: Memo1.Lines.Add(Format(Report, [Volume,
          'The drive is a RAM disk.']));
      else
        Memo1.Lines.Add(Format(Report, [Volume, 'Xpen znaet chto :)']));
      end;
    end;
end;


Ну а обновление по всей видимости будем производить по такому вот событию:
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, MMSystem;

type
  TForm1 = class(TForm)
  public
    procedure CD(var Msg: TMessage); message WM_DEVICECHANGE;
  end;

const
  CD_DEVICE_ENABLE = $8000;
  CD_DEVICE_DISABLE = $8004;
  NETFOLDER_MAP = CD_DEVICE_ENABLE;
  NETFOLDER_UNMAP = CD_DEVICE_DISABLE;
  DEVICE_FLASH = $7;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.CD(var Msg: TMessage);
begin
  case Msg.WParam of
    DEVICE_FLASH: Caption := 'Flash change';
    CD_DEVICE_ENABLE: Caption := 'CD close with new disk';
    CD_DEVICE_DISABLE: Caption := 'CD open';
    //NETFOLDER_MAP: Caption := 'New network disk maped';
    //NETFOLDER_UNMAP: Caption := 'Network disk unmaped';
  else
    Caption := 'Unknown';
  end;
end;

end.

Маленький коментарий:
При открытии сидирома срабатывает DEVICE_DISABLE, при закрытии DEVICE_ENABLE
При подключении сетевого диска также приходит DEVICE_ENABLE а при отключении DEVICE_DISABLE
При подключении или отключении флэшки срабатывает DEVICE_FLASH...

Автор: tricky 26.4.2005, 13:13
Цитата(Rouse_ @ 24.4.2005, 23:40)
Ну это очень глупый способ. Перехватил ты что?
............................
флэшки срабатывает DEVICE_FLASH...

Ты неправильно меня понял мне не нужно использовать функцию GetDriveType. Суть состоит в следующем я с помощью своего компонента InterceptorJmp(в скором времени появится на www.torry.net - аналога для DELPHI не существует) осуществляю перехват GetDriveType и вместо жестких дисков возращаю результат CD_ROM после чего файловый менеджер Windows Comander вместо жестких отображает CD-Rom'ы. В мой компьютере так не получится так как процесс explorer не использует GetDriveType а использует shell-функцию. Я могу перехватить эту shell - функцию, но т.к. результат этой функция запоминается один раз при старте системы,
то при дальнейшей ситуации обновлении инфы о дисках не происходит. Как заставить обновится инфу о дисках через shell - функцию.

Автор: Rouse_ 27.4.2005, 08:40
Ничего не пойму, про какую функцию ты говоришь?

Автор: Dr.No_xXx 27.4.2005, 11:24
Тебе надо немного изменить содержание dll(shell32.dll)/

Автор: Delphist 27.4.2005, 15:50
Цитата(Rouse_ @ 27.4.2005, 08:40)
Ничего не пойму, про какую функцию ты говоришь?

Я перехватываю функцию SHGetFileInfo возращаю результат для всех дисков возвращаю CD. Как заставить принять новую инфу к сведению. У меня вызов MySHGetFileInfo, MySHGetFileInfoA, MySHGetFileInfoW происходит вместо SHGetFileInfo, SHGetFileInfoA, SHGetFileInfoW. Но возвращаемые результаты не принимаются к сведению. Может быть результат возвращаю не в том формате хотя вряд ли. Как заставить принять систему новую инфу.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)