We help IT Professionals succeed at work.

How to use CreateFile() to open a hard disk for access?

4,130 Views
Last Modified: 2013-12-14
Hi everyone,

Background:
I am creating a simple GUI using Visual C++ MFC.  My IDE is Visual Studios 2005.  The GUI has a BUTTON with the title "Detect" and an EDIT CONTROL to display text.  When a user clicks on the Detect button, the program scans through all the devices on your computer to retrieve ONLY the external USB Hard Drives.  Please do take note that the HARD DRIVES are ALREADY PLUGGED IN.  I am not interested in detecting hard drives upon insertion.  The reason for this is that in my main app, I don't want the user to have access to the other drives other than the USB drive.  The drive letter is then displayed in the EDIT CONTROL.

Problem:
I have most of the program up and running.  The only problem right now is that the drive letter is not being displayed. I used a GetDriveType() function to obtain the type.  This works perfectly.  My current external USB hard disk is in E:.  All USB hard drives are detected as DRIVE_FIXED.  When the iteration of 'E' arrives, it enters DRIVE_FIXED, which is good.  However when I try to open a the drive using CreateFile() function, the returned output (hDevice) is always an INVALID_HANDLE_VALUE and hence the rest of the code is not executed.  

Observations:
I read up the MSDN on GetDriveType() and CreateFile().  GetDriveType() requires a trailing backslash for drive names but CreateFile() does not require one.  I am a bit confused what a trailing backslash is.  Then again there is the format of the drive string.  For GetDriveType "E:\" seems to be fine.  But for CreateFile(), as quoted from MSDN, " lpFileName string should be the following form: \\.\X: " .  What does this mean? What is the X?  How do we replace the X?  Can't we just use the same E:\ ?

During debugging, the value of my hDevice turns to 0xffffffff when the C drive is encountered.  However, even after I close the handle, when E drive is encountered, hDevice is still 0xffffffff.  I assume this is an error becuase the next if statement block is never executed (0xffffffff is equal to INVALID_HANDLE_VALUE).

HELP:
Can someone please help me with this?  I really need this to be working.  If you have any questions, please do not hesitate to ask.  I really  want the drive letter to be displayed.
DWORD			head;
DWORD			drivetype;
TCHAR			szDriveRoot[5];
TCHAR			szDriveCreate[5];
TCHAR			cDrive;
TCHAR			tempString[33];
HANDLE			hDevice;
PSTORAGE_DEVICE_DESCRIPTOR pDevDesc; 
head = GetLogicalDrives();
for ( cDrive = 'A'; cDrive <= 'Z'; cDrive++,head>>=1 )  
{
    if ( !(head&1) ) 
    {
        continue; 
    }
    _stprintf(szDriveRoot, _T("%c:\\"), cDrive);
    _stprintf(szDriveCreate, _T("\\.\%c:"), cDrive);
    switch ( GetDriveType( szDriveRoot ) )  
    {
    case 0:		// The drive type cannot be determined.
    case 1:		// The root directory does not exist.
        drivetype = DRVUNKNOWN;
    break;
 
    case DRIVE_REMOVABLE: // The drive can be removed from the drive.
	drivetype = DRVREMOVE;
    break;
 
    case DRIVE_CDROM:	 // The drive is a CD-ROM drive.
        drivetype = DRVCD;
    break;
 
    case DRIVE_FIXED:	 // The disk cannot be removed from the drive.
        drivetype = DRVFIXED;
	hDevice = CreateFile(szDriveCreate, 
                             GENERIC_READ,
			     FILE_SHARE_READ | FILE_SHARE_WRITE, 
                             NULL, OPEN_EXISTING, 
                             NULL, NULL);
 
	if (hDevice != INVALID_HANDLE_VALUE)
	{
            pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)new BYTE[sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1];
 
	    pDevDesc->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1;
 
	    if(GetDisksProperty(hDevice, pDevDesc))
	    {
	        if(pDevDesc->BusType == BusTypeUsb)
	        {
		    wsprintf(tempString, L"USB disk(s) are: \n%s",
                           &szDriveRoot);
                    m_text.SetWindowText(CString(tempString));
		}
	    }
	    delete pDevDesc;
	}
	CloseHandle(hDevice);
    break;
 
    case DRIVE_REMOTE:	// The drive is a remote (network) drive.
        drivetype = DRVREMOTE;
    break;
 
    case DRIVE_RAMDISK:		// The drive is a RAM disk.
        drivetype = DRVRAM;
    break;
    }
}
}

Open in new window

Comment
Watch Question

Jaime OlivaresSoftware Architect
CERTIFIED EXPERT
Top Expert 2008

Commented:
you should use:
_stprintf(szDriveCreate, _T(\\.\%c), cDrive);

so the string will be: \\.\E

Author

Commented:
I tried using:

_stprintf(szDriveCreate, _T(\\.\%c), cDrive);

but the string turned out to be \.E

Besides, this still doesn't solve the problem.  Some how the CreateFile() is still returning an INVALID_HANDLE_VALUE.

Whatever could be the problem....
Jaime OlivaresSoftware Architect
CERTIFIED EXPERT
Top Expert 2008

Commented:
ah ok, your format string is incorrect, it should be:
_stprintf(szDriveCreate, _T(\\\\.\\%c), cDrive);

the backslash is a special character and should be specified twice to display correctly.
Software Architect
CERTIFIED EXPERT
Top Expert 2008
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.