Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++ Builder
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.70/20: Рейтинг темы: голосов - 20, средняя оценка - 4.70
Ddv122
Почемучка)
1240 / 300 / 30
Регистрация: 23.12.2010
Сообщений: 2,000
Записей в блоге: 1
1

Безопасное извлечение флэшки.

02.05.2012, 19:01. Просмотров 4082. Ответов 13
Метки нет (Все метки)

Добрый вечер)Не кто не реализовывал функцию Безопасного извлечение флэшки?
Нужно копать в сторону функции CM_Request_Device_Eject.
Не кто примеров на С++ не видел?
Вот пример на Delphi
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.05.2012, 19:01
Ответы с готовыми решениями:

Cканировать подключенные флэшки
Не подскажите возможно ли прикрутить к кнопке код void __fastcall TForm1::WMDeviceChange(...

История подключения флэшки.
Всё работает и всё кажется отлично, но! void __fastcall TForm1::WMDeviceChange( TMessage &Message...

Определенные действия при подключении флэшки
if ( Message.Msg == WM_DEVICECHANGE && Message.WParam == 0x8000 ) { char DiskLabel; ...

Оследить момент появления флэшки в проводнике.
Как отловить момент появления дисков в проводнике а не в системе? UINT uDriveType =...

Как отследить момент отключения флэшки
void __fastcall TForm1::WMDeviceChange( TMessage &Message ) { if ( Message.Msg ==...

13
Ddv122
Почемучка)
1240 / 300 / 30
Регистрация: 23.12.2010
Сообщений: 2,000
Записей в блоге: 1
02.05.2012, 19:19  [ТС] 3
LK,
Это всё мои темы))))Там не разбирали вопрос про извлечение...
В одной теме вылаживали пример на си шарпе...он без кода...

Добавлено через 1 минуту
Похожие темы там тоже нечего нет)
0
LK
Заблокирован
02.05.2012, 19:33 4
Цитата Сообщение от EdarGp Посмотреть сообщение
Это всё мои темы
и я о том же.

Добавлено через 17 секунд
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void __fastcall RemoveDrive(int index)
{
  HDEVINFO DrivesPnPHandle;
  SP_DEVINFO_DATA DevInfo;
  int i;
  DWORD Parent;
  char * VetoName[MAX_PATH];
 
  DevInfo.cbSize = sizeof(SP_DEVINFO_DATA);
  DrivesPnPHandle = SetupDiGetClassDevsA(&GUID_DEVCLASS_DISKDRIVE, NULL, 0, 2);
  if (DrivesPnPHandle == INVALID_HANDLE_VALUE) {
    return;
  }
  if (SetupDiEnumDeviceInfo(DrivesPnPHandle,index,DevInfo)) {
    if (IsUSBDevice(DevInfo.DevInst))&&
                    (CM_Get_Parent(Parent,DevInfo.DevInst,0)==CR_SUCCESS) {
          CM_Request_Device_Eject(Parent,NULL,&VetoName,MAX_PATH,0);
          if (VetoName="") 
            ShowMessage("Устройство можно извлечь.");
          else
            ShowMessage("Устройство нельзя извлечь.");
    }
  }
  else {
    ShowMessage("Не USB устройство.");
  }
  SetupDiDestroyDeviceInfoList(DrivesPnPHandle);
}
0
02.05.2012, 19:33
Ddv122
Почемучка)
1240 / 300 / 30
Регистрация: 23.12.2010
Сообщений: 2,000
Записей в блоге: 1
02.05.2012, 20:07  [ТС] 5
Это вроде массовое отключение, а не по одному....
0
LK
Заблокирован
02.05.2012, 20:22 6
EdarGp, вы сами этот код нашли.
0
Ddv122
Почемучка)
1240 / 300 / 30
Регистрация: 23.12.2010
Сообщений: 2,000
Записей в блоге: 1
02.05.2012, 22:01  [ТС] 7
LK, а есть другая альтернатива этому коду?
0
LK
Заблокирован
03.05.2012, 01:38 8
How to Prepare a USB Drive for Safe Removal
1
QWIPQ
142 / 121 / 14
Регистрация: 10.10.2011
Сообщений: 359
Записей в блоге: 2
03.05.2012, 19:44 9
DeviceIoControl - почитай в мсдн, вчера там читал, а в двух словах нужно получить хендл путем вызова CreateFile... вчера и русскую статью видел на эт тему, вечером буду дома скину линки на статьи, сорт ща с моба

Добавлено через 37 минут
САМА ФУНКЦИЯ
ЕЕ ВЫЗОВ
Вот почитай

