Сбой FindNextFile в 64-битной Windows? - PullRequest
10 голосов
/ 18 сентября 2008

при использовании C ++ Builder 2007 функции FindFirstFile и FindNextFile, похоже, не могут найти некоторые файлы в 64-разрядных версиях Vista и XP. Мое тестовое приложение 32-битное.

Если я использую их для перебора папки C: \ Windows \ System32 \ Drivers, они находят только несколько файлов, хотя их 185, когда я запускаю команду dir в командной строке. Использование того же примера кода перечисляет все файлы нормально на 32-разрядной версии XP.

Вот небольшой пример программы:

int main(int argc, char* argv[])
{
  HANDLE hFind;
  WIN32_FIND_DATA FindData;
  int ErrorCode;
  bool cont = true;

  cout << "FindFirst/Next demo." << endl << endl;

  hFind = FindFirstFile("*.*", &FindData);
  if(hFind == INVALID_HANDLE_VALUE)
  {
    ErrorCode = GetLastError();
    if (ErrorCode == ERROR_FILE_NOT_FOUND)
    {
      cout << "There are no files matching that path/mask\n" << endl;
    }
    else
    {
      cout << "FindFirstFile() returned error code " << ErrorCode << endl;
    }
    cont = false;
  }
  else
  {
    cout << FindData.cFileName << endl;
  }

  if (cont)
  {
    while (FindNextFile(hFind, &FindData))
    {
      cout << FindData.cFileName << endl;
    }

    ErrorCode = GetLastError();
    if (ErrorCode == ERROR_NO_MORE_FILES)
    {
      cout << endl << "All files logged." << endl;
    }
    else
    {
      cout << "FindNextFile() returned error code " << ErrorCode << endl;
    }

    if (!FindClose(hFind))
    {
      ErrorCode = GetLastError();
      cout << "FindClose() returned error code " << ErrorCode << endl;
    }
  }
  return 0;
}

Запуск его в папке C: \ Windows \ System32 \ Drivers на 64-битной XP возвращает следующее:

C:\WINDOWS\system32\drivers>t:\Project1.exe
FindFirst/Next demo.

.
..
AsIO.sys
ASUSHWIO.SYS
hfile.txt
raspti.zip
stcp2v30.sys
truecrypt.sys

All files logged.

Команда dir в той же системе возвращает это:

C:\WINDOWS\system32\drivers>dir/p
 Volume in drive C has no label.
 Volume Serial Number is E8E1-0F1E

 Directory of C:\WINDOWS\system32\drivers

16-09-2008  23:12    <DIR>          .
16-09-2008  23:12    <DIR>          ..
17-02-2007  00:02            80.384 1394bus.sys
16-09-2008  23:12             9.453 a.txt
17-02-2007  00:02           322.560 acpi.sys
29-03-2006  14:00            18.432 acpiec.sys
24-03-2005  17:11           188.928 aec.sys
21-06-2008  15:07           291.840 afd.sys
29-03-2006  14:00            51.712 amdk8.sys
17-02-2007  00:03           111.104 arp1394.sys
08-05-2006  20:19             8.192 ASACPI.sys
29-03-2006  14:00            25.088 asyncmac.sys
17-02-2007  00:03           150.016 atapi.sys
17-02-2007  00:03           106.496 atmarpc.sys
29-03-2006  14:00            57.344 atmepvc.sys
17-02-2007  00:03            91.648 atmlane.sys
17-02-2007  00:03           569.856 atmuni.sys
24-03-2005  19:12             5.632 audstub.sys
29-03-2006  14:00             6.144 beep.sys
Press any key to continue . . .
etc.

Я озадачен. В чем причина?

Brian

Ответы [ 6 ]

9 голосов
/ 18 сентября 2008

Происходит ли перенаправление? См. Примечания к Wow64DisableWow64FsRedirection http://msdn.microsoft.com/en-gb/library/aa365743.aspx

2 голосов
/ 18 сентября 2008

Я нашел это в MSDN:

Если вы пишете 32-разрядное приложение для вывода списка всех файлов в каталоге и приложение может быть запущено на 64-разрядном компьютере, вам следует вызвать функцию Wow64DisableWow64FsRedirectionfunction перед вызовом FindFirstFile и вызвать Wow64RevertWow64FsRedirection после последнего вызов к FindNextFile. Дополнительные сведения см. В разделе «Перенаправитель файловой системы».

Вот ссылка

Мне придется обновить свой код из-за этого: -)

0 голосов
/ 18 сентября 2008

Понял:

http://msdn.microsoft.com/en-gb/library/aa384187(VS.85).aspx

Когда 32-битное приложение читает из одной из этих папок в 64-битной ОС:

%windir%\system32\catroot
%windir%\system32\catroot2
%windir%\system32\drivers\etc
%windir%\system32\logfiles
%windir%\system32\spool 

Windows фактически перечисляет содержимое:

%windir%\SysWOW64\catroot
%windir%\SysWOW64\catroot2
%windir%\SysWOW64\drivers\etc
%windir%\SysWOW64\logfiles
%windir%\SysWOW64\spool 

Спасибо за ваш вклад, Крис, это помогло мне узнать, что происходит.

РЕДАКТИРОВАТЬ: Спасибо, Людвиг тоже: -)

0 голосов
/ 18 сентября 2008

С примером кода проблем нет. У меня есть другое приложение, которое тоже не работает, написанное на Delphi. Я думаю, что нашел ответ, основываясь на ответе Криса о перенаправлении: http://msdn.microsoft.com/en-gb/library/aa364418(VS.85).aspx

0 голосов
/ 18 сентября 2008

Есть ли какие-нибудь предупреждения при компиляции?

Включили ли вы ALL предупреждения для этого конкретного теста (поскольку он не работает)?

Обязательно сначала устраните предупреждения.

0 голосов
/ 18 сентября 2008

Вы уверены, что он находится в том же каталоге, что и команда dir? Похоже, у них нет общих файлов.

Кроме того, это не проблема, но правильный «подстановочный знак» для «всех файлов» - *

*. * Означает «все файлы с хотя бы одним. В имени»

...