/* * Remove the devices that are no longer present in the system. */ int checkDiscoveryRemoveDevices() { int i; struct FreespaceDeviceStruct* list[FREESPACE_MAXIMUM_DEVICE_COUNT]; int listLength = 0; // Collect the removed devices. freespace_private_filterDevices(list, FREESPACE_MAXIMUM_DEVICE_COUNT, &listLength, filterSweep); // Remove them from the device list so that future API calls fail to this device // fail. See callbacks after this loop. for (i = 0; i < listLength; i++) { int idx; DEBUG_WPRINTF(L"device %d removed\n", list[i]->id_); for (idx = 0; idx < freespace_instance_->deviceCount_; idx++) { if (list[i] == freespace_instance_->devices_[idx]) { memmove(&freespace_instance_->devices_[idx], &freespace_instance_->devices_[idx + 1], (freespace_instance_->deviceCount_ - idx - 1) * sizeof(struct FreespaceDeviceStruct*)); freespace_instance_->deviceCount_--; } } } // Call the removal callbacks. for (i = 0; i < listLength; i++) { freespace_private_removeDevice(list[i]); } // Free the device structure. for (i = 0; i < listLength; i++) { freespace_private_freeDevice(list[i]); } return listLength; }
/** * Handle the case where the device unexpectedly fails. * @param device The device the failed. * @param ec The error code from GetLastError() * @return The device error code. */ int handleDeviceFailure(struct FreespaceDeviceStruct* device, int ec) { int rc = FREESPACE_ERROR_UNEXPECTED; int formatRc = 0; LPVOID lpMsgBuf; // Retrieve the system error message for the last-error code formatRc = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, ec, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); if (formatRc == 0) { DEBUG_WPRINTF(L"handleDeviceFailure: %d\n", ec); } else { // Display the error message and exit the process DEBUG_WPRINTF(L"handleDeviceFailure: %d => %s\n", ec, lpMsgBuf); LocalFree(lpMsgBuf); } // Clean up this device. freespace_private_removeDevice(device); freespace_private_forceCloseDevice(device); freespace_private_requestDeviceRescan(); if (ec == ERROR_DEVICE_NOT_CONNECTED) { rc = FREESPACE_ERROR_NOT_FOUND; } return rc; }
/* * Process devices with multiple handles that are not fully complete. */ int checkDiscoveryPartiallyRemovedDevices() { struct FreespaceDeviceStruct* list[FREESPACE_MAXIMUM_DEVICE_COUNT]; int listLength = 0; int i; // Collect the removed devices and call the removed callbacks. freespace_private_filterDevices(list, FREESPACE_MAXIMUM_DEVICE_COUNT, &listLength, filterPartiallyRemoved); for (i = 0; i < listLength; i++) { DEBUG_WPRINTF(L"device %d partially removed\n", list[i]->id_); } for (i = 0; i < listLength; i++) { freespace_private_removeDevice(list[i]); } // Close file handles of devices that are open. for (i = 0; i < listLength; i++) { freespace_closeDevice(list[i]->id_); } return listLength; }