Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2006.11.05;
Скачать: [xml.tar.bz2];

Вниз

Как сделать программное безопасное извлечение флешки?   Найти похожие ветки 

 
mlm68 ©   (2006-03-30 21:13) [0]

Как сделать программное безопасное извлечение флешки?


 
mlm68 ©   (2006-04-03 12:10) [1]

Или я неправильно сформулировал вопрос? Почему нет ответов?
Уважаемые мастера какая функция это делает?
типа
SafeEject("F:\");
и можно безопасно вытащить флешку
Заранее спасибо


 
BiN ©   (2006-04-03 12:21) [2]

в MSDN смотри Removable Storage Manager Functions


 
mlm68 ©   (2006-04-03 13:29) [3]


> BiN ©   (03.04.06 12:21) [2]
> в MSDN смотри Removable Storage Manager Functions

да смотрел, но что-то не выходит ничего
хотелось бы пример увидеть


 
balepa ©   (2006-04-03 13:55) [4]


> mlm68 ©   (03.04.06 13:29) [3]

А там нет примера ?


 
Игорь Шевченко ©   (2006-04-03 14:41) [5]


> Почему нет ответов?


А ты сам в интернете искать не умеешь ?


 
kaZaNoVa ©   (2006-04-03 15:59) [6]

программно кликнуть по значку на трее где флешка и кликнуть на остановить - можне с помощью mouse_event кажется или как-то так ...


 
Игорь Шевченко ©   (2006-04-03 16:08) [7]

kaZaNoVa ©   (03.04.06 15:59) [6]

Если уважаемый автор напишет работающий пример реализации своей идеи, у него есть большой шанс снискать почет и уважение.


 
kaZaNoVa ©   (2006-04-03 16:28) [8]

Игорь Шевченко ©   (03.04.06 16:08) [7]

всё-же при моей идее могут возникнуть проблемы с координатами и неприятное мелькание окон по экрану ..

так что прав  [2] EjectDiskFromSADrive   лучше ...


 
Игорь Шевченко ©   (2006-04-03 16:38) [9]

kaZaNoVa ©   (03.04.06 16:28) [8]

Давай для начала ответим на первый вопрос - как ты собираешься найти координаты иконки для флешки ? Например, в системе Windows XP, где ненужные иконки попросту скрыты.


 
kaZaNoVa ©   (2006-04-03 16:40) [10]

Игорь Шевченко ©   (03.04.06 16:38) [9]
Например, в системе Windows XP, где ненужные иконки попросту скрыты.

у меня она обычно видна .. (т.к. считается нужной)

а так если скрыта - то есть же значок "показать скрытые" - на него сперва кликнуть:)


 
kaZaNoVa ©   (2006-04-03 16:56) [11]

"путь к винде\system32\rundll32.exe" shell32.dll,Control_RunDLL hotplug.dll


 
Игорь Шевченко ©   (2006-04-03 17:09) [12]


> а так если скрыта - то есть же значок "показать скрытые"


А как ты его искать собираешься, этот значок ?


 
kaZaNoVa ©   (2006-04-03 17:12) [13]

Игорь Шевченко ©   (03.04.06 17:09) [12]
решение  [11] сразу показывает:) и кликать не нужно


 
Игорь Шевченко ©   (2006-04-03 17:16) [14]

kaZaNoVa ©   (03.04.06 17:12) [13]

Ты, если не трудно, приведи пожалуйста работающее решение [6].


 
kaZaNoVa ©   (2006-04-03 17:19) [15]

Игорь Шевченко ©   (03.04.06 17:16) [14]
думаю данное решение реализовать мне будет несколько проблематично, а в [6] была лишь высказана идея, как можно попробовать решить проблему :)

с уважением.


 
n0name   (2006-04-03 19:17) [16]

>>Давай для начала ответим на первый вопрос - как ты собираешься найти координаты иконки для флешки ?
А зачем искать?
Перебрать все иконки, найти нужную, отправить сообщение.
Хотя этим спопсобом я бы пользовался в последнюю очередь.


 
Rouse_ ©   (2006-04-03 21:17) [17]


> ы, если не трудно, приведи пожалуйста работающее решение
> [6].

Игорь, ну ты наскочил на парня :) В принципе его идея тоже имеет смысл, только конечно не через трей, а через IShellFolder и Context.InvokeCommand


 
Германн ©   (2006-04-04 00:20) [18]


> n0name   (03.04.06 19:17) [16]
>
> >>Давай для начала ответим на первый вопрос - как ты собираешься
> найти координаты иконки для флешки ?
> А зачем искать?
> Перебрать все иконки, найти нужную, отправить сообщение.
>

А как их перебрать?


 
Игорь Шевченко ©   (2006-04-04 10:33) [19]

Rouse_ ©   (03.04.06 21:17) [17]


> а через IShellFolder и Context.InvokeCommand


Ты тоже приведешь работающее решение ?


 
mlm68 ©   (2006-04-04 11:24) [20]

Где ошибка?
Есть форма Form1, на ней кнопка Button1.
При нажатии на кнопку выдается ошибка: Access violation at address 00000000. Read of address 00000000.
вот мой код

unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls;
type
 TEjectDiskFromSADrive=procedure(
 lpComputerName:LPCWSTR ;
 lpAppName:LPCWSTR;
 lpDeviceName:LPCWSTR;
 hWnd:HWND;
 lpTitle:LPCWSTR;
 lpMessage:LPCWSTR;
 dwOptions:DWORD
);
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
var
 Form1: TForm1;
 EjectDiskFromSADrive: TEjectDiskFromSADrive;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
 Handle:THandle;
begin
 Handle := LoadLibrary("Ntmsapi.DLL");
 if Handle <> 0 then
 begin
    @EjectDiskFromSADrive:=GetProcAddress(Handle, "EjectDiskFromSADrive");
    EjectDiskFromSADrive(nil,nil,"\\.\Cdrom0",1,"","",0);
    FreeLibrary(Handle);
 end;
end;
end.


 
Игорь Шевченко ©   (2006-04-04 11:29) [21]


> Где ошибка?


А отладчика у тебя нету ? Бедняга...


 
mlm68 ©   (2006-04-04 11:31) [22]

в этой строке проблемка
EjectDiskFromSADrive(nil,nil,"\\.\Cdrom0",1,"","",0);


 
Плохиш ©   (2006-04-04 11:48) [23]


> mlm68 ©   (04.04.06 11:31) [22]
> в этой строке проблемка
> EjectDiskFromSADrive(nil,nil,"\\.\Cdrom0",1,"","",0);

Ни кто и не сомневался. Чему равно @EjectDiskFromSADrive?
Почитай http://msdn.microsoft.com/library/default.asp?url=/library/en-us/stgmgmt/fs/ejectdiskfromsadrive.asp особенно про системные требования.


 
Rouse_ ©   (2006-04-04 12:46) [24]


