zoukankan      html  css  js  c++  java
  • 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;
    }


  • 相关阅读:
    数组下标索引的循环原来可以这样写
    移位运算>>与>>>
    java调用redis的多种方式与心得
    $.ajax传输js数组,spring接收异常
    div背景css样式笔记
    js监听网页页面滑动滚动事件,实现导航栏自动显示或隐藏
    设置系统时区
    安装与配置文本编辑器vim
    添加阿里云数据源
    spring controller获取web前端post数据乱码解决
  • 原文地址:https://www.cnblogs.com/new0801/p/6177728.html
Copyright © 2011-2022 走看看