Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 18.08.2016, 16:10
Pcrepair Pcrepair вне форума
Новичок
 
Регистрация: 20.01.2015
Сообщения: 52
Версия Delphi: Pascal
Репутация: 10
По умолчанию Как программно удалить драйвер из операционной системы

Добрый день. Есть код, который должен удалять драйвер из ОС :

Код:
//------------------------------------------------
procedure TMain.Button2Click(Sender: TObject);
begin
  if not ConnectSCM then
  begin
    ShowMessage(FLastError);
  end
  else
  begin
    ShowMessage('Connected SCM');
    if not DriverStop(Edit1.Text) then
    begin
      ShowMessage(FLastError);
      pDisconnectSCM
    end
    else
    begin
      ShowMessage('Driver Stopped');
      if not DriverRemove(Edit1.Text) then
      begin
        ShowMessage(FLastError);
        pDisconnectSCM
      end
      else
      begin
        ShowMessage('Driver Remuved');
        if not DisconnectSCM then
        begin
          ShowMessage(FLastError);
          pDisconnectSCM
        end
        else
        begin
          ShowMessage('DisConnected SCM');
        end;
      end;
    end;
  end;
//--------------------------------------

//--------------------------------------
uses
  Classes,SysUtils,Dialogs,StrUtils,Windows,WinSvc;
.....

var
  FLastError : String;
  hSCMan : SC_HANDLE;

implementation

(*Connects to the WinNT Service Control Manager *)
function ConnectSCM : Boolean;
const
  SC_MANAGER_CONNECT           = $0001;
  SC_MANAGER_QUERY_LOCK_STATUS = $0010;
  SC_MANAGER_ENUMERATE_SERVICE = $0004;
  SC_MANAGER_CREATE_SERVICE    = $0002;
  ERROR_ACCESS_DENIED          = $0005;
var
  dwStatus : DWORD;
  scAccess : DWORD;
