Jak usunąć plik .sys?

Jak usunąć plik .sys?
E8
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:16
0

Witam, mam mały problem z usunięciem pliku z katalogu \System32\Drivers\plik.sys

Otóż gdy chcę skasować plik ręcznie to uruchamia się kontrola UAC i muszę potwierdzić że chcę usunąć plik jako administrator.
Napisałem prosty program który ma kasować plik i gdy uruchamiam go jako administrator to niestety pliku nie kasuje, dlaczego?

Ale gdy uruchamiam plik del_plik.bat
Oto zawartość pliku del_plik.bat

Kopiuj
@echo off
del c:\windows\system32\drivers\plik.sys

to plik zostaje usunięty.

Poszedłem o krok dalej i napisałem programik który ma uruchamiać plik del_plik.bat jako administrator:

Kopiuj
procedure RunAsAdmin(const aFile: string; const aParameters: string = ''; Handle: HWND = 0);
var
  sei: TShellExecuteInfo;
begin
  FillChar(sei, SizeOf(sei), 0);
 
  sei.cbSize := SizeOf(sei);
  sei.Wnd := Handle;
  sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
  sei.lpVerb := 'runas';
  sei.lpFile := PChar(aFile);
  sei.lpParameters := PChar(aParameters);
  sei.nShow := SW_SHOWNORMAL;

  if not ShellExecuteexA(@sei) then
    RaiseLastOSError;
end;

procedure TForm1.Button1Click(Sender: TObject);
RunAsAdmin('plik del_plik.bat');
end;

program uruchamia plik del_plik.bat jako administrator ale plik nie jest skasowany.

Wyłączyłem kontrolę UAC i nadal nic, domyślam się że trzeba jakoś programowo potwierdzić że chcę usunąć plik jako administrator ale nie wiem jak to zrobić, co ciekawe nie działa nawet sprawdzanie czy plik istnieje:

Kopiuj
if FileExists('c:\windows\system32\drivers\plik.sys') then

i nie ma znaczenia czy program uruchamiam jako administrator czy normalnie, po prostu nie działa.

Czy ktoś ma pomysł jak usunąć plik systemowy z "c:\windows\system32\drivers\plik.sys"

Z góry dziękuję za pomoc.

dodanie znaczników <code class="winbatch"> i <code class="delphi"> - Furious Programming

edytowany 1x, ostatnio: flowCRANE
flowCRANE
Przypominam o wstawianiu kodu w znaczniki kolorujące składnię;
olesio
  • Rejestracja:około 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

Kod nie jest wstawiony w odpowiednie znaczniki, także go ignoruje. Co do rozwiązania. To o ile wiem, można spróbowac zrobić ShellExecute z zamiast open to runas dla tego batcha. Są przykłady na Google takich rozwiązan i w Delphi. Ja bym kobminował tak, że dodał bym do zasobów taki manifest i miałbym pewnośc, że program można uruchomić tylko jako admin. I wtedy z UAC nie ma problemów. Poza tym nie wiem, co to za program kombinujesz z usuwaniem *.sys czy to util na Twoje potrzeby czy modzisz jakieś malware. Bo jeżeli używasz komputera z głową, a program ma chodzić na Twoim komputerze i być używany przez Ciebie. To pozostaje jeszcze rozwiązanie extremalne, wyłączyć UAC.

Kopiuj
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
          manifestVersion="1.0"> 
<dependency> 
    <dependentAssembly> 
        <assemblyIdentity 
            type="win32" 
            name="Microsoft.Windows.Common-Controls" 
            version="6.0.0.0" 
            processorArchitecture="X86" 
            publicKeyToken="6595b64144ccf1df" 
            language="*" 
        /> 
    </dependentAssembly> 
</dependency> 
<v3:trustInfo xmlns:v3="urn:schemas-microsoft-com:asm.v3">
  <v3:security>
    <v3:requestedPrivileges>
      <v3:requestedExecutionLevel level="requireAdministrator" />
    </v3:requestedPrivileges>
  </v3:security>
</v3:trustInfo>
</assembly>

Pozdrawiam.
edytowany 1x, ostatnio: olesio
E8
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:16
0

Dzięki za odpowiedź Olesio, radzisz mi wyłączyć UAC a ja pisałem że już sprawdzałem z wyłączonym UAC i nic to nie dało, nadal nie można usunąć pliku.sys. Dla wiadomości osób czytających ten post nie piszę żadnego malware tylko chcę skasować jeden pliczek bo on mi blokuje urządzenie serwisowe i wtedy muszę czekać na odblokowanie czasami kilka dni, a tak się składa że korzystam z tego urządzenia na kilku komputerach w firmie i w domu i sprawdzanie za każdym razem ręcznie czy ten plik istnieje i usuwanie go ręcznie jest po prostu uciążliwe i chcę to zautomatyzować, tak że przyda się każda rada.
Możesz podać jakiś mały przykład jak to zrobić z tym manifestem? I skoro moja metoda uruchamiania pliku.bat za pomocą RunAsAdmin nie działa to czy będzie działać ta metoda ShellExecute z runas?

olesio
  • Rejestracja:około 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

Wywołanie runas powinno pokazać monit UAC, ale nie wiem czy to pomoże. Manifest dołączasz normalnie poprzez zasoby, w pliku *.rc dla starszych Delphi ma być jako rodzaj 24. Nie podawać tam stałej MANIFEST jak robi to za usera na przykład edytor ResEd. Bo wtedy brcc32.exe nie dołaczy tego w exeku jako manifest, tylko jakiś zasób z danymi.

Ewentualnie spróbuj użyć http://lockhunter.com i może on pozwoli odblokować plik. Jeżeli na chwilę wyłączysz UAC dla testów lub spróbujesz usunąc ten *.sys z pod TotalCommandera uruchomionego na prawach admina (poprzez potwierdzenie monitu od UAC przy uruchomieniu). I to się nadal nie powiedzie, to znaczy, że i tak plik jest używany i nie da się go w łatwy sposób usunąć.

Bo o ile wiem, to na ogół jeżeli nie jest uruchomiony jakiś program lub usługa, większośc plików daje się usunąć. Wyjątkiem jest pagefile.sys i niektóre dllki oraz chyba fizyczne pliki w ktorych jest Rejestr. I to co powiązane z shell'em, jeżeli dobrze kojarze.


Pozdrawiam.
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
1

Jeśli plik jest używany to można ew. próbować go rename'ować, ale nie wiem czy to Ci się przyda.

UAC działa z grubsza tak:

  • uruchamiasz aplikację jako admin, ona pobiera sobie jakieś tam uprawnienia i może trochę więcej, w ekstremalnych przypadkach zawsze się pyta (np. msconfig)
  • nie uruchamiasz aplikacji jako admin, to przy próbie czegoś tam zrobienia ona się pyta o konto admina

Żeby aplikacja za każdym razem się nie pytała, musiałaby być odpalona jako serwis lub zadanie w harmonogramie.

E8
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:16
0

To nie rozwiązuje problemu, problemem jest to:

user image

dopiero po kliknięciu kontynuuj można usunąć plik, czy ktoś wie jak zrobić to programowo z poziomu delphi?

olesio
  • Rejestracja:około 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

Trochę się pogubiłem w tym temacie. Bo jeśli dobrze zrozumiałem, to wywołanie programu w Delphi, który ma manifest wymuszajacy uruchomienie tylko na prawach admina. I w nim funkcja WinAPI DeleteFile nie skutkuje? Jeżeli tak jest to coś nadal używa pliku.


Pozdrawiam.
edytowany 2x, ostatnio: olesio
E8
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:16
0

Olesio sprawdziłem to z manifestem i nadal nie działa:

Dodałem manifest do projektu, a pliczek kasuje w ten sposób:

Kopiuj
"ShellExecute(0, 'runas', ('cmd.exe'), PChar('/c del c:\windows\system32\drivers\afd.sys'), PChar(''), SW_Normal);"

ale to też nie działa.

W tej sytuacji wystarczy mi program który by sprawdził czy plik istnieje, macie jakieś pomysły jak to zrobić?
Jak sprawdzić czy ten plik istnieje:

c:\windows\system32\drivers\afd.sys

bo ten kod też nie działa:

Kopiuj
procedure TForm1.Button2Click(Sender: TObject);
begin
if FileExists('c:\windows\system32\drivers\afd.sys') then
begin
showmessage('istnieje')
end else
showmessage('nie istnieje');
end;

Zwraca wartość "nie istnieje"

Oczywiście do projektu też dodałem manifest UAC, domyślam się że tu nie chodzi o kontrole UAC tylko o brak dostępu do pliku chroniony przez system, ale żeby nawet nie można sprawdzić czy plik istnieje?

edytowany 1x, ostatnio: enter.84
olesio
  • Rejestracja:około 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
1