> Игорь Шевченко ©   (04.04.06 10:33) [19]
> Rouse_ ©   (03.04.06 21:17) [17]
>
>
> > а через IShellFolder и Context.InvokeCommand
>
>
> Ты тоже приведешь работающее решение ?

Ну я както за свои слова привык отвечать:

unit Unit4;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ShlObj, ActiveX;

type
 TForm4 = class(TForm)
   lbFlashDriveList: TListBox;
   btnSafeEject: TButton;
   procedure btnSafeEjectClick(Sender: TObject);
   procedure FormCreate(Sender: TObject);
 private
   procedure FillFlashDriveList;
   function SafeEjectDrive(const DriveLetter: Char): Boolean;
 end;

var
 Form4: TForm4;

implementation

{$R *.dfm}

procedure TForm4.btnSafeEjectClick(Sender: TObject);
begin
 if lbFlashDriveList.ItemIndex >= 0 then
   SafeEjectDrive(lbFlashDriveList.Items[lbFlashDriveList.ItemIndex][1]);
end;

procedure TForm4.FillFlashDriveList;
const
 NameSize = 4;
 VolumeCount = 26;
 TotalSize = NameSize * VolumeCount;
var
 Buff, Volume, DosDevice: String;
 lpQuery: array [0..MAXCHAR - 1] of Char;
 I, Count: Integer;
begin
 SetLength(Buff, TotalSize);
 Count := GetLogicalDriveStrings(TotalSize, @Buff[1]) div NameSize;
 if Count = 0 then
   RaiseLastOSError
 else
   for I := 0 to Count - 1 do
   begin
     Volume := PChar(@Buff[(I * NameSize) + 1]);
     case GetDriveType(PChar(Volume)) of
       DRIVE_REMOVABLE:
       begin
         Volume[3] := #0;
         QueryDosDevice(PChar(Volume), @lpQuery[0], MAXCHAR);
         Volume[3] := "\";
         DosDevice := String(lpQuery);
         if (DosDevice <> "\Device\Floppy0") and (DosDevice <> "\Device\Floppy1") then
           lbFlashDriveList.Items.Add(Volume[1]);
       end;
     end;
   end;
end;

procedure TForm4.FormCreate(Sender: TObject);
begin
 FillFlashDriveList;
end;

function TForm4.SafeEjectDrive(const DriveLetter: Char): Boolean;
var
 CoInit, AResult: HRESULT;
 CommonDir: String;
 Desktop, ShellFolder: IShellFolder;
 pchEaten, Attr: Cardinal;
 PathPIDL: PItemIDList;
 FilePIDL: array [0..1] of PItemIDList;
 ShellContextMenu: HMenu;
 ICMenu: IContextMenu;
 CMD: TCMInvokeCommandInfo;
 M: IMAlloc;
 CallbackWindow: HWND;
begin
 Result := False;
 ShellContextMenu := 0;
 Attr := 0;
 PathPIDL := nil;
 CallbackWindow := 0;
 CoInit := CoInitializeEx(nil, COINIT_MULTITHREADED);
 try
   CommonDir := DriveLetter + ":\";
   if SHGetDesktopFolder(Desktop) <> S_OK then
     RaiseLastOSError;
   if (SHGetSpecialFolderLocation(0, CSIDL_DRIVES, PathPIDL) <> S_OK) or
     (Desktop.BindToObject(PathPIDL,  nil,  IID_IShellFolder,
       Pointer(ShellFolder)) <> S_OK) then RaiseLastOSError;
   ShellFolder.ParseDisplayName(Handle, nil, StringToOleStr(CommonDir),
     pchEaten, FilePIDL[0], Attr);
   AResult := ShellFolder.GetUIObjectOf(Handle, 1, FilePIDL[0],
     IID_IContextMenu, nil, Pointer(ICMenu));

   if Succeeded(AResult) then
   begin
       FillChar(CMD, SizeOf(CMD), #0);
       with CMD do
       begin
         cbSize := SizeOf(CMD);
         hWND := Handle;
         lpVerb := "Eject";
         nShow := SW_SHOWNORMAL;
       end;
       AResult := ICMenu.InvokeCommand(CMD);
       Result := AResult <> S_OK;
      end;
 finally
   if FilePIDL[0] <> nil then
   begin
     SHGetMAlloc(M);
     if M <> nil then
       M.Free(FilePIDL[0]);
     M:=nil;
   end;
   if PathPIDL <> nil then
   begin
     SHGetMAlloc(M);
     if M <> nil then
       M.Free(PathPIDL);
     M:=nil;
   end;
   if ShellContextMenu <>0 then
     DestroyMenu(ShellContextMenu);
   if CallbackWindow <> 0 then
     DestroyWindow(CallbackWindow);
   ICMenu := nil;
   ShellFolder := nil;
   Desktop := nil;
   if CoInit = S_OK then CoUninitialize;
 end;
end;

end.


 
mlm68 ©   (2006-04-04 13:14) [25]


> Rouse_ ©   (04.04.06 12:46) [24]
>
> Ну я както за свои слова привык отвечать:


Вот это круто!

А проще через EjectDiskFromSADrive можно?


 
Rouse_ ©   (2006-04-04 13:17) [26]


> А проще через EjectDiskFromSADrive можно?

не знаю - не пробовал... нет времени эксперементировать...


 
Игорь Шевченко ©   (2006-04-04 13:39) [27]

Rouse_ ©   (04.04.06 12:46) [24]


> Ну я както за свои слова привык отвечать:


Это безусловно радует.

Скомпилировав и запустив твой код, вынув после нажатия на кнопку на форме, флешку, я получил сообщение: Небезопасное извлечение устроства.
Вставив флешку обратно, выполнив твой код, я прекрасно вижу флешку среди дисков проводника.

Тут есть один ма-ааленький момент - флешка не компакт-диск.


 
fellix   (2006-04-04 13:46) [28]


> mlm68 ©   (04.04.06 11:24) [20]
> Где ошибка?


@EjectDiskFromSADrive:=GetProcAddress(Handle, "EjectDiskFromSADriveA");


 
fellix   (2006-04-04 13:48) [29]

Ну и объявить, желательно, как функцию - чтоб код возврата анализировать.


 
Rouse_ ©   (2006-04-04 14:07) [30]


> Игорь Шевченко ©   (04.04.06 13:39) [27]

Ну по всей видимости у тебя отключена галка в свойствах флешки "Enable write caching on the disk" которая стоит по умолчанию...


> Вставив флешку обратно, выполнив твой код, я прекрасно вижу
> флешку среди дисков проводника.

В списке проводника она безусловно пристутвует, но при попытке обращения к ней выдается надпись "Please insert dist into Drive ..."


 
mlm68 ©   (2006-04-04 14:32) [31]


> Ну и объявить, желательно, как функцию - чтоб код возврата
> анализировать.


Все равно ошибку выдает

unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls;
type
 TEjectDiskFromSADrive=function(
 lpComputerName:LPCWSTR ;
 lpAppName:LPCWSTR;
 lpDeviceName:LPCWSTR;
 hWnd:HWND;
 lpTitle:LPCWSTR;
 lpMessage:LPCWSTR;
 dwOptions:DWORD
):DWORD;
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
var
 Form1: TForm1;
 EjectDiskFromSADrive: TEjectDiskFromSADrive;
implementation

uses Unit2;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
 Handle:THandle;
 result:dword;
begin
 Handle := LoadLibrary("C:\WINDOWS\system32\Ntmsapi.DLL");
 if Handle <> 0 then begin
    @EjectDiskFromSADrive:=GetProcAddress(Handle, "EjectDiskFromSADriveA");
    if @EjectDiskFromSADrive <> nil then begin
       result:=EjectDiskFromSADrive(nil,nil,"\\.\Cdrom0",form2.Handle,"","",0);
    end;
    FreeLibrary(Handle);
 end;
end;
end.


 
Игорь Шевченко ©   (2006-04-04 14:36) [32]

Rouse_ ©   (04.04.06 14:07) [30]


> Ну по всей видимости у тебя отключена галка в свойствах
> флешки "Enable write caching on the disk" которая стоит
> по умолчанию...


По всей вероятности надо использовать другой способ. Например, тот, который сам проводник использует.
Кстати, гаек у меня никаких не отключено.


> В списке проводника она безусловно пристутвует, но при попытке
> обращения к ней выдается надпись "Please insert dist into
> Drive ..."


Не выдается...Все нормально обращается.


 
mlm68 ©   (2006-04-04 14:43) [33]


> Игорь Шевченко ©   (04.04.06 13:39) [27]
> Скомпилировав и запустив твой код, вынув после нажатия на
> кнопку на форме, флешку, я получил сообщение: Небезопасное
> извлечение устроства.


Перед нажатием на кнопку выбери диск в lbFlashDriveList:TListBox


 
Игорь Шевченко ©   (2006-04-04 15:05) [34]

mlm68 ©   (04.04.06 14:43) [33]

В жизни бы не догадался.

mlm68 ©   (04.04.06 14:32) [31]


> Все равно ошибку выдает


А чего же не выдавать-то. Вполне законные основания для выдачи имеются - первое, что объявление любой функции из MS-овских dll должно оканчиваться на stdcall, второе, что ты описываешь прототип для W-версии, а вызываешь A-версию.

Один совет - ты воспринимай код, который тебе здесь дается, как пищу для дальнейших размышлений и поисков, а не как готовое решение.


 
n0name   (2006-04-04 16:52) [35]

>>А как их перебрать?
Находишь окно трей.
TB_BUTTONCOUNT
TB_GETBUTTONINFO в цикле.


 
Игорь Шевченко ©   (2006-04-04 17:04) [36]

n0name   (04.04.06 16:52) [35]

Пример не затруднит ? Для извлечения...


 
n0name   (2006-04-04 20:25) [37]


> Пример не затруднит ? Для извлечения...

http://www.codeproject.com/shell/ctrayiconposition.asp


 
Игорь Шевченко ©   (2006-04-05 10:35) [38]

n0name   (04.04.06 20:25) [37]

Я не увидел в этом примере метода извлечения флешки. Если не затруднит, выложи ?


 
Arazel ©   (2006-04-05 12:08) [39]

И как же дорогой автор темы! Может узнать что пользователь решил
вынуть флешь носитель?
Это без толковое обсуждение и лишнее трата времени!!!

Флеш можно отключить точнее безопасное извлечение:
1) Прямое обращение к драйверу и послав спец идентификаторы
2) Использовать спец. предназначеные ф-ций
3) Просто закрыть том (Device\HardDisk1\...)

