VC++实现U盘开机锁


请见代码分析

#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <initguid.h>
#include <setupapi.h>
#include <string.h>


#define MAX_DEVICE 256
wchar_t USBSerial[5][100] = {TEXT("")};
int gTag = 0;
DEFINE_GUID(UsbClassGuid, 0xa5dcbf10L, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed);
// SetupDiGetInterfaceDeviceDetail所需要的输出长度,定义足够大
#define INTERFACE_DETAIL_SIZE    (1024)
// IOCTL控制码
#define IOCTL_STORAGE_QUERY_PROPERTY   CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)

#pragma comment(lib,"setupapi.lib")


//自动关机函数
void ExitWindowsCode()
{   
	OSVERSIONINFO   stOSVI;   
    ZeroMemory(&stOSVI   ,   sizeof   (   OSVERSIONINFO   ))   ;   
    stOSVI.dwOSVersionInfoSize   =   sizeof   (   OSVERSIONINFO   )   ;   
    if (!GetVersionEx   (   &stOSVI   ))   return;   
            
    if ( ( VER_PLATFORM_WIN32_NT == stOSVI.dwPlatformId ) && (  4  <= stOSVI.dwMajorVersion ) )   
    {   
	   HANDLE   hToken;       
       TOKEN_PRIVILEGES   tkp;       
       if   (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES   |   TOKEN_QUERY,   &hToken))       
         return;   
      // Get the LUID for the shutdown privilege.       
      LookupPrivilegeValue(NULL,   SE_SHUTDOWN_NAME,   &tkp.Privileges[0].Luid);       
    
      tkp.PrivilegeCount   =   1;   //   one   privilege   to   set       
      tkp.Privileges[0].Attributes   =   SE_PRIVILEGE_ENABLED;       
      AdjustTokenPrivileges(hToken,   FALSE,   &tkp,   0,(PTOKEN_PRIVILEGES)NULL,   0);       
    
      if   (GetLastError()   !=   ERROR_SUCCESS)       
        return;   
    
      if   (!ExitWindowsEx(EWX_SHUTDOWN   |   EWX_FORCE|EWX_POWEROFF,   0))       
        return;   
    
     }   
     else//WIN9X   
     {
		 ExitWindowsEx(EWX_SHUTDOWN   |   EWX_FORCE   |   EWX_POWEROFF,   0);//   关机   
     } 
}

// 根据GUID获得设备路径,用来判断U盘设备
// lpGuid: GUID指针
// pszDevicePath: 设备路径指针的指针
// 返回: 成功得到的设备路径个数,可能不止1个
int GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)
{
    HDEVINFO hDevInfoSet;    //设备信息集句柄;
    SP_DEVICE_INTERFACE_DATA ifdata;
    PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;
    int nCount;
    BOOL bResult;

    // 取得一个该GUID相关的设备信息集句柄
    hDevInfoSet = ::SetupDiGetClassDevs((LPGUID)&UsbClassGuid,     // class GUID 
        NULL,                    // 无关键字
        NULL,                    // 不指定父窗口句柄
        DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);    // 目前存在的设备

    // 失败...
    if (hDevInfoSet == INVALID_HANDLE_VALUE)
    {
      return 0;
    }

    // 申请设备接口数据空间
    pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);

    pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    nCount = 0;
    bResult = TRUE;

    // 设备序号=0,1,2... 逐一测试设备接口,到失败为止
    while (bResult)
    {
        ifdata.cbSize = sizeof(ifdata);

        // 枚举符合该GUID的设备接口
        bResult = ::SetupDiEnumDeviceInterfaces(
            hDevInfoSet,     // 设备信息集句柄
            NULL,            // 不需额外的设备描述
            lpGuid,          // GUID
            (ULONG)nCount,   // 设备信息集里的设备序号
            &ifdata);        // 设备接口信息

        if (bResult)
        {
            // 取得该设备接口的细节(设备路径)
            bResult = SetupDiGetInterfaceDeviceDetail(
                hDevInfoSet,    // 设备信息集句柄
                &ifdata,        // 设备接口信息
                pDetail,        // 设备接口细节(设备路径)
                INTERFACE_DETAIL_SIZE,   // 输出缓冲区大小
                NULL,           // 不需计算输出缓冲区大小(直接用设定值)
                NULL);          // 不需额外的设备描述
            if (bResult)
            {
                // 复制设备路径到输出缓冲区
                wcscpy_s(pszDevicePath[nCount],wcslen(pDetail->DevicePath)+1, pDetail->DevicePath);
               // 调整计数值
                nCount++;
            }
        }
    }
    // 释放设备接口数据空间
    ::GlobalFree(pDetail);
    // 关闭设备信息集句柄
    ::SetupDiDestroyDeviceInfoList(hDevInfoSet);
   return nCount;
}

// 返回U盘设备句柄 hDevice
HANDLE OpenDevice(wchar_t* DevicePath)
{
	HANDLE hDevice;
    hDevice = CreateFileW(DevicePath,
		GENERIC_READ && GENERIC_WRITE,
        FILE_SHARE_READ && FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        0,
        NULL);
	return hDevice;
}

