コード例 #1
0
nsresult
sbWinDeviceEject(DEVINST aDevInst)
{
  CONFIGRET cfgRet;

  // Try ejecting the device three times.
  WCHAR         vetoName[MAX_PATH];
  PNP_VETO_TYPE vetoType;
  bool        ejected = PR_FALSE;
  for (int i = 0; i < 3; i++) {
    // Try ejecting using CM_Request_Device_Eject.
    cfgRet = CM_Request_Device_EjectW(aDevInst,
                                      &vetoType,
                                      vetoName,
                                      MAX_PATH,
                                      0);
    if (cfgRet == CR_SUCCESS) {
      ejected = PR_TRUE;
      break;
    }
    // Wait for 1/10 second to give the device time to handle the eject.
    // This probably isn't needed, but all the examples I saw that used
    // the functions always put in a delay between calls at least for retries
    Sleep(100);
    // Try ejecting using CM_Query_And_Remove_SubTree.
    cfgRet = CM_Query_And_Remove_SubTreeW(aDevInst,
                                          &vetoType,
                                          vetoName,
                                          MAX_PATH,
                                          CM_REMOVE_NO_RESTART);
    if (cfgRet == CR_SUCCESS) {
      ejected = PR_TRUE;
      break;
    }
    // Wait 1/2 before retrying so we don't just slam the device with a bunch
    // of eject/remove requests and fail out.
    Sleep(500);
  }

  // Try one last time and let the PnP manager notify the user of failure.
  if (!ejected) {
    cfgRet = CM_Request_Device_Eject(aDevInst, NULL, NULL, 0, 0);
    NS_ENSURE_TRUE(cfgRet == CR_SUCCESS, NS_ERROR_FAILURE);
  }

  return NS_OK;
}
コード例 #2
0
ファイル: winutil.c プロジェクト: yeyanchao/calibre
static BOOL
eject_drive_letter(WCHAR DriveLetter) {
    LPWSTR szRootPath = L"X:\\", 
           szDevicePath = L"X:", 
           szVolumeAccessPath = L"\\\\.\\X:";
    WCHAR  szDosDeviceName[MAX_PATH];
    long DeviceNumber, res, tries;
    HANDLE hVolume; 
    STORAGE_DEVICE_NUMBER sdn;
    DWORD dwBytesReturned;
    DEVINST DevInst;
    ULONG Status;
    ULONG ProblemNumber;
    UINT DriveType;
    PNP_VETO_TYPE VetoType;
    WCHAR VetoNameW[MAX_PATH];
    BOOL bSuccess;
    DEVINST DevInstParent;
    
    szRootPath[0] = DriveLetter;
    szDevicePath[0] = DriveLetter;
    szVolumeAccessPath[4] = DriveLetter;

    DeviceNumber = -1;

    hVolume = CreateFile(szVolumeAccessPath, 0,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        NULL, OPEN_EXISTING, 0, NULL);
    if (hVolume == INVALID_HANDLE_VALUE) {
        PyErr_SetString(PyExc_ValueError, "Invalid handle value for drive letter");
        return FALSE;
    }

    dwBytesReturned = 0;
    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 ) {
        PyErr_SetString(PyExc_ValueError, "Can't find drive number");
        return FALSE;
    }

    res = QueryDosDevice(szDevicePath, szDosDeviceName, MAX_PATH);
    if ( !res ) {
       PyErr_SetString(PyExc_ValueError, "Can't find dos device");
       return FALSE;
    }

    DriveType = GetDriveType(szRootPath);

    DevInst = GetDrivesDevInstByDeviceNumber(DeviceNumber,
                  DriveType, szDosDeviceName);
    if (DevInst == 0) return FALSE;

    DevInstParent = 0;
    Status = 0;
    ProblemNumber = 0;
    bSuccess = FALSE;

    res = CM_Get_Parent(&DevInstParent, DevInst, 0);

    for ( tries = 0; 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); // required to give the next tries a chance!
    }
    if (!bSuccess)  PyErr_SetString(PyExc_ValueError, "Failed to eject drive after three tries");
    return bSuccess;
}
コード例 #3
0
int removeDrive(char drive)
{
	char driveLetter = drive;
    driveLetter &= ~0x20;

	if ( driveLetter < 'A' || driveLetter > 'Z' ) {
		return 1;
	}

	wchar_t szRootPath[] = L"X:\\";   // "X:\"  -> for GetDriveType
	szRootPath[0] = driveLetter;

	wchar_t szDevicePath[] = L"X:";   // "X:"   -> for QueryDosDevice
	szDevicePath[0] = driveLetter;

	wchar_t szVolumeAccessPath[] = L"\\\\.\\X:";   // "\\.\X:"  -> to open the volume
	szVolumeAccessPath[4] = driveLetter;

	long DeviceNumber = -1;

	HANDLE hVolume = CreateFile(szVolumeAccessPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
	if (hVolume == INVALID_HANDLE_VALUE) {
		return 1;
	}

	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;
	}

	UINT DriveType = GetDriveType(szRootPath);

	char szDosDeviceName[MAX_PATH];
	res = QueryDosDevice(szDevicePath, (LPWSTR)szDosDeviceName, MAX_PATH);
	if ( !res ) {
		return 1;
	}

	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;


	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 0;
	}

	printf("failed\n");
	
	printf("Result=0x%2X\n", res);

	if ( VetoNameW[0] ) {
		printf("VetoName=%ws)\n\n", VetoNameW);
	}	
	return 1;
}