Hmmm, czyli samo DeleteFile też się pewnie nie powiedzie. Bo nadal nie wiem dlaczego upierasz się na rozwiązanie z cmd.exe. Srawdź dla pewności czy pod na przykład TotalCommanderem da się usunąć ten plik. Jeżeli tak, to może problemem jest to, co opisano tutaj w opisie funkcji i przykładzie jej użycia http://msdn.microsoft.com/en-us/library/windows/desktop/aa365743(v=vs.85).aspx tylko mnie wydawało się, że to dotyczy innego folderu, ale pewnie i system32 również.


Pozdrawiam.
E8
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:16
0

Uruchamiam Total Commander jako administrator i gdy chcę usunąć plik z folderu \System32\Drivers\ mam komunikat "Odmowa dostępu"
Na razie nie mam pomysłu jak to obejść...

Ale dziwne jest to że nie da się nawet sprawdzić w normalny sposób czy istnieje plik w tym katalogu: \System32\Drivers\ bo zwykłe:

Kopiuj
if FileExists('c:\windows\system32\drivers\plik.sys') then

nie działa

edytowany 1x, ostatnio: enter.84
olesio
  • Rejestracja:około 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

Nie obejdziesz tego w takim razie, bo coś nadal używa pliku. Co do tego żeby FileExists lub inny kod oparty o wyszukiwanie pliku zadziałał spróbuj tego na poniższej stronie. Innych pomysłów nie mam.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365744(v=vs.85).aspx


Pozdrawiam.
KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Gorlice
2

Dokładne jeżeli aplikacja 32 bit na 64bit systemie to musi być wywołane Wow64DisableWow64FsRedirection dlatego podana niżej funkcja znajduje plik afd.sys w folderze c:\windows\system32\drivers\

Kopiuj
function WinApiFileExist(AFileName: string): Boolean;
{$IF CompilerVersion < 25}
{$DEFINE CPUX86} //od delphi XE5 mzna kompilowac 64bit w starszych zawsze 32bit
{$IFEND}
  function CheckFileExist(AFileName: string): Boolean;
  var
    FindFileData: WIN32_FIND_DATA;
    hFind: Cardinal;
  begin
    result:= False;
    hFind:= FindFirstFile(PChar(AFileName), FindFileData);
    if hFind <> INVALID_HANDLE_VALUE then
    begin
      {$IF CompilerVersion >= 23}WinApi.{$IFEND}Windows.FindClose(hFind);
      result:= True;
    end;
  end;
{$IFDEF CPUX86}
type
  TIsWow64Process = function(hProcess: THandle; var Wow64Process: LongBool): LongBool; stdcall;
  TWow64DisableWow64FsRedirection = function(var Wow64FsEnableRedirection: LongBool): LongBool; stdcall;
  TWow64EnableWow64FsRedirection = function (Wow64FsEnableRedirection: LongBool): LongBool; stdcall;
var
  hKernelLib: Cardinal;
  pIsWow64Proc: TIsWow64Process;
  pWow64DisableWow64FsRedirect: TWow64DisableWow64FsRedirection;
  pWow64EnableWow64FsRedirect: TWow64EnableWow64FsRedirection;
  IsWow64, Wow64FsEnableRedirection: LongBool;
{$ENDIF CPUX86}
begin
  {$IFDEF CPUX86}
  result := False;
  hKernelLib:= LoadLibrary('kernel32.dll');
  if hKernelLib <> INVALID_HANDLE_VALUE then
  begin
    IsWow64:= False;
    pIsWow64Proc:= GetProcAddress(hKernelLib, 'IsWow64Process');
    if Assigned(pIsWow64Proc) then
      pIsWow64Proc(GetCurrentProcess, IsWow64);
    if IsWow64 then
    begin
      pWow64DisableWow64FsRedirect:= GetProcAddress(hKernelLib, 'Wow64DisableWow64FsRedirection');
      pWow64EnableWow64FsRedirect:= GetProcAddress(hKernelLib, 'Wow64EnableWow64FsRedirection');
      if Assigned(pWow64DisableWow64FsRedirect) then
        pWow64DisableWow64FsRedirect(Wow64FsEnableRedirection);
      result:= CheckFileExist(AFileName);
      if Assigned(pWow64EnableWow64FsRedirect) then
        pWow64EnableWow64FsRedirect(Wow64FsEnableRedirection);
    end
    else
    {$ENDIF CPUX86}
      result:= CheckFileExist(AFileName);
    {$IFDEF CPUX86}
    FreeLibrary(hKernelLib);
  end;
  {$ENDIF CPUX86}
end;

