Безопасно извлекать USB-накопитель с помощью Win32 API?

Как удалить USB-накопитель с помощью Win32 API? Я много работаю со встроенными системами, и на одной из них мне нужно скопировать свои программы на USB-накопитель и вставить его в целевое оборудование.

Поскольку я в основном работаю на консоли, мне не нравится использовать мышь и щелкать по маленькому значку на панели задач сто раз в день.

Я бы с удовольствием написал небольшую программу, чтобы сделать именно это, чтобы я мог поместить ее в свои make-файлы, но я не нашел ни одного вызова API, который бы делал то же самое.

Любые идеи?


person Nils Pipenbrinck    schedule 17.09.2008    source источник
comment
Эта статья и образец должны помочь: support.microsoft.com /default.aspx?scid=kb;en-us;165721   -  person petr k.    schedule 17.09.2008
comment
См. Статью Q165721 базы знаний Майкрософт: support.microsoft.com/kb/165721 - включает полную Исходный код на C   -  person mdb    schedule 17.09.2008


Ответы (5)


Вы можете использовать функцию CM_Request_Device_Eject (), а также некоторые другие возможности. Ознакомьтесь со следующими проектами и статьями:

DevEject: Понятно. http://www.withopf.com/tools/deveject/

Полезная статья CodeProject: http://www.codeproject.com/KB/system/RemoveDriveByLetter.aspx

person Kris Kumler    schedule 17.09.2008
comment
Отлично .. Вы даже подключились к служебной программе для выполнения этой работы. Большое спасибо. - person Nils Pipenbrinck; 17.09.2008

Похоже, что Sync позволяет указать -e для извлечения съемных дисков. Хотя это и не Win32 API, вы, вероятно, могли бы просто вызвать sync -e [drive_letter] из своего make-файла.

person Grant Wagner    schedule 17.09.2008
comment
Но как узнать, какая буква была добавлена ​​для USB-накопителя? Я также хочу удалить USB-накопители на основе томов, таких как Не разрешать объем USB более 5 ГБ и т. Д. - person AZ_; 18.10.2010

Вот техническая статья о съемных носителях. Ищите DismountNtmsMedia.

person jop    schedule 17.09.2008

Вот решение на Delphi, которое я модифицировал и ввел в сервис для использования на очень большом предприятии. Перейдите по ссылке: текст ссылки

Найдите "scapi (Setup & Config Manager API)" и загрузите его. Будет демо-программа под названием USBView, которая поможет вам. Если у вас есть Delphi, это также включает компонент TUSBDeviceTree, который вы можете использовать для сбора информации о USB-устройстве, когда.

С Уважением

person Mick    schedule 26.11.2008

#include<SetupAPI.h>
#include <windows.h>  
#include<initguid.h>
#include <newdev.h>
#include <Cfgmgr32.h>

#pragma comment(lib, "Cfgmgr32.lib")
#pragma comment(lib, "Setupapi.lib")
#pragma comment(lib, "Newdev.lib")

int RemoveDevice(const GUID *guid, const wchar_t *hwID) {
    HDEVINFO m_hDevInfo;
    SP_DEVICE_INTERFACE_DATA         spdid;
    SP_DEVINFO_DATA                  spdd;
    DWORD                            dwSize;
    BYTE Buf[1024];
    PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd =
        (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;

    printf("try to remove device::%ws\n", hwID);

    m_hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT| DIGCF_DEVICEINTERFACE);
    if (m_hDevInfo == INVALID_HANDLE_VALUE)
    {
        printf("GetClassDevs Failed!\n");
        return 0;
    }
    spdid.cbSize = sizeof(spdid);
    for (int i = 0; SetupDiEnumDeviceInterfaces(m_hDevInfo, NULL, guid, i, &spdid); i++) {
        dwSize = 0;
        SetupDiGetDeviceInterfaceDetail(m_hDevInfo,
            &spdid, NULL, 0, &dwSize, NULL);
        if (dwSize != 0 && dwSize <= sizeof(Buf)) {
            pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!

            ZeroMemory((PVOID)&spdd, sizeof(spdd));
            spdd.cbSize = sizeof(spdd);

            long res =
                SetupDiGetDeviceInterfaceDetail(m_hDevInfo, &
                    spdid, pspdidd,
                    dwSize, &dwSize,
                    &spdd);
            if (res) {
                OLECHAR* guidString;
                OLECHAR* guidString2;
                StringFromCLSID(&spdd.ClassGuid, &guidString);
                StringFromCLSID(&spdid.InterfaceClassGuid, &guidString2);
                printf("%d, %ws, %ws, %ws\n", spdd.DevInst, pspdidd->DevicePath, guidString, guidString2);
                CoTaskMemFree(guidString);
                CoTaskMemFree(guidString2);
                if (!memcmp(pspdidd->DevicePath, hwID, 2 * lstrlenW(hwID))) {
                    DEVINST DevInstParent = 0;
                    res = CM_Get_Parent(&DevInstParent, spdd.DevInst, 0);
                    for (long tries = 0; tries < 10; tries++) {
                        // sometimes we need some tries...
                        WCHAR VetoNameW[MAX_PATH];
                        PNP_VETO_TYPE VetoType = PNP_VetoTypeUnknown;
                        VetoNameW[0] = 0;

                        res = CM_Request_Device_EjectW(DevInstParent,
                            &VetoType, VetoNameW, MAX_PATH, 0);
                        if ((res == CR_SUCCESS &&
                            VetoType == PNP_VetoTypeUnknown)) {
                            printf("remove %ws success!\n", pspdidd->DevicePath);
                            SetupDiDestroyDeviceInfoList(m_hDevInfo);
                            return 1;
                        }
                        Sleep(500); // required to give the next tries a chance!
                    }
                    break;
                }
            }
        }
    }
    printf("Remove Device Failed!\n");
    SetupDiDestroyDeviceInfoList(m_hDevInfo);
    return 0;
}

int main(){
    GUID GUID_DEVINTERFACE_USB_HUB;
    CLSIDFromString(L"F18A0E88-C30C-11D0-8815-00A0C906BED8", &GUID_DEVINTERFACE_USB_HUB);

    RemoveDevice(&GUID_DEVINTERFACE_USB_HUB, L"\\\\?\\usb#root_hub30");
    return 0;
}

ссылки:

Как подготовить USB-накопитель для безопасного удаления

GUID_DEVINTERFACE

person VictorV    schedule 16.10.2020