Link to home
Start Free TrialLog in
Avatar of rian
rian

asked on

Getting a TRUE PATH

Is there a way in C or C++ or MFC where I can get the TRUE Path of a Subsituted Drive. For example if I use SUBST K: C:\MYTEST\PROGRAMS. I would like a function or method which would return C:\MYTEST\PROGRAMS if I pass K: as the input.
My old DOS program used DOS interrupt register. But, this same code does not work under NT Server.
Appereciate any help.
Avatar of jhance
jhance

See the documentation on WNetGetUniversalName()
Avatar of rian

ASKER

I tried WNetGetUniversalName with my code and I always get a Error Code of 2250 - Network Connection could not be found. Make me think that this function only works for Network resource and not for substituted drive on a local machine.

// Start of Main Program
void main( int argc, char *argv[] )
{
    DWORD    dwDriveMask = GetLogicalDrives();
    int      i;
    char     szDir[3];
    BYTE     pBuffer[1024];
    DWORD dwBufsize;

    dwBufsize = 1024;

    szDir[1] = TEXT(':');
    szDir[2] = 0;
      int curdrive;
      curdrive = _getdrive();

    /* enumerate all fixed and logical drives */
      for (i=0; i < curdrive; i++)
      {
            dwDriveMask >>=1;
      }
    for (i = curdrive; i < MAX_DRIVES; dwDriveMask >>= 1, i++)
      {
      /* if drive exists */
            if (dwDriveMask & 0x01)
          {
                szDir[0] = TEXT('A') + i;

                  /* if it is a fixed drive */
                if (GetDriveType(szDir) == DRIVE_FIXED)
                  {
                        printf(" Validating Drive %s \n", szDir);
                        // Get the True Path of the Drive
                        WNetGetUniversalName(      szDir,
                                                            UNIVERSAL_NAME_INFO_LEVEL,
                                                            (LPVOID) &pBuffer,
                                                            &dwBufsize);
                        DWORD Error = GetLastError();
                        printf("Error Returned %d \n",Error);
                        if (Error == 0)
                        {
                        UNIVERSAL_NAME_INFO *uname;
                      uname = (UNIVERSAL_NAME_INFO *) pBuffer;
                        printf( "Drive True Path %s \n",uname->lpUniversalName);
                        }

 
                  }
            }
      }

According to my documentation:

lpLocalPath

Points to a null-terminated string that is a drive-based path for a network resource.

For example, if drive H has been mapped to a network drive share, and the network resource of interest is a file named SAMPLE.DOC in the directory \WIN32\EXAMPLES on that share, the drive-based path is H:\WIN32\EXAMPLES\SAMPLE.DOC.


It's a bit ambiguous but I believe that all the string data for this function is UNICODE.  Your example above is using ASCII.
Avatar of rian

ASKER

But my substitute drive is not a network resource. I will try it in Unicode.
ASKER CERTIFIED SOLUTION
Avatar of alexo
alexo
Flag of Antarctica image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
hmm, alexo, why when rian says he is running on NT did you copy & paste a technical note that allows WNetGetUniversalName to work on WIN95?

Win95 is not the reason WNetGetUniversalName won't work for rian. Also, unicode is not the reason WNetGetUniversalName won't work for rian. If you use ASCII but ask it about an actual network resource (gasp!), as opposed to a local one, it works just fine. The problem is that WNetGetUniversalName deals with Network drives and NOT local ones such as SUBST drives. It's the wrong function, as is implied by the doc and can be easily proven just by trying it.

rian, there is no perfect way to do what you want. The closest is QueryDosDevice (which is also unsupported on Win95, btw, though seems to be supported on Win98). The reason QueryDosDevice is tricky is it seems to know the true identity of all devices but it prepends internal desgnators like \Device which you have to wade through.

It does know the true path of SUBST drives under NT, though it prepends "\??\". I mapped Z: to D:\Program Files, and QueryDosDevice returns Z: as "\??\D:\Program Files". Here's the actual code I used, which enumerates all devices:

char alldrives[1000];
char thisdrive[1000];

QueryDosDevice(NULL, alldrives, sizeof(alldrives));
for (int i=0; alldrives[i]; i+=strlen(alldrives+i)+1) {
 QueryDosDevice(alldrives+i, thisdrive, sizeof(thisdrive));
 printf( "
Hmm, don't know why that cut off, here's the rest...

 printf("
Strange, happened again, wonder if it's an EE problem. Trying a third time, with a slightly modified version:

 printf( "
I give up :-) There was only a printf with the results, anyway.

Unfortunately rian, I don't see a more elegant way to do what you want, but this does at least work :-)

If you agree that this will work, and alexo's answer won't, then please reject his answer and allow me to repost this comment as an answer. But in any case, good luck!
>> hmm, alexo, why when rian says he is running on NT did you copy & paste a technical note that allows WNetGetUniversalName to work on WIN95?
Duh!  I must have been too tired to notice.

>> If you agree that this will work, and alexo's answer won't, then please reject his answer and allow me to repost this comment as an answer.
Reject my answer anyway.  Sorry for the inconvenience.
Avatar of rian

ASKER

Dear Alomo,

Can u email the sample code to rian@mindspring.com.
I will try QueryDosDevice and let everyone know the results.
Thanks

Avatar of rian

ASKER

Dear Experts,

I tried WNetOpenEnum and WNetEnumResource methods. These methods only give you the network connected resources not drives substituted to a local hard drive.

I also tried QueryDosDevice and alamo u are right. For every substituted drive it puts a ?? in front. Unfortunately, I have multiple substituted drives and it would be difficult to find out which drive letter is mapped to which path. Is there a way using some other function to find which drive is mapped to a path.
Thanks
rian, you misunderstand (partly I think because my printf got cut off due to the EE problem, which I posted in customer service and they have since fixed).

The line that got cut is:

printf( "%s is mapped to %s", alldrives+i, thisdrive);

Try my example again with that line and you'll see that you DO know which drive letter is mapped to which path.


Avatar of rian

ASKER

Thanks a lot. It works

Duh!  You gave me the points that alamo deserved.  I'll ask Linda to reimburse him.
Avatar of rian

ASKER

Thanks. I did not know how to give him the points. After I submitted my response, it mentioned u as the owner of the points and I did not know how to change that.
Sorry Alamo and Thanks Alexo.