
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.3] |
![]() |
|
Сообщ.
#1
,
|
|
|
Определить является ли диск съёмным USB Storage Device(флеш-диски, телефоны, подключенные как USB Storage, mp3-плееры и т.д.).
Код универсальный, может работать как с UNICODE, так и с обычной 8-ми битовой ANSI-строкой. 1 Способ Этот способ предпочтительней, так как второй может иногда внешний жесткий диск также определить как съёмное USB-устройство. IsFlashDrive ![]() ![]() //Входные данные: // 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) Простое использование ![]() ![]() __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) Использование с минимальным контролем ошибок ![]() ![]() __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)Использование с полным контролем ошибок ![]() ![]() __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 ![]() ![]() //Входные данные: // 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) Простое использование ![]() ![]() __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) Использование с минимальным контролем ошибок ![]() ![]() __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) Использование с полным контролем ошибок ![]() ![]() __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); } Полный исходный код ![]() ![]() #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; } //-------------------------------------------------------------------------------------------------------------------------- |
Сообщ.
#2
,
|
|
|
Для FAQ тема подходит и...
![]() |
Сообщ.
#3
,
|
|
|
Цитата Бублик @ Для FAQ тема подходит и... по-моему, на 25 Dgm тянет!!! Спасибо за высокую оценку Бублик ![]() ![]() |
Сообщ.
#4
,
|
|
|
надо бы StringCchPrintf заменить на wsprintf ибо StringCchPrintf компиляторозависимое.
да и использование malloc как то не кошерно, лучше через new |
Сообщ.
#5
,
|
|
|
Цитата Dem_max @ надо бы StringCchPrintf заменить на wsprintf ибо StringCchPrintf компиляторозависимое. wsprintf вообще-то уже давно не рекомендуется к использованию по соображениям безопасности. Кому надо пусть меняет. Мне больше нравится как StringCchPrintf обрабатывает ошибки. swprintf_s может организовать вылет из программы, если не использовать дополнительно _set_invalid_parameter_handler, вот эта дополнительность меня лично и обременяет. Цитата Dem_max @ да и использование malloc как то не кошерно, лучше через new Не вижу никаких причин для замены malloc на new. |
![]() |
Сообщ.
#6
,
|
|
Можно было бы придраться и к смешиванию юникода, макроса _T и ANSI, но это уже мелочи
Пост ушел в FAQ |
Сообщ.
#7
,
|
|
|
Цитата B.V. @ Можно было бы придраться и к смешиванию юникода, макроса _T и ANSI, но это уже мелочи Вряд ли ![]() |
Сообщ.
#8
,
|
|
|
в код невникал - какой-то он гнилой, я юзал вот это:
![]() ![]() #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; } |
Сообщ.
#9
,
|
|
|
Цитата Мальчиш @ в код невникал - какой-то он гнилой, я юзал вот это: Ты за базаром следи. Добавлено Цитата Мальчиш @ я юзал вот это: 3 раза ХА ![]() ![]() ![]() ![]() В общем ты в следующий раз прежде чем чей-то код называть гнилым, лучше повысь свой профессиональный навык, а то так умея только делать супер-пупер профессионально парсинг строки ты далеко не уедешь ![]() Главное сам "продемонстрировал" 4-х кратно вложенный IF, а меня в параллельной теме упрекает за чрезмерную вложенность ![]() |