0 / 0 / 1
Регистрация: 16.10.2011
Сообщений: 53
1

Точка монтирования USB диска SetupAPI

30.10.2013, 16:59. Показов 10505. Ответов 38
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Вообщем есть DeviceID которое получено через SetupAPI с помощью :
1.
C++
1
2
3
4
5
6
7
8
9
10
11
hDevInfo = SetupDiGetClassDevs(
                   guid,
                    NULL, // Enumerator
                    NULL,
                    DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
 
 
    for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++)
    {
......SPDRP_FRIENDLYNAME...извлечение DeviceInstanceID....
}
в итоге я получил DeviceID в виде USBSTOR#Disk&Ven_JetFlash&Prod_TS4GJFV30&Rev_8.07#OCJOK3DI&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b} потом преобразовал в USBSTOR\Disk&Ven_JetFlash&Prod_TS4GJFV30&Rev_8.07\OCJOK3DI&0.

2.
Далее я смог получить с помощью этого http://msdn.microsoft.com/en-u... s.85).aspx
в итоге получаю что-то вроде
C++
1
2
3
4
Found a device:
 \Device\HarddiskVolume2
Volume name: \\?\Volume{4c1b02c1-d990-11dc-99ae-806e6f6e6963}\
Paths:  C:\
дак вот теперь как связать пункт 1 и пункт 2? Знаю как сделать через WMI_ классы но слишком это объемно не хочется тащить за программой эти функции. Как можно решить вопрос через SetupAPI?
Скорее всего камень предкновения это Volume name: \\?\Volume{4c1b02c1-d990-11dc-99ae-806e6f6e6963}\ но неясно как куда и зачем)))
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.10.2013, 16:59
Ответы с готовыми решениями:

Перехват события монтирования диска
Как можно перехватить событие монтирования диска, в частности, после вставления флешки в USB-порт?...

Точка монтирования
Объясните пожалуйста. Например, у меня 2 диска по 1 разделу в каждом. /dev/sda, /dev/sdb. Если...

Получение буквы диска через SetupApi
Всем привет! Мне необходимо получить букву, которую ОС присваивает USB-накопителю. Так я получаю...

Работа с эндпоинтами устройств USB и setupapi
Как читать и записывать данные в эндпоинты EP0in, EP0out, EPi in, EPi out устройств USB , как...

38
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
07.11.2013, 12:02 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от mdvalex Посмотреть сообщение
Проблема в их стыковке в Windows XP. Т е у меня получается надо состыковать
\??\STORAGE#RemovableMedia#8&1c1fa76d&0&RM#{53f5630d-b6bf-11d0-94f2
-00a0c91efb8b}
и
\??\USBSTOR#disk&ven_jetflash&prod_ts4gjfv30&rev_8.0#serialn umber#{guid}
В обоих случаях символьная ссылка.
Может, правильнее сравнивать не сами ссылки, а объекты, на которые они указывают ?
Объект можно найти с помощью QueryDosDevice, ну или посмотреть в WinObj (Sysinternals).
Отпишитесь по результатам. Тема интересная, а воспроизвести такое поведение, как в
Вашем случае, у меня не на чем.
0
0 / 0 / 1
Регистрация: 16.10.2011
Сообщений: 53
07.11.2013, 12:30  [ТС] 22
Цитата Сообщение от Убежденный Посмотреть сообщение
В обоих случаях символьная ссылка.
Может, правильнее сравнивать не сами ссылки, а объекты, на которые они указывают ?
Объект можно найти с помощью QueryDosDevice, ну или посмотреть в WinObj (Sysinternals).
Отпишитесь по результатам. Тема интересная, а воспроизвести такое поведение, как в
Вашем случае, у меня не на чем.
нету ХР?

