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

Вниз

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

 
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. Делаю выводы о существовании этих фукнций.



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

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

Наверх





Память: 0.67 MB
Время: 0.06 c
15-1160848270
TUser
2006-10-14 21:51
2006.11.05
Преимущества альтернативных браузеров


1-1159182939
Max4
2006-09-25 15:15
2006.11.05
Перехват сообщения в наследнике.


2-1161336375
dest81
2006-10-20 13:26
2006.11.05
Fbird &amp; sqlserver


2-1161162997
viper7
2006-10-18 13:16
2006.11.05
Создание компонента


3-1157530675
alex_sc
2006-09-06 12:17
2006.11.05
запись и чтение GIF из MSSQL





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский