FindFile nie znajduje C:\WINDOWS\SYSNATIVE pomimo zastosowania Wow64DisableWow64FsRedirection.

0

Cześc. Tak jak w temacie. Mam taki kod jak poniżej i on nie pokazuje w wynikowym pliku istniejącego folderu SYSNATIVE. Oraz MessageBox z komunikatem "Mam go!" się nie ukaże. Przynajmnien u mnie. I to pomimo - jak widzicie - zastosowania - według mnie prawidłowo - funkcji Wow64DisableWow64FsRedirection oraz Wow64RevertWow64FsRedirection. Zgodnie z tym co piszą na MSDNie. Ale jednak DirectoryExists działa i wykrywa katalog. Kod testowany był pod Delphi 7 oraz na Windows 7 Ultimate 64 bit. Ma ktoś może pomysł jak to naprawić? Kombinowałem na różne sposoby, googlowałem i szukałem przykładów, według których takie rozwiąznie jak poniżej powinno działać. Ono jednak nie działa. Tylko jakoś 32 bitowy Total Commander znajduje ten niby "folder - przekierowanie" [?] w katalogu C:\WINDOWS. Z góry dziękuję za wszelką pomoc od bardziej doświadczonych użytkowników 64 bitowych Windowsów. Dodam, że moduł redirfunc.pas chyba z Inno Setup, który okroiłem, również mi nie pomógł. A potrzebuje uzyskiwać kompletną listę plików poniższą metodą z katalogu Windowsa. Ewentualne odpowiedzi, na które licze będę mógł przeczytać dopiero w poniedziałek po południu, także fajnie jakby ktoś (znowu @kAzek, a może @-123oho, a moze ktoś inny jeszcze? :)) dał radę mnie naprowadzić co robię nie tak.

program test;

{$APPTYPE CONSOLE}

uses
  Windows, SysUtils;

type
  TArrayOfString = array of string;

var
  FilesArr : TArrayOfString;

var
  Wow64Redirection : LongBool;

function DisableWowRedirection : boolean;
type
  TWow64DisableWow64FsRedirection = function(var Wow64FsEnableRedirection : LongBool) : LongBool; stdcall;
var
  HHandle : THandle;
  Wow64DisableWow64FsRedirection : TWow64DisableWow64FsRedirection;
begin
  Result := True;
  try
    HHandle := GetModuleHandle('kernel32.dll');
    @Wow64DisableWow64FsRedirection := GetProcAddress(HHandle,
      'Wow64DisableWow64FsRedirection');
    if ((HHandle <> 0) and (@Wow64DisableWow64FsRedirection <> nil)) then
      Wow64DisableWow64FsRedirection(Wow64Redirection);
  except
    Result := False;
  end;
end;

function RevertWowRedirection : boolean;
type
  TWow64RevertWow64FsRedirection = function(var Wow64RevertWow64FsRedirection : LongBool) : LongBool; stdcall;
var
  HHandle : THandle;
  Wow64RevertWow64FsRedirection : TWow64RevertWow64FsRedirection;
begin
  Result := True;
  try
    HHandle := GetModuleHandle('kernel32.dll');
    @Wow64RevertWow64FsRedirection := GetProcAddress(HHandle,
      'Wow64RevertWow64FsRedirection');
    if ((HHandle <> 0) and (@Wow64RevertWow64FsRedirection <> nil)) then
      Wow64RevertWow64FsRedirection(Wow64Redirection);
  except
    Result := False;
  end;
end;

function SaveTextToFile(AFileName : string; InStr : string) : boolean;
var
  OutFile : THandle;
  BytesWritten : DWORD;
  OutFileSize : integer;
