DeviceIOControl in C#...

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I'm having difficulties converting the GET_CONFIGURATION_HEADER from the
IOCTL_CDROM_GET_CONDIGURATION DeviceIoControl command to usable C# code.

The C struct look like this:

typedef struct _GET_CONFIGURATION_HEADER {
UCHAR DataLength[4];
UCHAR Reserved[2];
UCHAR CurrentProfile[2];
UCHAR Data[0];
} GET_CONFIGURATION_HEADER, *PGET_CONFIGURATION_HEADER;

Where the CurrentProfile is
actually an enumerator value of type FEATURE_PROFILE_TYPE:

typedef enum _FEATURE_PROFILE_TYPE {
ProfileInvalid = 0x0000,
ProfileNonRemovableDisk = 0x0001,
ProfileRemovableDisk = 0x0002,
ProfileMOErasable = 0x0003,
ProfileMOWriteOnce = 0x0004,
ProfileAS_MO = 0x0005,
// Reserved 0x0006 - 0x0007
ProfileCdrom = 0x0008,
ProfileCdRecordable = 0x0009,
ProfileCdRewritable = 0x000a,
ProfileDvdRom = 0x0010,
ProfileDvdRecordable = 0x0011,
ProfileDvdRam = 0x0012,
ProfileDvdRewritable = 0x0013,
ProfileDvdRWSequential = 0x0013,
// Reserved - 0x0014,
ProfileDvdPlusRW = 0x001a,
// Reserved - 0x001b,
ProfileDDCdrom = 0x0020,
ProfileDDCdRecordable = 0x0021,
ProfileDDCdRewritable = 0x0022,
// Reserved - 0x0023,
ProfileNonStandard = 0xffff
} FEATURE_PROFILE_TYPE, *PFEATURE_PROFILE_TYPE;

And the Data is FEATURE_HEADER struct:

typedef struct _FEATURE_HEADER {
UCHAR FeatureCode[2];
UCHAR Current:1;
UCHAR Persistent:1;
UCHAR Version:3;
UCHAR Reserved0:2;
UCHAR AdditionalLength;
} FEATURE_HEADER, *PFEATURE_HEADER;

Where FeatureCode is an enumerator value of type FEATURE_NUMBER:

typedef enum _FEATURE_NUMBER {
FeatureProfileList = 0x0000,
FeatureCore = 0x0001,
FeatureMorphing = 0x0002,
FeatureRemovableMedium = 0x0003,
FeatureWriteProtect = 0x0004,
// Reserved 0x0005 - 0x000f
FeatureRandomReadable = 0x0010,
// Reserved 0x0011 - 0x001c
FeatureMultiRead = 0x001d,
FeatureCdRead = 0x001e,
FeatureDvdRead = 0x001f,
FeatureRandomWritable = 0x0020,
FeatureIncrementalStreamingWritable = 0x0021,
FeatureSectorErasable = 0x0022,
FeatureFormattable = 0x0023,
FeatureDefectManagement = 0x0024,
FeatureWriteOnce = 0x0025,
FeatureRestrictedOverwrite = 0x0026,
FeatureCdrwCAVWrite = 0x0027,
FeatureMrw = 0x0028,
// Reserved - 0x0029
FeatureDvdPlusRW = 0x002a,
// Reserved - 0x002b
FeatureRigidRestrictedOverwrite = 0x002c,
FeatureCdTrackAtOnce = 0x002d,
FeatureCdMastering = 0x002e,
FeatureDvdRecordableWrite = 0x002f,
FeatureDDCDRead = 0x0030,
FeatureDDCDRWrite = 0x0031,
FeatureDDCDRWWrite = 0x0032,
// Reserved 0x0030 - 0x00ff
FeaturePowerManagement = 0x0100,
FeatureSMART = 0x0101,
FeatureEmbeddedChanger = 0x0102,
FeatureCDAudioAnalogPlay = 0x0103,
FeatureMicrocodeUpgrade = 0x0104,
FeatureTimeout = 0x0105,
FeatureDvdCSS = 0x0106,
FeatureRealTimeStreaming = 0x0107,
FeatureLogicalUnitSerialNumber = 0x0108,
// Reserved = 0x0109,
FeatureDiscControlBlocks = 0x010a,
FeatureDvdCPRM = 0x010b
// Reserved 0x010c - 0xfeff
// Vendor Unique 0xff00 - 0xffff
} FEATURE_NUMBER, *PFEATURE_NUMBER;

