Wrapping DeviceIoControl() for IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNES

G

Guest

I'm trying to write a wrapper in csharp to wrap DeviceIoControl() win32
method for IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS control code--without much
luck.

I've seen lots of examples out there for low-level file access but can't
seem to any for the display. Can you provide some samples of how I might do
this?

Below is my code thus far...

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace PowerManagementTest
{
[StructLayout(LayoutKind.Sequential)]
internal struct DISPLAY_BRIGHTNESS
{
public byte DisplayPolicy; // 0x00000001 Value can be DISPLAYPOLICY_AC or
DISPLAYPOLICY_DC or DISPLAYPOLICY_BOTH
public byte ACBrightness; // 0x00000002
public byte DCBrightness; // 0x00000001 | 0x00000002
}

/// <summary>
/// Constants lifted from winioctl.h from Platform SDK.
/// </summary>
internal class WinIoCtlConstants
{
const uint FILE_DEVICE_FILE_SYSTEM = 0x00000009;
const uint FILE_DEVICE_VIDEO = 0x00000023;

const uint FILE_ANY_ACCESS = 0;
const uint FILE_SPECIAL_ACCESS = FILE_ANY_ACCESS;

const uint METHOD_BUFFERED = 0;
const uint METHOD_NEITHER = 3;

public static uint FSCTL_GET_VOLUME_BITMAP =
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 27, METHOD_NEITHER, FILE_ANY_ACCESS);
public static uint FSCTL_GET_RETRIEVAL_POINTERS =
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 28, METHOD_NEITHER, FILE_ANY_ACCESS);
public static uint FSCTL_MOVE_FILE = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 29,
METHOD_BUFFERED, FILE_SPECIAL_ACCESS);

public static uint IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS =
CTL_CODE(FILE_DEVICE_VIDEO, 293, METHOD_BUFFERED, FILE_ANY_ACCESS);
public static uint IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS =
CTL_CODE(FILE_DEVICE_VIDEO, 294, METHOD_BUFFERED, FILE_ANY_ACCESS);
public static uint IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS =
CTL_CODE(FILE_DEVICE_VIDEO, 295, METHOD_BUFFERED, FILE_ANY_ACCESS);

static uint CTL_CODE(uint DeviceType, uint Function, uint Method, uint
Access)
{
return ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) |
(Method);
}
}

class WinIoCtl
{
// Constants.
const uint FILE_SHARE_READ = 0x00000001;
const uint FILE_SHARE_WRITE = 0x00000002;
const uint FILE_SHARE_DELETE = 0x00000004;
const uint OPEN_EXISTING = 3;

const uint GENERIC_READ = (0x80000000);
const uint GENERIC_WRITE = (0x40000000);

const uint FILE_FLAG_NO_BUFFERING = 0x20000000;
const uint FILE_READ_ATTRIBUTES = (0x0080);
const uint FILE_WRITE_ATTRIBUTES = 0x0100;
const uint ERROR_INSUFFICIENT_BUFFER = 122;

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
IntPtr lpInBuffer,
uint nInBufferSize,
[Out] IntPtr lpOutBuffer,
uint nOutBufferSize,
ref uint lpBytesReturned,
IntPtr lpOverlapped);

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile);

[DllImport("kernel32.dll", SetLastError = true)]
static extern int CloseHandle(IntPtr hObject);

static private IntPtr OpenVolume(string DeviceName)
{
IntPtr hDevice;
hDevice = CreateFile(
@"\\.\" + DeviceName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
0,
IntPtr.Zero);
if ((int)hDevice == -1)
{
throw new Exception(Marshal.GetLastWin32Error().ToString());
}
return hDevice;
}


static private IntPtr OpenFile(string path)
{
IntPtr hFile;
hFile = CreateFile(
path,
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
0,
IntPtr.Zero);
if ((int)hFile == -1)
{
throw new Exception(Marshal.GetLastWin32Error().ToString());
}
return hFile;
}

static private IntPtr OpenLcdDevice()
{
IntPtr hDevice;
hDevice = CreateFile(
@"\\.\LCD",
GENERIC_READ,
FILE_SHARE_READ,
IntPtr.Zero,
OPEN_EXISTING,
0,
IntPtr.Zero);
if ((int)hDevice == -1)
{
Debug.WriteLine("OpenLCD Win32 Error: " +
Marshal.GetLastWin32Error().ToString());
throw new Exception(Marshal.GetLastWin32Error().ToString());
}
return hDevice;
}

