0

just started with my first steps using the WinAPI calling functions.

So here is the Code:

public enum EMethod : uint
    {
        Buffered = 0,
        InDirect = 1,
        OutDirect = 2,
        Neither = 3
    }

    [Flags]
    public enum EFileDevice : uint
    {
        CDRom = 0x00000002,
        Disk = 0x00000007,
        VirtualDisk = 0x00000024
    }
    [Flags]
    public enum EIOControlCode : uint
    {
        DiskGetDriveGeometry = (EFileDevice.Disk << 16) | (0x0000 << 2) | EMethod.Buffered | (0 << 14),
        DiskGetDriveGeometryEx = (EFileDevice.Disk << 16) | (0x0028 << 2) | EMethod.Buffered | (0 << 14),
        DiskGetPartitionInfo = (EFileDevice.Disk << 16) | (0x0001 << 2) | EMethod.Buffered | (FileAccess.Read << 14),
        DiskGetPartitionInfoEx = (EFileDevice.Disk << 16) | (0x0012 << 2) | EMethod.Buffered | (0 << 14),
        DiskSetPartitionInfo = (EFileDevice.Disk << 16) | (0x0002 << 2) | EMethod.Buffered | (FileAccess.ReadWrite << 14),
        DiskPerformance = (EFileDevice.Disk << 16) | (0x0008 << 2) | EMethod.Buffered | (0 << 14),
        DiskIsWritable = (EFileDevice.Disk << 16) | (0x0009 << 2) | EMethod.Buffered | (0 << 14),
        DiskControllerNumber = (EFileDevice.Disk << 16) | (0x0011 << 2) | EMethod.Buffered | (0 << 14),
        DiskUpdateDriveSize = (EFileDevice.Disk << 16) | (0x0032 << 2) | EMethod.Buffered | (FileAccess.ReadWrite << 14),
        DiskGrowPartition = (EFileDevice.Disk << 16) | (0x0034 << 2) | EMethod.Buffered | (FileAccess.ReadWrite << 14),
        DiskFindNewDevices = (EFileDevice.Disk << 16) | (0x0206 << 2) | EMethod.Buffered | (FileAccess.Read << 14),
        DiskCreateDisk = (EFileDevice.Disk << 16) | (0x0016 << 2) | EMethod.Buffered | (FileAccess.ReadWrite << 14),
        DiskGetLengthInfo = (EFileDevice.Disk << 16) | (0x0017 << 2) | EMethod.Buffered | (FileAccess.Read << 14)
    }
    [DllImport("Kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)]
    public static extern bool DeviceIoControl(
    SafeFileHandle hDevice,
    EIOControlCode IoControlCode,
    [MarshalAs(UnmanagedType.AsAny)]
    [In] object InBuffer,
    uint nInBufferSize,
    [MarshalAs(UnmanagedType.AsAny)]
    [Out] object OutBuffer,
    uint nOutBufferSize,
    ref uint pBytesReturned,
    [In] IntPtr Overlapped
    );
    [DllImport("Kernel32.dll", SetLastError = true)]
    static extern Microsoft.Win32.SafeHandles.SafeFileHandle CreateFile(string filename, [MarshalAs(UnmanagedType.U4)]FileAccess fileaccess, [MarshalAs(UnmanagedType.U4)]FileShare fileshare, int securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode creationdisposition, int flags, IntPtr template);

Calling the functions here:

                int size = 600;
                uint usize = 600;
                uint bRet = 0;


                IntPtr p = Marshal.AllocHGlobal(size);

                var safeFileHandle = CreateFile("\\\\.\\C", FileAccess.ReadWrite, FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero);
                DeviceIoControl(safeFileHandle, EIOControlCode.DiskGetPartitionInfo, IntPtr.Zero, 0, p, usize,ref bRet,  IntPtr.Zero);

Why is bRet returning 0 ?

Shouldn't be bRet filled with the data from the Execution ?

What am i doing wrong ?

If i log this to the Console, bRet still showing 0.

The SafeFileHandler is pointing to the C Drive (i hope this is correct).

My Main Goal is to achive data from the function, that i can use for future operations.

Glowhollow
  • 132
  • 3
  • 13
  • There are many things that can go wrong here. The interop could be wrong, or you could be passing invalid args to the function. It's hard for you to work out which it is. So start by writing a C++ program that does what you need. Then you will know what the required arguments are, without having to worry about whether you translated the header correctly or not. Only then, when you have working template, consider writing the C# code that is your ultimate goal. – David Heffernan Jul 12 '18 at 09:52
  • DeviceIoControl() is surely about the trickiest pinvoke you could tackle, it is like learning how to swim by jumping into the deep end. Using *object* for the buffers just doesn't do what you hope it does. And it is always very, very important to provide good diagnostics when the call failed, take advantage of SetLastError=true and immediately throw a Win32Exception when you get 0 back. Now you know what it failed. Find a better way to tackle DeviceIoControl in [this post](https://stackoverflow.com/a/17354960/17034). – Hans Passant Jul 12 '18 at 10:09

0 Answers0