образовательная корпорация
Создать
Править
Отменить
Вверх

Левое меню

Последние

Изменить меня

1
Вкладки

Асгард сеть

Самарт сеть


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, + сверять вендора, продукт ид и серийник флешки с эталонными. Только это все лишь до тех пор, пока кому-нибудь действительно не понадобится запустить программу с другого носителя :)

Есть книжка Агурова. Там все написано, даже исхъодник есть.

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