Taken from this site
http://msdn.microsoft.com/library/d..._f15044b6-5bbe-4d82-9826-dbe0c96a488c.xml.asp

I hope there is a helpful soul out there who can help me out? Previous
attempts doesn't seem to work...
 
What happens? How does it not work? What error messages are you getting?

Please provide specifics.



Mads Tjørnelund Toustrup said:
I'm having difficulties converting the GET_CONFIGURATION_HEADER from the
IOCTL_CDROM_GET_CONDIGURATION DeviceIoControl command to usable C# code.

The C struct look like this:

typedef struct _GET_CONFIGURATION_HEADER {
UCHAR DataLength[4];
UCHAR Reserved[2];
UCHAR CurrentProfile[2];
UCHAR Data[0];
} GET_CONFIGURATION_HEADER, *PGET_CONFIGURATION_HEADER;

Where the CurrentProfile is
actually an enumerator value of type FEATURE_PROFILE_TYPE:

typedef enum _FEATURE_PROFILE_TYPE {
ProfileInvalid = 0x0000,
ProfileNonRemovableDisk = 0x0001,
ProfileRemovableDisk = 0x0002,
ProfileMOErasable = 0x0003,
ProfileMOWriteOnce = 0x0004,
ProfileAS_MO = 0x0005,
// Reserved 0x0006 - 0x0007
ProfileCdrom = 0x0008,
ProfileCdRecordable = 0x0009,
ProfileCdRewritable = 0x000a,
ProfileDvdRom = 0x0010,
ProfileDvdRecordable = 0x0011,
ProfileDvdRam = 0x0012,
ProfileDvdRewritable = 0x0013,
ProfileDvdRWSequential = 0x0013,
// Reserved - 0x0014,
ProfileDvdPlusRW = 0x001a,
// Reserved - 0x001b,
ProfileDDCdrom = 0x0020,
ProfileDDCdRecordable = 0x0021,
ProfileDDCdRewritable = 0x0022,
// Reserved - 0x0023,
ProfileNonStandard = 0xffff
} FEATURE_PROFILE_TYPE, *PFEATURE_PROFILE_TYPE;

And the Data is FEATURE_HEADER struct:

typedef struct _FEATURE_HEADER {
UCHAR FeatureCode[2];
UCHAR Current:1;
UCHAR Persistent:1;
UCHAR Version:3;
UCHAR Reserved0:2;
UCHAR AdditionalLength;
} FEATURE_HEADER, *PFEATURE_HEADER;

Where FeatureCode is an enumerator value of type FEATURE_NUMBER:

typedef enum _FEATURE_NUMBER {
FeatureProfileList = 0x0000,
FeatureCore = 0x0001,
FeatureMorphing = 0x0002,
FeatureRemovableMedium = 0x0003,
FeatureWriteProtect = 0x0004,
// Reserved 0x0005 - 0x000f
FeatureRandomReadable = 0x0010,
// Reserved 0x0011 - 0x001c
FeatureMultiRead = 0x001d,
FeatureCdRead = 0x001e,
FeatureDvdRead = 0x001f,
FeatureRandomWritable = 0x0020,
FeatureIncrementalStreamingWritable = 0x0021,
FeatureSectorErasable = 0x0022,
FeatureFormattable = 0x0023,
FeatureDefectManagement = 0x0024,
FeatureWriteOnce = 0x0025,
FeatureRestrictedOverwrite = 0x0026,
FeatureCdrwCAVWrite = 0x0027,
FeatureMrw = 0x0028,
// Reserved - 0x0029
FeatureDvdPlusRW = 0x002a,
// Reserved - 0x002b
FeatureRigidRestrictedOverwrite = 0x002c,
FeatureCdTrackAtOnce = 0x002d,
FeatureCdMastering = 0x002e,
FeatureDvdRecordableWrite = 0x002f,
FeatureDDCDRead = 0x0030,
FeatureDDCDRWrite = 0x0031,
FeatureDDCDRWWrite = 0x0032,
// Reserved 0x0030 - 0x00ff
FeaturePowerManagement = 0x0100,
FeatureSMART = 0x0101,
FeatureEmbeddedChanger = 0x0102,
FeatureCDAudioAnalogPlay = 0x0103,
FeatureMicrocodeUpgrade = 0x0104,
FeatureTimeout = 0x0105,
FeatureDvdCSS = 0x0106,
FeatureRealTimeStreaming = 0x0107,
FeatureLogicalUnitSerialNumber = 0x0108,
// Reserved = 0x0109,
FeatureDiscControlBlocks = 0x010a,
FeatureDvdCPRM = 0x010b
// Reserved 0x010c - 0xfeff
// Vendor Unique 0xff00 - 0xffff
} FEATURE_NUMBER, *PFEATURE_NUMBER;

Taken from this site:
http://msdn.microsoft.com/library/d..._f15044b6-5bbe-4d82-9826-dbe0c96a488c.xml.asp

I hope there is a helpful soul out there who can help me out? Previous
attempts doesn't seem to work...
 
Mads,

This is kind of thorny, because you have a structure with another
embedded structure, which has a variable length.

First, let's define the FEATURE_HEADER structure:

[StructLayout(LayoutKind.Sequential)]
public struct FEATURE_HEADER
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]
public byte[] FeatureCode;
public byte Current;
public byte Persistent;
public byte Version;
public byte Reserved0;
public byte AdditionalLength;
}

Now, you can define the GET_CONFIGURATION_HEADER structure.

[StructLayout(LayoutKind.Sequential)]
public struct GET_CONFIGURATION_HEADER
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
byte[] DataLength;
ushort Reserved
[MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]
byte[] CurrentProfile;
FEATURE_HEADER Data;
}

When you marshal this, you will have to pass IntPtr values to/from the
API calls. When you get an IntPtr back, you can call the static
PtrToStructure method on the Marshal class to get the
GET_CONFIGURATION_HEADER. Once you do that, you have to get the rest of the
data. First, you have to find the offset of the data. You can compute that
with this:

// retVal is the pointer returned to you.
IntPtr additionalDataPtr = new IntPtr(retVal.ToInt64() +
Marshal.SizeOf(typeof(GET_CONFIGURATION_HEADER)));

With that, you can then marshal the bytes from the unmanaged memory
space.

// Get the bytes. Assume you already called PtrToStructure for the
configuration header, and it is in a variable named
// configurationHeader.
byte[] additionalData = new byte[configurationHeader.Data.AdditionalLength];

// Copy the data.
Marshal.Copy(additionalDataPtr, additionalData, 0, additionalData.Length);

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Notice the Data field is missing, and the DataLength and CurrentProfile
fields are declared as byte arrays. I left them like this because you will
need to switch the order (they are big-endian, and you are most likely
running on a little-endian machine).

The DataField is missing because you will have to marshal that
separately. Here is the definition of that.

Mads Tjørnelund Toustrup said:
I'm having difficulties converting the GET_CONFIGURATION_HEADER from the
IOCTL_CDROM_GET_CONDIGURATION DeviceIoControl command to usable C# code.

The C struct look like this:

typedef struct _GET_CONFIGURATION_HEADER {
UCHAR DataLength[4];
UCHAR Reserved[2];
UCHAR CurrentProfile[2];
UCHAR Data[0];
} GET_CONFIGURATION_HEADER, *PGET_CONFIGURATION_HEADER;

Where the CurrentProfile is
actually an enumerator value of type FEATURE_PROFILE_TYPE:

