In this, I've tried to lock a physical disk using a small Windows C++ program. The steps to follow to achieve this are:
1. Get the Physical Drive and volume mapping. Say, the computer is attached with three physical drives, and we're interested to lock the Physical Drive 1 ("\\\\.\\PhysicalDrive1"). Then we need to figure out how many volumes are there on that physical disk.
2. Then Lock that volume one by one using control code FSCTL_LOCK_VOLUME.
3. Do the stuff we'd like to perform on the disk and then unlock each volume using control code FSCTL_UNLOCK_VOLUME.
4. Close disk and volume handle(s).
Few things to remember here. As per Microsoft documentation,
a. The NTFS file system treats a locked volume as a dismounted volume.
b. Lock volume call will fail with Access Code 5 (Access Denied) if the volume is in use. If we're not sure who's using the volume, just unmount it once.
c. The FSCTL_DISMOUNT_VOLUME control code functions similarly but does not check for open files before dismounting.
d. The operating system tries to mount an unmounted disk as soon as an attempt is made to access it. So, a call to GetLogicalDrives API will trigger the operating system to mount the disk.
Note: Since this deals with disk locks, please use it wisely.
Here is the code snippet, I tried to lock the drive here which has only one volume (J:).
void LockDisk()
{
HANDLE hDisk_Device = NULL;
HANDLE hDisk_Drive = NULL;
DWORD returnedLength;
// Open the drive(s) associated with this disk and lock.
hDisk_Drive = CreateFile(
L"\\\\.\\J:", // device interface name
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
NULL, // lpSecurityAttributes
OPEN_EXISTING, // dwCreationDistribution
0, // dwFlagsAndAttributes
NULL // hTemplateFile
);
if(hDisk_Drive != INVALID_HANDLE_VALUE)
{
BOOL status;
status = DeviceIoControl( hDisk_Drive, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &returnedLength, NULL );
if ( !status )
{
wprintf(L"IOCTL failed with error code: %d.\n\n", GetLastError() );
}
else
{
wprintf(L"IOCTL success, volume locked\n\n");
status = DeviceIoControl( hDisk_Drive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &returnedLength, NULL );
if( !status)
wprintf(L"IOCTL failed with error code: %d.\n\n", GetLastError() );
CloseHandle(hDisk_Drive);
}
}
}
We can test this piece of code by using debug breakpoint to see if it really works. I've used Windows 7 (x64).
On successful lock, if we try to access the drive from Windows Explorer, we'll get the following error:
1. Get the Physical Drive and volume mapping. Say, the computer is attached with three physical drives, and we're interested to lock the Physical Drive 1 ("\\\\.\\PhysicalDrive1"). Then we need to figure out how many volumes are there on that physical disk.
2. Then Lock that volume one by one using control code FSCTL_LOCK_VOLUME.
3. Do the stuff we'd like to perform on the disk and then unlock each volume using control code FSCTL_UNLOCK_VOLUME.
4. Close disk and volume handle(s).
Few things to remember here. As per Microsoft documentation,
a. The NTFS file system treats a locked volume as a dismounted volume.
b. Lock volume call will fail with Access Code 5 (Access Denied) if the volume is in use. If we're not sure who's using the volume, just unmount it once.
c. The FSCTL_DISMOUNT_VOLUME control code functions similarly but does not check for open files before dismounting.
d. The operating system tries to mount an unmounted disk as soon as an attempt is made to access it. So, a call to GetLogicalDrives API will trigger the operating system to mount the disk.
Note: Since this deals with disk locks, please use it wisely.
Here is the code snippet, I tried to lock the drive here which has only one volume (J:).
void LockDisk()
{
HANDLE hDisk_Device = NULL;
HANDLE hDisk_Drive = NULL;
DWORD returnedLength;
// Open the drive(s) associated with this disk and lock.
hDisk_Drive = CreateFile(
L"\\\\.\\J:", // device interface name
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
NULL, // lpSecurityAttributes
OPEN_EXISTING, // dwCreationDistribution
0, // dwFlagsAndAttributes
NULL // hTemplateFile
);
if(hDisk_Drive != INVALID_HANDLE_VALUE)
{
BOOL status;
status = DeviceIoControl( hDisk_Drive, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &returnedLength, NULL );
if ( !status )
{
wprintf(L"IOCTL failed with error code: %d.\n\n", GetLastError() );
}
else
{
wprintf(L"IOCTL success, volume locked\n\n");
status = DeviceIoControl( hDisk_Drive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &returnedLength, NULL );
if( !status)
wprintf(L"IOCTL failed with error code: %d.\n\n", GetLastError() );
CloseHandle(hDisk_Drive);
}
}
}
We can test this piece of code by using debug breakpoint to see if it really works. I've used Windows 7 (x64).
On successful lock, if we try to access the drive from Windows Explorer, we'll get the following error:
Comments