Ну я как подумал решить эту проблему.
1. Приходит событие подключения съемного диска DBT_DEVTYP_VOLUME
2. Из него я извлекаю букву диска (Е: или F: например)
3. Отправляю букву в функцию с MOUNTMNGR там идет перебор всех подключенных дисков и если в строке buffer типа (\DosDevices\A есть совпадение с нашей буквой то возвращается символьная ссылка устройства (\??\****#*****#{***})
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
.........
char buffer[256]; //Это для названия раздела
char deviceid[256]; //это для символьной ссылки устройства
 
sprintf (buffer, "%.*ls\n", pMountPoints->MountPoints[i].SymbolicLinkNameLength/sizeof(WCHAR),
                       pbyOutBuffer + pMountPoints->MountPoints[i].SymbolicLinkNameOffset);
//Ищем в строке подстроку E:(будет входной параметр в функцию)
int jk = countBasestrSubstr(buffer,"E:");  
if(jk == 1) {
break;
return deviceid;
}
..........
4. Дальше я уже думаю ввести специфику для ХР и для 7 (на висте незнаю как) 8-ую не рассматриваю.

4.1 Если у нас 7 то мы ничего не делаем а просто извлекаем информацию об этом устройстве с помощью
SetupDiGetClassDevs (указывая Enumerate = DeviceInstanseID)
SetupDiEnumDeviceInfo
SetupDiGetDeviceRegistryProperty
Ну мне достаточно Friendlyname, Class, Enumeratorname

4.2 А вот если у нас ХР тогда мы заведомо знаем что полученное в функции это USBSTOR#RemovableMedia#******#{***} и тогда отправляем эту символьную ссылку в функцию которая находит DeviceInstanceID родителя этого RemovableMedia (при помощи
SetupDiGetClassDevs
SetupDiEnumDeviceInterfaces
SetupDiGetDeviceInterfaceDetail
)
И в итоге получаю DeviceInstanceID который возвращаю в функцию которая на шаге(4.1)


!!Но вот неизвестно будет ли такая штука работать с переносными HDD которые определяются как логические диски. Будет ли приходить событие DBT_DEVTYP_VOLUME при их подключении или нет.

*Для тех устройств которые уже подключены до запуска программы еще не думал как реализовать.


PS что за объекты? это \Device\HarddiskVolume1 ? я думаю от них некуда шагать.

функция поиска строки в подстроке)
C++
1
2
3
4
5
6
7
8
9
10
int countBasestrSubstr(const char * basestr, const char * substr) {
    int count = 0;
    const char * buf = basestr;
    while (strstr(buf, substr) != NULL) {
        buf = strstr(buf, substr);
        ++count;
        ++buf;
    }
    return count;
}
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
07.11.2013, 13:28 23
Цитата Сообщение от mdvalex Посмотреть сообщение
нету ХР?
Только виртуальная. И для тех устройств, что я подключал, обе ссылки всегда
получаются идентичными.

Кстати, диспетчер оборудования ведь как-то умеет определять тома дисков.
На досуге посмотрю каким-нибудь API Monitor-ом, как он это делает.
Что-то мне подсказывает, что все должно быть проще, через IOCTL-запросы к
девайсам, разрешение символьных ссылок и прочую простую логику.

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

Цитата Сообщение от mdvalex Посмотреть сообщение
PS что за объекты? это \Device\HarddiskVolume1 ? я думаю от них некуда шагать.
Ну вот у нас есть две символьные ссылки.
Одна получена из SetupDiGetDeviceInterfaceDetail, вторая у mount manager-а.
Их нужно сравнить. На Win7 они (для данного конкретного случая) одинаковы, а
на WinXP разные (опять же, я рассматриваю эту ситуацию как некий специальный
случай, что она не обязана повторяться на других дисках).

Теперь вызовем на обеих ссылках QueryDosDevice и получим имя устройства,
на которое они указывают. И вот полученные имена уже можно сравнивать.
Повторяю, это лишь предположение, так как проверить мне не на чем.
0
0 / 0 / 1
Регистрация: 16.10.2011
Сообщений: 53
07.11.2013, 16:37  [ТС] 24
Цитата Сообщение от Убежденный Посмотреть сообщение
Только виртуальная. И для тех устройств, что я подключал, обе ссылки всегда
получаются идентичными.

Кстати, диспетчер оборудования ведь как-то умеет определять тома дисков.
На досуге посмотрю каким-нибудь API Monitor-ом, как он это делает.
Что-то мне подсказывает, что все должно быть проще, через IOCTL-запросы к
девайсам, разрешение символьных ссылок и прочую простую логику.

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



Ну вот у нас есть две символьные ссылки.
Одна получена из SetupDiGetDeviceInterfaceDetail, вторая у mount manager-а.
Их нужно сравнить. На Win7 они (для данного конкретного случая) одинаковы, а
на WinXP разные (опять же, я рассматриваю эту ситуацию как некий специальный
случай, что она не обязана повторяться на других дисках).