begin
  OutFile := CreateFile(PChar(AFileName), GENERIC_WRITE,
    FILE_SHARE_READ, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  Result := OutFile <> INVALID_HANDLE_VALUE;
  if Result then
  begin
    OutFileSize := Length(InStr);
    WriteFile(OutFile, InStr[1], OutFileSize, BytesWritten, nil);
    CloseHandle(OutFile);
  end;
end;

procedure FileSearch(const PathName, FileName : string; var OutputArr : TArrayOfString);
var
  X : integer;
  H : THandle;
  Path : string;
  WFD : TWIN32FindData;
begin
  Path := IncludeTrailingPathDelimiter(PathName);
  DisableWowRedirection;
  H := Windows.FindFirstFile(PChar(Path + FileName), WFD);
  if H <> INVALID_HANDLE_VALUE then
  begin
    try
      repeat
        if (Copy(WFD.cFileName, 1, 1) <> '.') and (WFD.cFileName <> '..') then
        begin
          if AnsiUpperCase(WFD.cFileName) = 'SYSNATIVE' then
          begin
            MessageBox(0, 'Mam go!', 'Test', MB_OK);
          end;
          X := Length(OutputArr);
          SetLength(OutputArr, X + 1);
          OutputArr[X] := AnsiUpperCase(WFD.cFileName);
        end;
      until not FindNextFile(H, WFD);
      RevertWowRedirection;
    finally
      Windows.FindClose(H);
    end;
  end;
end;

var
  S : string;
  I : integer;
begin
  if DirectoryExists('C:\WINDOWS\SYSNATIVE\') then
  begin
    MessageBox(0, 'Jest!', 'Test', MB_OK);
  end;
  S := '';
  SetLength(FilesArr, 0);
  FileSearch('C:\WINDOWS\', '*', FilesArr);
  for I := Low(FilesArr) to High(FilesArr) do
  begin
    if I < High(FilesArr) then
    begin
      S := S + FilesArr[I] + #13#10;
    end
    else
    begin
      S := S + FilesArr[I];
    end;
  end;
  SaveTextToFile('D:\from_code.txt', S);
end.
0

Po 1. DisableWowRedirection powoduje dla aplikacji 32-bitowej wyłączenie przekierowania ścieżki do folderu systemowego "Windows\SysWOW64", gdy ta się odwołuje do folderu "Windows\System32" i nie ma to nic wspólnego z odwołaniami do folderu nadrzędnego "Windows", jakie występują w Twoim kodzie.

Po 2. A czy chociaż funkcja FindFirstFile zwraca H <> INVALID_HANDLE_VALUE ?

Po 3. Skoro DirectoryExists jeszcze przed wywołaniem DisableWowRedirection zwraca true, to może wywalenie DisableWowRedirection przed FindFirstFile spowoduje, że FindFirstFile też zadziała.
Edit:
Po 4. Skoro folder "Windows\Sysnative" jest alternatywną ścieżką dla aplikacji 32-bitowych do folderu "Windows\System32" (folderu dla aplikacji 64-bitowych), to może właśnie wyłączenie przekierowania dla aplikacji 32-bitowych przez użycie DisableWowRedirection powoduje, ze ten folder jest dla nich niewidoczny (nie istnieje)?

0
marogo napisał(a):

Po 1. DisableWowRedirection powoduje dla aplikacji 32-bitowej wyłączenie przekierowania ścieżki do folderu systemowego "Windows\SysWOW64", gdy ta się odwołuje do folderu "Windows\System32" i nie ma to nic wspólnego z odwołaniami do folderu nadrzędnego "Windows", jakie występują w Twoim kodzie.
Z informacji na MSDNie wynika, że należy w aplikacji 32 bitowej na 64 bitowym systemie wywoływać funkcje DisableWowRedirection przed wywołanniem FindFirstFile, natomiast Wow64RevertWow64FsRedirection po ostatnim wywołaniu FindNextFile. Zobacz na: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx - przed słowem Examples. Przynajmniej ja tak to rozumiem.

Po 2. A czy chociaż funkcja FindFirstFile zwraca H <> INVALID_HANDLE_VALUE ?
Dokładnie tak. Dla testów taki kod:

var
  WFD : TWIN32FindData;
begin
  if Windows.FindFirstFile('C:\WINDOWS\SYSNATIVE', WFD) = INVALID_HANDLE_VALUE then
  begin
    MessageBox(0, PChar('Invalid Handle - GetLastError: ' + IntToStr(GetLastError)), 'Test', MB_OK);
  end;

Zwraca kod błedu 2 czyli według MSDN: ERROR_FILE_NOT_FOUND.

Po 3. Skoro DirectoryExists jeszcze przed wywołaniem DisableWowRedirection zwraca true, to może wywalenie DisableWowRedirection przed FindFirstFile spowoduje, że FindFirstFile też zadziała.
To oczywiście sprawdziłem na samym początku, bo jeżeli by ten problem nie istniał to bym go tutaj nie zgłaszał. A sugerując się informacjami na MSDnie kombinowałem w taki sposób, jak opisałem powyżej i nic to nie dało

Po 4. Skoro folder "Windows\Sysnative" jest alternatywną ścieżką dla aplikacji 32-bitowych do folderu "Windows\System32" (folderu dla aplikacji 64-bitowych), to może właśnie wyłączenie przekierowania dla aplikacji 32-bitowych przez użycie DisableWowRedirection powoduje, ze ten folder jest dla nich niewidoczny (nie istnieje)?
Bez wywołania również jest niestety niewidoczny. Masz może albo ktoś tutaj, jeszcze jakieś pomysły żeby umieć rozwiązać ten problem na przyszłość? Bo ja nie daje rady.

1 użytkowników online, w tym zalogowanych: 0, gości: 1