Но как я говорил это без толку!


 
Arazel ©   (2006-04-05 12:14) [40]

mlm68 ©   (04.04.06 11:24) [20]

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 StdCtrls;

type
 TForm1 = class(TForm)
   lbFlashDriveList: TListBox;
   Button1: TButton;
   procedure FormCreate(Sender: TObject);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
  procedure FillFlashDriveList;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FillFlashDriveList;
const
NameSize = 4;
VolumeCount = 26;
TotalSize = NameSize * VolumeCount;
var
Buff, Volume, DosDevice: String;
lpQuery: array [0..MAXCHAR - 1] of Char;
I, Count: Integer;
begin
SetLength(Buff, TotalSize);
Count := GetLogicalDriveStrings(TotalSize, @Buff[1]) div NameSize;
if Count = 0 then
  RaiseLastOSError
else
  for I := 0 to Count - 1 do
  begin
    Volume := PChar(@Buff[(I * NameSize) + 1]);
    case GetDriveType(PChar(Volume)) of
      DRIVE_REMOVABLE:
      begin
        Volume[3] := #0;
        QueryDosDevice(PChar(Volume), @lpQuery[0], MAXCHAR);
        Volume[3] := "\";
        DosDevice := String(lpQuery);
        if (DosDevice <> "\Device\Floppy0") and (DosDevice <> "\Device\Floppy1") then
          lbFlashDriveList.Items.Add(DosDevice);
          //Volume[1]
      end;
    end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
FillFlashDriveList;
end;

procedure TForm1.Button1Click(Sender: TObject);
type
TEjectDiskFromSADrive=function(
lpComputerName:LPCWSTR ;
lpAppName:LPCWSTR;
lpDeviceName:LPCWSTR;
hWnd:HWND;
lpTitle:LPCWSTR;
lpMessage:LPCWSTR;
dwOptions:DWORD
):DWORD;

const
ERROR_LIBRARY_OFFLINE      = 4305;
ERROR_DATABASE_FAILURE     = 4313;
ERROR_DATABASE_FULL        = 4314;
ERROR_INVALID_OPERATION    = 4317;
ERROR_MEDIA_NOT_AVAILABLE  = 4318;
ERROR_DEVICE_NOT_AVAILABLE = 4319;

