sl@0: // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test\usb\t_usb_win\src\eject.cpp sl@0: // eject functions sl@0: // sl@0: sl@0: #include "stdafx.h" sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "global.h" sl@0: sl@0: // Prototypes sl@0: extern void PrintOut(BOOL screenFlag, BOOL logFlag, BOOL timeFlag, const char *format, ...); sl@0: sl@0: HANDLE OpenVolume(char driveLetter) sl@0: { sl@0: HANDLE hVolume; sl@0: UINT uDriveType; sl@0: TCHAR szVolumeName[8]; sl@0: TCHAR szRootName[5]; sl@0: TCHAR cDriveLetter = driveLetter; sl@0: sl@0: if (driveLetter == ' ') sl@0: { sl@0: return INVALID_HANDLE_VALUE; sl@0: } sl@0: sl@0: wsprintf(szRootName, "%c:\\", cDriveLetter); sl@0: sl@0: uDriveType = GetDriveType(szRootName); sl@0: if (uDriveType != DRIVE_REMOVABLE) sl@0: { sl@0: return INVALID_HANDLE_VALUE; sl@0: } sl@0: sl@0: wsprintf(szVolumeName, "\\\\.\\%c:", cDriveLetter); sl@0: sl@0: hVolume = CreateFile( szVolumeName, sl@0: GENERIC_READ | GENERIC_WRITE, sl@0: FILE_SHARE_READ | FILE_SHARE_WRITE, sl@0: NULL, sl@0: OPEN_EXISTING, sl@0: 0, sl@0: NULL ); sl@0: sl@0: return hVolume; sl@0: } sl@0: sl@0: #define LOCK_RETRY_DELAY 500 // half a second sl@0: #define LOCK_RETRY_MAX 20 sl@0: sl@0: BOOL LockAndDismout(HANDLE hVolume) sl@0: { sl@0: DWORD dwBytesReturned; sl@0: sl@0: // Retry a number of times sl@0: for (int i = 0; i < LOCK_RETRY_MAX; i++) sl@0: { sl@0: if (DeviceIoControl(hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL)) sl@0: { sl@0: return DeviceIoControl( hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL); sl@0: } sl@0: Sleep (LOCK_RETRY_MAX); sl@0: } sl@0: sl@0: return FALSE; sl@0: } sl@0: sl@0: BOOL AllowRemovalAndEject (HANDLE hVolume) sl@0: { sl@0: DWORD dwBytesReturned; sl@0: PREVENT_MEDIA_REMOVAL PMRBuffer; sl@0: sl@0: PMRBuffer.PreventMediaRemoval = FALSE; sl@0: sl@0: if (DeviceIoControl( hVolume, IOCTL_STORAGE_MEDIA_REMOVAL, &PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL), sl@0: NULL, 0, &dwBytesReturned, NULL)) sl@0: return DeviceIoControl( hVolume, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &dwBytesReturned, NULL); sl@0: sl@0: return FALSE; sl@0: } sl@0: sl@0: sl@0: BOOL EjectVolume(char driveLetter) sl@0: { sl@0: HANDLE hVolume = INVALID_HANDLE_VALUE; sl@0: sl@0: sl@0: hVolume = OpenVolume(driveLetter); sl@0: sl@0: if (hVolume == INVALID_HANDLE_VALUE) sl@0: return FALSE; sl@0: sl@0: // Lock and dismount the volume. sl@0: if (LockAndDismout(hVolume)) sl@0: { sl@0: // Set prevent removal to false and eject the volume. sl@0: AllowRemovalAndEject(hVolume); sl@0: } sl@0: sl@0: // Close the volume so other processes can use the drive. sl@0: if (!CloseHandle(hVolume)) sl@0: return FALSE; sl@0: sl@0: return TRUE; sl@0: } sl@0: sl@0: #define WAIT_RETRIES 500 sl@0: #define WAIT_TIME 250 sl@0: #define WAIT_DELAY 1500 sl@0: sl@0: BOOL WaitDriveReady (char driveLetter) sl@0: { sl@0: UINT uDriveType = DRIVE_UNKNOWN ; sl@0: TCHAR szRootName[5]; sl@0: UINT waitTime = 0; sl@0: sl@0: wsprintf(szRootName, "%c:\\", driveLetter); sl@0: sl@0: for (int i = 0; i < WAIT_RETRIES && (uDriveType != DRIVE_REMOVABLE); i++) sl@0: { sl@0: uDriveType = GetDriveType(szRootName); sl@0: if (uDriveType != DRIVE_REMOVABLE) sl@0: { sl@0: Sleep (WAIT_TIME); sl@0: waitTime += WAIT_TIME; sl@0: } sl@0: else sl@0: { sl@0: Sleep (WAIT_DELAY); sl@0: waitTime += WAIT_DELAY; sl@0: } sl@0: } sl@0: sl@0: sl@0: PRINT_ALWAYS "Drive %c ready after %d milliseconds.\n",driveLetter,waitTime); sl@0: return uDriveType == DRIVE_REMOVABLE; sl@0: }