Добавлено через 5 часов 22 минуты
она же в MSDN
мне кажется надо копать в этом направлении... тема актуальна с флешками и дисками предлагаю скомпоновать товарищу LK и в FAQ поместить...
1
QWIPQ
142 / 121 / 14
Регистрация: 10.10.2011
Сообщений: 359
Записей в блоге: 2
06.05.2012, 23:07 10
может кто-нить уже смог это сделать из ныне здесь присутствующих?

Добавлено через 5 часов 46 минут
я тут случайно кое-что интересное нашел сижу ща изучаю, и вам предлагаю глянуть...
Как получить доступ к USB-устройству с помощью функции WinUSB
2
BRcr
4025 / 2314 / 292
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
07.05.2012, 10:24 11
Прямо конструктор "Драйвер - собери сам!" Правда, к флэшкам это относится исчезающе мало... признавайтесь, господа форумчане, кто себе для флэшки ставил WinUSB?
1
QWIPQ
142 / 121 / 14
Регистрация: 10.10.2011
Сообщений: 359
Записей в блоге: 2
08.05.2012, 13:49 12
Лучший ответ Сообщение было отмечено как решение

Решение

вообщем есть сказка про репку... ну и в итоге главные герои эту репку вытянули...
вот чтобы и нам нашу репку отключить нужно следующее...
C++
1
2
3
4
#include <Cfgmgr32.h>
#include <Setupapi.h>
#include <winioctl.h>
#include <devguid.h>
ниже появится возможно вопрос что це таке и почему оно не объявлено:
C++
1
2
DEFINE_GUID( GUID_DEVCLASS_USB,0x36FC9E60, 0xC465, 0x11CF, 0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 );
DEFINE_GUID( GUID_DEVCLASS_DISKDRIVE,0x4d36e967L, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
объясняю:GUID_DEVCLASS_DISKDRIVE и GUID_DEVCLASS_USB - это класс наших устройств в ПК которые прописаны в devguid.h и объявлять их совсем необязательно главн подключить библиотечку хотя некоторые и отдельно объявляют...

здесь приведен код результат которого нам потребуется для безопасного отключения флешек...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
////////////////////////////////////////////////////////////////////////////
////////////////////////////Список физ. дисков///////////////////////////
////////////////////////////////////////////////////////////////////////////
bool GetDeviceName(HDEVINFO PnPHandle, SP_DEVINFO_DATA DevData)
{
  DWORD BytesReturned;
  DWORD RegDataType;
  char Buffer[256];
////////////////////////
  BytesReturned = 0;
  RegDataType = 0;
  Buffer[0] = 0;
  SetupDiGetDeviceRegistryProperty(PnPHandle, &DevData, SPDRP_FRIENDLYNAME,
    NULL, &Buffer[0], sizeof(Buffer), NULL);
  Result = Buffer;
  if (Result == "") exit(1);
  Result+=" - ";
  BytesReturned = 0;
  RegDataType = 0;
  Buffer[0] = 0;
  SetupDiGetDeviceRegistryProperty(PnPHandle, &DevData, SPDRP_DEVICEDESC,
    NULL, &Buffer[0], sizeof(Buffer), NULL);
  Result+=Buffer;
}
bool FizicheskieYstroistva()
{
  Form1->DrivesListBox->Clear();
  HDEVINFO DrivePnPHandle;
  DWORD DeviceNumber;
  SP_DEVINFO_DATA DevData;
  BOOL RES;
  //запуск
  Form1->DrivesListBox->Clear();
  DrivePnPHandle = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL, DIGCF_PRESENT);
  if (DrivePnPHandle == INVALID_HANDLE_VALUE)exit(1);
  DeviceNumber = 0;
  while(true)
  {
   DevData.cbSize = sizeof(SP_DEVINFO_DATA);
   RES = SetupDiEnumDeviceInfo(DrivePnPHandle, DeviceNumber, &DevData);
   if (RES)
   {
        Result=NULL;
        GetDeviceName(DrivePnPHandle, DevData);
        Form1->DrivesListBox->Items->Add(Result);
   }
   else break;
   DeviceNumber++;
  }
   SetupDiDestroyDeviceInfoList(DrivePnPHandle);
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
результатом его выполнения выполнения является заполнение ListBox нашими физическими дисками и флешками, данные устройства находятся в классе GUID_DEVCLASS_DISKDRIVE и соответствующий номер в этом классе является номером нашего диска или флешки в ListBox, это сделано для удобства извлечения флеш носителей

ниже приведен код безопасного извлечения флеш носителей
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
////////////////////////////////////////////////////////////////////////////
//////////////////////////Безопасно удалить флеху///////////////////////////
////////////////////////////////////////////////////////////////////////////
BOOL IsUSBDevice(DWORD DevInst)
{
    DWORD size;
    LPBYTE pData;
    BOOL usb = FALSE;
    if (CM_Get_Device_ID_Size(&size, DevInst, 0) == CR_SUCCESS)
    {
        if (size)
        {
            pData = (LPBYTE)GlobalAlloc(GPTR, size + 1);
            if (pData)
            {
                if (CM_Get_Device_ID(DevInst, (PCHAR)pData, size + 1,0) == CR_SUCCESS)
                {
                    *(pData + 7) = 0x00;
                    if (!strcmp((char*)pData, "USBSTOR"))
                        usb = TRUE;
                }
                GlobalFree(pData);
            }
        }
    }
    return usb;
}
 
BOOL RemoveUSBDevice(int index)
{
    //объявляем переменные
    HDEVINFO DrivesPnPHandle;
    SP_DEVINFO_DATA DevInfo;
    DWORD Parent;
    //вызываем функции
    DrivesPnPHandle = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL, 2); //DIGCF_ALLCLASSES  DIGCF_PRESENT DIGCF_INTERFACEDEVICE
    if(DrivesPnPHandle == INVALID_HANDLE_VALUE)
    {
        exit(1);//вообще ни к чему
    }
    DevInfo.cbSize = sizeof(SP_DEVINFO_DATA);
    if(SetupDiEnumDeviceInfo(DrivesPnPHandle, index, &DevInfo))
    {
        if (IsUSBDevice(DevInfo.DevInst) && (CM_Get_Parent(&Parent, DevInfo.DevInst,0) == CR_SUCCESS))
        {
            CM_Request_Device_Eject(Parent, NULL, NULL, NULL, NULL);
        }
    }
    return FALSE;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
все функции в кодах описывать нет смысла т.к. все есть в MSDN, хочу лишь отметить главной здесь является функция CM_Request_Device_Eject так она объявлена в MSDN:
C++
1
2
3
4
5
6
7
8
9
CMAPI
CONFIGRET
WINAPI CM_Request_Device_Eject(
  __in       DEVINST dnDevInst,
  __out_opt  PPNP_VETO_TYPE pVetoType,
  __out_opt  LPTSTR pszVetoName,
  __in       ULONG ulNameLength,
  __in       ULONG ulFlags
);
Первый параметр это хендл устройства. Второй параметр это указатель на переменную, в которую будет сохранён код причины при неудаче. Третий параметр это указатель на строку, в которую будет сохранена причина неудачи при неудачном вызове. Оба этих параметра опциональны и могут быть равны нулю. Пятый параметр это максимальная длина строки. Шестой не используется. Если pszVetoName равен нулю, то при неудаче сообщение выведет сама система. В принципе нам необходим только первый параметр а все остальные могут быть NULL. Ведь любая «флешка» или внешний дисковый накопитель это составное устройство и отключать надо именно родительское устройство, для этих целий служит функция CM_Get_Parent которая получает хендл родительского устройства.

чтобы нам вызвать это все нам надо указать в ListBox то устройство какое хотим удалить и передать его индекс по нажатию кнопки, также необходимо обновить сразу ListBox
C++
1
2
3
4
5
void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
    RemoveUSBDevice(DrivesListBox->ItemIndex);
    FizicheskieYstroistva();
}
ListBox необходимо обновлять будет в 3х местах:
1. подключение флешки
2. по получению сообщения об отключению флешки (небезопасному - просто выдернуть из порта)
3. по безопасному отключению
таким способом сможем осуществить динамику наших устройств и эффективное их отключение.
Хочу также добавить что в ListBox выводится ваш жесткий диск, а его можите даже не стараться отключать

P.S. надеюсь что смог помочь кодом т.к. в инете вообще не нашел на С++ рассчитываю на ваши плюшки)))))
9
a_s_a_p
0 / 0 / 0
Регистрация: 12.02.2013
Сообщений: 375
23.03.2014, 10:15 13
Перезапуск explorer для извлечения никак ни на что не влияет? (win 8)
0
BRcr
4025 / 2314 / 292
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
23.03.2014, 10:19 14
Не должно влиять, эксплорер - всего лишь оболочка...
1
23.03.2014, 10:19
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.03.2014, 10:19

Извлечение флэшки с программы которая запущена с той же флэшки
Пишу типа авторана для флэшки. И там я хочу написать код который-би безопасно извлекал флэшку....

Безопасное извлечение флешки
Помогите пожалуйста. Используя среду программирования Free Pascal разработать программу,...

Безопасное извлечение флешки
Как из бат-скрипта можно инициировать безопасное извлечение флешки?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru