FSC, ну логично слямздить идею у работающих проэктов. Не помню где но встречал прогу которая запускалась при наличие флэшки с файлами. Но там был не перезаписуемый флэш накопитель. Ну а вам можно просто в обычную флэш закинуть файлик и проверять дату его изменения (что бы не накопировали гору таких флэш) или спрятать на флэшке какой нибудь файлик и всё. А потом при запуске проги сканировать все корневые каталоги дисков на наличие вашего файла.
нашел пример, которая вытаскивает аппаратный серийный номер флешки (наконец-то) не постесняюсь выложить код. Честно говоря у меня было такое ощущение, что люди постеснялись выложить код
но одна проблема встала: как мне серийный номер привязать к букве флешки?
Код C++ //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include <stdio.h> #include <windows.h> #include <Setupapi.h> #include <devguid.h> #include "conio.h" #include "tchar.h" //#include <devguid.h> DEFINE_GUID( GUID_DEVCLASS_USB,0x36FC9E60, 0xC465, 0x11CF, 0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 ); #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { HDEVINFO deviceInfoSet; GUID *guidDev = (GUID*) &GUID_DEVCLASS_USB; deviceInfoSet = SetupDiGetClassDevs(guidDev, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE); TCHAR buffer [4000]; int memberIndex = 0; while (true) { SP_DEVINFO_DATA deviceInfoData; ZeroMemory(&deviceInfoData, sizeof(SP_DEVINFO_DATA)); deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); if (SetupDiEnumDeviceInfo(deviceInfoSet, memberIndex, &deviceInfoData) == FALSE) { if (GetLastError() == ERROR_NO_MORE_ITEMS) { break; } } DWORD nSize=0 ; SetupDiGetDeviceInstanceId (deviceInfoSet, &deviceInfoData, buffer, sizeof(buffer), &nSize); buffer [nSize] ='\0'; _tprintf (_T("%s\n"), buffer); memberIndex++; //Label1->Caption=String(buffer); if (String(buffer).SubString(1,8)=="USB\\VID_") ShowMessage(String(buffer)); // AnsiString dsa; dsa=dsa.SubString(dsa.Pos("USB\\"),) } if (deviceInfoSet) { SetupDiDestroyDeviceInfoList(deviceInfoSet); } } //---------------------------------------------------------------------------
программа возвращает VID, PID и серийный номер в виде USB\VID_XXXX_PID_YYYY\ZZZZ, где XXXX-VID, YYYY-PID, ZZZZ-Серийный номер (Аппаратный!!!!!! который я так долго искал)
Программный серийный номер можно легко достать функцией GetVolumeInformation
Код C++ char FindFlash() // ищет флешку и если находит возвращает букву диска { char charRootPath[10]; bool bHave; UINT dt; for (charRootPath[0] = TEXT('c'); charRootPath[0] <= TEXT('z'); charRootPath[0]++) { // ищем флэшку charRootPath[1] = TEXT(':'); dt = GetDriveType(charRootPath); if (dt == DRIVE_REMOVABLE) { bHave = TRUE; break; } else bHave = FALSE; } if (bHave==true) { // если нашли то получаем информацию о флэшки char VolumeName[50]; char FSName[50]; GetVolumeInformation(charRootPath, VolumeName, 50, NULL, NULL, NULL, FSName, 50); char word[10]; char m_csFlashName[50]; int m_dwTotalSizeFlash; int m_dwFreespaceFlash; bool bEndTheard; word[0] = charRootPath[0]; // word[1]+="\0"; DWORD SecPerClaster, BytesPerSec, NumFreeClaster, TotalNumClaster; GetDiskFreeSpace(word, &SecPerClaster, &BytesPerSec, &NumFreeClaster, &TotalNumClaster); int freesize= (SecPerClaster * BytesPerSec * NumFreeClaster)/1024; int totalsize = (SecPerClaster * BytesPerSec * TotalNumClaster)/1024; if (VolumeName[0]==' ') strcpy(VolumeName, "NONAME"); m_csFlashName[0] = VolumeName[0]; m_dwTotalSizeFlash = totalsize; m_dwFreespaceFlash = freesize; bEndTheard = FALSE; bool bStartStore; bStartStore=TRUE; return word[0]; } else return NULL; }
Привязка к железу
Автор: C0ffe1n
дата: 11 марта 2009 года
сайт: http://z.alko-net.ru
Иногда в программах необходимо использовать возможность проверки типа носителя или его серийный номер. Причины могут быть разными от банального контроля устройств в системе до средств защит использующих привязку к железу. Сейчас я вам покажу как с помощью API реализовать эту простую задачу.
Нам понадобится всего 2 API - функции:
GetDriveType - определяет и возвращает тип носителя; GetVolumeInformation - определяет информацию о носителе, среди которой содержится серийный номер.
Рассмотрим описание этих функций для С++ и Delphi. Первой будет функция GetDriveType, она очень простая и использует всего один параметр - указатель на том. Например «c:\»,«a:\» и т.д. Функция возвращает одно из следующих значений:
DRIVE_UNKNOWN - 0 : диск неопределен/не существует DRIVE_NO_ROOT_DIR - 1 : неверный путь/ путь не указывает на том DRIVE_REMOVABLE - 2 : тип устройства определяется как съемный (дискета, флешка и т.д.) DRIVE_FIXED - 3 : тип устройства - фиксированный диск (жесткий диск) DRIVE_REMOTE - 4 : тип устройства - удаленный(сетевой) диск DRIVE_CDROM - 5 : это устройство CD-ROM DRIVE_RAMDISK - 6 : виртуальный диск, созданный в оперативной памяти
C/C++ UINT WINAPI GetDriveType( LPCTSTR lpRootPathName //путь к диску ); Delphi function GetDriveType( lpRootPathName: PChar //путь к диску ): UINT; stdcall;
Замечание: Если в качестве параметра указать для С/С++ NULL, а для Delphi - nil то тип устройства будет определяться для текущего диска (с которого была запущена программа).
А теперь взглянем на функцию GetVolumeInformation. Тоже достаточно простая функция, однако использует параметров значительно больше.
C/C++
BOOL WINAPI GetVolumeInformation( LPCTSTR lpRootPathName, //путь к сетевому или локальному // тому (пример: "\\MyServer\MyShare\" или "C:\". LPTSTR lpVolumeNameBuffer, //буфер - в котором будет храниться // имя тома DWORD nVolumeNameSize, //размер буфера LPDWORD lpVolumeSerialNumber, //серийный номер тома LPDWORD lpMaximumComponentLength, //размер тома LPDWORD lpFileSystemFlags, //тип файловой системы LPTSTR lpFileSystemNameBuffer, //название файловой системы DWORD nFileSystemNameSize //размер буфера под название ФС ); Delphi function GetVolumeInformation( lpRootPathName: PChar; //путь к сетевому или локальному //тому (пример: "\\MyServer\MyShare\" или "C:\". lpVolumeNameBuffer: PChar; //буфер - в котором будет храниться // имя тома nVolumeNameSize: DWORD; //размер буфера lpVolumeSerialNumber: PDWORD; //серийный номер тома var lpMaximumComponentLength, lpFileSystemFlags: DWORD; //размер // тома и тип файловой системы lpFileSystemNameBuffer: PChar; //название файловой системы nFileSystemNameSize: DWORD //размер буфера под название ФС ): BOOL; stdcall;
Замечание: Если в качестве первого параметра указать для С/С++ NULL, а для Delphi - nil то функция будет выполняется для текущего диска (с которого была запущена программа).
Ну а теперь собственно для пущего интересу приведу пример, как привязать программу к устройству. В данном примере будем привязывать программу к флешке. Смотрим пример:
C/C++
#include #include #include #include using namespace std; int main() { // Получаем тип носителя с которого запущена программа unsigned int drive_type = GetDriveType( NULL ); char VolumeNameBuffer[100]; char FileSystemNameBuffer[100]; DWORD sz,fs; unsigned long drive_sn; GetVolumeInformationA( NULL, VolumeNameBuffer, 100, &drive_sn, sz, fs, FileSystemNameBuffer, 100 ); cout << "Volume serial number:\t"; if(drive_sn == 1018821877) //сравниваем серийный номер cout << "correct" << endl; else cout << "invalid" << endl; cout << "Drive type:\t"; if(drive_type == DRIVE_REMOVABLE) cout << "correct" << endl; else cout << "invalid" << endl; getch(); } Delphi program Project1; {$APPTYPE CONSOLE} uses SysUtils,windows; var SerialNum,dtyp:DWORD; a,b:DWORD; Buffer,disk :Array[0..255]of char; begin dtyp:=GetDriveType(nil); if dtyp = DRIVE_REMOVABLE then writeln('Disk(type): Yes') else writeln('Disk(type): No'); GetVolumeInformation( nil, Buffer, sizeof(Buffer), @SerialNum, a, b, nil, 0); if SerialNum = 1018821877 then //сравниваем серийный номер writeln('S\N: Yes') else writeln('S\N: No'); readln; end.
Замечание: Может возникнуть вопрос, а как узнать серийник диска, чтобы знать с чем сравнивать? Очень просто, для этого пишем тестовую прогу, в которой пишем следующий код:
C/C++
…
GetVolumeInformationA(NULL, VolumeNameBuffer,100, &drive_sn,sz,fs,FileSystemNameBuffer,100);
…
Delphi
…
GetVolumeInformation(nil,Buffer,sizeof(Buffer), @SerialNum, a,b, nil, 0); writeln('S/N drive: ',SerialNum); readln;
…
Первое, что приходит на ум, это привязка к MBR. А туда в неиспользуемую область можно еще пару байт записать, а в проге проверить всё совпадает или нет.
Проверять, что программа запускается с removable device, + сверять вендора, продукт ид и серийник флешки с эталонными. Только это все лишь до тех пор, пока кому-нибудь действительно не понадобится запустить программу с другого носителя :)
Есть книжка Агурова. Там все написано, даже исхъодник есть.
хранить прогу в зашифрованом виде, ключ - какая-нибудь строка в служебной области - бутсекторе, мбр и др. или серийник флэшки. и написать запускальщик, который будет ее расшифровывать и запускать, а дождавшись завершения - затирать и удалять.
Инструменты страницы
