Link to home
Start Free TrialLog in
Avatar of scuzz1
scuzz1Flag for United States of America

asked on

How can I find the drive letter of a known volume

Hi everybody,

    I'm writing a print executable for a group that is mapped to a particular directory need to print from. But not everyone can use the same drive letters to map with. The executable we use to create the postscript files for printing needs the drive letter of the directory to print from. I've tried pathing a bunch of different ways but the drive letter is the only thing it recognizes. Is there a way I can find out what letter was used for that particular volume with my executable?

Using VS 6.0

Thanks in advance.

Jim

Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image


If you're looking for the drive where the executable resides, you could check argv[0].  It will normally be something like:

C:\Program File\Vendor Name\Package Name\executable.exe


Kent
Avatar of scuzz1

ASKER

No.

We map to a server where a bunch of files reside and this group prints files from this server. A certain amount are mapped one drive letter and another bunch is mapped a different letter.

My exe gets the filename of what they want to print. It then goes to the directory and determines what type of file it is that will be printed. The type of file I'm having trouble with is a composite file. Within this composite file (which is just a text file) are the pathnames of two seperate files that are combined to create the postscript file. It is in this composite file that I have to change the pathnames and replace them with the drive letter designations. I literally have to open the composite, read and write the new path into it. Problem is I don't know how to determine what drive letter to insert in the file.

Jim

Ok.  The "standard" way would be to call IoVolumeDeviceToDosName() or RtlVolumeDeviceToDosName().

True to Microsoft form, you have an API for WINXP and one for everything else.


Kent

Avatar of grg99
grg99

Are you sure there is a drive letter mapped to the directory you want?  

How about putting in the more modern "\\server\volume\filename"  type of name?

Avatar of scuzz1

ASKER

I've tried //sever/share and \\server\share. That composite file doesn't like anything but DOS pathname ( ie. ::drive:(share) )

We are running WINXP.

I looked up IoVolumeDeviceToDosName and this is what it says:

++++++++ From MSDN +++++++++++++++++

IoVolumeDeviceToDosName

The IoVolumeDeviceToDosName routine returns the MS-DOS path for a specified device object that represents a file system volume.

NTSTATUS
  IoVolumeDeviceToDosName(
    IN  PVOID  VolumeDeviceObject,
    OUT PUNICODE_STRING  DosName
    );


Parameters
VolumeDeviceObject - Pointer to a device object that represents a volume device object created by a storage class driver.
DosName - Pointer to a Unicode string containing the MS-DOS path of the volume device object specified by VolumeDeviceObject.

Return Value - IoVolumeDeviceToDosName returns STATUS_SUCCESS or an appropriate error status.

Headers
Declared in ntddk.h. Include ntddk.h.

Comments
This routine is only available on Windows XP and later. Drivers that must work on earlier versions of NT-based operating systems can use RtlVolumeDeviceToDosName, which behaves identically.

IoVolumeDeviceToDosName allocates the Unicode string buffer for the MS-DOS path from the memory pool. After the buffer is no longer required, a caller of this routine should use ExFreePool to free it.

Callers of this routine must be running at IRQL = PASSIVE_LEVEL.

++++++++++++++++++++++++++++++++++++++

This sounds kindof like what I want. If I am reading it right.

Looking at MSDN it appears to need two parameters.

The first I believe is a pointer with the "pathname of the volume I want to lookup?".

(i.e. //server/share)

Not sure what they mean by this either:
Pointer to a device object that represents a  "volume device object created by a storage class driver"

The second is a pointer to recieve the DOS pathname back?

Hi scuzz1,

The first parameter to IoVolumeDeviceToDosName() is returned by IoGetDeviceObjectPointer().  The first parameter to this function is the pathname of the volume you want to look up.

Microsoft describes it in their documentation a whole lot better than I can.  Look here:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/kmarch/hh/kmarch/k104_c57b87e5-8316-4c45-a245-0fe7592c3471.xml.asp


Good Luck!
Kent
Avatar of scuzz1

ASKER

>> VolumeDeviceObject - Pointer to a device object that represents a volume device object created by a storage class driver.

I have to create a class driver with DDK in order to do this?

Avatar of scuzz1

ASKER

Problem Solved.

Thanks for your response but I could not figure out how to use the functions you pointed me to.

They both say to use ntddk.h or wdm.h but these header files are not on my system and I could not locate a copy on the web either. After looking at the sites that I found on these it was looking like I could not use Visual Studio 6.0 to build it anyway.

So after all that here is what I came up with (and it works) :

char finddrv( char *fname ){
       
int drive;
char let;
char file[50];
char *artlog = NULL;

artlog = strdup(fname);

for( drive = 5; drive <= 26; drive++ ){
        switch ( drive )
        {
        case 5:
                strcpy(file, "e:\\pdm.arthome\\");
                strcat(file, artlog);
                if( (_access( file, 0 )) == 0 ){
                let = 'e';
                return(let);
                }
        break;
        case 6:
                strcpy(file, "f:\\pdm.arthome\\");
                strcat(file, artlog);
                if( (_access( file, 0 )) == 0 ){
                let = 'f';
                return(let);
                }
        break;

SO ON and SO ON

        case 25:
                strcpy(file, "y:\\pdm.arthome\\");
                strcat(file, artlog);
                if( (_access( file, 0 )) == 0 ){
                let = 'y';
                return(let);
                }
        break;
        case 26:
                strcpy(file, "z:\\pdm.arthome\\");
                strcat(file, artlog);
                if( (_access( file, 0 )) == 0 ){
                let = 'z';
                return(let);
                }
        break;
        default:
                printf( "Arthome has not been mapped.\n Please map Arthome and try again.\n");
                exit(-1);
        break;
        }      
    }
}

Thanks Again.

Going to request for deletion.
ASKER CERTIFIED SOLUTION
Avatar of OzzMod
OzzMod

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