0

I'm trying to get Informations about DVDs by ioctl in C#

the C Structure Looks like this and is working in a mixed CLR C++ Library

typedef enum {
    DvdChallengeKey = 0x01,
    DvdBusKey1,
    DvdBusKey2,
    DvdTitleKey,
    DvdAsf,
    DvdSetRpcKey = 0x6,
    DvdGetRpcKey = 0x8,
    DvdDiskKey = 0x80,
    DvdInvalidateAGID = 0x3f
} DVD_KEY_TYPE;

typedef struct DVD_COPY_PROTECT_KEY
{
ULONG KeyLength;
DVD_SESSION_ID SessionId;
DVD_KEY_TYPE KeyType;
ULONG KeyFlags;
union
{
    struct
    {
        ULONG FileHandle;
        ULONG Reserved;   // used for NT alignment
    };
    LARGE_INTEGER TitleOffset;
} Parameters;
UCHAR KeyData[0];
} DVD_COPY_PROTECT_KEY, * PDVD_COPY_PROTECT_KEY;

My C# equivalent Looks

public enum DVD_KEY_TYPE
    {
        DvdChallengeKey = 0x01,
        DvdBusKey1,
        DvdBusKey2,
        DvdTitleKey,
        DvdAsf,
        DvdSetRpcKey = 0x6,
        DvdGetRpcKey = 0x8,
        DvdDiskKey = 0x80,
        DvdInvalidateAGID = 0x3f
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DVD_COPY_PROTECT_KEY
    {
        public uint KeyLength;
        public int SessionId;
        public DVD_KEY_TYPE KeyType;
        public uint KeyFlags;

        [MarshalAs(UnmanagedType.Struct)]
        public DVD_COPY_PROTECT_KEY_Parameters Parameters;
        
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
        private byte[] KeyData;
        
        public DVD_COPY_PROTECT_KEY(DVD_KEY_TYPE keyType, int sessionId)
        {
            SessionId = sessionId;
            KeyType = keyType;
            KeyFlags = 0;
            KeyData = new byte[10];
            KeyLength = 32;//GetKeyLength(this);
            
            Parameters = new DVD_COPY_PROTECT_KEY_Parameters();
            

            var t = Marshal.SizeOf(Parameters);
            var t1 = Marshal.SizeOf(Parameters.Inner); 
            var t2 = Marshal.SizeOf(Parameters.TitleOffset);

            var challenge = GetChallenge();

            /* Get challenge from host */
            for (int i = 0; i < 10; ++i)
            {
                KeyData[9 - i] = challenge[i];
            }
            
        }

        public static byte[] GetChallenge()
        {
            byte[] p_challenge = new byte[10];

            /* Setup a challenge, any values should work */
            for (int i = 0; i < 10; ++i)
            {
                p_challenge[i] = (byte)i;
            }
            return p_challenge;
        }

        public static uint GetKeyLength(DVD_COPY_PROTECT_KEY dcpk)
        {
            int size = Marshal.SizeOf(dcpk);
            switch (dcpk.KeyType)
            {
                case DVD_KEY_TYPE.DvdChallengeKey:
                    return (uint)(12 + size); //36
                case DVD_KEY_TYPE.DvdBusKey1:
                    return (uint)(8 + size); //32
                case DVD_KEY_TYPE.DvdBusKey2:
                    return (uint)(8 + size);
                default:
                    return 0;
            }
        }
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct DVD_COPY_PROTECT_KEY_Parameters
    {
        [FieldOffset(0)]
        public DVD_COPY_PROTECT_KEY_Parameters_Inner Inner;
        [FieldOffset(0)]
        public int TitleOffset;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DVD_COPY_PROTECT_KEY_Parameters_Inner
    {
        public IntPtr FileHandle;
        public uint Reserved;
    }

If i call DeviceIoControl i get an Exception PInvokeStackImbalance, if i use classes instead i get ErrorCode 87 from Marshal.GetLastWin32Error();

Someone any Idea?

Update My DeviceIoControl

[System.Runtime.InteropServices.DllImport("Kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
    public extern static int DeviceIoControl(IntPtr hDevice, uint IoControlCode, ref DVD_COPY_PROTECT_KEY dcpk, uint InBufferSize, ref DVD_COPY_PROTECT_KEY dcpk2, uint OutBufferSize, ref uint BytesReturned, IntPtr Overlapped);

I have add ref keywords now i get with structs no Exception but ErrorCode 87

My Code can be found here

0 Answers0