begin
  dwStatus := 0;                                 (*Assume success, until we prove otherwise*)

  scAccess := SC_MANAGER_CONNECT or
              SC_MANAGER_QUERY_LOCK_STATUS or
              SC_MANAGER_ENUMERATE_SERVICE or
              SC_MANAGER_CREATE_SERVICE;         (*Try and connect as administrator*)

  hSCMan := OpenSCManager(nil, nil, scAccess);   (*Connect to the SCM*)

  if ((hSCMan=0) and (GetLastError=ERROR_ACCESS_DENIED)) then
  begin
    scAccess := SC_MANAGER_CONNECT or
                SC_MANAGER_QUERY_LOCK_STATUS or
                SC_MANAGER_ENUMERATE_SERVICE;     (*If we're not in administrator mode, try and reconnect*)

    hSCMan := OpenSCManager(nil, nil, scAccess);  (*Connect to the SCM*)
  end;

  if (hSCMan=0) then
  begin
      // Failed, save error information
    dwStatus:=GetLastError;
    FLastError:='ConnectSCM: Error #'+IntToStr(dwStatus);
  end;                                             (*Did it succeed?*)

  Result := (dwStatus=0);                          (*Success == 0 *)
end;
(*---------------------------------------------------*)

(*Disconnects from the WinNT Service Control Manager *)
function DisconnectSCM: Boolean;
begin
  Result:=False;
  if (hSCMan<>0) then
  begin
    CloseServiceHandle(hSCMan);
    hSCMan:=0;
    Result:=True;
  end;
end;
(*---------------------------------------------------*)

(**)
function DriverStop(const DrvName:string) : Boolean;
const
  SERVICE_QUERY_STATUS   = $00004;
  SERVICE_STOP           = $00020;
  SERVICE_CONTROL_STOP   = $00001;
var
  hService      : SC_HANDLE;                     (*Handle to the new service*)
  dwStatus      : DWORD;
  Temp          : LongBool;
  ServiceStatus : TServiceStatus;
begin
  dwStatus := 0;                                 (*Assume success, until we prove otherwise*)

  hService := OpenService(hSCMan,
                          PChar(DrvName),
                          SERVICE_STOP or
                          SERVICE_QUERY_STATUS);  (*Get a handle to the service to stop *)

  if (hService<>0) then
  begin
    Temp := ControlService(hService,
                           SERVICE_CONTROL_STOP,
                           ServiceStatus);        (*Stop the driver, then close the service*)

    if (not Temp) then dwStatus := GetLastError();
    CloseServiceHandle(hService);                 (*Close the service *)
  end
  else  dwStatus := GetLastError;

  if (dwStatus<>0) then
     FLastError:='DriverStop: Error #'+IntToStr(dwStatus);

  Result := (dwStatus=0);                         (*Success == 0 *)
end;
(*------------------------------------------------------------*)

(**)
function DriverRemove(const DrvName:string) : Boolean;
const
  DELETE = $10000;
var
  hService      : SC_HANDLE;                      (*Handle to the new service *)
  dwStatus      : DWORD;
  Temp          : LongBool;
begin
  dwStatus := 0; (*Assume success, until we prove otherwise*)

  hService := OpenService(hSCMan,
                          //PChar(DRIVER_NAME),
                          PChar(DrvName),
                          DELETE);                (*Get a handle to the service to stop *)

  if (hService<>0) then
  begin
    Temp := DeleteService(hService);              (*Remove the driver then close the service again *)
    if (not Temp) then
      dwStatus := GetLastError;
      CloseServiceHandle(hService);               (*Close the service *)
  end else dwStatus := GetLastError;

  if (dwStatus<>0) then
    FLastError:='DriverRemove: Error #'+IntToStr(dwStatus);

  Result := (dwStatus=0);                         (* Success == 0 *)
end;
(*------------------------------------------*)

(*Disconnect from our local Service Control Manager*)
procedure pDisconnectSCM;
begin
  if (hSCMan<>0) then
  begin
    CloseServiceHandle(hSCMan);
    hSCMan:=0;
  end;
end;
(*----------------------------------------------*)

end.
//------------------------------------------------------------
для "левого" драйвера DLPORTIO.sys все работает, удаляет драйвер, правда непонятно откуда, в диспетчере устройств (ВЫНьХР) его не видно, в реестре DLPORTIO записывается, некоторые программы(самопальные) видят этот драйвер в куче еще таких же невидимок.
(DLPORTIO.sys - древний код для доступа к чипу проца для снятия данных по температуре проца и прочему но на ВЫНьХР работает. И вообще весь код из PortIO.pas, немного модифицированный под задачу - удалить указанный драйвер программно)

Проблема в том что этот код не удаляет драйвера имеющие вид записи типа: имя драйвера = {4D36E966-E325-11CE-BFC1-08002BE10318}\0000 - (реестр), реально это "вторичный канал IDE" имя драйвера atapi.sys (в диспетчере устройств)

При этом к SCM подключение есть, затем выходит ошибка (при попытке остановить драйвер, перед удалением, впрочем если сразу попробовать удалить то та же ошибка с кодом 1066 или еще каким нибуть).

Вручную через диспетчер задач, драйвера удаляются без вопросов, но надо программно

Подскажите, если кто знает, как все таки программно удалить драйвер с использованием DELPHI
Ответить с цитированием
  #2  
Старый 18.08.2016, 23:37
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Приведённый код понятен частично, есть вопросы, но, используя подсказки из drkb нарисовался другой сценарий, выходит следующее - перед удалением предварительно получаем привилегиии
Код:
...
// секция uses
 uses
   windows, NativeAPI, advApiHook;
...
// секция implementation
implementation
const
DrRegPath = '\registry\machine\system\CurrentControlSet\Services\';
...
// секция initialization (завершающая юнит)
initialization
EnablePrivilege('SeLoadDriverPrivilege');
...
затем
Код:
//Выгрузка драйвера
function UnloadDriver(dName: PChar): boolean;
var
Image: TUnicodeString;
Buff: array [0..MAX_PATH] of WideChar;
begin
StringToWideChar(DrRegPath + dName, Buff, MAX_PATH); 
RtlInitUnicodeString(@Image, Buff);
Result := ZwUnloadDriver(@Image) = STATUS_SUCCESS;
end;
опосля
Код:
//Удаление записи о драйвере из реестра
function UninstallDriver(drName: PChar): boolean;
var
Key: HKEY;
begin
Result := false;
if RegOpenKeyA(HKEY_LOCAL_MACHINE, 'system\CurrentControlSet\Services', Key) = ERROR_SUCCESS then
   begin
     RegDeleteKey(Key, PChar(drName+'\Enum'));
     RegDeleteKey(Key, PChar(drName+'\Security'));
     Result := RegDeleteKey(Key, drName) = ERROR_SUCCESS;
     RegCloseKey(Key);
   end;
end;
должно быть так, пжлст, проверьте
Ответить с цитированием
  #3  
Старый 19.08.2016, 08:16
Pcrepair Pcrepair вне форума
Новичок
 
Регистрация: 20.01.2015
Сообщения: 52
Версия Delphi: Pascal
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
должно быть так, пжлст, проверьте
проверю. скоро.
Ответить с цитированием
  #4  
Старый 19.08.2016, 11:03
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Как-то пробовал ф-ю ZwUnloadDriver, ф-я драйвер удаляет, но в системе тот продолжает работать до перезапуска.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 00:49.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter