-
May 19th, 2009, 11:35 AM
#1
Force stop/kill/eject usb mass storage device
Hi,
I am writing a security app that would disable or stop or eject a usb mass storage device if its detected. But so far I can only disable or eject it successfully if its not being used, if a file is opened on that storage device, calling the api to eject or disable the device do not work. I know that windows does this to prevent data corruption but what if its more important for security to kill the device than to prevent data corruption. How do i force stop/kill/eject a usb mass storage device ?
Also in vista, you dont event have to have a file opened on the USB mass storage device, you just need to have it opened in your file explorer and it wont allow you to eject/disable the device.
thanks,
Elman
-
May 19th, 2009, 02:26 PM
#2
Re: Force stop/kill/eject usb mass storage device
I'm pretty certain windows has built in security features in the policies to prevent the use of removable media.
Simplest case... Give them a zero write quota except for their home drive.
-
May 19th, 2009, 06:38 PM
#3
Re: Force stop/kill/eject usb mass storage device
How do I implement this zero write quota ? Would this effectively prevent access both read/write on the USB mass storage device ?
as I understand it, this will only limit write access to the mass storage device but still allows read access. Which could be bad especially if you dont want malicious software/virus copied from the removable device and installed on your system.
-
May 19th, 2009, 06:57 PM
#4
Re: Force stop/kill/eject usb mass storage device
Also would this affect already opened devices ?
I know that setting the group policy to prevent the use of mass storage devices works only as long as the device was not in used when the policy was enforced. But if a device was being used when the policy was applied, a reboot will be necessary or the device will need to be unplugged and replugged for the group policy to be applied.
So I was wondering if there is a way to force stop/kill/eject a usb mass storage device when its in use. I know when I reboot/shutdown the computer, windows seems to know how to shut down the device and eject it, there must be a way to kill the device short of rebooting windows ?
-
May 20th, 2009, 03:35 PM
#5
Re: Force stop/kill/eject usb mass storage device
Discussing how to set up and organise security policies in windows isn't really the topic for a programmers forum
You may want to go check out forums dealing with this very subject... I'd be highly surprised if features to block external devices aren't built into the OS. But I'm not that up to spec with the latest in security
-
May 21st, 2009, 11:34 AM
#6
Re: Force stop/kill/eject usb mass storage device
Sorry, I guess I was misunderstood, I do not want to set up and organize windows policy on blocking usb mass storage devices.
My question is how to programmatically force kill/stop/eject a usb mass storage thats in use in VC++.
what I have tried:
- I programmatically disabled the device by changing its state to disabled, unfortunately, if the device is in use, it will change the device state to disabled and return that the change state to disable was successful in the api, however the device will still be functional, a reboot is required for it to be disabled.
- I programmatically eject the device, the api returns fail if the device is in use
- I programmatically change the registry to how the group policy OReubens was talking about in order to disallow usb mass storage device. again If the device is in used when I made the change, it will not kill/eject/stop the device. A reboot is required for it to get blocked.
- I have tried all 3 above together and differing combinations, but no luck
if anyone has any insight, I just want to force kill a USB mass storage device so that it wont be accessible. The app I have right now only works at blocking USB devices if it hasn't been plugged in yet but if a device is being used, there is no way I can force kill it Any help would be kindly appreciated.
-
May 23rd, 2009, 07:40 PM
#7
Re: Force stop/kill/eject usb mass storage device
Well... things aren't as easy. There's the whole "sharing" thing going on afterall...
If your VC program is the one and only programm accessing the USB... then ejecting it should be easy enough and you can do that with this.
If however the USB is accessed by other programs... you cannot safely remove it and windows will not allow you to eject it programmatically. you can manuall yank the usb device out of the port, but that could very well leave the data corrupt, and may crash the other applications.
-
May 25th, 2009, 12:10 PM
#8
Re: Force stop/kill/eject usb mass storage device
Thanks for your thoughts OReubens.
However I am already using that eject api and another eject api not for scsi devices. Both returns that it could not eject the device since its in used.
Anyone else have a solution to my problem ?
how to programmatically force kill/stop/eject a usb mass storage thats in use by other apps ?
any usb mass storage device guru out there ?
if not in xp maybe in vista ?
-
May 26th, 2009, 08:18 AM
#9
Re: Force stop/kill/eject usb mass storage device
If you can't find a direct way of doing this you can try the same approach used by unlocker i.e finding which processes have locked the drive and unlocking/killing them.
Or if you're into reverse engineering try reversing Starforce Nightmare. That program can even disconnect your main hard drive while windows is running Almost screwed my HDD once.
-
May 26th, 2009, 08:57 AM
#10
Re: Force stop/kill/eject usb mass storage device
I have one question ( and this is all I care to say / ask ) :
Why on earth do you want to do this elmanl ¿
I can't see any reason for doing this properly.
-
May 27th, 2009, 12:59 PM
#11
Re: Force stop/kill/eject usb mass storage device
HanneSThEGreaT,
I am currently working at a security software project, one of the minor capabilities is to prevent access to USB mass storage devices. I can easily block USB mass storage devices from being used, or if its plugged in but not being used, I can also block that. However if a device is already being used when the server administrator sets the command to block all USB devices, I am not able to secure the client machines from possible security breaches. Thus I am looking for a way to somehow kill/eject/stop a USB mass storage device irregardless of data loss or corruption since in this scenario, the security of the client machine is critical vs the consequence of data corruption/loss on the USB mass storage device (hostile device).
-
June 5th, 2009, 12:34 AM
#12
Re: Force stop/kill/eject usb mass storage device
hi Elman,
Did u get any solution for this?
I am also having same problem. I have not got any solution but here is alink which can be of your help.
http://social.msdn.microsoft.com/For...e-79ec5f927eb3
-
June 10th, 2009, 03:39 PM
#13
Re: Force stop/kill/eject usb mass storage device
thanks vipink85,
I looked at the thread, and I tried setting the surprise removal flag before I eject the USB mass storage device, still no luck. As long as the usb is being accessed ie a file is open or being copied, you cannot eject/stop the usb device.
There has to be a way to force kill or stop a usb device. Does not matter if the data in the USB device gets corrupted. Heck I am considering formating the offending usb device.
-
June 10th, 2009, 03:57 PM
#14
Re: Force stop/kill/eject usb mass storage device
try this code
you'll have to use WinDDK
and link to setupapi.lib
worked for me
if you want i can send you a link to the project
USBFixedDiskSafeRemoval.h
Code:
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the USBFIXEDDISKSAFEREMOVAL_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// USBFIXEDDISKSAFEREMOVAL_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef USBFIXEDDISKSAFEREMOVAL_EXPORTS
#define USBFIXEDDISKSAFEREMOVAL_API __declspec(dllexport)
#else
#define USBFIXEDDISKSAFEREMOVAL_API __declspec(dllimport)
#endif
// This class is exported from the USBFixedDiskSafeRemoval.dll
class USBFIXEDDISKSAFEREMOVAL_API CUSBFixedDiskSafeRemoval {
public:
CUSBFixedDiskSafeRemoval(void);
// TODO: add your methods here.
};
extern USBFIXEDDISKSAFEREMOVAL_API int nUSBFixedDiskSafeRemoval;
USBFIXEDDISKSAFEREMOVAL_API int fnUSBFixedDiskSafeRemoval(char cDriveLetter);
USBFixedDiskSafeRemoval.cpp
Code:
// USBFixedDiskSafeRemoval.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "USBFixedDiskSafeRemoval.h"
#include <winioctl.h>
#include <Setupapi.h>
#include <stdio.h>
#include <cfgmgr32.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// This is an example of an exported variable
USBFIXEDDISKSAFEREMOVAL_API int nUSBFixedDiskSafeRemoval=0;
DEVINST GetDrivesDevInstByDeviceNumber(long DeviceNumber, UINT DriveType, char* szDosDeviceName)
{
bool IsFloppy = (strstr(szDosDeviceName, "\\Floppy") != NULL); // who knows a better way?
GUID* guid;
switch (DriveType) {
case DRIVE_REMOVABLE:
if ( IsFloppy ) {
guid = (GUID*)&GUID_DEVINTERFACE_FLOPPY;
} else {
guid = (GUID*)&GUID_DEVINTERFACE_DISK;
}
break;
case DRIVE_FIXED:
guid = (GUID*)&GUID_DEVINTERFACE_DISK;
break;
case DRIVE_CDROM:
guid = (GUID*)&GUID_DEVINTERFACE_CDROM;
break;
default:
return 0;
}
// Get device interface info set handle for all devices attached to system
HDEVINFO hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDevInfo == INVALID_HANDLE_VALUE) {
return 0;
}
// Retrieve a context structure for a device interface of a device information set
DWORD dwIndex = 0;
long res;
BYTE Buf[1024];
PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;
SP_DEVICE_INTERFACE_DATA spdid;
SP_DEVINFO_DATA spdd;
DWORD dwSize;
spdid.cbSize = sizeof(spdid);
while ( true ) {
res = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guid, dwIndex, &spdid);
if ( !res ) {
break;
}
dwSize = 0;
SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, NULL, 0, &dwSize, NULL); // check the buffer size
if ( dwSize!=0 && dwSize<=sizeof(Buf) ) {
pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!
ZeroMemory(&spdd, sizeof(spdd));
spdd.cbSize = sizeof(spdd);
long res = SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, pspdidd, dwSize, &dwSize, &spdd);
if ( res ) {
// in case you are interested in the USB serial number:
// the device id string contains the serial number if the device has one,
// otherwise a generated id that contains the '&' char...
/*
DEVINST DevInstParent = 0;
CM_Get_Parent(&DevInstParent, spdd.DevInst, 0);
char szDeviceIdString[MAX_PATH];
CM_Get_Device_ID(DevInstParent, szDeviceIdString, MAX_PATH, 0);
printf("DeviceId=%s\n", szDeviceIdString);
*/
// open the disk or cdrom or floppy
HANDLE hDrive = CreateFile(pspdidd->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if ( hDrive != INVALID_HANDLE_VALUE ) {
// get its device number
STORAGE_DEVICE_NUMBER sdn;
DWORD dwBytesReturned = 0;
res = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dwBytesReturned, NULL);
if ( res ) {
if ( DeviceNumber == (long)sdn.DeviceNumber ) { // match the given device number with the one of the current device
CloseHandle(hDrive);
SetupDiDestroyDeviceInfoList(hDevInfo);
return spdd.DevInst;
}
}
CloseHandle(hDrive);
}
}
}
dwIndex++;
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return 0;
}
// This is an example of an exported function.
USBFIXEDDISKSAFEREMOVAL_API int fnUSBFixedDiskSafeRemoval(char cDriveLetter)
{
cDriveLetter &= ~0x20; // uppercase
if ( cDriveLetter < 'A' || cDriveLetter > 'Z' ) {
return 1;
}
char szRootPath[] = "X:\\"; // "X:\" -> for GetDriveType
szRootPath[0] = cDriveLetter;
char szDevicePath[] = "X:"; // "X:" -> for QueryDosDevice
szDevicePath[0] = cDriveLetter;
char szVolumeAccessPath[] = "\\\\.\\X:"; // "\\.\X:" -> to open the volume
szVolumeAccessPath[4] = cDriveLetter;
long DeviceNumber = -1;
// open the storage volume
HANDLE hVolume = CreateFile(szVolumeAccessPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
if (hVolume == INVALID_HANDLE_VALUE) {
return 1;
}
// get the volume's device number
STORAGE_DEVICE_NUMBER sdn;
DWORD dwBytesReturned = 0;
long res = DeviceIoControl(hVolume, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dwBytesReturned, NULL);
if ( res ) {
DeviceNumber = sdn.DeviceNumber;
}
CloseHandle(hVolume);
if ( DeviceNumber == -1 ) {
return 1;
}
// get the drive type which is required to match the device numbers correctely
UINT DriveType = GetDriveType(szRootPath);
// get the dos device name (like \device\floppy0) to decide if it's a floppy or not - who knows a better way?
char szDosDeviceName[MAX_PATH];
res = QueryDosDevice(szDevicePath, szDosDeviceName, MAX_PATH);
if ( !res ) {
return 1;
}
// get the device instance handle of the storage volume by means of a SetupDi enum and matching the device number
DEVINST DevInst = GetDrivesDevInstByDeviceNumber(DeviceNumber, DriveType, szDosDeviceName);
if ( DevInst == 0 ) {
return 1;
}
PNP_VETO_TYPE VetoType = PNP_VetoTypeUnknown;
WCHAR VetoNameW[MAX_PATH];
VetoNameW[0] = 0;
bool bSuccess = false;
// get drives's parent, e.g. the USB bridge, the SATA port, an IDE channel with two drives!
DEVINST DevInstParent = 0;
res = CM_Get_Parent(&DevInstParent, DevInst, 0);
for ( long tries=1; tries<=3; tries++ ) { // sometimes we need some tries...
VetoNameW[0] = 0;
// CM_Query_And_Remove_SubTree doesn't work for restricted users
//res = CM_Query_And_Remove_SubTreeW(DevInstParent, &VetoType, VetoNameW, MAX_PATH, CM_REMOVE_NO_RESTART); // CM_Query_And_Remove_SubTreeA is not implemented under W2K!
//res = CM_Query_And_Remove_SubTreeW(DevInstParent, NULL, NULL, 0, CM_REMOVE_NO_RESTART); // with messagebox (W2K, Vista) or balloon (XP)
res = CM_Request_Device_EjectW(DevInstParent, &VetoType, VetoNameW, MAX_PATH, 0);
//res = CM_Request_Device_EjectW(DevInstParent, NULL, NULL, 0, 0); // with messagebox (W2K, Vista) or balloon (XP)
bSuccess = (res==CR_SUCCESS && VetoType==PNP_VetoTypeUnknown);
if ( bSuccess ) {
break;
}
Sleep(500); // required to give the next tries a chance!
}
if ( bSuccess ) {
printf("Success\n\n");
return 1;
}
printf("failed\n");
printf("Result=0x%2X\n", res);
if ( VetoNameW[0] ) {
printf("VetoName=%ws)\n\n", VetoNameW);
}
return 0;
}
// This is the constructor of a class that has been exported.
// see USBFixedDiskSafeRemoval.h for the class definition
CUSBFixedDiskSafeRemoval::CUSBFixedDiskSafeRemoval()
{
return;
}
"Use The source Luke"
-
June 11th, 2009, 04:07 AM
#15
Re: Force stop/kill/eject usb mass storage device
Thanks Karpatuz,
I executed the code but it does not seem to work. The USB is rejected if no process are running.
If you open a txt file in notepad from the USB then this will code fail. But I want it to eject even if any file open.
Regards,
Vipin
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|