os/kernelhwsrv/kerneltest/e32test/usb/t_usb_win/src/eject.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test\usb\t_usb_win\src\eject.cpp
    15 // eject functions
    16 //
    17 
    18 #include "stdafx.h"
    19 #include <windows.h>
    20 #include <winioctl.h>
    21 #include <tchar.h>
    22 #include <stdio.h>
    23 #include "global.h"
    24 
    25 // Prototypes
    26 extern void PrintOut(BOOL screenFlag, BOOL logFlag, BOOL timeFlag, const char *format, ...);
    27 
    28 HANDLE OpenVolume(char driveLetter)
    29 {
    30     HANDLE hVolume;
    31     UINT uDriveType;
    32     TCHAR szVolumeName[8];
    33     TCHAR szRootName[5];
    34  	TCHAR cDriveLetter = driveLetter;
    35 	
    36 	if (driveLetter == ' ')
    37 	{
    38 		return INVALID_HANDLE_VALUE;
    39 	}
    40 
    41     wsprintf(szRootName, "%c:\\", cDriveLetter);
    42 
    43     uDriveType = GetDriveType(szRootName);
    44     if (uDriveType != DRIVE_REMOVABLE)
    45 	{
    46         return INVALID_HANDLE_VALUE;
    47     }
    48 
    49     wsprintf(szVolumeName, "\\\\.\\%c:", cDriveLetter);
    50 
    51     hVolume = CreateFile(   szVolumeName,
    52                             GENERIC_READ | GENERIC_WRITE,
    53                             FILE_SHARE_READ | FILE_SHARE_WRITE,
    54                             NULL,
    55                             OPEN_EXISTING,
    56                             0,
    57                             NULL );
    58     
    59     return hVolume;
    60 }
    61 
    62 #define LOCK_RETRY_DELAY	500       // half a second
    63 #define LOCK_RETRY_MAX		20
    64 
    65 BOOL LockAndDismout(HANDLE hVolume)
    66 {
    67    DWORD dwBytesReturned;
    68 
    69    // Retry a number of times
    70    for (int i = 0; i < LOCK_RETRY_MAX; i++)
    71    {
    72        if (DeviceIoControl(hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL))
    73 			{
    74 			return DeviceIoControl( hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
    75 			}
    76        Sleep (LOCK_RETRY_MAX);
    77    }
    78 
    79    return FALSE;
    80 }
    81 
    82 BOOL AllowRemovalAndEject (HANDLE hVolume)
    83 {
    84     DWORD dwBytesReturned;
    85     PREVENT_MEDIA_REMOVAL PMRBuffer;
    86 
    87     PMRBuffer.PreventMediaRemoval = FALSE;
    88 
    89     if (DeviceIoControl( hVolume, IOCTL_STORAGE_MEDIA_REMOVAL, &PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
    90                             NULL, 0, &dwBytesReturned, NULL))
    91 	    return DeviceIoControl( hVolume, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
    92 
    93 	return FALSE;   
    94 }
    95 
    96 
    97 BOOL EjectVolume(char driveLetter)
    98 {
    99     HANDLE hVolume = INVALID_HANDLE_VALUE;
   100 
   101 
   102 	hVolume = OpenVolume(driveLetter);
   103 
   104 	if (hVolume == INVALID_HANDLE_VALUE)
   105 		return FALSE;
   106 
   107     // Lock and dismount the volume.
   108     if (LockAndDismout(hVolume))
   109 		{
   110         // Set prevent removal to false and eject the volume.
   111         AllowRemovalAndEject(hVolume);
   112 		}
   113 
   114     // Close the volume so other processes can use the drive.
   115     if (!CloseHandle(hVolume))
   116         return FALSE;
   117 
   118     return TRUE;
   119 }
   120 
   121 #define WAIT_RETRIES 500
   122 #define WAIT_TIME 250
   123 #define WAIT_DELAY 1500
   124 
   125 BOOL WaitDriveReady (char driveLetter)
   126 {
   127     UINT uDriveType = DRIVE_UNKNOWN ;
   128     TCHAR szRootName[5];
   129 	UINT waitTime = 0;
   130 
   131     wsprintf(szRootName, "%c:\\", driveLetter);
   132 
   133 	for (int i = 0; i < WAIT_RETRIES && (uDriveType != DRIVE_REMOVABLE); i++)
   134 		{
   135 		uDriveType = GetDriveType(szRootName);
   136 		if (uDriveType != DRIVE_REMOVABLE)
   137 			{
   138 			Sleep (WAIT_TIME);
   139 			waitTime += WAIT_TIME;
   140 			}
   141 		else
   142 			{
   143 			Sleep (WAIT_DELAY);
   144 			waitTime += WAIT_DELAY;
   145 			}
   146 		}
   147 	
   148 
   149     PRINT_ALWAYS "Drive %c ready after %d milliseconds.\n",driveLetter,waitTime);
   150     return uDriveType == DRIVE_REMOVABLE;
   151 }