Форум: "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.
Страницы: 1 2 3 вся ветка
Форум: "WinAPI";
Текущий архив: 2006.11.05;
Скачать: [xml.tar.bz2];
Память: 0.58 MB
Время: 0.053 c