var
EjectDiskFromSADrive: TEjectDiskFromSADrive;
hNtMsApi:THandle;
result:dword;
begin
if lbFlashDriveList.ItemIndex <= 0 then Exit;
hNtMsApi := LoadLibrary("NtMSAPI.DLL");
if hNtMsApi <> 0 then
 begin
   EjectDiskFromSADrive:=GetProcAddress(hNtMsApi, "EjectDiskFromSADriveA");
   if @EjectDiskFromSADrive <> nil then
      Result:=EjectDiskFromSADrive(
      nil,
      PWideChar(Caption),
      PWideChar(lbFlashDriveList.Items[lbFlashDriveList.ItemIndex]),
      Handle,"exit?", "Exit?",0);
      if Result = ERROR_SUCCESS then
      MessageBox(GetForegroundWindow,"&#199;&#224;&#247;&#232;&#242; &#238;&#239;&#240;&#224;&#246;&#232;&#255; &#239;&#240;&#238;&#248;&#235;&#224; &#243;&#241;&#239;&#229;&#248;&#237;&#238;!",nil,0) else
      Begin
        Caption:=IntToStr(result);
       Case Result of
     ERROR_ACCESS_DENIED:MessageBox(GetForegroundWindow,"&#209;&#236;&#238;&#242;&#24 0;&#232;&#242;&#229; &#237;&#224; &#241;&#224;&#233;&#242;&#229; microsoft",nil,0);
        ERROR_DATABASE_FAILURE:MessageBox(GetForegroundWindow,"&#209;&#236;&#238;&#242;& #240;&#232;&#242;&#229; &#237;&#224; &#241;&#224;&#233;&#242;&#229; microsoft",nil,0);
        ERROR_DATABASE_FULL:MessageBox(GetForegroundWindow,"&#209;&#236;&#238;&#242;&#24 0;&#232;&#242;&#229; &#237;&#224; &#241;&#224;&#233;&#242;&#229; microsoft",nil,0);
        ERROR_DEVICE_NOT_AVAILABLE:MessageBox(GetForegroundWindow,"&#209;&#236;&#238;&#2 42;&#240;&#232;&#242;&#229; &#237;&#224; &#241;&#224;&#233;&#242;&#229; microsoft",nil,0);
        ERROR_INVALID_HANDLE:MessageBox(GetForegroundWindow,"&#209;&#236;&#238;&#242;&#2 40;&#232;&#242;&#229; &#237;&#224; &#241;&#224;&#233;&#242;&#229; microsoft",nil,0);
        ERROR_INVALID_OPERATION:MessageBox(GetForegroundWindow,"&#209;&#236;&#238;&#242; &#240;&#232;&#242;&#229; &#237;&#224; &#241;&#224;&#233;&#242;&#229; microsoft",nil,0);
        ERROR_INVALID_PARAMETER:MessageBox(GetForegroundWindow,"&#209;&#236;&#238;&#242; &#240;&#232;&#242;&#229; &#237;&#224; &#241;&#224;&#233;&#242;&#229; microsoft",nil,0);
        ERROR_LIBRARY_OFFLINE:MessageBox(GetForegroundWindow,"&#209;&#236;&#238;&#242;&# 240;&#232;&#242;&#229; &#237;&#224; &#241;&#224;&#233;&#242;&#229; microsoft",nil,0);
        ERROR_MEDIA_NOT_AVAILABLE:MessageBox(GetForegroundWindow,"&#209;&#236;&#238;&#24 2;&#240;&#232;&#242;&#229; &#237;&#224; &#241;&#224;&#233;&#242;&#229; microsoft",nil,0);
        ERROR_NOT_ENOUGH_MEMORY:MessageBox(GetForegroundWindow,"&#209;&#236;&#238;&#242; &#240;&#232;&#242;&#229; &#237;&#224; &#241;&#224;&#233;&#242;&#229; microsoft",nil,0);
       end;
      end;
   FreeLibrary(hNtMsApi);
end;
end;

end.


 
Игорь Шевченко ©   (2006-04-05 12:18) [41]

Arazel ©   (05.04.06 12:14) [40]

Только бледнолицый брат наступает на одни и те же грабли по нескольку раз.


 
n0name   (2006-04-05 12:43) [42]

>>Я не увидел в этом примере метода извлечения флешки. Если не затруднит, выложи ?
Извини, я подумал что тебе пример перечисления иконок в трее.
Извлечение сейчас напишу, только не так как писал, у меня нестандартная оболочка -> тестирование проблематично.


 
n0name   (2006-04-05 16:37) [43]


> Ну я както за свои слова привык отвечать


program USBEject;

uses
Windows;

const
setupapi = "SetupApi.dll";

type
HDEVINFO = THandle;

PSP_DEVINFO_DATA = ^SP_DEVINFO_DATA;
SP_DEVINFO_DATA = packed record
 cbSize: DWORD;
 ClassGuid: TGUID;
 DevInst: DWORD;
 Reserved: DWORD;
end;

function SetupDiGetClassDevsA(ClassGuid: PGUID; Enumerator: PChar; hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall; external setupapi;
function SetupDiEnumDeviceInfo(DeviceInfoSet: HDEVINFO; MemberIndex: DWORD; DeviceInfoData: PSP_DEVINFO_DATA): boolean; stdcall; external setupapi;
function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): boolean; stdcall; external setupapi;
function CM_Get_Parent(pdnDevInst: PDWORD; dnDevInst: DWORD; ulFlags: DWORD): DWORD; stdcall; external setupapi;
function CM_Get_Device_ID_Size(pulLen: PDWORD; dnDevInst: DWORD; ulFlags: DWORD): DWORD; stdcall; external setupapi;
function CM_Get_Device_IDA(dnDevInst: DWORD; Buffer: PChar; BufferLen: DWORD; ulFlags: DWORD): DWORD; stdcall; external setupapi;
function CM_Locate_DevNodeA(pdnDevInst: PDWORD; pDeviceID: PChar; ulFlags: DWORD): DWORD; stdcall; external setupapi;
function CM_Request_Device_EjectA(dnDevInst: DWORD; pVetoType: Pointer; pszVetoName: PChar; ulNameLength: DWORD;
ulFlags: DWORD): DWORD; stdcall; external setupapi;

function IsUSBDevice(DevInst: DWORD): boolean;
function CompareMem(p1, p2: Pointer; len: DWORD): boolean;
var
 i: DWORD;
begin
 result := false;
 if len = 0 then exit;
 for i := 0 to len-1 do
  if PByte(DWORD(p1) + i)^ <> PByte(DWORD(p2) + i)^ then exit;
 result := true;
end;
var
IDLen: DWORD;
ID: PChar;
begin
result := false;
if (CM_Get_Device_ID_Size(@IDLen, DevInst, 0) <> 0) or (IDLen = 0) then exit;
inc(IDLen);
ID := GetMemory(IDLen);
if ID = nil then exit;
if (CM_Get_Device_IDA(DevInst, ID, IDLen, 0) <> 0) or (not CompareMem(ID, PChar("USBSTOR"), 7)) then
 begin
  FreeMemory(ID);
  exit;
 end;
FreeMemory(ID);
result := true;
end;

procedure EjectUSB();
const
GUID_DEVCLASS_DISKDRIVE: TGUID = (D1: $4D36E967; D2: $E325; D3: $11CE; D4: ($BF, $C1, $08, $00, $2B, $E1, $03, $18));
var
hDevInfoSet: HDEVINFO;
DevInfo: SP_DEVINFO_DATA;
i: Integer;
Parent: DWORD;
VetoName: PChar;
begin
DevInfo.cbSize := sizeof(SP_DEVINFO_DATA);
hDevInfoSet := SetupDiGetClassDevsA(@GUID_DEVCLASS_DISKDRIVE, nil, 0, 2);
if hDevInfoSet = INVALID_HANDLE_VALUE then exit;
i := 0;
while (SetupDiEnumDeviceInfo(hDevInfoSet, i, @DevInfo)) do
 begin
  if (IsUSBDevice(DevInfo.DevInst)) and (CM_Get_Parent(@Parent, DevInfo.DevInst, 0) = 0) then
   begin
    VetoName := GetMemory(260);
    if (CM_Request_Device_EjectA(Parent, nil, VetoName, 260, 0) <> 0) then
     begin
      if (CM_Locate_DevNodeA(@Parent, VetoName, 0) <> 0) then
       begin
        FreeMemory(VetoName);
        continue;
       end;
      FreeMemory(VetoName);
      if (CM_Request_Device_EjectA(Parent, nil, nil, 0, 0) <> 0) then continue;
     end;
    FreeMemory(VetoName);
    break;
   end;
  inc(i);
 end;
