#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獲得裝置路徑,用來判斷隨身碟裝置 // 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; } // 返回隨身碟裝置控制代碼 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; // 表示多少個隨身碟裝置(可進行讀寫的裝置) 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("隨身碟序號為:"); //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; }