Форум: "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,"Çà÷èò îïðàöèÿ ïðîøëà óñïåøíî!",nil,0) else
Begin
Caption:=IntToStr(result);
Case Result of
ERROR_ACCESS_DENIED:MessageBox(GetForegroundWindow,"Ñìîò 0;èòå íà ñàéòå microsoft",nil,0);
ERROR_DATABASE_FAILURE:MessageBox(GetForegroundWindow,"Ñìîò& #240;èòå íà ñàéòå microsoft",nil,0);
ERROR_DATABASE_FULL:MessageBox(GetForegroundWindow,"Ñìîò 0;èòå íà ñàéòå microsoft",nil,0);
ERROR_DEVICE_NOT_AVAILABLE:MessageBox(GetForegroundWindow,"Ñìî 42;ðèòå íà ñàéòå microsoft",nil,0);
ERROR_INVALID_HANDLE:MessageBox(GetForegroundWindow,"Ñìîò 40;èòå íà ñàéòå microsoft",nil,0);
ERROR_INVALID_OPERATION:MessageBox(GetForegroundWindow,"Ñìîò ðèòå íà ñàéòå microsoft",nil,0);
ERROR_INVALID_PARAMETER:MessageBox(GetForegroundWindow,"Ñìîò ðèòå íà ñàéòå microsoft",nil,0);
ERROR_LIBRARY_OFFLINE:MessageBox(GetForegroundWindow,"Ñìîò&# 240;èòå íà ñàéòå microsoft",nil,0);
ERROR_MEDIA_NOT_AVAILABLE:MessageBox(GetForegroundWindow,"Ñìî 2;ðèòå íà ñàéòå microsoft",nil,0);
ERROR_NOT_ENOUGH_MEMORY:MessageBox(GetForegroundWindow,"Ñìîò ðèòå íà ñàéòå 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