SetupDiDestroyDeviceInfoList(hDevInfoSet);
end;

begin
if MessageBoxA(0, "Вы действительно хотите извлечь USB-диск?", "Подтверждение", MB_YESNO) = ID_YES then
 EjectUSB();
end.


 
GrayFace ©   (2006-04-05 16:47) [44]

>  Handle := LoadLibrary("C:\WINDOWS\system32\Ntmsapi.DLL");
надо
h := LoadLibrary("Ntmsapi.DLL");
А Handle он и у формы есть - не ошибка, но криво.


 
Игорь Шевченко ©   (2006-04-05 16:50) [45]

n0name   (05.04.06 16:37) [43]

Так не честно. Нету перечисления икон, нету поиска в трее :)

Через setupapi в тырнете примеров много, об чем автору было сказано в одном из первых постов.


 
Arazel ©   (2006-04-05 18:28) [46]

Игорь Шевченко ©   (05.04.06 12:18) [41]
Я лишь ошибку исправил!


 
n0name   (2006-04-05 18:37) [47]


> Так не честно. Нету перечисления икон, нету поиска в трее
> :)

Хех, Так я же кидал ссылку на перечисление иконок.
Мне неохото переключаться в explorer, так бы потестил и первый способ :)


 
Игорь Шевченко ©   (2006-04-05 18:38) [48]

Arazel ©   (05.04.06 18:28) [46]

нет, все ошибки остались. Почитай пост 34


 
Игорь Шевченко ©   (2006-04-05 23:41) [49]

n0name   (05.04.06 18:37) [47]

А какой смысл перечислять иконки, если можно через SetupApi сделать (как оно и должно быть сделано) ?


 
n0name   (2006-04-06 10:38) [50]


> А какой смысл перечислять иконки, если можно через SetupApi
> сделать (как оно и должно быть сделано) ?

Поправка [6].


 
Игорь Шевченко ©   (2006-04-06 10:54) [51]


> Поправка [6].


"микроскоп штука хорошая, пока не начнёшь им гвозди забивать - неудобства начинаются почти сразу - то по пальцам больше попадаешь, то гвоздики не так вбиваются.."


 
n0name   (2006-04-06 11:48) [52]


> "микроскоп штука хорошая, пока не начнёшь им гвозди забивать
> - неудобства начинаются почти сразу - то по пальцам больше
> попадаешь, то гвоздики не так вбиваются.."

Ага, поэтому надо делать через SetupAPI =)


 
Arazel ©   (2006-04-07 07:26) [53]

ALL
Кое что я выяснил насчет вашей проблемы
для того что бы безопасно извлечь флешку
не обходимо остановить драйвер  USBSTOR.SYS
какторый отвечает за USB носителями
Вот и все!

Игорь Шевченко ©   (05.04.06 18:38) [48]
Извений, но я не вглядываюсь в чужой код, но ты меня вынудил :) ;)
Вот этот код полноценно работоспособен!

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs,ShlObj, ActiveX, StdCtrls;

type
 TForm1 = class(TForm)
   btnSafeEject: TButton;
   procedure btnSafeEjectClick(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

const
   NTMS_EJECT_START          = 00000000;
   NTMS_EJECT_STOP           = 00000001;

const
  ERROR_LIBRARY_OFFLINE      = 00004305;
  ERROR_DATABASE_FAILURE     = 00004313;
  ERROR_DATABASE_FULL        = 00004314;
  ERROR_INVALID_OPERATION    = 00004317;
  ERROR_MEDIA_NOT_AVAILABLE  = 00004318;
  ERROR_DEVICE_NOT_AVAILABLE = 00004319;
  ERROR_DEVICE__CAN_NOT_OPEN = 00000003;

function EjectDiskFromSADriveW(
 lpComputerName:PWideChar;
 lpAppName:PWideChar;
 lpDeviceName:PWideChar;
 hWnd:HWND;
 lpTitle:PWideChar;
 lpMessage:PWideChar;
 dwOptions:DWORD
):DWORD;stdcall; external "NtMSAPI.DLL";

function StringToPWideChar(sStr: string): PWideChar;
var
 pwc: PWideChar;
 iSize: integer;
begin
 iSize := Length(sStr) + 1;
 pwc := AllocMem(iSize * 2);
 MultiByteToWideChar(CP_ACP, 0, PChar(sStr), iSize, pwc,iSize * 2);
 Result := pwc;
end;

Procedure FlashEjectError(ErrorCode:DWORD);

Procedure ShowText(Txt:Pchar);
Begin
 MessageBox(GetForegroundWindow,Txt,"Status eject flash drive",0);
end;

Begin
 Case ErrorCode of
    ERROR_SUCCESS              : ShowText("The eject operation was successful.");
    ERROR_ACCESS_DENIED        : ShowText("NTMS_CONTROL_ACCESS to the library is denied. Other security errors"#13#10+
                                          "are also possible, but they would indicate a security subsystem error.");
    ERROR_DATABASE_FAILURE     : ShowText("The database is inaccessible or damaged.");
    ERROR_DATABASE_FULL        : ShowText("The database is full.");
    ERROR_DEVICE_NOT_AVAILABLE : ShowText("The library is disabled.");
    ERROR_INVALID_HANDLE       : ShowText("The session ID is invalid or missing.");
    ERROR_INVALID_OPERATION    : ShowText("A stop was performed on an invalid operation ID.");
    ERROR_INVALID_PARAMETER    : ShowText("A library ID or operation ID pointer is missing.");
    ERROR_LIBRARY_OFFLINE      : ShowText("The library ID refers to an offline library that cannot eject media.");
    ERROR_MEDIA_NOT_AVAILABLE  : ShowText("The media is disabled.");
    ERROR_NOT_ENOUGH_MEMORY    : ShowText("There was an allocation failure during processing.");
    ERROR_DEVICE__CAN_NOT_OPEN : ShowText("Can""not open device.") else
    ShowText(PChar("Unknown error code: "+IntToStr(ErrorCode)));
end;
end;

procedure TForm1.btnSafeEjectClick(Sender: TObject);
begin

 FlashEjectError                                              // \\.\PhysicalDrive1
 (
  EjectDiskFromSADriveW(nil,StringToPWideChar(Caption),"\\.\PhysicalDrive1",
  Handle,"exit?", "Exit?",NTMS_EJECT_START)
 );

end;

end.


 
n0name   (2006-04-07 10:22) [54]

>>не обходимо остановить драйвер  USBSTOR.SYS
И отрубятся сразу все USB-диски, а не какой-то конкретный, способ приведённый в [43] более корректен.


 
Arazel ©   (2006-04-07 10:45) [55]

n0name   (07.04.06 10:22) [54]
Тогда драйвер нужного ТОМА :)


 
Arazel ©   (2006-04-07 11:04) [56]