static public void QueryDisplayBrightness()
{
IntPtr hDevice = IntPtr.Zero;

// Allocate memory for the Display Brightness structure.
Type structType = typeof(DISPLAY_BRIGHTNESS);
int structSize = Marshal.SizeOf(structType);
IntPtr pDisplayBrightness = Marshal.AllocHGlobal(structSize);

DISPLAY_BRIGHTNESS brightness;
brightness =
(DISPLAY_BRIGHTNESS)Marshal.PtrToStructure((IntPtr)pDisplayBrightness,
structType);
// brightness.DisplayPolicy = Convert.ToByte(1);

try
{
hDevice = OpenLcdDevice();

Int64 i64 = 0;

uint outputBufferSize = Convert.ToUInt32(structSize);
uint bytesReturned = 0;

bool fResult = DeviceIoControl(
hDevice,
WinIoCtlConstants.IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS,
IntPtr.Zero, // Set to NULL.
(uint)Marshal.SizeOf(i64), // Set to zero.
pDisplayBrightness, // Pointer to a buffer that receives the
DISPLAY_BRIGHTNESS structure.
outputBufferSize,
ref bytesReturned,
IntPtr.Zero);

Debug.WriteLine("Bytes returned: " + bytesReturned.ToString());

if (!fResult)
{
Debug.WriteLine("WIN32 Error: " +
Marshal.GetLastWin32Error().ToString(), "QueryDisplayBrightness");
throw new Exception(Marshal.GetLastWin32Error().ToString());
}

int resultAddress = (int)pDisplayBrightness;
brightness =
(DISPLAY_BRIGHTNESS)Marshal.PtrToStructure((IntPtr)resultAddress, structType);

Debug.WriteLine("AC Brightness: " + brightness.ACBrightness.ToString());
Debug.WriteLine("DC Brightness: " + brightness.DCBrightness.ToString());

}
catch(Exception ex)
{
Debug.WriteLine(ex.ToString());
}
finally
{
CloseHandle(hDevice);
hDevice = IntPtr.Zero;

Marshal.FreeHGlobal(pDisplayBrightness);
pDisplayBrightness = IntPtr.Zero;
}
}

static public void QuerySupportedBrightness()
{
IntPtr pAlloc = IntPtr.Zero;
IntPtr hDevice = IntPtr.Zero;

try
{
// Get a handle to the device.
hDevice = OpenLcdDevice();

Int64 i64 = 0;

// Create storage area in memory and get a handle to it.
pAlloc = Marshal.AllocHGlobal((int)512);
IntPtr pDest = pAlloc;

uint outputBufferSize = 512;
uint bytesReturned = 0;

bool fResult = DeviceIoControl(
hDevice,
WinIoCtlConstants.IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS,
IntPtr.Zero, // Set to NULL.
(uint)Marshal.SizeOf(i64), // Set to zero.
pDest, // Pointer to a buffer that receives an array of available
power levels.
outputBufferSize,
ref bytesReturned,
IntPtr.Zero);

Debug.WriteLine("Bytes returned: " + bytesReturned.ToString());
Debug.WriteLine("WIN32 Error: " +
Marshal.GetLastWin32Error().ToString(), "QuerySupportedBrightness");

if (!fResult)
{
Debug.WriteLine("WIN32 Error: " +
Marshal.GetLastWin32Error().ToString(), "QuerySupportedBrightness");
throw new Exception(Marshal.GetLastWin32Error().ToString());
}

Int64 StartingLcn = (Int64)Marshal.PtrToStructure(pDest, typeof(Int64));
}
catch(Exception ex)
{
Debug.WriteLine(ex.ToString());
}
finally
{
CloseHandle(hDevice);
hDevice = IntPtr.Zero;

Marshal.FreeHGlobal(pAlloc);
pAlloc = IntPtr.Zero;
}
}

[DllImport("kernel32.dll")]
public static extern IntPtr CreateFile(
string lpFileName, int dwDesiredAccess, int dwShareMode,
IntPtr lpSecurityAttributes, int dwCreationDisposition,
int dwFlagsAndAttributes, IntPtr hTemplateFile );

private const int INVALID_HANDLE_VALUE = -1;

// The DeviceIoControl Win32 function.
[DllImport("kernel32.dll", ExactSpelling=true) ]
internal static extern bool DeviceIoControl(
IntPtr hDevice, int dwIoControlCode, IntPtr lpInBuffer, int nInBufferSize,
IntPtr lpOutBuffer, int nOutBufferSize, ref int lpBytesReturned, IntPtr
lpOverlapped );


}
}
 

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

Top