Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.190.152.38] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Получить инфо о серийном номере, производителе и названии USB Storage Device.
Если тестируемый диск является съёмным диском USB Storage Device(флешка, телефон, mp3-плеер и т.д.) функция PrintFlashDriveInfo печатает название производителя устройства, название продукта и серийный номер устройства. Если диск не является USB Storage Device, то выводится об этом сообщение. Функция работает с полным контролем ошибок. При необходимости получения выходных параметров(серийный номер, вендор, название) в качестве переменных вместо печати, функция легко переделывается: можно ввести дополнительный выходной параметр-структуру из 3-х строк и их размеров и заполнять её вместо печати. Примечание: при получении инфо о USB-устройстве таким способом, иногда внешний жесткий диск также может определиться как съёмное USB-устройство. В этом случае можно ввести доп. проверку того является ли диск съёмным USB Storage Device (1 Способ по ссылке) PrintFlashDriveInfo 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); } } Использование PrintFlashDriveInfo(_T('G')); PrintFlashDriveInfo(_T('C')); PrintFlashDriveInfo(_T('H')); PrintFlashDriveInfo(_T('I')); Полный исходный код #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. |
Сообщ.
#2
,
|
|
|
А вот здесь уже слишком много смешений wcs* и _t*-функций. neokoder, можешь привести их все к одному виду?
|
Сообщ.
#3
,
|
|
|
Цитата B.V. @ А вот здесь уже слишком много смешений wcs* и _t*-функций. neokoder, можешь привести их все к одному виду? Смешений? Нет никаких смешений, B.V., здесь всё используется так как надо. Изначально я и сделал так как ты запрашиваешь, но при выключении юникода функции не будут работать, поскольку в реестре все бинарные данные хранятся в юникоде(по крайней мере у меня на Win7, но думаю что в XP таже). Именно поэтому для работы со строкой реестра можно ипользовть только WCHAR. Всё остальное универсально, настроено на работу как с Юникодом так и без него. Можешь попробовать заменить: #define UNICODE #define _UNICODE на #undef UNICODE #undef _UNICODE Всё будет работать без проблем. |
Сообщ.
#4
,
|
|
|
Цитата Смешений? Нет никаких смешений Если нет, тогда убери из исходников это #include <tchar.h> так как у тебя только юникод используется. |
Сообщ.
#5
,
|
|
|
Цитата Dem_max @ Если нет, тогда убери из исходников это #include <tchar.h> так как у тебя только юникод используется. Надо думать прежде чем писать, Dem_max. |
Сообщ.
#6
,
|
|
|
Цитата neokoder @ Изначально я и сделал так как ты запрашиваешь, но при выключении юникода функции не будут работать, поскольку в реестре все бинарные данные хранятся в юникоде(по крайней мере у меня на Win7, но думаю что в XP таже). Так и переведи весь вывод на юникод, к чему выводить одни сообщения посредством tprintf, а другие -- юникодным wprintf? В рамках данного кода переносимости нет, а отдельные его фрагменты вряд ли кто будет использовать, применение tchar неоправданно |
Сообщ.
#7
,
|
|
|
Я устал уже доказывать, B.V.. Честное слово. Как в стенку лбом.
Цитата neokoder @ Всё остальное универсально, настроено на работу как с Юникодом так и без него Почему ты хочешь отнять универсальность кода? |
Сообщ.
#8
,
|
|
|
поддержку тех, кто высказывался выше: код - комплит булщит
помесь WCHAR/TCHAR еще меньшая из твоих проблем goto, вложенные if/while'ы фиг знает какого уровня разрывают мозг и воскресное настроение парсинг строчек, дорогой, neokoder, можно делать более внятными и вменяемыми методами поддерживать такой "КОД", читать его,разбираться невозможно и крайне утомительно.. нужно неуважать других, чтобы просить их вникнуть в сие творение мысли заблудшей души |
Сообщ.
#9
,
|
|
|
Цитата Мальчиш @ поддержку тех, кто высказывался выше: код - комплит булщит Ну это ваше мнение только. Цитата Мальчиш @ помесь WCHAR/TCHAR еще меньшая из твоих проблем Здесь нет никакой помеси. У вас бзик что ли? Или вы вообще не знаете как строятся универсальные приложения с поддержкой UNICODE и без, которая вкл/выкл изменением двух макроопределений. Цитата Мальчиш @ goto, вложенные Сделано для простоты. Такие примеры есть в MSDN. Не хотелось использовать __try/__finally/_leave(как сам обычно делаю) в FAQ, а goto он и в африке goto - всем известен. Цитата Мальчиш @ if/while'ы фиг знает какого уровня разрывают мозг и воскресное настроение Ну так продемонстрируйте как надо разбирать строку, может у вас действительно будет более наглядный и классный код, исправлю. Честно говоря я делал быстро и не задумывался нд эффективностью. Цель этого кода - определить информацию, это главная задача, а не сделать супер-пупер наилучший пример парсинга строки. Цитата Мальчиш @ парсинг строчек, дорогой, neokoder, можно делать более внятными и вменяемыми методами Я жду ваш пример. Цитата Мальчиш @ поддерживать такой "КОД", читать его,разбираться невозможно и крайне утомительно.. Ваше личное мнение. Цитата Мальчиш @ нужно неуважать других, чтобы просить их вникнуть в сие творение мысли заблудшей души О своей заблудшей душе подумайте лучше. Добавлено Я вообще не понимаю, тут спецы по синтаксису языка собрались или же важнее чтобы код правильно работал и решал функциональную задачу |
Сообщ.
#10
,
|
|
|
В общем всем любителям обрезанного НЕ универсального и потенциально не безопасного кода(хотя бы иногда обращайте внимание на warnings в вашей студии ), НО зато понятного, читаемого(надеюсь Мальчиш осилит в этот раз и разберется ) делаю по вашему заказу, пожалуйста. Плюс сделал разбор строки по-другому. Также заменил goto на try/finally/leave и убрал использование безопасных функций StringCchPrintf.
Полный исходный код #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; } |
Сообщ.
#11
,
|
|
|
Цитата Мальчиш @ поддержку тех, кто высказывался выше: код - комплит булщит помесь WCHAR/TCHAR еще меньшая из твоих проблем goto, вложенные if/while'ы фиг знает какого уровня разрывают мозг и воскресное настроение парсинг строчек, дорогой, neokoder, можно делать более внятными и вменяемыми методами поддерживать такой "КОД", читать его,разбираться невозможно и крайне утомительно.. нужно неуважать других, чтобы просить их вникнуть в сие творение мысли заблудшей души B.V., в следующий раз когда вы вновь удивитесь почему neokoder в последнее время неоднократно нарушал правила, хамил я вам советую обратить внимание на причину. А если к тем кто хамит первым не применяются никакие меры, я что не имею право ответить на хамство? |
Сообщ.
#12
,
|
|
|
кстати goto надо было оставить в коде, это самый лучший вариант для всех компиляторов, ибо __leave поддерживается только Visual Studio.
|
Сообщ.
#13
,
|
|
|
Цитата Dem_max @ кстати goto надо было оставить в коде Скажи это Мальчишу. |
Сообщ.
#14
,
|
|
|
Ничего плохого в goto нету, холивал бесполезен.
|
Сообщ.
#15
,
|
|
|
Цитата neokoder @ Ничего плохого в goto нету, холивал бесполезен. Убеди в этом Мальчиша. |