views:

181

answers:

1

Hello,
I have a strange problem with some code that calls WNetGetUniversalName. When I call the function I always get error 67 (ERROR_BAD_NET_NAME). But the network connection really does exist.
So from the scratch. I'm writing a Windows shell extension that shall do some stuff with text files that are located on a specified network drive. So when the IShellExtInit::Initialize method is called I store the dragged file and will then get the connection name by using the WNetGetUniversalName method.
So I can be really sure that the network drive does exist (as it comes from the DragQueryFile method).
Here's some code:

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);  

file is an ATL::CString that comes from the DragQueryFile method and error is always 67.
Odd thing is that it did work some days ago but not anymore, and I didn't change any of that code posted.

A: 

It's a little hard to guess about the problem. One possibility is that the file you're passing as the file name isn't formatted quite correctly. For example, even if the file is in the root shared directory, something like z:test.txt would not work -- it requires: z:\\test.txt.

The usual way to call WNetGetUniversalName involves a sequence like:

  1. Call with small buffer to get required size
  2. allocate proper-sized buffer
  3. call again with buffer of proper size

Unlike quite a few Windows network functions, however, this one apparently checks that you've sent a non-NULL pointer with a positive size first, then checks whether the buffer is large enough for what it wants to return, so the sequence looks something like this:

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;
Jerry Coffin
Sorry that didn't help. But it's getting more odd. I tried out WNetGetConnection and it did work but WNetGetUniversalName still doesn't. Nevertheless I'd like to know why WNetGetUniversalName doesn't work anymore because I'd prefer using that method.
Simon Linder