Powered By Blogger
Showing posts with label registry. Show all posts
Showing posts with label registry. Show all posts

If you are experiencing system performance issues in ROM based File systems, here is a nice tweak to boost up the performance. Most of the times, this slowdown will be due to constant registry flushing in to ROM in background.

[HKEY_LOCAL_MACHINE\init\BootVars]
"RegistryFlags"=dword:2
If this variable is set to 1, it will enable aggressive flushing of registry on to ROM. Setting it to 2 will disable background flushing and can improve performance of system significantly.

Reference: http://msdn.microsoft.com/en-us/library/aa914382.aspx

Sunday, September 7, 2008

Making a device "Power-Managed"

Power manager uses IOCTLs to interact with Power-Managed devices. So inorder to make a device power managed implement certain set of IOCTLs in the driver with registry changes.

For the purpose of explaining, i am taking the sample of the Power Button driver implemented in Mainstone platform available in windows ce 6.0. Please bear in mind that this driver is already having a function which monitors system power state transitions using Notification Queues. But I am not going to make use of them.

Here I will briefly describe the steps involved in doing the same. We can divide the changes in to two parts:
  1. Change in registry settings for driver
  2. Implementing IOCTLs

Change in registry settings for driver

Now as the documentation for power manager, each power managed device needs to be classified under a certain category i.e Generic power-manageable devices, Power-manageable block devices and Power-manageable NDIS miniports. Each class is identified by a certain GUID(defined in pm.h). Associating a device to a power manager class is really easy, just by adding a registry entry to the device driver entry, as follows.

I will make this power button driver as a generic device
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\PWB]
"Prefix"="PWB"
"Dll"="mainstoneii_pwrbutton.dll"
"Order"=dword:3
"IClass"="{A32942B7-920C-486b-B0E6-92A702A99B35}" ;; we are making it as generic device over here

When device manager loads the driver, it will associate the device to the class.

Now power manager will start issuing the IOCTLs to the driver and query the capabilities of the driver. The details I will explain in the next section.
Note : We should atleast implement IOCTL_POWER_CAPABILITIES in a driver to make it power managed

Implementing IOCTLs

The driver needs to implement the following IOCTLs for interacting with power manager:
  • IOCTL_POWER_CAPABILITIES **
  • IOCTL_POWER_GET
  • IOCTL_POWER_QUERY *
  • IOCTL_POWER_SET
  • IOCTL_REGISTER_POWER_RELATIONSHIP *
** - This IOCTL is mandatory for the entire thing to work
* - rather optional


When power manager receives a request to register a device driver under a particular device class, it first passes IOCTL_POWER_CAPABILITIES to the driver. If the call returns false, the driver wont be registered otherwise it will be. This IOCTL should return the device capabilities.

BOOL IOControl( ............. )
{

................
case IOCTL_POWER_CAPABILITIES :
if (NULL != pOutBuf)
{
memcpy(pOutBuf, &PWBDrvPowerCaps, sizeof(PWBDrvPowerCaps));
*pdwBytesTransferred = sizeof(PWBDrvPowerCaps);
OutBufLen = sizeof(PWBDrvPowerCaps);
dwErr = ERROR_SUCCESS;
}
else
{
dwErr = ERROR_INVALID_PARAMETER;
}
break; // IOCTL_POWER_CAPABILITIES
...............
if(dwErr != ERROR_SUCCESS) {
bRc = FALSE;
} else {
bRc = TRUE;
}

return bRc;

}


The variable PWBDrvPowerCaps contains the device power capabilities of the driver in a POWER_CAPABILITIES structure.

POWER_CAPABILITIES PWBDrvPowerCaps =
{
DX_MASK(D0) | DX_MASK(D2) | DX_MASK(D3) | DX_MASK(D4),
0,
0,
{
0x00000000, // D0
0x00000000, // D1
0x00000000, // D2
0x00000000, // D3
0x00000000 // D4
},
{
0x00000000, // D0
0x00000000, // D1
0x00000000, // D2
0x00000000, // D3
0x00000000 // D4
},
0
};


For information on the meaning of each parameter please refer MSDN. After returning true from the IOCTL, power manager will register this device under the requested class in registry.

From now on wards, when ever a state change occurs (or is requested) for the device or system, power manager will send the IOCTL_POWER_SET to the driver and the driver can take care of the same.

case IOCTL_POWER_SET:
if ( pOutBuf != NULL )
{
SetPwbPowerState(*(PCEDEVICE_POWER_STATE) pOutBuf);
dwErr = ERROR_SUCCESS;
}
else
dwErr = ERROR_INVALID_PARAMETER;
break; // IOCTL_POWER_SET


In SetPwbPowerState(), you can define the power depending on the paramater.