48 #include <sbWindowsUtils.h>
72 { 0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8 }
105 DWORD aDesiredAccess,
107 LPSECURITY_ATTRIBUTES aSecurityAttributes,
108 DWORD aCreationDisposition,
109 DWORD aFlagsAndAttributes,
110 HANDLE aTemplateFile)
113 NS_ENSURE_ARG_POINTER(aDevFile);
114 NS_ENSURE_ARG_POINTER(aGUID);
120 nsAutoString devicePath;
122 NS_ENSURE_SUCCESS(rv, rv);
125 HANDLE devFile = CreateFileW(devicePath.get(),
129 aCreationDisposition,
132 NS_ENSURE_TRUE(devFile != INVALID_HANDLE_VALUE, NS_ERROR_FAILURE);
165 DWORD aDesiredAccess,
167 LPSECURITY_ATTRIBUTES aSecurityAttributes,
168 DWORD aCreationDisposition,
169 DWORD aFlagsAndAttributes,
170 HANDLE aTemplateFile)
173 NS_ENSURE_ARG_POINTER(aDevFile);
180 DEVINST ancestorDevInst;
181 DEVINST devInst = aDevInst;
184 cfgRet = CM_Get_Parent(&ancestorDevInst, devInst, 0);
185 if (cfgRet != CR_SUCCESS)
186 return NS_ERROR_NOT_AVAILABLE;
191 NS_ENSURE_SUCCESS(rv, rv);
196 devInst = ancestorDevInst;
206 aCreationDisposition,
225 PRBool* aHasInterface)
228 NS_ENSURE_ARG_POINTER(aGUID);
229 NS_ENSURE_ARG_POINTER(aHasInterface);
235 *aHasInterface = PR_FALSE;
238 nsAutoString deviceInstanceID;
240 NS_ENSURE_SUCCESS(rv, rv);
241 HDEVINFO devInfo = SetupDiGetClassDevsW(aGUID,
242 deviceInstanceID.get(),
244 DIGCF_DEVICEINTERFACE);
245 NS_ENSURE_TRUE(devInfo != INVALID_HANDLE_VALUE, NS_ERROR_FAILURE);
246 sbAutoHDEVINFO autoDevInfo(devInfo);
250 SP_DEVINFO_DATA devInfoData;
257 PSP_DEVICE_INTERFACE_DETAIL_DATA devIfDetailData;
267 *aHasInterface = PR_TRUE;
285 nsAString& aDevicePath)
288 NS_ENSURE_ARG_POINTER(aGUID);
294 nsAutoString deviceInstanceID;
296 NS_ENSURE_SUCCESS(rv, rv);
297 HDEVINFO devInfo = SetupDiGetClassDevsW(aGUID,
298 deviceInstanceID.get(),
300 DIGCF_DEVICEINTERFACE);
301 NS_ENSURE_TRUE(devInfo != INVALID_HANDLE_VALUE, NS_ERROR_FAILURE);
302 sbAutoHDEVINFO autoDevInfo(devInfo);
305 SP_DEVINFO_DATA devInfoData;
307 NS_ENSURE_SUCCESS(rv, rv);
310 PSP_DEVICE_INTERFACE_DETAIL_DATA devIfDetailData;
315 NS_ENSURE_SUCCESS(rv, rv);
319 aDevicePath.Assign(devIfDetailData->DevicePath);
347 (nsTArray<DEVINST>& aDevInstList,
348 DEVINST aRootDevInst,
350 PRBool aSearchAncestors);
354 DEVINST aRootDevInst,
356 PRBool aSearchAncestors)
359 aDevInstList.Clear();
369 DEVINST aRootDevInst,
371 PRBool aSearchAncestors)
374 NS_ENSURE_ARG_POINTER(aGUID);
383 NS_ENSURE_SUCCESS(rv, rv);
385 NS_ENSURE_TRUE(aDevInstList.AppendElement(aRootDevInst),
386 NS_ERROR_OUT_OF_MEMORY);
390 if (aSearchAncestors) {
391 DEVINST parentDevInst;
392 cr = CM_Get_Parent(&parentDevInst, aRootDevInst, 0);
393 if (cr == CR_SUCCESS) {
399 NS_ENSURE_SUCCESS(rv, rv);
402 DEVINST childDevInst;
403 cr = CM_Get_Child(&childDevInst, aRootDevInst, 0);
404 while (cr == CR_SUCCESS) {
410 NS_ENSURE_SUCCESS(rv, rv);
414 cr = CM_Get_Sibling(&childDevInst, childDevInst, 0);
436 DEVINST aRootDevInst,
437 const nsAString& aClass)
440 NS_ENSURE_ARG_POINTER(aDevInst);
441 NS_ENSURE_ARG_POINTER(aFound);
444 PRBool found = PR_FALSE;
449 WCHAR propBuffer[256];
450 ULONG length =
sizeof(propBuffer);
451 cr = CM_Get_DevNode_Registry_PropertyW(aRootDevInst,
457 NS_ENSURE_TRUE(cr == CR_SUCCESS, NS_ERROR_FAILURE);
460 nsDependentString property(propBuffer);
461 if (property.Equals(aClass)) {
462 *aDevInst = aRootDevInst;
468 DEVINST childDevInst;
469 cr = CM_Get_Child(&childDevInst, aRootDevInst, 0);
470 while (cr == CR_SUCCESS) {
473 NS_ENSURE_SUCCESS(rv, rv);
481 cr = CM_Get_Sibling(&childDevInst, childDevInst, 0);
506 PSP_DEVINFO_DATA aDevInfoData)
509 NS_ENSURE_ARG_POINTER(aDevInfoData);
518 aDevInfoData->cbSize =
sizeof(SP_DEVINFO_DATA);
519 success = SetupDiEnumDeviceInfo(aDevInfo, devIndex, aDevInfoData);
521 return NS_ERROR_NOT_AVAILABLE;
524 if (aDevInfoData->DevInst == aDevInst)
550 SP_DEVINFO_DATA* aDevInfoData,
556 NS_ENSURE_ARG_POINTER(aDevIfDetailData);
557 NS_ENSURE_ARG_POINTER(aDevInfoData);
558 NS_ENSURE_ARG_POINTER(aGUID);
565 SP_DEVICE_INTERFACE_DATA devIfData;
566 ZeroMemory(&devIfData,
sizeof(SP_DEVICE_INTERFACE_DATA));
567 devIfData.cbSize =
sizeof(SP_DEVICE_INTERFACE_DATA);
568 success = SetupDiEnumDeviceInterfaces(aDevInfo,
574 return NS_ERROR_NOT_AVAILABLE;
578 success = SetupDiGetDeviceInterfaceDetailW(aDevInfo,
584 NS_ENSURE_TRUE(size > 0, NS_ERROR_FAILURE);
588 PSP_DEVICE_INTERFACE_DETAIL_DATA
589 devIfDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(size);
590 NS_ENSURE_TRUE(devIfDetailData, NS_ERROR_OUT_OF_MEMORY);
592 autoDevIfDetailData(devIfDetailData);
593 devIfDetailData->cbSize =
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
596 ZeroMemory(aDevInfoData,
sizeof(SP_DEVINFO_DATA));
597 aDevInfoData->cbSize =
sizeof(SP_DEVINFO_DATA);
598 success = SetupDiGetDeviceInterfaceDetailW(aDevInfo,
604 NS_ENSURE_SUCCESS(success, NS_ERROR_FAILURE);
608 (PSP_DEVICE_INTERFACE_DETAIL_DATA) autoDevIfDetailData.
forget();
636 SP_DEVINFO_DATA* aDevInfoData,
640 NS_ENSURE_ARG_POINTER(aDevIfDetailData);
641 NS_ENSURE_ARG_POINTER(aDevInfoData);
642 NS_ENSURE_ARG_POINTER(aGUID);
648 SP_DEVICE_INTERFACE_DATA devIfData;
649 ZeroMemory(&devIfData,
sizeof(SP_DEVICE_INTERFACE_DATA));
650 devIfData.cbSize =
sizeof(SP_DEVICE_INTERFACE_DATA);
651 success = SetupDiEnumDeviceInterfaces(aDevInfo,
657 return NS_ERROR_NOT_AVAILABLE;
661 success = SetupDiGetDeviceInterfaceDetailW(aDevInfo,
668 NS_ENSURE_TRUE(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
671 NS_ENSURE_TRUE(size > 0, NS_ERROR_FAILURE);
675 PSP_DEVICE_INTERFACE_DETAIL_DATA devIfDetailData;
677 static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA
>(NS_Alloc(size));
678 NS_ENSURE_TRUE(devIfDetailData, NS_ERROR_OUT_OF_MEMORY);
682 devIfDetailData->cbSize =
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
683 success = SetupDiGetDeviceInterfaceDetailW(aDevInfo,
689 NS_ENSURE_SUCCESS(success, NS_ERROR_FAILURE);
693 static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA
>(autoDevIfDetailData.
forget());
709 nsAString& aDeviceInstanceID)
715 HDEVINFO devInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL);
716 NS_ENSURE_TRUE(devInfoSet != INVALID_HANDLE_VALUE, NS_ERROR_FAILURE);
717 sbAutoHDEVINFO autoDevInfoSet(devInfoSet);
721 SP_DEVICE_INTERFACE_DATA devIfData;
722 ZeroMemory(&devIfData,
sizeof(SP_DEVICE_INTERFACE_DATA));
723 devIfData.cbSize =
sizeof(SP_DEVICE_INTERFACE_DATA);
724 success = SetupDiOpenDeviceInterfaceW(devInfoSet,
725 aDeviceInterfaceName.BeginReading(),
728 NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
731 SP_DEVINFO_DATA devInfoData;
732 devInfoData.cbSize =
sizeof(SP_DEVINFO_DATA);
733 success = SetupDiEnumDeviceInfo(devInfoSet, 0, &devInfoData);
734 NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
738 NS_ENSURE_SUCCESS(rv, rv);
754 nsAString& aDeviceInstanceID)
759 TCHAR deviceInstanceID[MAX_DEVICE_ID_LEN];
760 cr = CM_Get_Device_ID(aDevInst, deviceInstanceID, MAX_DEVICE_ID_LEN, 0);
761 NS_ENSURE_TRUE(cr == CR_SUCCESS, NS_ERROR_FAILURE);
762 aDeviceInstanceID.Assign(deviceInstanceID);
780 WCHAR vetoName[MAX_PATH];
781 PNP_VETO_TYPE vetoType;
782 PRBool ejected = PR_FALSE;
783 for (
int i = 0;
i < 3;
i++) {
785 cfgRet = CM_Request_Device_EjectW(aDevInst,
790 if (cfgRet == CR_SUCCESS) {
799 cfgRet = CM_Query_And_Remove_SubTreeW(aDevInst,
803 CM_REMOVE_NO_RESTART);
804 if (cfgRet == CR_SUCCESS) {
815 cfgRet = CM_Request_Device_Eject(aDevInst, NULL, NULL, 0, 0);
816 NS_ENSURE_TRUE(cfgRet == CR_SUCCESS, NS_ERROR_FAILURE);
833 nsString volumePath(NS_LITERAL_STRING(
"\\\\.\\"));
834 volumePath.Append(aMountPath);
835 volumePath.Trim(
"\\", PR_FALSE, PR_TRUE);
838 sbAutoHANDLE diskHandle = CreateFileW(volumePath.BeginReading(),
839 GENERIC_READ | GENERIC_WRITE,
840 FILE_SHARE_READ | FILE_SHARE_WRITE,
845 NS_ENSURE_TRUE(diskHandle.get() != INVALID_HANDLE_VALUE, NS_ERROR_FAILURE);
847 const PRUint32 LOCK_RETRY = 3;
848 const PRUint32 LOCK_RETRY_WAIT= 500;
850 for (PRUint32 retry = 0; retry < LOCK_RETRY; ++retry) {
851 success = DeviceIoControl(diskHandle,
862 if (!success && retry == LOCK_RETRY - 1) {
863 const DWORD error = GetLastError();
864 printf(
"FSTL_LOCK_VOLUME failed on %s with code %u\n",
865 NS_LossyConvertUTF16toASCII(volumePath).
get(),
869 Sleep(LOCK_RETRY_WAIT);
871 NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
873 success = DeviceIoControl(diskHandle,
874 FSCTL_DISMOUNT_VOLUME,
881 const DWORD error = GetLastError();
882 printf(
"FSCTL_DISMOUNT_VOLUME failed on %s with code %u\n",
883 NS_LossyConvertUTF16toASCII(volumePath).
get(),
887 NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
889 PREVENT_MEDIA_REMOVAL preventMediaRemoval;
891 preventMediaRemoval.PreventMediaRemoval = FALSE;
893 success = DeviceIoControl(diskHandle,
894 IOCTL_STORAGE_MEDIA_REMOVAL,
895 &preventMediaRemoval,
sizeof(preventMediaRemoval),
901 const DWORD error = GetLastError();
902 printf(
"IOCTL_STORAGE_MEDIA_REMOVAL failed on %s with code %u\n",
903 NS_LossyConvertUTF16toASCII(volumePath).
get(),
907 NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
909 success = DeviceIoControl(diskHandle,
910 IOCTL_STORAGE_EJECT_MEDIA,
919 const DWORD error = GetLastError();
920 printf(
"IOCTL_STORAGE_EJECT_MEDIA failed on %s with code %u\n",
921 NS_LossyConvertUTF16toASCII(volumePath).
get(),
924 return NS_ERROR_FAILURE;
942 DEVINST aDescendantDevInst,
943 PRBool* aIsDescendant)
946 NS_ENSURE_ARG_POINTER(aIsDescendant);
949 PRBool isDescendant = PR_FALSE;
953 DEVINST currentAncestor = aDescendantDevInst;
956 cfgRet = CM_Get_Parent(¤tAncestor, currentAncestor, 0);
957 if (cfgRet != CR_SUCCESS)
961 if (currentAncestor == aDevInst) {
962 isDescendant = PR_TRUE;
968 *aIsDescendant = isDescendant;
994 NS_ENSURE_ARG_POINTER(aDeviceNotification);
1000 sbAutoHANDLE deviceHandle;
1005 FILE_SHARE_READ | FILE_SHARE_WRITE,
1010 NS_ENSURE_SUCCESS(rv, rv);
1015 HDEVNOTIFY deviceNotification;
1016 DEV_BROADCAST_HANDLE devBroadcast = {0};
1017 devBroadcast.dbch_size =
sizeof(devBroadcast);
1018 devBroadcast.dbch_devicetype = DBT_DEVTYP_HANDLE;
1019 devBroadcast.dbch_handle = deviceHandle;
1020 deviceNotification = RegisterDeviceNotification(aEventWindow,
1023 NS_ENSURE_TRUE(deviceNotification, NS_ERROR_FAILURE);
1026 *aDeviceNotification = deviceNotification;
nsresult sbWinCreateDeviceFile(HANDLE *aDevFile, DEVINST aDevInst, const GUID *aGUID, DWORD aDesiredAccess, DWORD aShareMode, LPSECURITY_ATTRIBUTES aSecurityAttributes, DWORD aCreationDisposition, DWORD aFlagsAndAttributes, HANDLE aTemplateFile)
nsresult sbWinGetDeviceInstanceID(DEVINST aDevInst, nsAString &aDeviceInstanceID)
static const GUID GUID_DEVINTERFACE_USB_HUB
Songbird Windows Device Utilities Definitions.
static nsresult _sbWinFindDevicesByInterface(nsTArray< DEVINST > &aDevInstList, DEVINST aRootDevInst, const GUID *aGUID, PRBool aSearchAncestors)
nsresult sbWinGetDevInfoData(DEVINST aDevInst, HDEVINFO aDevInfo, PSP_DEVINFO_DATA aDevInfoData)
nsresult sbWinGetDevDetail(PSP_DEVICE_INTERFACE_DETAIL_DATA *aDevIfDetailData, SP_DEVINFO_DATA *aDevInfoData, HDEVINFO aDevInfo, const GUID *aGUID, DWORD aDevIndex)
nsresult sbWinCreateAncestorDeviceFile(HANDLE *aDevFile, DEVINST aDevInst, const GUID *aGUID, DWORD aDesiredAccess, DWORD aShareMode, LPSECURITY_ATTRIBUTES aSecurityAttributes, DWORD aCreationDisposition, DWORD aFlagsAndAttributes, HANDLE aTemplateFile)
nsresult sbWinFindDevicesByInterface(nsTArray< DEVINST > &aDevInstList, DEVINST aRootDevInst, const GUID *aGUID, PRBool aSearchAncestors)
nsresult sbWinFindDeviceByClass(DEVINST *aDevInst, PRBool *aFound, DEVINST aRootDevInst, const nsAString &aClass)
nsresult sbWinDeviceIsDescendantOf(DEVINST aDevInst, DEVINST aDescendantDevInst, PRBool *aIsDescendant)
nsresult sbWinDeviceEject(DEVINST aDevInst)
nsresult sbWinRegisterDeviceHandleNotification(HDEVNOTIFY *aDeviceNotification, HWND aEventWindow, DEVINST aDevInst, const GUID &aGUID)
nsresult sbWinGetDevicePath(DEVINST aDevInst, const GUID *aGUID, nsAString &aDevicePath)
nsresult sbWinGetDeviceInstanceIDFromDeviceInterfaceName(nsAString &aDeviceInterfaceName, nsAString &aDeviceInstanceID)
nsresult sbWinDeviceHasInterface(DEVINST aDevInst, const GUID *aGUID, PRBool *aHasInterface)
_getSelectedPageStyle s i
nsresult sbWinGetDevInterfaceDetail(PSP_DEVICE_INTERFACE_DETAIL_DATA *aDevIfDetailData, HDEVINFO aDevInfo, SP_DEVINFO_DATA *aDevInfoData, const GUID *aGUID)