From: Christian ASTOR on
Steve wrote:

> On Nov 8, 2:58 pm, Christian ASTOR <casto...(a)club-internet.fr> wrote:
>>Steve wrote:
>>>On Oct 30, 8:51 pm, Christian ASTOR <casto...(a)club-internet.fr> wrote:
>>>
>>>>e.g. with IOCTL_STORAGE_GET_MEDIA_TYPES_EX
>>
>>>While that DeviceIoControl call does return some information, as far
>>>as I can tell it will only tell me that the drive is capabale of CD or
>>>DVD and whether or not it can do writing (burning) and erasing. I
>>>need to find out what specific types of media the drive supports. For
>>>instance I need to know if the drive supports CD-R or CD+R or CD-RW or
>>>DVD-R etc.
>>
>>No, you get a STORAGE_MEDIA_TYPE value.
>
>
> True...but that enumeration does not (at least as far as I can tell)
> differentiate between CD-R and CD+R or DVD-R and DVD+R


For DVD+, with SCSIOP_GET_CONFIGURATION or IDiscRecorder2Ex interface
(::GetSupportedProfiles())
CD+, I don't know this format...
From: Steve on
Well it seems like a possible solution is to use
IOCTL_CDROM_GET_CONFIGURATION. Reading all I can find on this
DeviceIoControl method sound like it will do exactly what I need.
However I can not find an example of how to use this method. Does
anybody have an example code using this function. I would prefer a
VB6 example but any language will work.

Thanks,
Steve
From: Christian ASTOR on
Steve wrote:
> Well it seems like a possible solution is to use
> IOCTL_CDROM_GET_CONFIGURATION. Reading all I can find on this
> DeviceIoControl method sound like it will do exactly what I need.
> However I can not find an example of how to use this method. Does
> anybody have an example code using this function. I would prefer a
> VB6 example but any language will work.

I don't use VB.
A Win32 Console sample, with FeatureProfileList =>

#include <tchar.h>
#include <windows.h>
#include <stdio.h>

#include <Ntddmmc.h>
#include <Ntddcdrm.h>

typedef struct _sPROFILES
{
DWORD dwProfileType;
LPTSTR pProfileText;
} sPROFILES;

#define STR(s) {(DWORD)s, TEXT(#s)}

sPROFILES Profiles[] =
{
STR(ProfileInvalid),
STR(ProfileNonRemovableDisk),
STR(ProfileRemovableDisk),
STR(ProfileMOErasable),
STR(ProfileMOWriteOnce),
STR(ProfileAS_MO),
STR(ProfileCdrom),
STR(ProfileCdRecordable),
STR(ProfileCdRewritable),
STR(ProfileDvdRom),
STR(ProfileDvdRecordable),
STR(ProfileDvdRam),
STR(ProfileDvdRewritable),
STR(ProfileDvdRWSequential),
STR(ProfileDvdPlusRW),
STR(ProfileDDCdrom),
STR(ProfileDDCdRecordable),
STR(ProfileDDCdRewritable),
};

void Usage(char* sModule)
{
TCHAR sExeName[MAX_PATH];
_splitpath(sModule, NULL, NULL, sExeName, NULL);
printf("Usage: %s <drive letter>\n\n", sExeName);
}

int _tmain(int argc, _TCHAR* argv[])
{
if (argc != 2)
{
Usage(argv[0]);
return 1;
}
TCHAR sVolumeName[8];
wsprintf(sVolumeName, TEXT("\\\\.\\%c:"), argv[1][0]);
HANDLE hVolume;
hVolume = CreateFile(sVolumeName, GENERIC_READ, FILE_SHARE_READ |
FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
if (hVolume == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "CreateFile() Error : %d", GetLastError());
return 1;
}
printf("Volume: %s\n", argv[1]);

DWORD dwBytesReturned;
GET_CONFIGURATION_IOCTL_INPUT input;
DWORD dwBufferSize = sizeof(GET_CONFIGURATION_HEADER) +
sizeof(FEATURE_HEADER);
GET_CONFIGURATION_HEADER* pConfigHeader =
(GET_CONFIGURATION_HEADER*)LocalAlloc(LPTR, dwBufferSize);
if (pConfigHeader)
{
ZeroMemory(&input, sizeof(GET_CONFIGURATION_IOCTL_INPUT));
input.Feature = FeatureProfileList;
input.RequestType =
SCSI_GET_CONFIGURATION_REQUEST_TYPE_ONE;//SCSI_GET_CONFIGURATION_REQUEST_TYPE_ALL;
BOOL bReturn = DeviceIoControl(hVolume, IOCTL_CDROM_GET_CONFIGURATION,
&input,
sizeof(GET_CONFIGURATION_IOCTL_INPUT),
pConfigHeader, dwBufferSize, &dwBytesReturned, NULL);
if (bReturn)
{
dwBufferSize = pConfigHeader->DataLength[0] << 24 |
pConfigHeader->DataLength[1] << 16 |
pConfigHeader->DataLength[2] << 8 | pConfigHeader->DataLength[3] << 0;
GET_CONFIGURATION_HEADER* pConfigHeader2;
pConfigHeader2 = (PGET_CONFIGURATION_HEADER) LocalAlloc(LPTR,
dwBufferSize);
if (pConfigHeader2)
{
input.RequestType = SCSI_GET_CONFIGURATION_REQUEST_TYPE_ALL;
bReturn = DeviceIoControl(hVolume,
IOCTL_CDROM_GET_CONFIGURATION,
&input,
sizeof(GET_CONFIGURATION_IOCTL_INPUT),
pConfigHeader2,
dwBufferSize,
&dwBytesReturned,
NULL);
if (bReturn)
{
FEATURE_DATA_PROFILE_LIST* pProfileList =
(FEATURE_DATA_PROFILE_LIST*)pConfigHeader2->Data;
for (int n = 0; n < (pProfileList->Header.AdditionalLength / 4); n++)
{
FEATURE_DATA_PROFILE_LIST_EX* pProfileListEx =
&(pProfileList->Profiles[n]);
for (DWORD dw = 0; dw < ARRAYSIZE(Profiles); dw++)
{
if ( (FEATURE_PROFILE_TYPE)(Profiles[dw].dwProfileType) ==
(pProfileListEx->ProfileNumber[0] << 8 |
pProfileListEx->ProfileNumber[1] << 0))
{
printf("\t%s (0x%04X) - Current Media : %s\n",
Profiles[dw].pProfileText, Profiles[dw].dwProfileType,
(pProfileListEx->Current?"Yes":"No"));
}

}
}
}
LocalFree(pConfigHeader2);
}
}
LocalFree(pConfigHeader);
}

CloseHandle(hVolume);
return 0;
}
From: Steve on
Christian,

Thanks for the code.
My C/C++ skills are not so good but I am sure I can figure this out.

Steve