Проблема с WNetGetUniversalName - PullRequest
2 голосов
/ 25 января 2010

У меня странная проблема с некоторым кодом, который вызывает WNetGetUniversalName. Когда я вызываю функцию, я всегда получаю ошибку 67 (ERROR_BAD_NET_NAME). Но сетевое соединение действительно существует.
Так что с нуля. Я пишу расширение оболочки Windows, которое должно что-то делать с текстовыми файлами, расположенными на указанном сетевом диске. Поэтому, когда вызывается метод IShellExtInit :: Initialize, я сохраняю перетаскиваемый файл, а затем получаю имя соединения с помощью метода WNetGetUniversalName.
Поэтому я могу быть уверен, что сетевой диск существует (как это происходит из метода DragQueryFile).
Вот некоторый код:

char buffer[4096];  
REMOTE_NAME_INFO *info = (REMOTE_NAME_INFO*)buffer;  
DWORD length = 4096;  
info->lpConnectionName = NULL;  
info->lpRemainingPath = NULL;  
info->lpUniversalName = NULL;  
DWORD error = WNetGetUniversalName(file, REMOTE_NAME_INFO_LEVEL, info, &length);  

Файл представляет собой ATL :: CString, получаемый из метода DragQueryFile, и ошибка всегда равна 67.
Странно то, что он работал несколько дней назад, но больше не работал, и я не изменил ни один из опубликованных кодов.

1 Ответ

0 голосов
/ 25 января 2010

Сложно догадаться о проблеме. Одна возможность состоит в том, что file, который вы передаете как имя файла, отформатирован не совсем правильно. Например, даже если файл находится в корневом общем каталоге, что-то вроде z:test.txt не будет работать - для этого потребуется: z:\\test.txt.

Обычный способ вызова WNetGetUniversalName включает следующую последовательность:

  1. Вызов с небольшим буфером для получения необходимого размера
  2. выделить буфер правильного размера
  3. вызовите снова с буфером правильного размера

Однако, в отличие от многих сетевых функций Windows, этот, по-видимому, сначала проверяет, что вы отправили ненулевой указатель с положительным размером, а затем проверяет, достаточно ли большой буфер для того, что он хочет вернуть, последовательность выглядит примерно так:

REMOTE_NAME_INFO temp;
REMOTE_NAME_INFO *info = &temp;  
DWORD size = sizeof(temp);

// call with buffer that's valid but too small.    
WNetGetUniversalNameA("z:\\test.txt", REMOTE_NAME_INFO_LEVEL, info, &size);

// allocate large enough buffer:
info = static_cast<REMOTE_NAME_INFO *>(::operator new(size));

// call again with large enough buffer:
WNetGetUniversalNameA("z:\\test.txt", REMOTE_NAME_INFO_LEVEL, info, &size);

// Show result:
std::cout << info->lpUniversalName;
...