Теперь вызовем на обеих ссылках QueryDosDevice и получим имя устройства,
на которое они указывают. И вот полученные имена уже можно сравнивать.
Повторяю, это лишь предположение, так как проверить мне не на чем.
Может быть у меня не правильный MOUNTMGR?
А у вас на ХР когда флешку вставляете появляется в диспетчере как у меня отдельный раздел с RemovableMedia?
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
07.11.2013, 16:56 25
Цитата Сообщение от mdvalex Посмотреть сообщение
Может быть у меня не правильный MOUNTMGR?
А у вас на ХР когда флешку вставляете появляется в диспетчере как у меня отдельный раздел с RemovableMedia?
В том-то и дело, что XP виртуальная, в нее USB-накопитель не вставишь.
0
0 / 0 / 1
Регистрация: 16.10.2011
Сообщений: 53
07.11.2013, 17:01  [ТС] 26
Цитата Сообщение от Убежденный Посмотреть сообщение
В том-то и дело, что XP виртуальная, в нее USB-накопитель не вставишь.
Ах ну да точно, уже забыл о обычных виртуалках ибо сам с мака работаю и виртуалкой стоит и ХР и 7)) и тут позволяет такое делать) VMwareFusion)
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
07.11.2013, 17:26 27
VMWare и под Windows позволяет прокидывать устройства, насколько я знаю.
Но я пользуюсь Hyper-V на 2008-ом серваке, там этой возможности нет.
А вживую видел XP где-то год назад
Так что результаты изысканий в этой теме очень интересуют.
Я позже покопаю диспетчер устройств, если удастся что-то найти - отпишусь.
0
0 / 0 / 1
Регистрация: 16.10.2011
Сообщений: 53
07.11.2013, 18:55  [ТС] 28
Испытал DBT_DEVTYPE_VOLUME событие приходит кстати во всех случая появления нового диска
1. Флешка
2. Внешний жесткий диск
3. Флешка-модем монтирующаяся как CD-привод!!
0
0 / 0 / 1
Регистрация: 16.10.2011
Сообщений: 53
08.11.2013, 19:54  [ТС] 29
Вообщем поставил виртуалкой Vista, всё также как и на Windows 7

Т е никаких RemovableMedia так что получается это специфика Windows XP (то что появляется эта дополнительная ветка в Диспетчере устройств)

Ну придется находить родителя RemovableMedia немного муторно но будет точно работать)
Миниатюры
Точка монтирования USB диска SetupAPI  
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
08.11.2013, 20:05 30
Цитата Сообщение от mdvalex Посмотреть сообщение
Ну придется находить родителя RemovableMedia немного муторно но будет точно работать)
Вы так и не проверили, что выдает QueryDosDevice, если ей "скормить"
обе символьные ссылки, которые получаются на XP...
0
0 / 0 / 1
Регистрация: 16.10.2011
Сообщений: 53
08.11.2013, 20:21  [ТС] 31
Скорее всего я непонимаю что куда кормить))

Вот структура

DWORD WINAPI QueryDosDevice(
_In_opt_ LPCTSTR lpDeviceName, - это у нас буква диска C: E: D:
_Out_ LPTSTR lpTargetPath, - это чтото вроде \Device\CdRom
_In_ DWORD ucchMax - чтото вроде кол-ва символов
);
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
08.11.2013, 20:52 32
Первый параметр - символьная ссылка.
На XP у Вас получаются две ссылки:
\??\STORAGE#RemovableMedia#8&1c1fa76d&0&RM#{53f5630d-b6bf-11d0-94f2
-00a0c91efb8b}
и
\??\USBSTOR#disk&ven_jetflash&prod_ts4gjfv30&rev_8.0#serialn umber#{guid}
Второй параметр - выходной буфер, третий - его размер, в символах.
0
0 / 0 / 1
Регистрация: 16.10.2011
Сообщений: 53
08.11.2013, 21:22  [ТС] 33
Цитата Сообщение от Убежденный Посмотреть сообщение
Первый параметр - символьная ссылка.
На XP у Вас получаются две ссылки:

Второй параметр - выходной буфер, третий - его размер, в символах.
Ладно на выходных попробую, только что оно мне вернуть должно.

DWORD i = QueryDosDevice(device1,device2,sizeof(device2)); чтото типа того ?

на выходных попробую)
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
08.11.2013, 21:34 34
Цитата Сообщение от mdvalex Посмотреть сообщение
Ладно на выходных попробую, только что оно мне вернуть должно.
Имя устройства, на которое указывает символьная ссылка.

Грубо говоря:
C++
1
2
wchar_t Buffer[1000];
QueryDosDeviceW(pSymLink, Buffer, 1000);
После этого содержимое Buffer - в студию !

P.S.
Удачных выходных !
0
0 / 0 / 1
Регистрация: 16.10.2011
Сообщений: 53
10.11.2013, 12:56  [ТС] 35
Цитата Сообщение от Убежденный Посмотреть сообщение
Имя устройства, на которое указывает символьная ссылка.
Грубо говоря:
Код C++
wchar_t Buffer[1000];
QueryDosDeviceW(pSymLink, Buffer, 1000);
После этого содержимое Buffer - в студию !
P.S.
Удачных выходных !
printf("%s",Buffer);
ничего не возвращает (пробывал и с %ls) тоже пусто.

А теперь появилась еще проблема как узнать по букве диска что это именно съемный диск? С сетевыми понятно.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
#include<windows.h>
#include <conio.h>
using namespace std;
int main()
{
    char buf[26];
    GetLogicalDriveStringsA(sizeof(buf),buf);
    char *DRF [] = {"Unknown" , "Invalid path",
        "Removable", "Fixed" , "Network drive","CD-ROM", "RAM disk"};
    for(char *s=buf; *s; s+=strlen(s)+1)
         cout<<s<<"  "<<DRF[GetDriveTypeA(s)]<<endl;
 
    getch();
    return 0;
}
вот таким образом я проверяю уже смонтированные диски.
Но проблема в чем
1. Флоппик определяется как Removable
2. Переносной HDD на 500гб определяется как Fixed
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
10.11.2013, 16:36 36
Цитата Сообщение от mdvalex Посмотреть сообщение
printf("%s",Buffer);
ничего не возвращает (пробывал и с %ls) тоже пусто.
Надо wprintf, это же Unicode, "широкие символы". Ну или в MessageBoxW вывести.
Сначала одну ссылку скормить в QueryDosDevice, затем вторую. И сравнить полученные значения.

Цитата Сообщение от mdvalex Посмотреть сообщение
А теперь появилась еще проблема как узнать по букве диска что это именно съемный диск?
SetupDiGetDeviceRegistryProperty с кодом SPDRP_REMOVAL_POLICY не пробовали ?
0
Maniac
Эксперт С++
1464 / 965 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
11.11.2013, 17:04 37
Может чем поможет

Получить пути к USB накопителям
1
0 / 0 / 1
Регистрация: 16.10.2011
Сообщений: 53
23.11.2013, 11:25  [ТС] 38
Цитата Сообщение от Убежденный Посмотреть сообщение
SetupDiGetDeviceRegistryProperty с кодом SPDRP_REMOVAL_POLICY не пробовали ?
Немогу понять что за значение возвращает это SPDRP_REMOVAL_POLICY вроде как DWORD но что с ним делать ? как мне определить что это за устройство ? Если выводить как строку то нулевой символ какойто возвращает и все.


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
55
56
void print_property2
(
    __in HDEVINFO        hDevInfo,
    __in SP_DEVINFO_DATA DeviceInfoData,
    __in PCWSTR          Label,
    __in DWORD           Property
)
{
    DWORD  DataT;
    LPTSTR buffer     = NULL;
    DWORD  buffersize = 0;
    
    //
    // Call function with null to begin with, 
    // then use the returned buffer size (doubled)
    // to Alloc the buffer. Keep calling until
    // success or an unknown failure.
    //
    //  Double the returned buffersize to correct
    //  for underlying legacy CM functions that 
    //  return an incorrect buffersize value on 
    //  DBCS/MBCS systems.
    // 
    while (!SetupDiGetDeviceRegistryProperty(
                hDevInfo,
                &DeviceInfoData,
                Property,
                &DataT,
                (PBYTE)buffer,
                buffersize,
                &buffersize))
    {
        if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
        {
            // Change the buffer size.
            if (buffer)
            {
                LocalFree(buffer);
            }
            // Double the size to avoid problems on 
            // W2k MBCS systems per KB 888609. 
            buffer = (LPTSTR)LocalAlloc(LPTR, buffersize * 2);
        }
        else
        {
            break;
        }
    }
    
    wprintf(L"%s %d\n",Label, buffer);
    
    if (buffer)
    {
        LocalFree(buffer);
    }
}
Вот так обращаюсь к функции
C++
1
 print_property2(hDevInfo, DeviceInfoData, L"\tRemoval Policy :", SPDRP_REMOVAL_POLICY);
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
23.11.2013, 11:41 39
WinDDK 7600.1, /inc/api/cfgmgr32.h

C
1
2
3
4
5
6
7
// Removal policies (retrievable via CM_Get_DevInst_Registry_Property with
// the CM_DRP_REMOVAL_POLICY, CM_DRP_REMOVAL_POLICY_OVERRIDE, or
// CM_DRP_REMOVAL_POLICY_HW_DEFAULT properties)
//
#define CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL             1
#define CM_REMOVAL_POLICY_EXPECT_ORDERLY_REMOVAL        2
#define CM_REMOVAL_POLICY_EXPECT_SURPRISE_REMOVAL       3
0
23.11.2013, 11:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.11.2013, 11:41
Помогаю со студенческими работами здесь

Ошибка монтирования образа диска на VirtualBox
Доброго! Поставил на VB убунту. Хочу установить дополнения, выбираю как обычно Устройства -...

Программа для монтирования образа диска (iso)
Пожалуйста, какой пакет(программа) надо установить в Mandriva, чтобы она монтировала образ диска...

Как изменить флаги монтирования по умолчанию для usb-носителей?
Хочу изменить флаги монтирования по умочанию, где это можно сделать. В /etc/udev/rules.d не...

Python linux нужно написать программу для монтирования и размонтирования usb
Здравствуйте, сразу скажу, что в питоне я полный чайник, нужно написать программу для монтирования...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru