123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- #include <windows.h>
- #include <stdio.h>
- #include <winioctl.h>
- #define LOCK_TIMEOUT 3000
- #define LOCK_RETRIES 20
- #if 1
- static HANDLE OpenVolume(TCHAR cDriveLetter)
- {
- HANDLE hVolume;
- UINT uDriveType;
- wchar_t szVolumeName[8] = {0};
- wchar_t szRootName[5] = {0};
- DWORD dwAccessFlags = 0;
- cDriveLetter &= ~0x20;
- wsprintf(szRootName, L"%c:\\", cDriveLetter);
- uDriveType = GetDriveType(szRootName);
- switch(uDriveType) {
- case DRIVE_REMOVABLE:
- dwAccessFlags = GENERIC_READ | GENERIC_WRITE;
- break;
- case DRIVE_CDROM:
- dwAccessFlags = GENERIC_READ;
- break;
- default:
- printf("Cannot eject. Drive type is incorrect.\n");
- return INVALID_HANDLE_VALUE;
- }
- wsprintf(szVolumeName, L"\\\\.\\%c:", cDriveLetter);
- hVolume = CreateFile( szVolumeName,
- dwAccessFlags,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL );
- if (hVolume == INVALID_HANDLE_VALUE)
- printf("CreateFile error %d\n", GetLastError());
- return hVolume;
- }
- static BOOL CloseVolume(HANDLE hVolume)
- {
- return CloseHandle(hVolume);
- }
- static BOOL LockVolume(HANDLE hVolume)
- {
- DWORD dwBytesReturned;
- DWORD dwSleepAmount;
- int nTryCount;
- dwSleepAmount = LOCK_TIMEOUT / LOCK_RETRIES;
-
- for (nTryCount = 0; nTryCount < LOCK_RETRIES; nTryCount++) {
- if (DeviceIoControl(hVolume,
- FSCTL_LOCK_VOLUME,
- NULL, 0,
- NULL, 0,
- &dwBytesReturned,
- NULL))
- return TRUE;
- Sleep(dwSleepAmount);
- }
- return FALSE;
- }
- static BOOL DismountVolume(HANDLE hVolume)
- {
- DWORD dwBytesReturned;
- return DeviceIoControl( hVolume,
- FSCTL_DISMOUNT_VOLUME,
- NULL, 0,
- NULL, 0,
- &dwBytesReturned,
- NULL);
- }
- static BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPreventRemoval)
- {
- DWORD dwBytesReturned;
- PREVENT_MEDIA_REMOVAL PMRBuffer;
- PMRBuffer.PreventMediaRemoval = fPreventRemoval;
- return DeviceIoControl( hVolume,
- IOCTL_STORAGE_MEDIA_REMOVAL,
- &PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
- NULL, 0,
- &dwBytesReturned,
- NULL);
- }
- static int AutoEjectVolume(HANDLE hVolume)
- {
- DWORD dwBytesReturned;
- return DeviceIoControl( hVolume,
- IOCTL_STORAGE_EJECT_MEDIA,
- NULL, 0,
- NULL, 0,
- &dwBytesReturned,
- NULL);
- }
- BOOL EjectVolume(TCHAR cDriveLetter)
- {
- HANDLE hVolume;
- BOOL fAutoEject = FALSE;
- hVolume = OpenVolume(cDriveLetter);
- if (hVolume == INVALID_HANDLE_VALUE)
- return FALSE;
-
- if (LockVolume(hVolume) && DismountVolume(hVolume)) {
-
- if (PreventRemovalOfVolume(hVolume, FALSE) && AutoEjectVolume(hVolume))
- fAutoEject = TRUE;
- }
-
- if (!CloseVolume(hVolume))
- return FALSE;
- if (fAutoEject) return TRUE;
- else return FALSE;
- }
- #else
- #include <stdio.h>
- #include <windows.h>
- #include <Setupapi.h>
- #include <winioctl.h>
- #include <winioctl.h>
- #include <cfgmgr32.h>
- #pragma comment(lib, "setupapi.lib")
- static DEVINST GetDrivesDevInstByDeviceNumber(long DeviceNumber, UINT DriveType, const wchar_t* szDosDeviceName)
- {
- bool IsFloppy = (wcsstr(szDosDeviceName, L"\\Floppy") != NULL);
- 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;
- }
-
- HDEVINFO hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
- if (hDevInfo == INVALID_HANDLE_VALUE) {
- return 0;
- }
-
- DWORD dwIndex = 0;
- long res;
- BYTE Buf[1024] = {0};
- 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);
- if ( dwSize!=0 && dwSize<=sizeof(Buf) ) {
- pspdidd->cbSize = sizeof(*pspdidd);
- ZeroMemory(&spdd, sizeof(spdd));
- spdd.cbSize = sizeof(spdd);
- long res = SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, pspdidd, dwSize, &dwSize, &spdd);
- if ( res ) {
-
-
-
-
-
- HANDLE hDrive = CreateFile(pspdidd->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
- if ( hDrive != INVALID_HANDLE_VALUE ) {
-
- 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 ) {
- CloseHandle(hDrive);
- SetupDiDestroyDeviceInfoList(hDevInfo);
- return spdd.DevInst;
- }
- }
- CloseHandle(hDrive);
- }
- }
- }
- dwIndex++;
- }
- SetupDiDestroyDeviceInfoList(hDevInfo);
- return 0;
- }
- BOOL EjectVolume(TCHAR DriveLetter)
- {
- DriveLetter &= ~0x20;
- if ( DriveLetter < 'A' || DriveLetter > 'Z' ) {
- return FALSE;
- }
- wchar_t szRootPath[] = L"X:\\";
- szRootPath[0] = DriveLetter;
- wchar_t szDevicePath[] = L"X:";
- szDevicePath[0] = DriveLetter;
- wchar_t szVolumeAccessPath[] = L"\\\\.\\X:";
- szVolumeAccessPath[4] = DriveLetter;
- long DeviceNumber = -1;
-
- HANDLE hVolume = CreateFileW(szVolumeAccessPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
- if (hVolume == INVALID_HANDLE_VALUE) {
- return FALSE;
- }
-
- 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 FALSE;
- }
-
- UINT DriveType = GetDriveType(szRootPath);
-
- wchar_t szDosDeviceName[MAX_PATH] = {0};
- res = QueryDosDevice(szDevicePath, szDosDeviceName, MAX_PATH);
- if ( !res ) {
- return FALSE;
- }
-
- DEVINST DevInst = GetDrivesDevInstByDeviceNumber(DeviceNumber, DriveType, szDosDeviceName);
- if ( DevInst == 0 ) {
- return FALSE;
- }
- PNP_VETO_TYPE VetoType = PNP_VetoTypeUnknown;
- wchar_t VetoNameW[MAX_PATH] = {0};
- bool bSuccess = false;
-
- DEVINST DevInstParent = 0;
- res = CM_Get_Parent(&DevInstParent, DevInst, 0);
- for ( long tries=1; tries<=3; tries++ ) {
- VetoNameW[0] = 0;
-
-
-
-
- res = CM_Request_Device_EjectW(DevInstParent, &VetoType, VetoNameW, MAX_PATH, 0);
-
- bSuccess = (res==CR_SUCCESS && VetoType==PNP_VetoTypeUnknown);
- if ( bSuccess ) {
- break;
- }
- Sleep(500);
- }
- if ( bSuccess ) {
- printf("Success\n\n");
- return TRUE;
- }
- printf("failed\n");
-
- printf("Result=0x%2X\n", res);
- if ( VetoNameW[0] ) {
- printf("VetoName=%ws)\n\n", VetoNameW);
- }
- return FALSE;
- }
- #endif
|