На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Определить является ли диск съёмным USB Storage Device , тема для FAQ
    Определить является ли диск съёмным USB Storage Device(флеш-диски, телефоны, подключенные как USB Storage, mp3-плееры и т.д.).
    Код универсальный, может работать как с UNICODE, так и с обычной 8-ми битовой ANSI-строкой.

    1 Способ
    Этот способ предпочтительней, так как второй может иногда внешний жесткий диск также определить как съёмное USB-устройство.

    IsFlashDrive
    ExpandedWrap disabled
      //Входные данные:
      // drive_letter - буква тетируемого диска
      //Коды возврата:
      //0 - диск не является флешкой
      //1 - диск является флешкой
      //2,3 - ошибки
      __int8 IsFlashDrive(TCHAR drive_letter)
      {
         UINT drive_type;
         STORAGE_PROPERTY_QUERY spq;
         STORAGE_DEVICE_DESCRIPTOR sdd;
         DWORD BytesReturned;
         HANDLE hdrive=INVALID_HANDLE_VALUE;
         TCHAR drive_name1[20],drive_name2[20];
       
         StringCchPrintf(drive_name1,20,_T("%c:\\"),drive_letter);
         StringCchPrintf(drive_name2,20,_T("\\\\.\\%c:"),drive_letter);
        
         drive_type=GetDriveType(drive_name1);
        
         hdrive = CreateFile(drive_name2,0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
         if (hdrive==INVALID_HANDLE_VALUE)
            return 2;
       
         memset(&spq,0,sizeof(spq));
         memset(&sdd,0,sizeof(sdd));
       
         spq.PropertyId=StorageDeviceProperty;
         spq.QueryType=PropertyStandardQuery;
         if (!DeviceIoControl(hdrive,IOCTL_STORAGE_QUERY_PROPERTY,&spq,sizeof(spq),&sdd,sizeof(sdd),&BytesReturned,NULL))
         {
           CloseHandle(hdrive);
           return 3;
         }
       
         CloseHandle(hdrive);
         if ((drive_type==DRIVE_REMOVABLE)&&(sdd.BusType==BusTypeUsb)&&(sdd.RemovableMedia==true))
            return 1;
         else
            return 0;
      }


    Использование:
    1) Простое использование
    ExpandedWrap disabled
       
         __int8 ret_code;
         TCHAR test_disk=_T('H');
       
        ret_code=IsFlashDrive(test_disk);
         if (ret_code==1)
            _tprintf(_T("Диск %c: является флешкой\n"),test_disk);
         else if (ret_code==0)
            _tprintf(_T("Диск %c: НЕ является флешкой\n"),test_disk);


    2) Использование с минимальным контролем ошибок
    ExpandedWrap disabled
         __int8 ret_code;
         TCHAR test_disk=_T('H');
       
         ret_code=IsFlashDrive(test_disk);
         if (ret_code==1)
            _tprintf(_T("Диск %c: является флешкой\n"),test_disk);
         else if (ret_code==0)
            _tprintf(_T("Диск %c: НЕ является флешкой\n"),test_disk);
         else
            _tprintf(_T("Ошибка IsFlashDrive\n"),test_disk);


    3)Использование с полным контролем ошибок
    ExpandedWrap disabled
         __int8 ret_code;
         TCHAR test_disk=_T('H');
       
         ret_code=IsFlashDrive(test_disk);
         if (ret_code==1)
            _tprintf(_T("Диск %c: является флешкой\n"),test_disk);
         else if (ret_code==0)
            _tprintf(_T("Диск %c: НЕ является флешкой\n"),test_disk);
         else
         {
            if (ret_code==2)
              _tprintf(_T("Ошибка IsFlashDrive. Ошибка CreateFile: %u\n"),GetLastError());
            else if (ret_code==3)
              _tprintf(_T("Ошибка IsFlashDrive. Ошибка DeviceIoControl: %u\n"),GetLastError());
         }




    2 Способ(спасибо ЫукпШ за наводку)
    IsFlashDrive2
    ExpandedWrap disabled
      //Входные данные:
      // drive_letter - буква тетируемого диска
      //Выходные данные:
      // sys_err_code - код системной ошибки в случае её возникновения
      //Коды возврата:
      //0 - диск не является флешкой
      //1 - диск является флешкой
      //2,3,4,5 - ошибки
      __int8 IsFlashDrive2(TCHAR drive_letter, LONG *sys_err_code)
      {
         __int8 ret_code=0;
         HKEY hk=NULL;
         HANDLE hdrive=INVALID_HANDLE_VALUE;
         LONG Ret;
         DWORD data_size,dtype;
         WCHAR *data=NULL;
         TCHAR dos_link[50];
         DWORD ld;
         TCHAR drive_name2[20];
       
         //проверяем существует ли диск в системе
         StringCchPrintf(drive_name2,20,_T("\\\\.\\%c:"),drive_letter);
         hdrive = CreateFile(drive_name2,0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
         if (hdrive==INVALID_HANDLE_VALUE)
         {
            *sys_err_code=GetLastError();
            ret_code=5;
            goto free_resources;
         }
         CloseHandle(hdrive);
       
       
         Ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SYSTEM\\MountedDevices"),0,KEY_READ,&hk);
         if (Ret!=ERROR_SUCCESS)
         {
            ret_code=2;
            *sys_err_code=Ret;
            goto free_resources;
         }
       
         StringCchPrintf(dos_link,50,_T("\\DosDevices\\%c:"),drive_letter);
         Ret=RegQueryValueEx(hk,dos_link,NULL,&dtype,NULL,&data_size);
         if (Ret==ERROR_SUCCESS)
         {
            data=(WCHAR *)malloc(data_size+2);
            if (data==NULL)
            {
               ret_code=3;
               *sys_err_code=0;
               goto free_resources;
            }
            memset(data,0,data_size+2);
       
            Ret=RegQueryValueEx(hk,dos_link,NULL,&dtype,(LPBYTE)data,&data_size);
            if (Ret!=ERROR_SUCCESS)
            {
               ret_code=4;
               *sys_err_code=Ret;
               goto free_resources;
            }
            
            if(wcsstr(data,L"USBSTOR")!=NULL)
               ret_code=1;
            else
               ret_code=0;
         }
         else
         {
            ret_code=4;
            *sys_err_code=Ret;
         }
       
      free_resources:
         if (data!=NULL) free(data);
         if (hk!=NULL) RegCloseKey(hk);
        
         return ret_code;
      }


    Использование

    1) Простое использование
    ExpandedWrap disabled
         __int8 ret_code;
         TCHAR test_disk=_T('H');
         LONG sec;
       
         ret_code=IsFlashDrive2(test_disk,&sec);
         if (ret_code==1)
            _tprintf(_T("Диск %c: является флешкой\n"),test_disk);
         else if (ret_code==0)
            _tprintf(_T("Диск %c: НЕ является флешкой\n"),test_disk);



    2) Использование с минимальным контролем ошибок
    ExpandedWrap disabled
         __int8 ret_code;
         TCHAR test_disk=_T('H');
         LONG sec;
       
         ret_code=IsFlashDrive2(test_disk,&sec);
         if (ret_code==1)
            _tprintf(_T("Диск %c: является флешкой\n"),test_disk);
         else if (ret_code==0)
            _tprintf(_T("Диск %c: НЕ является флешкой\n"),test_disk);
         else
            _tprintf(_T("Ошибка IsFlashDrive2\n"),test_disk);



    3) Использование с полным контролем ошибок
    ExpandedWrap disabled
         __int8 ret_code;
         TCHAR test_disk=_T('H');
         LONG sec;
       
         ret_code=IsFlashDrive2(test_disk,&sec);
         if (ret_code==1)
            _tprintf(_T("Диск %c: является флешкой\n"),test_disk);
         else if (ret_code==0)
            _tprintf(_T("Диск %c: НЕ является флешкой\n"),test_disk);
         else
         {
            if (ret_code==2)
              _tprintf(_T("Ошибка IsFlashDrive2. Ошибка RegOpenKeyEx: %u\n"),sec);
            else if (ret_code==3)
              _tprintf(_T("Ошибка IsFlashDrive2. Ошибка malloc.\n"));
            else if (ret_code==4)
              _tprintf(_T("Ошибка IsFlashDrive2. Ошибка RegQueryValueEx: %u\n"),sec);
            else if (ret_code==5)
              _tprintf(_T("Ошибка IsFlashDrive2. Ошибка CreateFile: %u\n"),sec);
         }



    Полный исходный код
    ExpandedWrap disabled
      #ifndef UNICODE
      #define UNICODE
      #endif
      #ifndef _UNICODE
      #define _UNICODE
      #endif
       
      #include <tchar.h>
      #include <windows.h>
      #include <stdio.h>
      #include <conio.h>
      #include <locale.h>
      #include <WinIoCtl.h>
      #include <StrSafe.h>
       
      //--------------------------------------------------------------------------------------------------------------------------
      //Входные данные:
      //IN drive_letter - буква тетируемого диска
      //Коды возврата:
      //0 - диск не является флешкой
      //1 - диск является флешкой
      //2,3 - ошибки
      __int8 IsFlashDrive(TCHAR drive_letter)
      {
         UINT drive_type;
         STORAGE_PROPERTY_QUERY spq;
         STORAGE_DEVICE_DESCRIPTOR sdd;
         DWORD BytesReturned;
         HANDLE hdrive=INVALID_HANDLE_VALUE;
         TCHAR drive_name1[20],drive_name2[20];
       
         StringCchPrintf(drive_name1,20,_T("%c:\\"),drive_letter);
         StringCchPrintf(drive_name2,20,_T("\\\\.\\%c:"),drive_letter);
        
         drive_type=GetDriveType(drive_name1);
        
         hdrive = CreateFile(drive_name2,0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
         if (hdrive==INVALID_HANDLE_VALUE)
            return 2;
       
         memset(&spq,0,sizeof(spq));
         memset(&sdd,0,sizeof(sdd));
       
         spq.PropertyId=StorageDeviceProperty;
         spq.QueryType=PropertyStandardQuery;
         if (!DeviceIoControl(hdrive,IOCTL_STORAGE_QUERY_PROPERTY,&spq,sizeof(spq),&sdd,sizeof(sdd),&BytesReturned,NULL))
         {
           CloseHandle(hdrive);
           return 3;
         }
       
         CloseHandle(hdrive);
         if ((drive_type==DRIVE_REMOVABLE)&&(sdd.BusType==BusTypeUsb)&&(sdd.RemovableMedia==true))
            return 1;
         else
            return 0;
      }
      //--------------------------------------------------------------------------------------------------------------------------
       
       
      //--------------------------------------------------------------------------------------------------------------------------
      //Входные данные:
      //IN drive_letter - буква тетируемого диска
      //OUT sys_err_code - код системной ошибки в случае её возникновения
      //Коды возврата:
      //0 - диск не является флешкой
      //1 - диск является флешкой
      //2,3,4,5 - ошибки
      __int8 IsFlashDrive2(TCHAR drive_letter, LONG *sys_err_code)
      {
         __int8 ret_code=0;
         HKEY hk=NULL;
         HANDLE hdrive=INVALID_HANDLE_VALUE;
         LONG Ret;
         DWORD data_size,dtype;
         WCHAR *data=NULL;
         TCHAR dos_link[50];
         TCHAR drive_name2[20];
       
         //проверяем существует ли диск в системе
         StringCchPrintf(drive_name2,20,_T("\\\\.\\%c:"),drive_letter);
         hdrive = CreateFile(drive_name2,0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
         if (hdrive==INVALID_HANDLE_VALUE)
         {
            *sys_err_code=GetLastError();
            ret_code=5;
            goto free_resources;
         }
         CloseHandle(hdrive);
       
       
         Ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SYSTEM\\MountedDevices"),0,KEY_READ,&hk);
         if (Ret!=ERROR_SUCCESS)
         {
            ret_code=2;
            *sys_err_code=Ret;
            goto free_resources;
         }
       
         StringCchPrintf(dos_link,50,_T("\\DosDevices\\%c:"),drive_letter);
         Ret=RegQueryValueEx(hk,dos_link,NULL,&dtype,NULL,&data_size);
         if (Ret==ERROR_SUCCESS)
         {
            data=(WCHAR *)malloc(data_size+2);
            if (data==NULL)
            {
               ret_code=3;
               *sys_err_code=0;
               goto free_resources;
            }
            memset(data,0,data_size+2);
       
            Ret=RegQueryValueEx(hk,dos_link,NULL,&dtype,(LPBYTE)data,&data_size);
            if (Ret!=ERROR_SUCCESS)
            {
               ret_code=4;
               *sys_err_code=Ret;
               goto free_resources;
            }
            
            if(wcsstr(data,L"USBSTOR")!=NULL)
               ret_code=1;
            else
               ret_code=0;
         }
         else
         {
            ret_code=4;
            *sys_err_code=Ret;
         }
       
      free_resources:
         if (data!=NULL) free(data);
         if (hk!=NULL) RegCloseKey(hk);
        
         return ret_code;
      }
      //--------------------------------------------------------------------------------------------------------------------------
       
       
      //--------------------------------------------------------------------------------------------------------------------------
      int _tmain(int argc, _TCHAR* argv[])
      {
         __int8 ret_code;
         TCHAR test_disk=_T('H');
         LONG sec;
       
         setlocale(LC_ALL,"Russian");
       
         //IsFlashDrive
         //Простое использование
         ret_code=IsFlashDrive(test_disk);
         if (ret_code==1)
            _tprintf(_T("Диск %c: является флешкой\n"),test_disk);
         else if (ret_code==0)
            _tprintf(_T("Диск %c: НЕ является флешкой\n"),test_disk);
        
         //Использование с минимальным контролем ошибок
         ret_code=IsFlashDrive(test_disk);
         if (ret_code==1)
            _tprintf(_T("Диск %c: является флешкой\n"),test_disk);
         else if (ret_code==0)
            _tprintf(_T("Диск %c: НЕ является флешкой\n"),test_disk);
         else
            _tprintf(_T("Ошибка IsFlashDrive\n"),test_disk);
       
         //Использование с полным контролем ошибок
         ret_code=IsFlashDrive(test_disk);
         if (ret_code==1)
            _tprintf(_T("Диск %c: является флешкой\n"),test_disk);
         else if (ret_code==0)
            _tprintf(_T("Диск %c: НЕ является флешкой\n"),test_disk);
         else
         {
            if (ret_code==2)
              _tprintf(_T("Ошибка IsFlashDrive. Ошибка CreateFile: %u\n"),GetLastError());
            else if (ret_code==3)
              _tprintf(_T("Ошибка IsFlashDrive. Ошибка DeviceIoControl: %u\n"),GetLastError());
         }
       
       
         //IsFlashDrive2
         //Простое использование
         ret_code=IsFlashDrive2(test_disk,&sec);
         if (ret_code==1)
            _tprintf(_T("Диск %c: является флешкой\n"),test_disk);
         else if (ret_code==0)
            _tprintf(_T("Диск %c: НЕ является флешкой\n"),test_disk);
       
         //Использование с минимальным контролем ошибок
         ret_code=IsFlashDrive2(test_disk,&sec);
         if (ret_code==1)
            _tprintf(_T("Диск %c: является флешкой\n"),test_disk);
         else if (ret_code==0)
            _tprintf(_T("Диск %c: НЕ является флешкой\n"),test_disk);
         else
            _tprintf(_T("Ошибка IsFlashDrive2\n"),test_disk);
       
         //Использование с полным контролем ошибок
         ret_code=IsFlashDrive2(test_disk,&sec);
         if (ret_code==1)
            _tprintf(_T("Диск %c: является флешкой\n"),test_disk);
         else if (ret_code==0)
            _tprintf(_T("Диск %c: НЕ является флешкой\n"),test_disk);
         else
         {
            if (ret_code==2)
              _tprintf(_T("Ошибка IsFlashDrive2. Ошибка RegOpenKeyEx: %u\n"),sec);
            else if (ret_code==3)
              _tprintf(_T("Ошибка IsFlashDrive2. Ошибка malloc.\n"));
            else if (ret_code==4)
              _tprintf(_T("Ошибка IsFlashDrive2. Ошибка RegQueryValueEx: %u\n"),sec);
            else if (ret_code==5)
              _tprintf(_T("Ошибка IsFlashDrive2. Ошибка CreateFile: %u\n"),sec);
         }
       
         _tprintf(_T("Нажмите любую клавишу..."));
         _getch();
         return 0;
      }
      //--------------------------------------------------------------------------------------------------------------------------
    Сообщение отредактировано: neokoder -
      Для FAQ тема подходит и... ;) по-моему, на 25 Dgm тянет!!!
        Цитата Бублик @
        Для FAQ тема подходит и... по-моему, на 25 Dgm тянет!!!

        Спасибо за высокую оценку Бублик ;), но в правилах вроде прописано максимум 10 DigiMania за один FAQ. А вообще не ради DigiMania пишу, но повышение рейтинга это тож хорошо :yes: !
        Сообщение отредактировано: neokoder -
          надо бы StringCchPrintf заменить на wsprintf ибо StringCchPrintf компиляторозависимое.

          да и использование malloc как то не кошерно, лучше через new
          Сообщение отредактировано: Dem_max -
            Цитата Dem_max @
            надо бы StringCchPrintf заменить на wsprintf ибо StringCchPrintf компиляторозависимое.

            wsprintf вообще-то уже давно не рекомендуется к использованию по соображениям безопасности.
            Кому надо пусть меняет. Мне больше нравится как StringCchPrintf обрабатывает ошибки. swprintf_s может организовать вылет из программы, если не использовать дополнительно _set_invalid_parameter_handler, вот эта дополнительность меня лично и обременяет.

            Цитата Dem_max @
            да и использование malloc как то не кошерно, лучше через new

            Не вижу никаких причин для замены malloc на new.
            Сообщение отредактировано: neokoder -
              Можно было бы придраться и к смешиванию юникода, макроса _T и ANSI, но это уже мелочи
              Пост ушел в FAQ
                Цитата B.V. @
                Можно было бы придраться и к смешиванию юникода, макроса _T и ANSI, но это уже мелочи

                Вряд ли 8-) . Здесь по-другому просто нельзя поскольку строка из реестра WCHAR.
                Сообщение отредактировано: neokoder -
                  в код невникал - какой-то он гнилой, я юзал вот это:

                  ExpandedWrap disabled
                    #define DRIVE_FIXED_USB 7
                     
                    BOOL GetDisksProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc)
                    {
                        STORAGE_PROPERTY_QUERY  Query;  // input param for query
                        DWORD dwOutBytes;               // IOCTL output length
                     
                        // specify the query type
                        Query.PropertyId = StorageDeviceProperty;
                        Query.QueryType = PropertyStandardQuery;
                     
                        // Query using IOCTL_STORAGE_QUERY_PROPERTY
                        return DeviceIoControl(hDevice,         // device handle
                            IOCTL_STORAGE_QUERY_PROPERTY,           // info of device property
                            &Query, sizeof(STORAGE_PROPERTY_QUERY), // input data buffer
                            pDevDesc, pDevDesc->Size,               // output data buffer
                            &dwOutBytes,                            // out's length
                            (LPOVERLAPPED)NULL);                    
                    }
                     
                    BOOL isItUsbDrive(const QString & drive)
                    {
                        bool bUsb = false;
                        PSTORAGE_DEVICE_DESCRIPTOR pDevDesc;
                     
                        HANDLE hDevice = CreateFile(drive.utf16(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
                     
                        if(hDevice != INVALID_HANDLE_VALUE)
                        {
                            pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)new BYTE[sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1];
                     
                            if(pDevDesc != NULL)
                            {
                                pDevDesc->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 -1;
                     
                                if(GetDisksProperty(hDevice, pDevDesc))
                                {
                                    if(pDevDesc->BusType == BusTypeUsb)
                                        bUsb = true;
                                }
                     
                                delete [] pDevDesc;
                     
                            }
                     
                            CloseHandle(hDevice);
                        }
                     
                        return bUsb;
                    }
                  Сообщение отредактировано: Мальчиш -
                    Цитата Мальчиш @
                    в код невникал - какой-то он гнилой, я юзал вот это:

                    Ты за базаром следи.

                    Добавлено
                    Цитата Мальчиш @
                    я юзал вот это:

                    3 раза ХА :D . Это ты только по шине USB определял? Твой код во многих случаях работать не будет, в частности внешний жесткий диск сочтёт за флешку. И твой код не будет работать под бычным юзером в XP :). Кроме того если на вход твоей функции подать несуществующую букву диска, то она вернёт не ошибку, как должно быть а сообщит, что диск не флешка! :D :D

                    В общем ты в следующий раз прежде чем чей-то код называть гнилым, лучше повысь свой профессиональный навык, а то так умея только делать супер-пупер профессионально парсинг строки ты далеко не уедешь :D !

                    Главное сам "продемонстрировал" 4-х кратно вложенный IF, а меня в параллельной теме упрекает за чрезмерную вложенность :) .
                    Сообщение отредактировано: neokoder -
                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                    0 пользователей:


                    Рейтинг@Mail.ru
                    [ Script execution time: 0,0783 ]   [ 16 queries used ]   [ Generated: 18.07.25, 00:32 GMT ]