![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | 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, ф-я драйвер удаляет, но в системе тот продолжает работать до перезапуска.
|