n0name   (05.04.06 16:37) [43]
Извиний но я не заметил, ты уже решил проблему :)
Осталось:

1) Проверить действительно ли это безопасное извлечение
2) Превести код до ума...
3) Придумать автоматическое безопасное извлечение

Сомнение:
1) При извлечение драйвер должен подать сигнал о том что устройство
   освобожденно и перейти в режим ожидание... Такое нет! Драйвер
   остается ждать следующие устройство... об этом говрит сам драйвер
   тома!
2) Перечислить нужные устройста затем воспользоватся твоим кодом
   затем выгрузить драйвер тома...

3) Ну это уже мало у кого мозгов хватит. Здесь надо применять ядровые
   ф-ций.

Вообще зачем я в лип в эту историю.  :D


 
Игорь Шевченко ©   (2006-04-07 11:37) [57]


> Ну это уже мало у кого мозгов хватит


У разработчиков Explorer"а хватило.

Кстати, твой пример из [53] не работает. Пишет, что "The eject operation was successful", но ничего не извлекается. Флешка как была видна, так и остается. И файлы с нее преспокойно открываются. Более того, программа даже не выдает ошибки, если флешка открыта в другом приложении.


 
Arazel ©   (2006-04-07 12:46) [58]

Игорь Шевченко ©   (07.04.06 11:37) [57]
Во первых как я уже не раз повторял, это лишь правильное определение
ф-ций. В том числе пример.
Документацию по этой ф-ций я не читал...

Ф-ция работает 100%. Наверное, она не совсем для этого предназначено!

У меня тоже не изчезает диск, хотя досуп закрыт!

Ошибки обрабатываются нормально! ПРОВЕРЕННО!


 
Игорь Шевченко ©   (2006-04-07 12:52) [59]

Arazel ©   (07.04.06 12:46) [58]


> Вот этот код полноценно работоспособен!


Это чьи слова из поста [53] ?


> Документацию по этой ф-ций я не читал...
>
> Ф-ция работает 100%. Наверное, она не совсем для этого предназначено!
>


Нафига тогда ты пишешь код ?


 
n0name   (2006-04-07 14:41) [60]

>>1) Проверить действительно ли это безопасное извлечение
AFAIK именно так и реализованно в Win. "Безопасное извлечение" использует hotplug.dll, в котором и используется SetupAPI.
>>2) Превести код до ума...
Гм. Все необходимые проверки выполнены. Полностью рабочий пример.
>>3) Придумать автоматическое безопасное извлечение
Смысл фразы малопонятен.
>>Сомнение:
Зачем тебе производить какие-то действия с драйверами?


 
Arazel ©   (2006-04-07 14:49) [61]

n0name   (07.04.06 14:41) [60]
Смысл фразы малопонятен.
Ну зачем тебе иметь вторую программу для извлечение?
Только лишь для того если ты используешь другой Shell
но разве тебе этого мало?

Зачем тебе производить какие-то действия с драйверами?
Так как Безопасное извлечение как раз таки и заключается в выгрузке
драйвера. Если драйвер находится в режиме функционирований и в это
время вынуть Флешь, то вполне вероятно, что дело дойдет до переустановки
системы в целом! Так как пакеты успешного выполнение, должны передоватся
в конце каждой процедуры.


 
Arazel ©   (2006-04-07 14:53) [62]

Игорь Шевченко ©   (07.04.06 12:52) [59]
Я имел введу что выполняется правельно... а что она делает
это ты можешь прочитать на сайте microsoft
Хотя зачем я тебе это говорю :) Ты и сам сможешь с этим разобратся.
А лиш исправил приведеный код Автор(а) темы.

Думаю на этом закончим.


 
Игорь Шевченко ©   (2006-04-07 15:09) [63]


> Если драйвер находится в режиме функционирований и в это
>
> время вынуть Флешь, то вполне вероятно, что дело дойдет
> до переустановки
> системы в целом


Невероятно.


> Так как пакеты успешного выполнение, должны передоватся
> в конце каждой процедуры


Переведи на русский язык.


> Я имел введу что выполняется правельно... а что она делает
> это ты можешь прочитать на сайте microsoft


Ты можешь ответить на простой вопрос - нафига ты этот код привел, если он флешку не извлекает ?


 
n0name   (2006-04-07 15:27) [64]


> Ну зачем тебе иметь вторую программу для извлечение?

Мало ли какие причины у автора. Это не моя идея, я лишь привёл пример реализации.

> Так как Безопасное извлечение как раз таки и заключается
> в выгрузкедрайвера.

Так зачем тебе это делать, если всё это выполняют функции SetupAPI.


 
mlm68 ©   (2006-04-08 00:03) [65]

Огромное спасибо всем откликнувшимся на мою просьбу!

Я когда создал тему, даже и не думал, что она так вас заинтересует.

Мне очень помог код [24] - это было собствено то что мне было нужно.
он даже CD-ROM заставляет выезжать (если в качестве параметра SafeEjectDrive указать его), что мне тоже необходимо.

код [43] немного не подошел по причине того, что он отключает картридер, и чтобы прочитать следующую флешку нужно выдернуть картридер и воткнуть его снова.

Еще раз всем спасибо.


 
n0name   (2006-04-08 04:55) [66]


> код [43] немного не подошел по причине того, что он отключает
> картридер, и чтобы прочитать следующую флешку нужно выдернуть
> картридер и воткнуть его снова.

Там отключает первый попавшийся USB накопитель, немного модифицируй код, и всё.


 
Arazel ©   (2006-04-08 08:05) [67]

Игорь Шевченко ©   (07.04.06 15:09) [63]
Невероятно. Сразу видно мало ты знаешь про ДРАЙВЕРА.
Переведи на русский язык. Если ты не смог понять выше строчку
то наврятли ты поймешь про IRP пакеты.
Ты можешь ответить на простой вопрос - нафига ты этот код привел, если он флешку не извлекает ?
Читай 62 пост.


 
mlm68 ©   (2006-04-08 23:18) [68]


> n0name   (08.04.06 04:55) [66]
>
> Там отключает первый попавшийся USB накопитель, немного
> модифицируй код, и всё.


Но отключается намертво (удаляет том), после вытаскивания - впихивания флешки диск система не видит, приходится вытаскивать картридер, а так как он у меня встроеный то только перезакрузка помогает.

Кстати так делает и система, когла нажимаешь в трее безопасное отключение, а код [24] делает  команду "Извлечь", которая в контекстном меню диска, и после вставления флешки, её опять видно.


 
Игорь Шевченко ©   (2006-04-10 11:16) [69]

Arazel ©   (08.04.06 08:05) [67]


> Сразу видно мало ты знаешь про ДРАЙВЕРА.


Может быть, я не претендую на полноту знаний.


> Если драйвер находится в режиме функционирований и в это
>
> время вынуть Флешь, то вполне вероятно, что дело дойдет
> до переустановки
> системы в целом!


Но моих знаний хватает, для того, чтобы утверждать, что процитированная фраза не совпадает с поведением системы. Либо ты приводишь пример, когда такая ситуация возможно (при извлечении флешки в неподходящий момент надо переустанавливать систему в целом), либо пишешь, что твои фантазии не имеют ничего общего с реальностью.


> Так как пакеты успешного выполнение, должны передоватся
> в конце каждой процедуры


Фразу нельзя понять по двум причинам - либо не хватает знаний, либо фраза написана непонятно. Сдается мне, что имеет место второй случай.


 
Arazel ©   (2006-04-11 06:59) [70]

Игорь теперь ты видишь, сколько ошибок происходит!
Зачем тебе это нужно. Я лишь любитель, а вот если заглянут
профессионалы они засмеют тебя, тебе этот позор нужен? Знаток ;)

unit IO;

INTERFACE

{$I NTDDK.INC}
{$I NTOSKRNL.INC}

CONST
    DEVICE_NAME_STRING = "IO";
    DeviceNameString   = "\DosDevices\"  +DEVICE_NAME_STRING;
    DriverNameString   = "\Device\"      +DEVICE_NAME_STRING;
    UserModeDeviceName = "\\.\Global\"   +DEVICE_NAME_STRING;

    IOCTL_BEEP   =
    (IOCTL_UNKNOWN_BASE shl 16) or
    ((FILE_READ_ACCESS) shl 14) or
    ($800 shl 2) or
    (METHOD_BUFFERED);

TYPE
    PParams     = ^TParams;
    TParams     = RECORD
      ParamType : ULONG;
      Param1    : ULONG;
      Param2    : ULONG;
      Param3    : ULONG;
    END;

 function DriverEntry(
 const DriverObject : PDRIVER_OBJECT;
 const RegistryPath : PUNICODE_STRING
 ) : NTStatus; stdcall;

IMPLEMENTATION

{$I MACROS.INC}

VAR
    DriverName    : UNICODE_STRING;
    DeviceName    : UNICODE_STRING;
    DeviceObject  : PDEVICE_OBJECT;
    Params        : TParams;

PROCEDURE ADriverUnload(const DriverObject : PDRIVER_OBJECT); stdcall;
BEGIN
  DbgPrint("DriverUnload ");
  // Удаляем символьную сылку
  IoDeleteSymbolicLink(@DeviceName);
  // Удаляем устройство
  IoDeleteDevice(DeviceObject);
END;

function CloseDispatch(
        const DeviceObject : PDEVICE_OBJECT;
        const Irp : PIRP) : NTSTATUS; stdcall;
BEGIN
 (***********************************************)
  // Если при завершений ф-ций/процедуры потеряеются данные
  // то есть, которые ниже... То это уже говорит что в драйвер
  // поступят ошибки.
  //   DbgPrint("CloseDispatch");
  //   IRP.IoStatus.Status        :=0;
  //   IRP.IoStatus.Information   :=0;
  //   IoCompleteRequest(IRP,IO_NO_INCREMENT);
  //   Result:=STATUS_SUCCESS;
 (***********************************************)
 IoCompleteRequest(IRP,IO_NO_INCREMENT);
END;

function CreateDispatch(
        const DeviceObject : PDEVICE_OBJECT;
        const Irp : PIRP) : NTSTATUS; stdcall;
BEGIN
  DbgPrint("CreateDispatch");
  IRP.IoStatus.Status        :=STATUS_SUCCESS;
  IRP.IoStatus.Information   :=0;
  IoCompleteRequest(IRP,IO_NO_INCREMENT);
  Result:=STATUS_SUCCESS;
END;

function IOCTLDispatch(
        const DeviceObject : PDEVICE_OBJECT;
        const dIrp : PIRP) : NTSTATUS; stdcall;
VAR
        IRPStack : PIO_STACK_LOCATION;
BEGIN
 DbgPrint("IOCTLDispatch");
 // Кстати, на вход могут вообще чудо-юдо поступить.
 // и система встанит по полной!
 // Просто прикол :)))
 dIrp:=nil;
 IRPStack:=IoGetCurrentIrpStackLocation(dIrp);
 CASE IRPStack^.Parameters.DeviceIoControl.IoControlCode OF
 IOCTL_BEEP :
 BEGIN
 (***********************************************)
  // Также Buffer может обнулится или передоватся не правельные данные
  // это первая ошибка твоя! Не говоря уж BSOD.
  // if  (IRPStack^.Parameters.DeviceIoControl.OutputBufferLength >= SizeOf(TParams))
  // and (dIrp.AssociatedIrp.SystemBuffer<>nil) then
 (***********************************************)
 BEGIN
 // load
  Params:=TParams(dIrp.AssociatedIrp.SystemBuffer^);
  Beep(Params.Param1,Params.Param2);

  Params.ParamType:=5;
  Params.Param1:=12345;
  Params.Param2:=54321;
  Params.Param3:=55555;

 (***********************************************)
  // Это вторая ошибка.
  // TParams(dIrp.AssociatedIrp.SystemBuffer^):=Params;
  // dIrp.IoStatus.Information:=SizeOf(TParams);
 (***********************************************)
 // report
 Result:=STATUS_SUCCESS;
 END
  ELSE Result:=STATUS_INVALID_PARAMETER;
 END;
  ELSE Result:=STATUS_NOT_IMPLEMENTED;
END;

 (***********************************************)
  // Вот сюда должны передоватся обработанные IRP пакеты
  // IoCompleteRequest(dIrp,IO_NO_INCREMENT);
 (***********************************************)
END;

function DriverEntry;
BEGIN
  DbgPrint("DriverEntry");
  RtlInitUnicodeString(DriverName,DriverNameString);
  Result:=IoCreateDevice(
           DriverObject,        // указатель на DriverObject
           0,                   // максимальный размер принимаемых данных
           @DriverName,         // имя создаваемого устройства
           FILE_DEVICE_UNKNOWN, // тип создаваемого устройства
           0,                   // метод буфферизации
           False,               // "эксклюзивное" устройство
           DeviceObject         // указатель на обьект устройства
           );

  IF (Result = STATUS_SUCCESS) THEN
  BEGIN
  RtlInitUnicodeString(DeviceName,DeviceNameString);
  Result:=IoCreateSymbolicLink(@DeviceName,@DriverName);
   IF (Result = STATUS_SUCCESS) THEN
   BEGIN
    DriverObject^.DriverUnload:=ADriverUnload;
    DriverObject^.MajorFunction[IRP_MJ_CREATE] := CreateDispatch;
    DriverObject^.MajorFunction[IRP_MJ_CLOSE]  := CloseDispatch;
    DriverObject^.MajorFunction[IRP_MJ_DEVICE_CONTROL]:= IOCTLDispatch;
   END ELSE
   Result:=STATUS_UNSUCCESSFUL;
   if (Result<>STATUS_SUCCESS) THEN
   IoDeleteSymbolicLink(@DeviceName);
  END;
  if (Result<>STATUS_SUCCESS) THEN
  IoDeleteDevice(DeviceObject);
END;

end.


 
Игорь Шевченко ©   (2006-04-11 10:42) [71]

Arazel ©   (11.04.06 06:59) [70]


> Я лишь любитель


Так учи матчасть. Развелось тут любителей неграмотных.


>  Также Buffer может обнулится или передоватся не правельные
> данные


1. Возьми орфографический словарь русского языка и выучи его наизусть.
2. Буфера проверяются при вызове NtDeviceIoControlFile еще до вызова драйвера. Возьми отладчик и посмотри.


 
Woolen ©   (2006-04-11 13:29) [72]

Уважаемые кодеры, горячо обсуждавшие выше EjectDiskFromSADrive. У вас всех Windows Server 2003? Насколько я понимаю, это единственная ось на сегодня, в которой эта функция реализована. Если я не прав, поправьте, пожалуйста.


 
Игорь Шевченко ©   (2006-04-11 13:45) [73]

Woolen ©   (11.04.06 13:29) [72]

В Windows 2000 в упомянутой библиотеке эта функция есть.


 
Rouse_ ©   (2006-04-11 14:14) [74]

EjectDiskFromSADriveA, EjectDiskFromSADriveW


 
Arazel ©   (2006-04-11 14:55) [75]

Игорь Шевченко ©   (11.04.06 10:42) [71]

Ты на моей неграмотности не отматывайся! :)))

Прочитай книгу Солдатова там все написано а также есть теже
ответы, на которые я и отвечал ;) Так что не нужно умничать...

Кстати я даже тебе скажу, где она лежит на сайте Rouse_
http://rouse.front.ru

Любитель всегда лучше профисионала... ЭТО ФАКТ ;)D ;)


 
Игорь Шевченко ©   (2006-04-11 15:34) [76]

Arazel ©   (11.04.06 14:55) [75]


> Прочитай книгу Солдатова


Спасибо, я предпочитаю Руссиновича с Соломоном. Они ближе к разработчикам Windows, чем приведенный тобой автор.


> Так что не нужно умничать...


Не нужно писать бред, пусть он хоть у какого автора вычитан.


 
Arazel ©   (2006-04-11 16:39) [77]

Руссиновича с Соломоном.
Да уж.
Прям как я, Молодец.

:)


 
Игорь Шевченко ©   (2006-04-11 17:10) [78]

Arazel ©   (11.04.06 16:39) [77

Любезный, у меня к вам просьба - избавьте меня пожалуйста от ваших глубокомысленных заключений. Я в них не нуждаюсь.


 
Woolen ©   (2006-04-11 17:58) [79]


> Игорь Шевченко ©   (11.04.06 13:45) [73]


> В Windows 2000 в упомянутой библиотеке эта функция есть.

Открываю MSDN по функции EjectDiskFromSADrive.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/stgmgmt/fs/ejectdiskfromsadrive.asp
Читаю:
Requirements
Client Requires Windows Vista.
Server Requires Windows Server "Longhorn" or Windows Server 2003.
И перестаю вообще что-либо понимать.


 
Игорь Шевченко ©   (2006-04-11 18:17) [80]

Woolen ©   (11.04.06 17:58) [79]


> Открываю MSDN по функции EjectDiskFromSADrive


Открываю в depends.exe %SystemRoot%\System32\ntmsapi.dll, вижу EjectDiskFromSADriveA и EjectDiskFromSADriveW. Делаю выводы о существовании этих фукнций.


 
Woolen ©   (2006-04-11 19:48) [81]


> Открываю в depends.exe %SystemRoot%\System32\ntmsapi.dll,
>  вижу EjectDiskFromSADriveA и EjectDiskFromSADriveW. Делаю
> выводы о существовании этих фукнций.

Я тоже решил посмотреть. На ХР SP2. Есть. Теперь я тем более ничего не понимаю. Остается только одно. Тот, кто писал MSDN - ошибся.


 
n0name   (2006-04-11 20:10) [82]

Arazel ©   (11.04.06 06:59) [70]
Irp^.IoStatus.Status := 0;
Irp^.IoStatus.Info := 0;

Для надежности лучше добавить в Diaptch процедуры.
И IoCompleteRequest забыл в обработчике IRP_DEVICE_CONTROL.

PS: Скинь plz. NTOSKRNL.INC и NTDDK.INC, надоело вручную прописывать :(


 
n0name   (2006-04-11 20:16) [83]

Arazel ©   (11.04.06 06:59) [70]
А чё это за комментарии про какие-то ошибки?
Чё то не вижу первичного кода :\


 
Arazel ©   (2006-04-12 08:28) [84]

n0name   (11.04.06 20:10) [82]
Спасибо за совет но я это знаю ;)

Давай Mail. Я тебе ещё пару скину.


 
Arazel ©   (2006-04-12 08:34) [85]

Удалено модератором


 
n0name   (2006-04-12 12:00) [86]

Arazel ©   (12.04.06 08:28) [84]
А где ответ на [83]?
Мыло в этом посте.


 
Arazel ©   (2006-04-12 13:19) [87]

Удалено модератором


 
Arazel ©   (2006-04-13 05:47) [88]

Удалено модератором
Примечание: Создание пустых сообщений


 
GrayFace ©   (2006-04-13 18:29) [89]

Woolen ©   (11.04.06 19:48) [81]
> Я тоже решил посмотреть. На ХР SP2. Есть. Теперь я тем более
> ничего не понимаю. Остается только одно. Тот, кто писал
> MSDN - ошибся.

Попробуй вызвать. Скорее всего будет ошибка Not Supported. Хотя MSDN тоже иногда ошибается.


 
WondeRu ©   (2006-06-21 09:48) [90]

Вот нашел http://www.codeproject.com/useritems/usbeject.asp



Страницы: 1 2 3 вся ветка

Форум: "WinAPI";
Текущий архив: 2006.11.05;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.76 MB
Время: 0.041 c
15-1160562761
Anatoly Podgoretsky
2006-10-11 14:32
2006.11.05
Top 10


11-1137399364
savva
2006-01-16 11:16
2006.11.05
У кого есть оболочка для UPX от Gandalf - UGH ??


2-1161604152
gidd
2006-10-23 15:49
2006.11.05
Копирование по сети


2-1161494250
Любовь
2006-10-22 09:17
2006.11.05
delphi


2-1161365018
kcol
2006-10-20 21:23
2006.11.05
функция / процедура





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский