Windows disk operation 7 -- get all the current physical disk numbers

Source: Internet
Author: User
Original Works are allowed to be reprinted. During reprinting, please mark the article in hyperlink form
Original source, author information, and this statement. Otherwise, legal liability will be held. Http://cutebunny.blog.51cto.com/301216/625577

 

With the basics of the previous sections, this section provides a more complex but practical example. In many cases, we want to know how many disks are installed in the current system, how many physical drive numbers are there, how many partitions are there on each disk, and how the partition numbers are distributed, the size of each partition. This is similar to the clear list we see in disk management on Windows. For the next few questions, we call Section 5 refer based on the physical drive number. The focus of this section is on how to obtain all the current physical drive numbers. Introduce a new concept, device guid, which is a uniform and unique identifier code of similar devices. For a disk, The GUID is guid_devinterface_disk. The specific value is {53f56307-b6bf-11d0-94f2-00a0c91efb8b }. Windows provides a set of APIs to list all devices of this type using guid. First, we will give a brief introduction to several related APIs (in lpguid classguid, optionalin pctstr enumerator, optionalin hwnd hwndparent, optionalin DWORD flags). The classguid is filled with the guid of the device that we are interested, this function returns the handle of a set of device information that meets the query conditions. This handle is the key to obtaining device information. Winsetupapi bool handle (in hdevinfo deviceinfoset, in response to deviceinfodata, optionalin lpguid interfaceclassguid, in DWORD memberindex, out response deviceinterfacedata); this function enumerates all the devices contained in the handle. Set the deviceinfoset parameter to the handle we obtained in the previous step. interfaceclassguid is still the guid we are interested in. memberindex is the index of the device in the set and starts counting from 0. Finally, deviceinterfacedata is the output parameter, stores the listed device interfaces. You can use these interfaces to obtain detailed device information. Note that the deviceinterfacedata. cbsize parameter must be initialized to sizeof (sp_device_interface_data) before calling. This is a mandatory requirement of the function. Winsetupapi bool destroy (in hdevinfo deviceinfoset, In response deviceinterfacedata, out response timeout, optionalin DWORD merge, out pdword requiredsize, optionalout psp_devinfo_data deviceinfodata optional ); this function obtains detailed device information data based on the handle and interface in the previous two steps. The deviceinfoset and deviceinterfacedata parameters are obtained in the previous two steps. The output parameter deviceinterfacedetaildata stores device information data. The devicepath in this struct is something we have worked hard to find. You can call the createfile function as the device name to open the device... The following is the specific code /*********************************** **************************************** * *** function: get device path from guid * input: lpguid, guid pointer * output: pszdevicepath, device paths * return: succeed, the amount of found device paths * fail, -1 ************************************** **************************************** /DWORD getdevicepath (lpguid, char ** pszdevicepath) {hdevinfo hdevinfoset; sp_device_interface_data ifdata; psp_device_interface_detail_data pdetail; DWORD ncount; bool result; // get a handle to a device information set
Hdevinfoset = setupdigetclassdevs (lpguid, // class guid
Null, // enumerator null, // hwndparent digcf_present | digcf_deviceinterface // present devices); // fail... if (hdevinfoset = invalid_handle_value) {fprintf (stderr, "handle error: % LD \ n", getlasterror (); Return (DWORD)-1;} pdetail = (response) malloc (interface_detail_size); If (pdetail = NULL) {return (DWORD)-1;} pdetail-> cbsize = sizeof (sp_d Evice_interface_detail_data); ncount = 0; Result = true; // device Index = 0, 1, 2... test the device interface one by one while (result) {ifdata. cbsize = sizeof (ifdata); // enumerates the device interfaces that are contained in a device information set result = setupdienumdeviceinterfaces (hdevinfoset, // deviceinfoset null, // deviceinfodata lpguid, // guid ncount, // memberindex & ifdata // Devi Ceinterfacedata); If (result) {// get details about a device interface result = require (hdevinfoset, // deviceinfoset & ifdata, // deviceinterfacedata pdetail, // deviceinterfacedetaildata interface_detail_size, // deviceinterfacedetaildatasize null, // requiredsize null // deviceinfodata); If (result) {// copy the path to output buffer strcpy (pszdevicepath [ncount], PVDF Tail-> devicepath); // printf ("% s \ n", pdetail-> devicepath); ncount ++ ;}}free (pdetail); (void) setupdidestroydeviceinfolist (hdevinfoset); Return ncount;} after execution, all the disk device names that meet the conditions are stored in the string array pszdevicepath. With this key array, you can do whatever you want. The following is the complete code for obtaining all the physical disk numbers /***************************** **************************************** * ********* function: get all present disks 'physical Number * input: N/A * output: ppdisks, array of disks 'physical Number * return: succeed, the amount of present disks * fail, -1 ************************************** **************************************** /DWORD getallpresentdisks (DWORD ** ppdisks) {char * szdevice Path [max_device]; // device path DWORD ndevice; handle hdevice; storage_device_number number; bool result; DWORD readed; word I, j; for (I = 0; I <max_device; I ++) {szdevicepath [I] = (char *) malloc (interface_detail_size); If (null = szdevicepath [I]) {for (j = 0; j <I; j ++) {free (szdevicepath [I]);} return (DWORD)-1 ;}// get the device paths ndevice = getdevicepath (const_cast <lpguid> (& guid _ Devinterface_disk), szdevicepath); If (DWORD)-1 = ndevice) {for (I = 0; I <max_device; I ++) {free (szdevicepath [I]);} return (DWORD)-1;} * ppdisks = (DWORD *) malloc (sizeof (DWORD) * ndevice ); // get the disk's physical number one by one for (I = 0; I <ndevice; I ++) {hdevice = createfile (szdevicepath [I], // drive to open generic_read | generic_write, // access to the drive file_assist_read | File_share_write, // share mode null, // default security attributes open_existing, // disposition 0, // file attributes null // do not copy file attribute ); if (hdevice = invalid_handle_value) // cannot open the drive {for (j = 0; j <max_device; j ++) {free (szdevicepath [J]);} free (* ppdisks); fprintf (stderr, "createfile () error: % LD \ n", getlasterror (); Return DWORD (-1);} result = deviceioco Ntrol (hdevice, // handle to device ioctl_storage_get_device_number, // dwiocontrolcode null, // lpinbuffer 0, // ninbuffersize & number, // output buffer sizeof (number ), // size of output buffer & readed, // number of bytes returned null // overlapped structure); If (! Result) // fail {fprintf (stderr, "ioctl_storage_get_device_number error: % LD \ n", getlasterror (); For (j = 0; j <max_device; j ++) {free (szdevicepath [J]);} Free (* ppdisks); (void) closehandle (hdevice); Return (DWORD)-1;} * (* ppdisks + I) = number. devicenumber; (void) closehandle (hdevice) ;}for (I = 0; I <max_device; I ++) {free (szdevicepath [I]);} return ndevice ;} code Description: 1. call the getdevicepath function to obtain the previously mentioned magnetic Disk device name array. 2. For each disk device, call createfile to open and obtain the device handle. 3. Call the deviceiocontrol function with the operation code ioctl_storage_get_device_number to obtain the Disk Physical drive number. 4. save all the physical disk numbers to the array and return them. It's done. Some may ask, isn't getdevicepath obtaining the disk path? As you mentioned earlier, this path is either \. \ physicaldrivex or \. \ x:
Then, let's parse this string to get the disk number or drive letter. Unfortunately, there is a third form of disk path, and there is no rule. Open the annotation line/printf ("% s \ n", pdetail-> devicepath) in the getdevicepath function. Print the path in this form and you can see the path similar \\? \ Ide # diskwdc_wd1600aajs-08b4a0 ___________________ 01.03a01 #5 & 245a6b6d & 0 & 0.0.0 # {53f56307-b6bf-11d0-94f2-00a0c91efb8b }\\? \ Ide # diskwdc_wd1600aajs-08b4a0 ___________________ 01.03a01 #5 & 37141c12 & 0 & 0.1.0 # {53f56307-b6bf-11d0-94f2-00a0c91efb8b} So, no way, we still have to use deviceiocontrol to find the disk number.

 

 

 

This article is from the "bunny Technology Workshop" blog, please be sure to keep this source http://cutebunny.blog.51cto.com/301216/625577

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.