|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Как программно удалить драйвер из операционной системы
Добрый день. Есть код, который должен удалять драйвер из ОС :
Код:
//------------------------------------------------ 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 - древний код для доступа к чипу проца для снятия данных по температуре проца и прочему но на ВЫНьХР работает. И вообще весь код из PortIO.pas, немного модифицированный под задачу - удалить указанный драйвер программно) Проблема в том что этот код не удаляет драйвера имеющие вид записи типа: имя драйвера = {4D36E966-E325-11CE-BFC1-08002BE10318}\0000 - (реестр), реально это "вторичный канал IDE" имя драйвера atapi.sys (в диспетчере устройств) При этом к SCM подключение есть, затем выходит ошибка (при попытке остановить драйвер, перед удалением, впрочем если сразу попробовать удалить то та же ошибка с кодом 1066 или еще каким нибуть). Вручную через диспетчер задач, драйвера удаляются без вопросов, но надо программно Подскажите, если кто знает, как все таки программно удалить драйвер с использованием DELPHI |
#2
|
||||
|
||||
Приведённый код понятен частично, есть вопросы, но, используя подсказки из 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
|
|||
|
|||
Цитата:
|
#4
|
||||
|
||||
Как-то пробовал ф-ю ZwUnloadDriver, ф-я драйвер удаляет, но в системе тот продолжает работать до перезапуска.
— Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |