Force stop/kill/eject usb mass storage device
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 23

Thread: Force stop/kill/eject usb mass storage device

  1. #1
    Join Date
    May 2009
    Posts
    15

    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

  2. #2
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,791

    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.

  3. #3
    Join Date
    May 2009
    Posts
    15

    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.

  4. #4
    Join Date
    May 2009
    Posts
    15

    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 ?

  5. #5
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,791

    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

  6. #6
    Join Date
    May 2009
    Posts
    15

    Question 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.

  7. #7
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,791

    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.

  8. #8
    Join Date
    May 2009
    Posts
    15

    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 ?

  9. #9
    Join Date
    May 2009
    Posts
    4

    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.

  10. #10
    Join Date
    Jul 2001
    Location
    Sunny South Africa
    Posts
    11,090

    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.

  11. #11
    Join Date
    May 2009
    Posts
    15

    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).

  12. #12
    Join Date
    Apr 2009
    Posts
    4

    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

  13. #13
    Join Date
    May 2009
    Posts
    15

    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.

  14. #14
    Join Date
    Jun 2009
    Posts
    7

    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=&#37;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"

  15. #15
    Join Date
    Apr 2009
    Posts
    4

    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

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center