int _stdcall WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) 
{
	int i, nDevice; // nDevice 表示有多少个USB设备
	int ndevice = 0; // 表示多少个U盘设备(可进行读写的设备)
    wchar_t* szDevicePath[MAX_DEVICE];        // 设备路径
	HANDLE hDevice;

    // DWORD dwOutBytes; // IOCTL输出数据长度
    // 定义一个 PSTORAGE_DEVICE_DESCRIPTOR 变量,存放设备属性
    PSTORAGE_DEVICE_DESCRIPTOR DeviceDesc;
    // 变量初始化
    DeviceDesc=(PSTORAGE_DEVICE_DESCRIPTOR)new BYTE[sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1];
    DeviceDesc->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1;

    // 分配需要的空间
    for (i = 0; i < MAX_DEVICE; i++)
    {
        szDevicePath[i] = new wchar_t[256];
    }

    // 取设备路径
    nDevice = ::GetDevicePath((LPGUID)&UsbClassGuid, szDevicePath);


    // 逐一获取设备信息
	for (i = 0; i < nDevice; i++)
    {
        // 打开设备
        hDevice = OpenDevice(szDevicePath[i]);
     
        if (hDevice != INVALID_HANDLE_VALUE)
        {
			for(int j = 0; j < 4; j++)
			{
                USBSerial[ndevice][j] = szDevicePath[i][j+12]; 
			}
			for(int j = 4; j < 28; j++)
            {
                USBSerial[ndevice][j] = szDevicePath[i][j+22]; 
            }
            //printf("U盘序列号为:");
            //wprintf(L"%ws\n", USBSerial[ndevice]);
            ndevice ++;
     
            ::CloseHandle(hDevice);
         }
		

    } 

    // 释放空间
    for (i = 0; i < MAX_DEVICE; i++)
    {
        delete []szDevicePath[i];
    }

////////////////// 文件操作 ////////////////////////////////////////
HANDLE hFile; 
DWORD nBytesRead = 0, dwBytesWritten = 0;

    
   

// 打开文件
hFile = CreateFile(TEXT("C:\\Windows\\system32\\USBID.ID"),    // file to open
                   GENERIC_READ | GENERIC_WRITE,          // open for reading
                   FILE_SHARE_READ | FILE_SHARE_WRITE,       // share for reading
                   NULL,                  // default security
                   OPEN_EXISTING ,         // existing file only
                   FILE_ATTRIBUTE_NORMAL, // normal file
                   NULL);                 // no attr. template
if (hFile != INVALID_HANDLE_VALUE)
{
	long nFileSize = GetFileSize(hFile, NULL);
	if (nFileSize == 0)
	{
		bool flag2 = CloseHandle(hFile);
		
		if(::SetFileAttributes(TEXT("C:\\Windows\\system32\\USBID.ID"),FILE_ATTRIBUTE_NORMAL))
		{
		   if (DeleteFile(TEXT("C:\\Windows\\system32\\USBID.ID")))
		   {
			   //MessageBox(NULL,TEXT("oo"),TEXT("oo"),MB_OK);
		   }
		}
	}
}


// 打开文件
hFile = CreateFile(TEXT("C:\\Windows\\system32\\USBID.ID"),    // file to open
                   GENERIC_READ | GENERIC_WRITE,          // open for reading
                   FILE_SHARE_READ | FILE_SHARE_WRITE,       // share for reading
                   NULL,                  // default security
                   OPEN_EXISTING ,         // existing file only
                   FILE_ATTRIBUTE_NORMAL, // normal file
                   NULL);                 // no attr. template
if (hFile == INVALID_HANDLE_VALUE) 
{
   hFile = CreateFile(TEXT("C:\\Windows\\system32\\USBID.ID"),     // file to create
                   GENERIC_READ | GENERIC_WRITE,          // open for writing
                   FILE_SHARE_READ | FILE_SHARE_WRITE,                      // do not share
                   NULL,                   // default security
                   CREATE_ALWAYS,          // overwrite existing
                   FILE_ATTRIBUTE_NORMAL | // normal file
                   FILE_ATTRIBUTE_NORMAL,   // asynchronous I/O
                   NULL); 
  
}
else
{
	if (ndevice < 1)
	   {
		   ExitWindowsCode();
	   }
}
long nFileSize = GetFileSize(hFile, NULL);
wchar_t   *tempbuf =   new   wchar_t[nFileSize]   ; 
// 读文件内容
if (nFileSize == 0) 
{ 
   // 创建文件,并把序列号写入文件中
   hFile = CreateFile(TEXT("C:\\Windows\\system32\\USBID.ID"),     // file to create
                   GENERIC_READ | GENERIC_WRITE,          // open for writing
                   FILE_SHARE_READ | FILE_SHARE_WRITE,                      // do not share
                   NULL,                   // default security
                   CREATE_ALWAYS,          // overwrite existing
                   FILE_ATTRIBUTE_NORMAL | // normal file
                   FILE_ATTRIBUTE_NORMAL,   // asynchronous I/O
                   NULL);                  // no attr. template

   if (hFile == INVALID_HANDLE_VALUE) 
    { 
     return 0; 
    }
   // 把序列号写入文件中
   WriteFile(hFile, 
      USBSerial, 
      2*wcslen(* USBSerial), 
      &dwBytesWritten, 
      NULL); 
   nFileSize = GetFileSize(hFile, NULL);

   if (nFileSize == 0)
   {
	   bool flag1 = CloseHandle(hFile);
   }
   else
   {
	   if (ndevice < 1)
	   {
		   ExitWindowsCode();
	   }
   }

}
else
{
   //进入比较序列号
   ReadFile(hFile, 
    tempbuf, 
    nFileSize, 
    &nBytesRead, 
    NULL);

   // 比较已经有的序列号与新读的是否相等
   for(int i = 0; i< ndevice; i ++)
   {
    for(int j = 0; j < nFileSize/2; j++)
    {
     if(tempbuf[j] == USBSerial[i][j])    
        gTag = 1;
     else
	 {
	    ExitWindowsCode();
	 }
    }
    if(gTag == 1)
     break;

   }
   delete tempbuf;
}
return 0;
}


原文地址:https://www.cnblogs.com/new0801/p/6177728.html