На главную Наши проекты:
Журнал   ·   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.
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Получить инфо о серийном номере, производителе и названии USB Storage Device , тема для FAQ
    Получить инфо о серийном номере, производителе и названии USB Storage Device.
    Если тестируемый диск является съёмным диском USB Storage Device(флешка, телефон, mp3-плеер и т.д.) функция PrintFlashDriveInfo печатает название производителя устройства, название продукта и серийный номер устройства. Если диск не является USB Storage Device, то выводится об этом сообщение. Функция работает с полным контролем ошибок.

    При необходимости получения выходных параметров(серийный номер, вендор, название) в качестве переменных вместо печати, функция легко переделывается: можно ввести дополнительный выходной параметр-структуру из 3-х строк и их размеров и заполнять её вместо печати.

    Примечание: при получении инфо о USB-устройстве таким способом, иногда внешний жесткий диск также может определиться как съёмное USB-устройство. В этом случае можно ввести доп. проверку того является ли диск съёмным USB Storage Device (1 Способ по ссылке)

    PrintFlashDriveInfo
    ExpandedWrap disabled
      WCHAR* GetElem(WCHAR *ptr,WCHAR delim,WCHAR *buf)
      {
         WCHAR *ptr1=NULL;
         ptr1=wcschr(ptr,delim);
         if (ptr1)
         {
            wcsncpy(buf,ptr,(int)(ptr1-ptr));
            buf[(int)(ptr1-ptr)]=0;
            return (ptr1+1);
         }
         else
         {
            wcscpy(buf,ptr);
            return NULL;
         }
      }
       
      //Входные данные:
      //IN drive_letter - буква диска
      void PrintFlashDriveInfo(WCHAR drive_letter)
      {
         HKEY hk=NULL;
         LONG Ret=0;
         HANDLE hdrive=INVALID_HANDLE_VALUE;
         DWORD data_size,dtype;
         WCHAR *data=NULL,*buf1=NULL,*buf2=NULL;
         WCHAR *ptr1_1=NULL,*ptr1_2=NULL,*ptr2_1=NULL,*ptr2_2=NULL;
         WCHAR dos_link[50];
         WCHAR drive_name2[20];
       
         __try
         {
            //проверяем существует ли диск в системе
            wsprintf(drive_name2,L"\\\\.\\%c:",drive_letter);
            hdrive = CreateFileW(drive_name2,0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
            if (hdrive==INVALID_HANDLE_VALUE)
            {
               wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка CreateFile: %u\n\n",GetLastError());
               __leave;
            }
            CloseHandle(hdrive);
       
            Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE,L"SYSTEM\\MountedDevices",0,KEY_READ,&hk);
            if (Ret!=ERROR_SUCCESS)
            {
               wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка RegOpenKeyEx: %u\n\n",Ret);
               __leave;
            }
       
            wsprintf(dos_link,L"\\DosDevices\\%c:",drive_letter);
            Ret=RegQueryValueExW(hk,dos_link,NULL,&dtype,NULL,&data_size);
            if (Ret==ERROR_SUCCESS)
            {
               data=(WCHAR *)malloc(data_size+2);
               buf1=(WCHAR *)malloc(data_size+2);
               buf2=(WCHAR *)malloc(data_size+2);
               if (data==NULL||buf1==NULL||buf2==NULL)
               {
                  wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка malloc.\n\n");
                  __leave;
               }
               memset(data,0,data_size+2);
       
               Ret=RegQueryValueExW(hk,dos_link,NULL,&dtype,(LPBYTE)data,&data_size);
               if (Ret!=ERROR_SUCCESS)
               {
                  wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка RegQueryValueEx: %u\n\n",Ret);
                  __leave;
               }
               if(wcsstr(data,L"USBSTOR")!=NULL)
               {
                  wprintf(L"Данные флеш-диска %c:\n",drive_letter);
                  ptr1_1=GetElem(data,L'#',buf1);
                  if (ptr1_1)
                  {
                     ptr1_2=GetElem(ptr1_1,L'#',buf1);
                     ptr1_1=buf1;
                     do
                     {
                        ptr2_2=GetElem(ptr1_1,L'&',buf2);
                        if (wcsstr(buf2,L"Ven_"))
                           wprintf(L"Производитель: %s\n",buf2+4);
                        else if (wcsstr(buf2,L"Prod_"))
                           wprintf(L"Название продукта: %s\n",buf2+5);
                        ptr1_1=ptr2_2;
                     } while (ptr2_2);
       
                     ptr1_1=GetElem(ptr1_2,L'#',buf1);
                     ptr1_1=buf1;
                     do
                     {
                        ptr2_2=GetElem(ptr1_1,L'&',buf2);
                        if (wcslen(buf2)>3)
                        {
                           wprintf(L"Серийный номер: %s\n",buf2);
                           break;
                        }
                        ptr1_1=ptr2_2;
                     } while (ptr2_2);
                  }
               }//if USBSTOR
               else
                  wprintf(L"Диск %c: НЕ является флешкой\n",drive_letter);
            }
            else
               wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка RegQueryValueEx: %u\n",Ret);
       
            wprintf(L"\n");
         }
         __finally
         {
            if (data!=NULL) free(data);
            if (buf1!=NULL) free(buf1);
            if (buf2!=NULL) free(buf2);
            if (hk!=NULL) RegCloseKey(hk);
         }
      }


    Использование
    ExpandedWrap disabled
         PrintFlashDriveInfo(_T('G'));
         PrintFlashDriveInfo(_T('C'));
         PrintFlashDriveInfo(_T('H'));
         PrintFlashDriveInfo(_T('I'));



    Полный исходный код
    ExpandedWrap disabled
      #define UNICODE
      #define _UNICODE
      #include <windows.h>
      #include <stdio.h>
      #include <conio.h>
      #include <locale.h>
      #include <WinIoCtl.h>
       
      WCHAR* GetElem(WCHAR *ptr,WCHAR delim,WCHAR *buf)
      {
         WCHAR *ptr1=NULL;
         ptr1=wcschr(ptr,delim);
         if (ptr1)
         {
            wcsncpy(buf,ptr,(int)(ptr1-ptr));
            buf[(int)(ptr1-ptr)]=0;
            return (ptr1+1);
         }
         else
         {
            wcscpy(buf,ptr);
            return NULL;
         }
      }
       
      //Входные данные:
      //IN drive_letter - буква диска
      void PrintFlashDriveInfo(WCHAR drive_letter)
      {
         HKEY hk=NULL;
         LONG Ret=0;
         HANDLE hdrive=INVALID_HANDLE_VALUE;
         DWORD data_size,dtype;
         WCHAR *data=NULL,*buf1=NULL,*buf2=NULL;
         WCHAR *ptr1_1=NULL,*ptr1_2=NULL,*ptr2_1=NULL,*ptr2_2=NULL;
         WCHAR dos_link[50];
         WCHAR drive_name2[20];
       
         __try
         {
            //проверяем существует ли диск в системе
            wsprintf(drive_name2,L"\\\\.\\%c:",drive_letter);
            hdrive = CreateFileW(drive_name2,0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
            if (hdrive==INVALID_HANDLE_VALUE)
            {
               wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка CreateFile: %u\n\n",GetLastError());
               __leave;
            }
            CloseHandle(hdrive);
       
            Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE,L"SYSTEM\\MountedDevices",0,KEY_READ,&hk);
            if (Ret!=ERROR_SUCCESS)
            {
               wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка RegOpenKeyEx: %u\n\n",Ret);
               __leave;
            }
       
            wsprintf(dos_link,L"\\DosDevices\\%c:",drive_letter);
            Ret=RegQueryValueExW(hk,dos_link,NULL,&dtype,NULL,&data_size);
            if (Ret==ERROR_SUCCESS)
            {
               data=(WCHAR *)malloc(data_size+2);
               buf1=(WCHAR *)malloc(data_size+2);
               buf2=(WCHAR *)malloc(data_size+2);
               if (data==NULL||buf1==NULL||buf2==NULL)
               {
                  wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка malloc.\n\n");
                  __leave;
               }
               memset(data,0,data_size+2);
       
               Ret=RegQueryValueExW(hk,dos_link,NULL,&dtype,(LPBYTE)data,&data_size);
               if (Ret!=ERROR_SUCCESS)
               {
                  wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка RegQueryValueEx: %u\n\n",Ret);
                  __leave;
               }
               if(wcsstr(data,L"USBSTOR")!=NULL)
               {
                  wprintf(L"Данные флеш-диска %c:\n",drive_letter);
                  ptr1_1=GetElem(data,L'#',buf1);
                  if (ptr1_1)
                  {
                     ptr1_2=GetElem(ptr1_1,L'#',buf1);
                     ptr1_1=buf1;
                     do
                     {
                        ptr2_2=GetElem(ptr1_1,L'&',buf2);
                        if (wcsstr(buf2,L"Ven_"))
                           wprintf(L"Производитель: %s\n",buf2+4);
                        else if (wcsstr(buf2,L"Prod_"))
                           wprintf(L"Название продукта: %s\n",buf2+5);
                        ptr1_1=ptr2_2;
                     } while (ptr2_2);
       
                     ptr1_1=GetElem(ptr1_2,L'#',buf1);
                     ptr1_1=buf1;
                     do
                     {
                        ptr2_2=GetElem(ptr1_1,L'&',buf2);
                        if (wcslen(buf2)>3)
                        {
                           wprintf(L"Серийный номер: %s\n",buf2);
                           break;
                        }
                        ptr1_1=ptr2_2;
                     } while (ptr2_2);
                  }
               }//if USBSTOR
               else
                  wprintf(L"Диск %c: НЕ является флешкой\n",drive_letter);
            }
            else
               wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка RegQueryValueEx: %u\n",Ret);
       
            wprintf(L"\n");
         }
         __finally
         {
            if (data!=NULL) free(data);
            if (buf1!=NULL) free(buf1);
            if (buf2!=NULL) free(buf2);
            if (hk!=NULL) RegCloseKey(hk);
         }
      }
       
       
      int wmain(int argc, WCHAR* argv[])
      {
         setlocale(LC_ALL,"Russian");
       
         PrintFlashDriveInfo(L'H');
         PrintFlashDriveInfo(L'G');
         PrintFlashDriveInfo(L'C');
         PrintFlashDriveInfo(L'Я');
       
         wprintf(L"Нажмите любую клавишу...");
         _getch();
         return 0;
      }


    p.s. учитывая "просьбы" :) код передалан из универсального(работающего как с UNICODE так и с обычной 8-ми битовой ANSI-строкой) в код работающий только с UNICODE.
    Сообщение отредактировано: neokoder -
      А вот здесь уже слишком много смешений wcs* и _t*-функций. neokoder, можешь привести их все к одному виду?
        Цитата B.V. @
        А вот здесь уже слишком много смешений wcs* и _t*-функций. neokoder, можешь привести их все к одному виду?

        Смешений? Нет никаких смешений, B.V., здесь всё используется так как надо. Изначально я и сделал так как ты запрашиваешь, но при выключении юникода функции не будут работать, поскольку в реестре все бинарные данные хранятся в юникоде(по крайней мере у меня на Win7, но думаю что в XP таже). Именно поэтому для работы со строкой реестра можно ипользовть только WCHAR. Всё остальное универсально, настроено на работу как с Юникодом так и без него. Можешь попробовать заменить:
        ExpandedWrap disabled
          #define UNICODE
          #define _UNICODE

        на
        ExpandedWrap disabled
          #undef UNICODE
          #undef _UNICODE


        Всё будет работать без проблем.
        Сообщение отредактировано: neokoder -
          Цитата
          Смешений? Нет никаких смешений

          Если нет, тогда убери из исходников это #include <tchar.h> так как у тебя только юникод используется.
          Сообщение отредактировано: Dem_max -
            Цитата Dem_max @
            Если нет, тогда убери из исходников это #include <tchar.h> так как у тебя только юникод используется.

            :) Надо думать прежде чем писать, Dem_max.
            Сообщение отредактировано: neokoder -
              Цитата neokoder @
              Изначально я и сделал так как ты запрашиваешь, но при выключении юникода функции не будут работать, поскольку в реестре все бинарные данные хранятся в юникоде(по крайней мере у меня на Win7, но думаю что в XP таже).

              Так и переведи весь вывод на юникод, к чему выводить одни сообщения посредством tprintf, а другие -- юникодным wprintf? В рамках данного кода переносимости нет, а отдельные его фрагменты вряд ли кто будет использовать, применение tchar неоправданно
                Я устал уже доказывать, B.V.. Честное слово. Как в стенку лбом.

                Цитата neokoder @
                Всё остальное универсально, настроено на работу как с Юникодом так и без него


                Почему ты хочешь отнять универсальность кода?
                Сообщение отредактировано: neokoder -
                  поддержку тех, кто высказывался выше: код - комплит булщит
                  помесь WCHAR/TCHAR еще меньшая из твоих проблем
                  goto, вложенные if/while'ы фиг знает какого уровня разрывают мозг и воскресное настроение
                  парсинг строчек, дорогой, neokoder, можно делать более внятными и вменяемыми методами
                  поддерживать такой "КОД", читать его,разбираться невозможно и крайне утомительно.. нужно неуважать других, чтобы просить их вникнуть в сие творение мысли заблудшей души :whistle:
                  Сообщение отредактировано: Мальчиш -
                    Цитата Мальчиш @
                    поддержку тех, кто высказывался выше: код - комплит булщит

                    Ну это ваше мнение только.

                    Цитата Мальчиш @
                    помесь WCHAR/TCHAR еще меньшая из твоих проблем

                    Здесь нет никакой помеси. У вас бзик что ли? Или вы вообще не знаете как строятся универсальные приложения с поддержкой UNICODE и без, которая вкл/выкл изменением двух макроопределений.

                    Цитата Мальчиш @
                    goto, вложенные

                    Сделано для простоты. Такие примеры есть в MSDN. Не хотелось использовать __try/__finally/_leave(как сам обычно делаю) в FAQ, а goto он и в африке goto - всем известен.

                    Цитата Мальчиш @
                    if/while'ы фиг знает какого уровня разрывают мозг и воскресное настроение


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

                    Цитата Мальчиш @
                    парсинг строчек, дорогой, neokoder, можно делать более внятными и вменяемыми методами

                    Я жду ваш пример.

                    Цитата Мальчиш @
                    поддерживать такой "КОД", читать его,разбираться невозможно и крайне утомительно..

                    Ваше личное мнение.

                    Цитата Мальчиш @
                    нужно неуважать других, чтобы просить их вникнуть в сие творение мысли заблудшей души

                    О своей заблудшей душе подумайте лучше.

                    Добавлено
                    Я вообще не понимаю, тут спецы по синтаксису языка собрались или же важнее чтобы код правильно работал и решал функциональную задачу :-?
                      В общем всем любителям обрезанного НЕ универсального и потенциально не безопасного кода(хотя бы иногда обращайте внимание на warnings в вашей студии :yes: ), НО зато понятного, читаемого(надеюсь Мальчиш осилит в этот раз и разберется :D ) делаю по вашему заказу, пожалуйста. Плюс сделал разбор строки по-другому. Также заменил goto на try/finally/leave и убрал использование безопасных функций StringCchPrintf.


                      Полный исходный код
                      ExpandedWrap disabled
                        #define UNICODE
                        #define _UNICODE
                        #include <windows.h>
                        #include <stdio.h>
                        #include <conio.h>
                        #include <locale.h>
                        #include <WinIoCtl.h>
                         
                        WCHAR* GetElem(WCHAR *ptr,WCHAR delim,WCHAR *buf)
                        {
                           WCHAR *ptr1=NULL;
                           ptr1=wcschr(ptr,delim);
                           if (ptr1)
                           {
                              wcsncpy(buf,ptr,(int)(ptr1-ptr));
                              buf[(int)(ptr1-ptr)]=0;
                              return (ptr1+1);
                           }
                           else
                           {
                              wcscpy(buf,ptr);
                              return NULL;
                           }
                        }
                         
                        //Входные данные:
                        //IN drive_letter - буква диска
                        void PrintFlashDriveInfo(WCHAR drive_letter)
                        {
                           HKEY hk=NULL;
                           LONG Ret=0;
                           HANDLE hdrive=INVALID_HANDLE_VALUE;
                           DWORD data_size,dtype;
                           WCHAR *data=NULL,*buf1=NULL,*buf2=NULL;
                           WCHAR *ptr1_1=NULL,*ptr1_2=NULL,*ptr2_1=NULL,*ptr2_2=NULL;
                           WCHAR dos_link[50];
                           WCHAR drive_name2[20];
                         
                           __try
                           {
                              //проверяем существует ли диск в системе
                              wsprintf(drive_name2,L"\\\\.\\%c:",drive_letter);
                              hdrive = CreateFileW(drive_name2,0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
                              if (hdrive==INVALID_HANDLE_VALUE)
                              {
                                 wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка CreateFile: %u\n\n",GetLastError());
                                 __leave;
                              }
                              CloseHandle(hdrive);
                         
                              Ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE,L"SYSTEM\\MountedDevices",0,KEY_READ,&hk);
                              if (Ret!=ERROR_SUCCESS)
                              {
                                 wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка RegOpenKeyEx: %u\n\n",Ret);
                                 __leave;
                              }
                         
                              wsprintf(dos_link,L"\\DosDevices\\%c:",drive_letter);
                              Ret=RegQueryValueExW(hk,dos_link,NULL,&dtype,NULL,&data_size);
                              if (Ret==ERROR_SUCCESS)
                              {
                                 data=(WCHAR *)malloc(data_size+2);
                                 buf1=(WCHAR *)malloc(data_size+2);
                                 buf2=(WCHAR *)malloc(data_size+2);
                                 if (data==NULL||buf1==NULL||buf2==NULL)
                                 {
                                    wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка malloc.\n\n");
                                    __leave;
                                 }
                                 memset(data,0,data_size+2);
                         
                                 Ret=RegQueryValueExW(hk,dos_link,NULL,&dtype,(LPBYTE)data,&data_size);
                                 if (Ret!=ERROR_SUCCESS)
                                 {
                                    wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка RegQueryValueEx: %u\n\n",Ret);
                                    __leave;
                                 }
                                 if(wcsstr(data,L"USBSTOR")!=NULL)
                                 {
                                    wprintf(L"Данные флеш-диска %c:\n",drive_letter);
                                    ptr1_1=GetElem(data,L'#',buf1);
                                    if (ptr1_1)
                                    {
                                       ptr1_2=GetElem(ptr1_1,L'#',buf1);
                                       ptr1_1=buf1;
                                       do
                                       {
                                          ptr2_2=GetElem(ptr1_1,L'&',buf2);
                                          if (wcsstr(buf2,L"Ven_"))
                                             wprintf(L"Производитель: %s\n",buf2+4);
                                          else if (wcsstr(buf2,L"Prod_"))
                                             wprintf(L"Название продукта: %s\n",buf2+5);
                                          ptr1_1=ptr2_2;
                                       } while (ptr2_2);
                         
                                       ptr1_1=GetElem(ptr1_2,L'#',buf1);
                                       ptr1_1=buf1;
                                       do
                                       {
                                          ptr2_2=GetElem(ptr1_1,L'&',buf2);
                                          if (wcslen(buf2)>3)
                                          {
                                             wprintf(L"Серийный номер: %s\n",buf2);
                                             break;
                                          }
                                          ptr1_1=ptr2_2;
                                       } while (ptr2_2);
                                    }
                                 }//if USBSTOR
                                 else
                                    wprintf(L"Диск %c: НЕ является флешкой\n",drive_letter);
                              }
                              else
                                 wprintf(L"Ошибка PrintFlashDriveInfo: Ошибка RegQueryValueEx: %u\n",Ret);
                         
                              wprintf(L"\n");
                           }
                           __finally
                           {
                              if (data!=NULL) free(data);
                              if (buf1!=NULL) free(buf1);
                              if (buf2!=NULL) free(buf2);
                              if (hk!=NULL) RegCloseKey(hk);
                           }
                        }
                         
                         
                        int wmain(int argc, WCHAR* argv[])
                        {
                           setlocale(LC_ALL,"Russian");
                         
                           PrintFlashDriveInfo(L'H');
                           PrintFlashDriveInfo(L'G');
                           PrintFlashDriveInfo(L'C');
                           PrintFlashDriveInfo(L'Я');
                          
                           wprintf(L"Нажмите любую клавишу...");
                           _getch();
                           return 0;
                        }
                      Сообщение отредактировано: neokoder -
                        Цитата Мальчиш @
                        поддержку тех, кто высказывался выше: код - комплит булщит
                        помесь WCHAR/TCHAR еще меньшая из твоих проблем
                        goto, вложенные if/while'ы фиг знает какого уровня разрывают мозг и воскресное настроение
                        парсинг строчек, дорогой, neokoder, можно делать более внятными и вменяемыми методами
                        поддерживать такой "КОД", читать его,разбираться невозможно и крайне утомительно.. нужно неуважать других, чтобы просить их вникнуть в сие творение мысли заблудшей души


                        Цитата Мальчиш @
                        в код невникал - какой-то он гнилой, я юзал вот это:



                        B.V., в следующий раз когда вы вновь удивитесь почему neokoder в последнее время неоднократно нарушал правила, хамил я вам советую обратить внимание на причину. А если к тем кто хамит первым не применяются никакие меры, я что не имею право ответить на хамство?
                          кстати goto надо было оставить в коде, это самый лучший вариант для всех компиляторов, ибо __leave поддерживается только Visual Studio.
                            Цитата Dem_max @
                            кстати goto надо было оставить в коде

                            Скажи это Мальчишу.
                              Ничего плохого в goto нету, холивал бесполезен.
                                Цитата neokoder @
                                Ничего плохого в goto нету, холивал бесполезен.

                                Убеди в этом Мальчиша. :)
                                Сообщение отредактировано: neokoder -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0598 ]   [ 16 queries used ]   [ Generated: 27.04.24, 12:36 GMT ]