Добрый день. Есть код, который должен удалять драйвер из ОС :
Код:
//------------------------------------------------
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