![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как сделать программное безопасное извлечение флешки?
mlm68 © (2006-03-30 21:13:00)Как сделать программное безопасное извлечение флешки?
Rouse_ (2006-04-04 14:07:00) [61]
> Игорь Шевченко © (04.04.06 13:39) [27]
Ну по всей видимости у тебя отключена галка в свойствах флешки "Enable write caching on the disk" которая стоит по умолчанию...
> Вставив флешку обратно, выполнив твой код, я прекрасно вижу
> флешку среди дисков проводника.
В списке проводника она безусловно пристутвует, но при попытке обращения к ней выдается надпись "Please insert dist into Drive ..."
fellix (2006-04-04 13:48:00) [62]Ну и объявить, желательно, как функцию - чтоб код возврата анализировать.
fellix (2006-04-04 13:46:00) [63]
> mlm68 © (04.04.06 11:24) [20]
> Где ошибка?
@EjectDiskFromSADrive:=GetProcAddress(Handle, 'EjectDiskFromSADrive A ');
Игорь Шевченко (2006-04-04 13:39:00) [64]Rouse_ © (04.04.06 12:46) [24]
> Ну я както за свои слова привык отвечать:
Это безусловно радует.
Скомпилировав и запустив твой код, вынув после нажатия на кнопку на форме, флешку, я получил сообщение: Небезопасное извлечение устроства.
Вставив флешку обратно, выполнив твой код, я прекрасно вижу флешку среди дисков проводника.
Тут есть один ма-ааленький момент - флешка не компакт-диск.
Rouse_ (2006-04-04 13:17:00) [65]
> А проще через EjectDiskFromSADrive можно?
не знаю - не пробовал... нет времени эксперементировать...
mlm68 (2006-04-04 13:14:00) [66]
> Rouse_ © (04.04.06 12:46) [24]
>
> Ну я както за свои слова привык отвечать:
Вот это круто!
А проще черезEjectDiskFromSADriveможно?
Rouse_ (2006-04-04 12:46:00) [67]
> Игорь Шевченко © (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.
Плохиш (2006-04-04 11:48:00) [68]
> 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особенно про системные требования.
mlm68 (2006-04-04 11:31:00) [69]в этой строке проблемка
EjectDiskFromSADrive(nil,nil,'\\.\Cdrom0',1,'','',0);
Игорь Шевченко (2006-04-04 11:29:00) [70]
> Где ошибка?
А отладчика у тебя нету ? Бедняга...
mlm68 (2006-04-04 11:24:00) [71]Где ошибка?
Есть форма 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 10:33:00) [72]Rouse_ © (03.04.06 21:17) [17]
> а через IShellFolder и Context.InvokeCommand
Ты тоже приведешь работающеерешение ?
Германн (2006-04-04 00:20:00) [73]
> n0name (03.04.06 19:17) [16]
>
> >>Давай для начала ответим на первый вопрос - как ты собираешься
> найти координаты иконки для флешки ?
> А зачем искать?
> Перебрать все иконки, найти нужную, отправить сообщение.
>
А как их перебрать?
Rouse_ (2006-04-03 21:17:00) [74]
> ы, если не трудно, приведи пожалуйста работающее решение
> [6].
Игорь, ну ты наскочил на парня :) В принципе его идея тоже имеет смысл, только конечно не через трей, а через IShellFolder и Context.InvokeCommand
n0name (2006-04-03 19:17:00) [75]>>Давай для начала ответим на первый вопрос - как ты собираешься найти координаты иконки для флешки ?
А зачем искать?
Перебрать все иконки, найти нужную, отправить сообщение.
Хотя этим спопсобом я бы пользовался в последнюю очередь.
kaZaNoVa (2006-04-03 17:19:00) [76]Игорь Шевченко © (03.04.06 17:16) [14]
думаю данное решение реализовать мне будет несколько проблематично, а в [6] была лишь высказана идея, как можно попробоватьрешить проблему :)
с уважением.
Игорь Шевченко (2006-04-03 17:16:00) [77]kaZaNoVa © (03.04.06 17:12) [13]
Ты, если не трудно, приведи пожалуйста работающеерешение [6].
kaZaNoVa (2006-04-03 17:12:00) [78]Игорь Шевченко © (03.04.06 17:09) [12]
решение [11] сразу показывает:) и кликать не нужно
Игорь Шевченко (2006-04-03 17:09:00) [79]
> а так если скрыта - то есть же значок "показать скрытые"
А как ты его искать собираешься, этот значок ?
kaZaNoVa (2006-04-03 16:56:00) [80]
"путь к винде\system32\rundll32.exe" shell32.dll,Control_RunDLL hotplug.dll