Enable or Disable “Enable write caching on disk” behavior on disk
Couple of times I got a question to <Enable or Disable “Enable write caching on disk” behavior on disk>, How to do it programmatically on Windows? When I got this question for the first time, it was tough but doing research I was able to solve it and it works well. Every next time, it was easy :)
In this post, I will not discuss what exactly this feature does and pros and cons of enable/disable it. I will only discuss, How to do it.
You can do it manually as well.
#1, Select a volume from Explorer, right click –> Properties
#2, Select “Hardware” tab, select disk and click “Properties” button
#3, Select “Policies” tab.
#4, Check/Uncheck to enable/disable “write caching on the disk”
To do it programmatically.
#1, You will need to work with below APIs and control code.
DISK_CACHE_INFORMATION Structure
IOCTL_DISK_GET_CACHE_INFORMATION Control Code
IOCTL_DISK_SET_CACHE_INFORMATION Control Code
The information is actually gets stored in below registry key, I would not recommend to look for the value in the key directly and design your application on that. It may change in future.
HKLM\SYSTEM\CurrentControlSet\Enum\IDE\Diskxxxxxxxxxxxx\DeviceParameters\Disk
Key : UserWriteCacheSetting
where xxxxxxx is manufacturer information.
The sample will look like below. This is just a test sample and provided only to demonstrate the functionality. You might need to use put more error handling and test the code as you do for regular production environment code.
//////////////////////SAMPLE CODE
///////////////////////////////////////////////////////////
#define _WIN32_WINNT 0x0503
#include <windows.h>
DISK_CACHE_INFORMATION info;
DISK_CACHE_INFORMATION rinfo;
void main(void)
{
DWORD rr;
HANDLE hDevice;
DWORD err;
DWORD returned;
hDevice = CreateFile("\\\\.\\C:", // drive to open
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
// share mode
NULL, // default security attributes
OPEN_EXISTING, // disposition
FILE_ATTRIBUTE_SYSTEM, // file attributes
NULL); // do not copy file attributes
if(hDevice==INVALID_HANDLE_VALUE)
{
return;
}
rr = DeviceIoControl(hDevice,IOCTL_DISK_GET_CACHE_INFORMATION,NULL,
0,(LPVOID)&info,(DWORD)sizeof(info),(LPDWORD)&returned, (LPOVERLAPPED)NULL);
if (!rr)
{
err = GetLastError();
return;
}
info.WriteCacheEnabled = true;
info.ReadCacheEnabled = false;
info.DisablePrefetchTransferLength = 1;
rr = DeviceIoControl(hDevice,IOCTL_DISK_SET_CACHE_INFORMATION,(LPVOID)&info,(DWORD)sizeof(info),
NULL,0,(LPDWORD)&returned,(LPOVERLAPPED)NULL);
if (!rr)
{
err = GetLastError();
return;
}
rr = DeviceIoControl(hDevice,IOCTL_DISK_GET_CACHE_INFORMATION,NULL,0,
(LPVOID)&rinfo,(DWORD)sizeof(rinfo),(LPDWORD)&returned,(LPOVERLAPPED)NULL);
if (!rr)
{
err = GetLastError();
return;
}
CloseHandle(hDevice);
}
//////////////////////SAMPLE CODE
///////////////////////////////////////////////////////////
*Note—Not all disks and controllers implements write disk caching, I have not tested the behavior or any such disk yet, so behavior is unknown to me.
Nitin Dhawan
Windows SDK - Microsoft
Comments
Anonymous
January 26, 2010
This works fine for XP, but starting with Vista and Windows 7, The CreateFile call in this code fails. According to http://support.microsoft.com/kb/942448, there are restrictions on doing a CreatFile on PhysicalDiskX for direct disk access. But that article refers mainly to reading and writing boot sectors and not how to enable IOCTL calls. What is the minimum security way of doing the createfile so that disk caching can be controlled in Windows 7?Anonymous
April 27, 2011
Our system are deployed to our customers without the end user having Admin privileges. Does this code work from a LUA for Windows XP SP3 (WES 2009)?