Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Translate Logical Drive to Physical Drive

Translate Logical Drive to Physical Drive

Scheduled Pinned Locked Moved C / C++ / MFC
json
10 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bram van Kampen
    wrote on last edited by
    #1

    I can discover from the trusty old DOS functions on which logical drive I currently am say, drive 'C:', or drive 2. logical drive typically represents a volume on a physical drive, say '\\\\.\\PhysicalDrive0' What API's are there to translate from a locical drive identifier to the physical drive which contains the volume. regards :)

    L 1 Reply Last reply
    0
    • B Bram van Kampen

      I can discover from the trusty old DOS functions on which logical drive I currently am say, drive 'C:', or drive 2. logical drive typically represents a volume on a physical drive, say '\\\\.\\PhysicalDrive0' What API's are there to translate from a locical drive identifier to the physical drive which contains the volume. regards :)

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      You could use the IOCTL_STORAGE_GET_DEVICE_NUMBER[^] control code to obtain the physical drive and volume number. For example:#include <Winioctl.h> VOID LogicalToPhysical(TCHAR *szDrive) { CString szPhysical; HANDLE h = CreateFile(szDrive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); if(INVALID_HANDLE_VALUE != h) { STORAGE_DEVICE_NUMBER sd; DWORD dwRet; if(DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sd, sizeof(STORAGE_DEVICE_NUMBER), &dwRet, NULL)) { szPhysical.Format(_T("\\\\.\\PhysicalDrive%d"), sd.DeviceNumber); } CloseHandle(h); } } //Usage: LogicalToPhysical(_T("\\\\.\\\\C:"));
      Note that this control code will fail to return correct information for mirrored and striped volumes. A more complete solution for these types of drives would be the IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS[^] control code which will return an array of partitions for the drive. Best Wishes, -David Delaune

      B A 2 Replies Last reply
      0
      • L Lost User

        You could use the IOCTL_STORAGE_GET_DEVICE_NUMBER[^] control code to obtain the physical drive and volume number. For example:#include <Winioctl.h> VOID LogicalToPhysical(TCHAR *szDrive) { CString szPhysical; HANDLE h = CreateFile(szDrive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); if(INVALID_HANDLE_VALUE != h) { STORAGE_DEVICE_NUMBER sd; DWORD dwRet; if(DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sd, sizeof(STORAGE_DEVICE_NUMBER), &dwRet, NULL)) { szPhysical.Format(_T("\\\\.\\PhysicalDrive%d"), sd.DeviceNumber); } CloseHandle(h); } } //Usage: LogicalToPhysical(_T("\\\\.\\\\C:"));
        Note that this control code will fail to return correct information for mirrored and striped volumes. A more complete solution for these types of drives would be the IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS[^] control code which will return an array of partitions for the drive. Best Wishes, -David Delaune

        B Offline
        B Offline
        Bram van Kampen
        wrote on last edited by
        #3

        Thanks David, Exactly the hint I Needed. Only One Snag, Cannot find the (hex)Value of IOCTL_STORAGE_GET_DEVICE_NUMBER. Could you let me know? Thanks and Regards, :rose::rose:

        Bram van Kampen

        modified on Tuesday, August 11, 2009 5:17 PM

        L 1 Reply Last reply
        0
        • B Bram van Kampen

          Thanks David, Exactly the hint I Needed. Only One Snag, Cannot find the (hex)Value of IOCTL_STORAGE_GET_DEVICE_NUMBER. Could you let me know? Thanks and Regards, :rose::rose:

          Bram van Kampen

          modified on Tuesday, August 11, 2009 5:17 PM

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          Bram van Kampen wrote:

          Cannot find the (hex)Value of IOCTL_STORAGE_GET_DEVICE_NUMBER.

          Interesting. They are declared in the Winioctl.h header file. Some questions: 1.) What development environment are you using? 2.) What version of the Platform/Windows SDK are you using if any? You can probably get away with dropping these declarations somewhere:#define FILE_ANY_ACCESS 0 #define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) #define FILE_READ_ACCESS ( 0x0001 ) // file & pipe #define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe #define METHOD_BUFFERED 0 #define METHOD_IN_DIRECT 1 #define METHOD_OUT_DIRECT 2 #define METHOD_NEITHER 3 #define FILE_DEVICE_MASS_STORAGE 0x0000002d #define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE #define CTL_CODE( DeviceType, Function, Method, Access ) ( \ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ ) #define IOCTL_STORAGE_GET_DEVICE_NUMBER CTL_CODE(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS) typedef struct _STORAGE_DEVICE_NUMBER { // // The FILE_DEVICE_XXX type for this device. // DEVICE_TYPE DeviceType; // // The number of this device // DWORD DeviceNumber; // // If the device is partitionable, the partition number of the device. // Otherwise -1 // DWORD PartitionNumber; } STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER;
          You should really correctly setup your development environment rather than dropping the above declarations into your project. Are you using VC6 or something? Best Wishes, -David Delaune

          B 1 Reply Last reply
          0
          • L Lost User

            Bram van Kampen wrote:

            Cannot find the (hex)Value of IOCTL_STORAGE_GET_DEVICE_NUMBER.

            Interesting. They are declared in the Winioctl.h header file. Some questions: 1.) What development environment are you using? 2.) What version of the Platform/Windows SDK are you using if any? You can probably get away with dropping these declarations somewhere:#define FILE_ANY_ACCESS 0 #define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) #define FILE_READ_ACCESS ( 0x0001 ) // file & pipe #define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe #define METHOD_BUFFERED 0 #define METHOD_IN_DIRECT 1 #define METHOD_OUT_DIRECT 2 #define METHOD_NEITHER 3 #define FILE_DEVICE_MASS_STORAGE 0x0000002d #define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE #define CTL_CODE( DeviceType, Function, Method, Access ) ( \ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ ) #define IOCTL_STORAGE_GET_DEVICE_NUMBER CTL_CODE(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS) typedef struct _STORAGE_DEVICE_NUMBER { // // The FILE_DEVICE_XXX type for this device. // DEVICE_TYPE DeviceType; // // The number of this device // DWORD DeviceNumber; // // If the device is partitionable, the partition number of the device. // Otherwise -1 // DWORD PartitionNumber; } STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER;
            You should really correctly setup your development environment rather than dropping the above declarations into your project. Are you using VC6 or something? Best Wishes, -David Delaune

            B Offline
            B Offline
            Bram van Kampen
            wrote on last edited by
            #5

            Thanks, My version of Winioctl.h does not contain the Macro for IOCTL_STORAGE_GET_DEVICE_NUMBER, but contains all the other declarations, so, all I really needed was the Function Number (0x420). This Should (and does) work in this instance by 'dropping in', because the underlying mechanism is implemented directly by the OS and the Device Drivers, and not by a linked in compiler library. Thanks again regards, :) :rose: :)

            Bram van Kampen

            1 Reply Last reply
            0
            • L Lost User

              You could use the IOCTL_STORAGE_GET_DEVICE_NUMBER[^] control code to obtain the physical drive and volume number. For example:#include <Winioctl.h> VOID LogicalToPhysical(TCHAR *szDrive) { CString szPhysical; HANDLE h = CreateFile(szDrive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); if(INVALID_HANDLE_VALUE != h) { STORAGE_DEVICE_NUMBER sd; DWORD dwRet; if(DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sd, sizeof(STORAGE_DEVICE_NUMBER), &dwRet, NULL)) { szPhysical.Format(_T("\\\\.\\PhysicalDrive%d"), sd.DeviceNumber); } CloseHandle(h); } } //Usage: LogicalToPhysical(_T("\\\\.\\\\C:"));
              Note that this control code will fail to return correct information for mirrored and striped volumes. A more complete solution for these types of drives would be the IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS[^] control code which will return an array of partitions for the drive. Best Wishes, -David Delaune

              A Offline
              A Offline
              Andy Belton
              wrote on last edited by
              #6

              Many thanks, that solved the problem. I had looked at DeviceIoControl() but my (outdated) Winioctl.h did not have is call param! Regards Andy

              L 1 Reply Last reply
              0
              • A Andy Belton

                Many thanks, that solved the problem. I had looked at DeviceIoControl() but my (outdated) Winioctl.h did not have is call param! Regards Andy

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #7

                Hey Andy, Great to hear that it solved your problem. Yeah... I am also using old Microsoft compilers such as VC6/2005 and I have them all installed side-by-side. You should probably keep an updated 'Platform SDK'... which I believe has been renamed to 'Windows SDK'. Somebody should probably post an article or tip that shows which SDK updates are compatible with each compiler... I am somewhat surprised that Microsoft does not have such a document. You cannot use many of the more recent 'Microsoft SDK' packages with older MS compilers. I have actually been successful with modifying some of the later SDK headers to make it work with older compilers... but that's probably not encouraged or supported. Anyway, good luck with your project. (Why are you working the day after Christmas?) ;) Best Wishes, -David Delaune

                A 1 Reply Last reply
                0
                • L Lost User

                  Hey Andy, Great to hear that it solved your problem. Yeah... I am also using old Microsoft compilers such as VC6/2005 and I have them all installed side-by-side. You should probably keep an updated 'Platform SDK'... which I believe has been renamed to 'Windows SDK'. Somebody should probably post an article or tip that shows which SDK updates are compatible with each compiler... I am somewhat surprised that Microsoft does not have such a document. You cannot use many of the more recent 'Microsoft SDK' packages with older MS compilers. I have actually been successful with modifying some of the later SDK headers to make it work with older compilers... but that's probably not encouraged or supported. Anyway, good luck with your project. (Why are you working the day after Christmas?) ;) Best Wishes, -David Delaune

                  A Offline
                  A Offline
                  Andy Belton
                  wrote on last edited by
                  #8

                  Hi David I was a bit suprised to receive your last mail. Most people don't bother to 'follow up'. Yes, all my stuff belongs in a museum. But, funds don't permit upgrades yet. I'm now in my 60's after over forty years in computing, single, live alone - hence working over the holidays. A couple of questions. In your solution you gave this format "\\\\.\\\\%c:". I assume this to be for extended filepath string length support. But the documenation with my old compiler has it as "\\\\.\\" Is this the norm for extended length support? Users are bound to come up super long path names. Also, in my application I also access network drives. Does the "\\\\pc name\\drive name\\" give this extended length support? Regards Andy Belton

                  L 1 Reply Last reply
                  0
                  • A Andy Belton

                    Hi David I was a bit suprised to receive your last mail. Most people don't bother to 'follow up'. Yes, all my stuff belongs in a museum. But, funds don't permit upgrades yet. I'm now in my 60's after over forty years in computing, single, live alone - hence working over the holidays. A couple of questions. In your solution you gave this format "\\\\.\\\\%c:". I assume this to be for extended filepath string length support. But the documenation with my old compiler has it as "\\\\.\\" Is this the norm for extended length support? Users are bound to come up super long path names. Also, in my application I also access network drives. Does the "\\\\pc name\\drive name\\" give this extended length support? Regards Andy Belton

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #9

                    Hey Andy,

                    Andy Belton wrote:

                    A couple of questions. In your solution you gave this format "\\\\.\\\\%c:". I assume this to be for extended filepath string length support. But the documenation with my old compiler has it as "\\\\.\\"

                    Actually the documentation to your old compiler is correct... for opening the device namespace you need to prepend "\\.\" which as you know escaped looks like "\\\\.\\" I have no idea why my old code snippit from 2009 contains an extra backslash. I write alot of these code snippits impromptu... so some of them may contain typos or minor flaws. I can tell by looking at the above code snippit that I wrote it on the spot... because it doesn't return a value... or modify any variables being passed into the function. It is just enough to illustrate the idea and help the developer move forward.

                    Andy Belton wrote:

                    Is this the norm for extended length support? Users are bound to come up super long path names.

                    I believe that you are referring to the Unicode version of the CreateFile Function[^]... you would need to prepend a L"\\?\" which escaped for c++ looks like L"\\\\?\\"

                    Andy Belton wrote:

                    Also, in my application I also access network drives. Does the "\\\\pc name\\drive name\\" give this extended length support?

                    Yes, you can access files over the network with a path greater than 260 characters however you will need to use the Unicode version of CreateFile function[^] Best Wishes, -David Delaune

                    A 1 Reply Last reply
                    0
                    • L Lost User

                      Hey Andy,

                      Andy Belton wrote:

                      A couple of questions. In your solution you gave this format "\\\\.\\\\%c:". I assume this to be for extended filepath string length support. But the documenation with my old compiler has it as "\\\\.\\"

                      Actually the documentation to your old compiler is correct... for opening the device namespace you need to prepend "\\.\" which as you know escaped looks like "\\\\.\\" I have no idea why my old code snippit from 2009 contains an extra backslash. I write alot of these code snippits impromptu... so some of them may contain typos or minor flaws. I can tell by looking at the above code snippit that I wrote it on the spot... because it doesn't return a value... or modify any variables being passed into the function. It is just enough to illustrate the idea and help the developer move forward.

                      Andy Belton wrote:

                      Is this the norm for extended length support? Users are bound to come up super long path names.

                      I believe that you are referring to the Unicode version of the CreateFile Function[^]... you would need to prepend a L"\\?\" which escaped for c++ looks like L"\\\\?\\"

                      Andy Belton wrote:

                      Also, in my application I also access network drives. Does the "\\\\pc name\\drive name\\" give this extended length support?

                      Yes, you can access files over the network with a path greater than 260 characters however you will need to use the Unicode version of CreateFile function[^] Best Wishes, -David Delaune

                      A Offline
                      A Offline
                      Andy Belton
                      wrote on last edited by
                      #10

                      Hi David Sorry to bug you again. My application was finished and put out for field trials. Yup - it hit a couple of problems (well quite a few actually). Most were trivial to solve. However, I am stuck with two, both related (one directly the other indirectly) to my original question. To help understand the setup, the application is XP platorm based and used primarily at the client office. Howeverm the application also needs to be used in the field (litteraly). So the client wanted the facility to copy work data files on to a second drive that could then be sent out to 'engineers' working in the field who could then interogate them on whatever they have there. The reason for getting the Physocal drive info wsa to ensure that the files were not written to the same physical drive. After writing, the target drive is removed and sent out. (The drive can be internal or external). (That is about the limit as to what I can disclose for security reasons). In my code, I used your solution to obtain the physical drive information. I compare the DriveNumber and PartionNumber numbers to enure they are different drives. This is fine. But I think that I should also be check which controller is being used as I could be blocking a drive that is actually on a different controller. So, Question 1 - How do I determine the drive controller? I have spent some time searching both MSDN and CodeProject and have not found an obvious answer. I think what I need to find are the four parameters as used in boot.ini to select the boot operating system. Now for the indirectly related problem. In practice, the client is using whatever hard drive comes to them from another source. Normally this drive is NTFS formated but some times it is FAT formated. I have no control over this and neither does the client. Out in the field I am using the file modified date from GetFileInformationEx(). This is because all files are loaded to be shipped out but, only those that have a later date to those exisiting in the field are used. However, we are getting problems with file dates. It appears that if you copy a file from NTFS to a FAT file system the date can change. The FAT system does not store the milliseconds, instead the time is rounded up. I could deal with this if it were consistant but, I have seen a direct file copy between two drives and the times have been different by as much as five minutes! In one instance, I actually witnessed the file date being two minutes ahead of the current time! Any thoughts on this one? Please? S

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups