In the last post, I described how to open/close cd tray. Some of you might have raised your eye brows as there is no description how to find the drive letter of cd drive. Here is a sample program which prints all cd drive letters in a system.
#include <iostream>
#include <string>
#include "wtypes.h"
#include "basetsd.h"
#include "winbase.h"
using namespace std;
int main()
{
// Iterate through all the 26 drives possible
for (char Drive = 'a'; Drive <= 'z'; ++Drive)
{
// Format drive like "c:\"
string StrDrive = "";
StrDrive.push_back(Drive);
StrDrive.append(":\\");
// Print the drive letter if it is a cd drive
if (DRIVE_CDROM == GetDriveType(StrDrive.c_str()))
{
cout << Drive << '\n';
}
}
return 0;
}
Some Background Info
The GetDriveType() function can give the type of a drive. The possible values are given below.
DRIVE_UNKNOWN = 0 : The drive type can not be determined.
DRIVE_NO_ROOT_DIR = 1 :The root path is invalid; for example, there is no volume is mounted at the path.
DRIVE_REMOVABLE = 2 : The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader.
DRIVE_FIXED = 3 : The drive has fixed media; for example, a hard drive or flash drive.
DRIVE_REMOTE = 4 : The drive is a remote (network) drive.
DRIVE_CDROM = 5 : The drive is a CD-ROM drive.
DRIVE_RAMDISK = 6 : The drive is a RAM disk.
The GetDriveType() function expects an argument of type LPCTSTR, which can specify the root path of the drive with a trailing slash (as in c:\). if the argument is NULL, it will take the root of the current directory.
GetDriveType() will be expanded to GetDriveTypeW (for UNIODE) and GetDriveTypeA (for ANSI). The macro _T() can automatically expand the argument to multibyte character string if unicode is defined.
Using VC++, it is quite simple. We can treat cd drive as an IO file using the windows API CreateFile(). Then we cann eject or retract using the function DeviceIoControl(). The following program illustrates this.
#include "wtypes.h"
#include "winioctl.h"
#include <string>
using namespace std;
// DriveName specifies the cd drive name (as string, eg: "D")
// Open specifies whether to open or close drive
bool OpenCloseDoor(const string& DriveName, const bool Open)
{
// Make drive name in the format "\\.\D:" where D is the cd drive
const string Drive = string("\\\\.\\") + DriveName + string(":");
// Treat cd drive as an IO device file
HANDLE hDrive = INVALID_HANDLE_VALUE;
hDrive = CreateFile(Drive.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
// Open or close as needed
BOOL bRetVal = FALSE;
if ((hDrive != INVALID_HANDLE_VALUE) && (NO_ERROR == GetLastError()))
{
DWORD dwDummy = 0;
if (Open)
{
bRetVal = DeviceIoControl(hDrive, IOCTL_STORAGE_EJECT_MEDIA,
NULL, 0, NULL, 0, &dwDummy, NULL);
}
else
{
bRetVal = DeviceIoControl(hDrive, IOCTL_STORAGE_LOAD_MEDIA,
NULL, 0, NULL, 0, &dwDummy, NULL);
}
}
return (!!bRetVal); // To avoid performance warning
}
int main()
{
OpenCloseDoor("D", true); //D is my cd drive
OpenCloseDoor("D", false);
return 0;
}