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

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

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

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

Есть идеи?

Эта статья и образец должны помочь: support.microsoft.com/default.aspx?scid=kb;en-us;165721

petr k. 17.09.2008 21:37

См. Статью базы знаний Майкрософт Q165721: support.microsoft.com/kb/165721 - включает полный исходный код C

mdb 17.09.2008 21:38
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
31
2
35 864
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

Но как узнать, какая буква была добавлена ​​для USB-накопителя? Я также хочу удалить USB-накопители на основе томов, таких как Не разрешать объем USB более 5 ГБ и т.

AZ_ 18.10.2010 13:41
Ответ принят как подходящий

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

DevEject: Просто. http://www.withopf.com/tools/deveject/

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

Отлично .. Вы даже подключились к служебной программе для выполнения этой работы. Большое спасибо.

Nils Pipenbrinck 17.09.2008 21:39

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

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

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

С Уважением

#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

Другие вопросы по теме