typedef enum _FEATURE_PROFILE_TYPE {
ProfileInvalid = 0x0000,
ProfileNonRemovableDisk = 0x0001,
ProfileRemovableDisk = 0x0002,
ProfileMOErasable = 0x0003,
ProfileMOWriteOnce = 0x0004,
ProfileAS_MO = 0x0005,
// Reserved 0x0006 - 0x0007
ProfileCdrom = 0x0008,
ProfileCdRecordable = 0x0009,
ProfileCdRewritable = 0x000a,
ProfileDvdRom = 0x0010,
ProfileDvdRecordable = 0x0011,
ProfileDvdRam = 0x0012,
ProfileDvdRewritable = 0x0013,
ProfileDvdRWSequential = 0x0013,
// Reserved - 0x0014,
ProfileDvdPlusRW = 0x001a,
// Reserved - 0x001b,
ProfileDDCdrom = 0x0020,
ProfileDDCdRecordable = 0x0021,
ProfileDDCdRewritable = 0x0022,
// Reserved - 0x0023,
ProfileNonStandard = 0xffff
} FEATURE_PROFILE_TYPE, *PFEATURE_PROFILE_TYPE;

And the Data is FEATURE_HEADER struct:

typedef struct _FEATURE_HEADER {
UCHAR FeatureCode[2];
UCHAR Current:1;
UCHAR Persistent:1;
UCHAR Version:3;
UCHAR Reserved0:2;
UCHAR AdditionalLength;
} FEATURE_HEADER, *PFEATURE_HEADER;

Where FeatureCode is an enumerator value of type FEATURE_NUMBER:

typedef enum _FEATURE_NUMBER {
FeatureProfileList = 0x0000,
FeatureCore = 0x0001,
FeatureMorphing = 0x0002,
FeatureRemovableMedium = 0x0003,
FeatureWriteProtect = 0x0004,
// Reserved 0x0005 - 0x000f
FeatureRandomReadable = 0x0010,
// Reserved 0x0011 - 0x001c
FeatureMultiRead = 0x001d,
FeatureCdRead = 0x001e,
FeatureDvdRead = 0x001f,
FeatureRandomWritable = 0x0020,
FeatureIncrementalStreamingWritable = 0x0021,
FeatureSectorErasable = 0x0022,
FeatureFormattable = 0x0023,
FeatureDefectManagement = 0x0024,
FeatureWriteOnce = 0x0025,
FeatureRestrictedOverwrite = 0x0026,
FeatureCdrwCAVWrite = 0x0027,
FeatureMrw = 0x0028,
// Reserved - 0x0029
FeatureDvdPlusRW = 0x002a,
// Reserved - 0x002b
FeatureRigidRestrictedOverwrite = 0x002c,
FeatureCdTrackAtOnce = 0x002d,
FeatureCdMastering = 0x002e,
FeatureDvdRecordableWrite = 0x002f,
FeatureDDCDRead = 0x0030,
FeatureDDCDRWrite = 0x0031,
FeatureDDCDRWWrite = 0x0032,
// Reserved 0x0030 - 0x00ff
FeaturePowerManagement = 0x0100,
FeatureSMART = 0x0101,
FeatureEmbeddedChanger = 0x0102,
FeatureCDAudioAnalogPlay = 0x0103,
FeatureMicrocodeUpgrade = 0x0104,
FeatureTimeout = 0x0105,
FeatureDvdCSS = 0x0106,
FeatureRealTimeStreaming = 0x0107,
FeatureLogicalUnitSerialNumber = 0x0108,
// Reserved = 0x0109,
FeatureDiscControlBlocks = 0x010a,
FeatureDvdCPRM = 0x010b
// Reserved 0x010c - 0xfeff
// Vendor Unique 0xff00 - 0xffff
} FEATURE_NUMBER, *PFEATURE_NUMBER;

Taken from this site:
http://msdn.microsoft.com/library/d..._f15044b6-5bbe-4d82-9826-dbe0c96a488c.xml.asp

I hope there is a helpful soul out there who can help me out? Previous
attempts doesn't seem to work...
 
Well, the funny(!) thing about DeviceIOControl commands is that it only
returns true or false. It is then up to you to figure out where the error
is...

Mads Tjørnelund Toustrup said:
I'm having difficulties converting the GET_CONFIGURATION_HEADER from the
IOCTL_CDROM_GET_CONDIGURATION DeviceIoControl command to usable C# code.

The C struct look like this:

typedef struct _GET_CONFIGURATION_HEADER {
UCHAR DataLength[4];
UCHAR Reserved[2];
UCHAR CurrentProfile[2];
UCHAR Data[0];
} GET_CONFIGURATION_HEADER, *PGET_CONFIGURATION_HEADER;

Where the CurrentProfile is
actually an enumerator value of type FEATURE_PROFILE_TYPE:

typedef enum _FEATURE_PROFILE_TYPE {
ProfileInvalid = 0x0000,
ProfileNonRemovableDisk = 0x0001,
ProfileRemovableDisk = 0x0002,
ProfileMOErasable = 0x0003,
ProfileMOWriteOnce = 0x0004,
ProfileAS_MO = 0x0005,
// Reserved 0x0006 - 0x0007
ProfileCdrom = 0x0008,
ProfileCdRecordable = 0x0009,
ProfileCdRewritable = 0x000a,
ProfileDvdRom = 0x0010,
ProfileDvdRecordable = 0x0011,
ProfileDvdRam = 0x0012,
ProfileDvdRewritable = 0x0013,
ProfileDvdRWSequential = 0x0013,
// Reserved - 0x0014,
ProfileDvdPlusRW = 0x001a,
// Reserved - 0x001b,
ProfileDDCdrom = 0x0020,
ProfileDDCdRecordable = 0x0021,
ProfileDDCdRewritable = 0x0022,
// Reserved - 0x0023,
ProfileNonStandard = 0xffff
} FEATURE_PROFILE_TYPE, *PFEATURE_PROFILE_TYPE;

And the Data is FEATURE_HEADER struct:

typedef struct _FEATURE_HEADER {
UCHAR FeatureCode[2];
UCHAR Current:1;
UCHAR Persistent:1;
UCHAR Version:3;
UCHAR Reserved0:2;
UCHAR AdditionalLength;
} FEATURE_HEADER, *PFEATURE_HEADER;

Where FeatureCode is an enumerator value of type FEATURE_NUMBER:

typedef enum _FEATURE_NUMBER {
FeatureProfileList = 0x0000,
FeatureCore = 0x0001,
FeatureMorphing = 0x0002,
FeatureRemovableMedium = 0x0003,
FeatureWriteProtect = 0x0004,
// Reserved 0x0005 - 0x000f
FeatureRandomReadable = 0x0010,
// Reserved 0x0011 - 0x001c
FeatureMultiRead = 0x001d,
FeatureCdRead = 0x001e,
FeatureDvdRead = 0x001f,
FeatureRandomWritable = 0x0020,
FeatureIncrementalStreamingWritable = 0x0021,
FeatureSectorErasable = 0x0022,
FeatureFormattable = 0x0023,
FeatureDefectManagement = 0x0024,
FeatureWriteOnce = 0x0025,
FeatureRestrictedOverwrite = 0x0026,
FeatureCdrwCAVWrite = 0x0027,
FeatureMrw = 0x0028,
// Reserved - 0x0029
FeatureDvdPlusRW = 0x002a,
// Reserved - 0x002b
FeatureRigidRestrictedOverwrite = 0x002c,
FeatureCdTrackAtOnce = 0x002d,
FeatureCdMastering = 0x002e,
FeatureDvdRecordableWrite = 0x002f,
FeatureDDCDRead = 0x0030,
FeatureDDCDRWrite = 0x0031,
FeatureDDCDRWWrite = 0x0032,
// Reserved 0x0030 - 0x00ff
FeaturePowerManagement = 0x0100,
FeatureSMART = 0x0101,
FeatureEmbeddedChanger = 0x0102,
FeatureCDAudioAnalogPlay = 0x0103,
FeatureMicrocodeUpgrade = 0x0104,
FeatureTimeout = 0x0105,
FeatureDvdCSS = 0x0106,
FeatureRealTimeStreaming = 0x0107,
FeatureLogicalUnitSerialNumber = 0x0108,
// Reserved = 0x0109,
FeatureDiscControlBlocks = 0x010a,
FeatureDvdCPRM = 0x010b
// Reserved 0x010c - 0xfeff
// Vendor Unique 0xff00 - 0xffff
} FEATURE_NUMBER, *PFEATURE_NUMBER;

Taken from this site:
http://msdn.microsoft.com/library/d..._f15044b6-5bbe-4d82-9826-dbe0c96a488c.xml.asp

I hope there is a helpful soul out there who can help me out? Previous
attempts doesn't seem to work...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top