Funkcja trochę długa bo oparta na WinApi a do tego funkcje importuje dynamicznie ponieważ w starszych systemach ich nie ma. Myślę że jeżeli wcześniej wywołasz Wow64DisableWow64FsRedirection to zwykłe FileExists też się powiedzie a nawet prawdopodobnie usunięcie pliku (oczywiście z prawami admina) też pewnie dlatego nie działało.

EDIT Poprawa zgodności Dla starych i nowych Delphi


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
edytowany 5x, ostatnio: kAzek
flowCRANE
&quot;32 bit na 54bit&quot; -> &quot;32 bit na 64bit&quot;
olesio
A czy funkcja sprawdzając istnienie pliku nie powina się jeszcze upewniać czy atrybut to nie katalog dla nazw które ewentualnie można podać . i .. oraz ewentualnie innych przypadków, bo zdaje się takie sprawdzanie ma funkcja FileExists w pakiecie TNT. Poza tym ja w swoich kodach WinAPI sprawdzam jeszcze czy podany parametr nie jest symlinkiem, zdaje się określa to stała wynosząca 1024.
KA
Może i powinna ja widziałem w źródłach Delphi funkcję FileExists która sprawdza nawet datę pliku nie wiem po co... ale jak ktoś chce to łatwo uzupełnić mi się już nie chce.
olesio
Zgadza się, funkcja z użyciem FileAge ma tę wadę, że jak się nam coś z datą może pokaszanić i plik będzie przypadkowo utworzony z datą przed chyba 1970 rokiem, to ten kod z VCL Delphi 7 i wcześniejszych pewnie. Stwierdzi, że plik nie istnieje. Dlatego w TNT i nowszych Delphi ta funkcja jest poprawiona (na pewno w TNT).
Azarien
Nie używaj Wow64EnableCośtamCośtam tylko Wow64RevertCośtamCośtam, z wartością którą zwróciło wcześniejsze Disable jako parametr.
E8
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:16
0

Dzięki kAzek to może rozwiązać ten problem, czy możesz podać zastosowanie tej funkcji, jak ją wywołać?

olesio
  • Rejestracja:około 17 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Szczecin
  • Postów:4191
0

No nie załamuj nas. Przecież funkcja, którą podał poprzednik jest oczywista w użyciu. Natomiast te z Wow64 są opisane na MSDNie.


Pozdrawiam.
E8
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:16
0

Olesio możesz podać przykład użycia tej funkcji?

Nie każdy jest tak dobrym programistą jak Ty, a nie którzy muszą od czegoś zacząć tak jak ja, być może jest to oczywiste jak wywołać tę funkcję.

I może przydać się innym początkującym programistą.

vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
0

Z funkcjami api jest zwykle tak, że:

  • są wymienione w postaci "reference" w co najmniej 3 miejscach w sieci
  • do tego są "tutorial"-e
  • a oprócz tego wypowiedzi takie jak powyższa (im starsza funkcja i bardziej problematyczna tym więcej)

Naprawdę mało jest przypadków gdy do funkcji API trzeba podawać przykład bo go nie ma.

Co dotychczas znalazłeś? Z czym masz problem?
Czy wykonujesz pełną obsługę błędów wywołania funkcji?

Podpowiedź: wywołaj po KAŻDEJ funkcji API to:

Kopiuj
ShowMessage(SysErrorMessage(GetLastError)))

lub to:

Kopiuj
RaiseLastOSError;
edytowany 1x, ostatnio: vpiotr
E8
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:16
0

Dzięki vpiotr, ale zamiast odsyłać mnie do tutoriali łatwiej było by jak byś podał przykład użycia w/w kodu.

Jak wywołać tę funkcję i sprawdzić czy plik istnieje?

kAzek możesz wkleić kod który sprawdza czy plik istnieje? I możesz napisać czy sprawdzałeś czy da się usunąć za pomocą tej funkcji plik .sys?

KA
Jaką masz wersję Delphi?
E8
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:16
0

Używam Delphi 2007

E8
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:16
0

Nie sądziłem że użycie tej funkcji jest takie proste :)

Kopiuj
 procedure TForm1.Button1Click(Sender: TObject);
begin
begin if WinApiFileExist('c:\windows\system32\drivers\afd.sys') then
begin
showmessage('istnieje')
end else
showmessage('nie istnieje');
end;
end;

Kod działa, dzięki za pomoc :)

flowCRANE
Jeśli wątek uważasz za zakończony - rozdaj plusiki pomocnym postom i zaznacz fajeczkę przy poście z rozwiązaniem problemu; Pamiętaj o tym na przyszłość, że tak zakańcza się wątki i dziękuje użytkownikom za okazaną pomoc;

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.