www.pudn.com > Usb_Install_2KXP.rar > Usb_Install_2KXPDlg.cpp
// Usb_Install_2KXPDlg.cpp : implementation file // #include "stdafx.h" #include "Usb_Install_2KXP.h" #include "Usb_Install_2KXPDlg.h" #include "Dlg_ProcessIng.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #include// Make all functions UNICODE safe. #include // for SetupDiXxx functions. #include // for the API UpdateDriverForPlugAndPlayDevices(). #include #include "cfgmgr32.h" //need cfgmgr32.lib #define MAX_LEN 128 // Stolen from char HardwareID[MAX_LEN]; int g_iPos = 0; BOOL m_bFinishThread = FALSE; UINT UnInstallThreadProc(LPVOID pParam) { if (!GetHardwareIDFromINF()) { theApp.m_bSuccess = FALSE; goto Exit_Thread; } if (!UnInstallDriver()) { theApp.m_bSuccess = FALSE; goto Exit_Thread; } Exit_Thread: m_bFinishThread = TRUE; return 0; // ends the thread } UINT InstallThreadProc(LPVOID pParam) { if (!InstallDriver()) { theApp.m_bSuccess = FALSE; } m_bFinishThread = TRUE; return 0; // ends the thread } ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CUsb_Install_2KXPDlg dialog CUsb_Install_2KXPDlg::CUsb_Install_2KXPDlg(CWnd* pParent /*=NULL*/) : CDialog(CUsb_Install_2KXPDlg::IDD, pParent) { //{{AFX_DATA_INIT(CUsb_Install_2KXPDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CUsb_Install_2KXPDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CUsb_Install_2KXPDlg) DDX_Control(pDX, IDC_RADIO_INSTALL, m_ctrlRadio_Install); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CUsb_Install_2KXPDlg, CDialog) //{{AFX_MSG_MAP(CUsb_Install_2KXPDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_EXIT, OnButtonExit) ON_BN_CLICKED(IDC_BUTTON_NEXT, OnButtonNext) ON_WM_DESTROY() ON_WM_TIMER() ON_WM_CLOSE() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CUsb_Install_2KXPDlg message handlers BOOL CUsb_Install_2KXPDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here m_pDlgProgress = NULL; m_ctrlRadio_Install.SetCheck(TRUE); return TRUE; // return TRUE unless you set the focus to a control } void CUsb_Install_2KXPDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CUsb_Install_2KXPDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CUsb_Install_2KXPDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CUsb_Install_2KXPDlg::OnButtonExit() { // TODO: Add your control notification handler code here OnOK(); } void CUsb_Install_2KXPDlg::OnButtonNext() { // TODO: Add your control notification handler code here if (!m_pDlgProgress) { m_pDlgProgress = new CDlg_ProcessIng(); if (m_ctrlRadio_Install.GetCheck()) { theApp.bInstall = TRUE; } else { theApp.bInstall = FALSE; } this->ShowWindow(SW_HIDE); theApp.m_bSuccess = TRUE; m_nTimer = SetTimer(1,100,NULL); if ( theApp.bInstall) { AfxBeginThread(InstallThreadProc, GetSafeHwnd(), THREAD_PRIORITY_NORMAL); } else { AfxBeginThread(UnInstallThreadProc, GetSafeHwnd(), THREAD_PRIORITY_NORMAL); } m_pDlgProgress->DoModal(); if (theApp.bInstall) { if (theApp.m_bSuccess) AfxMessageBox("iPOS T700 USB 驱动安装成功!", MB_OK | MB_ICONINFORMATION); else AfxMessageBox("iPOS T700 USB 驱动安装失败!", MB_OK | MB_ICONINFORMATION); } else { if (theApp.m_bSuccess) AfxMessageBox("iPOS T700 USB 驱动卸载成功!", MB_OK | MB_ICONINFORMATION); else AfxMessageBox("iPOS T700 USB 驱动卸载失败!", MB_OK | MB_ICONINFORMATION); } ::Sleep(10); } this->DestroyWindow(); //this->DestroyWindow(); //::InstallDriver(); } // Get the full path of .exe file, not include the filename CString GetFilePath() { CString strPath; ::GetModuleFileName(NULL, strPath.GetBufferSetLength(MAX_LEN + 1), MAX_LEN); strPath.ReleaseBuffer(); int iPos; iPos = strPath.ReverseFind('\\'); strPath = strPath.Left(iPos); return strPath; } //Get the Hardware ID from the .inf file, store the ID in global array HardwareID BOOL GetHardwareIDFromINF() { CString strInfFile(GetFilePath() + "\\iPOS_T700.inf"); char *strFile = (LPSTR)(LPCTSTR)strInfFile; HINF inf_handle; INFCONTEXT inf_context; CString str; // open the .inf file inf_handle = SetupOpenInfFile(strFile, NULL, INF_STYLE_WIN4, NULL); if(inf_handle == INVALID_HANDLE_VALUE) { str.Format("Error : unable to open INF file %s", strFile); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); return FALSE; } // find the .inf file's device description section marked "ROUTON" if(!SetupFindFirstLine(inf_handle, "ROUTON", NULL, &inf_context)) { str.Format("Error: INF file %s does not contain any device descriptions", strFile); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); SetupCloseInfFile(inf_handle); return FALSE; } // Get the hardware ID in "ROUTON" section if(!SetupGetStringField(&inf_context, 2, HardwareID, sizeof(HardwareID), NULL)) { str.Format("Error: cannot get invalid hardware ID from INF file"); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); return FALSE; } // convert the string to lowercase strlwr(HardwareID); return TRUE; } BOOL FindExistingDevice(LPTSTR HardwareId) { HDEVINFO DeviceInfoSet; SP_DEVINFO_DATA DeviceInfoData; DWORD i,err; BOOL bFound = FALSE; CString str; // Create a Device Information Set with all present devices. DeviceInfoSet = SetupDiGetClassDevs(NULL, // All Classes 0, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system if (DeviceInfoSet == INVALID_HANDLE_VALUE) { str.Format("Error: SetupDiGetClassDevs "); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); return FALSE; } // Enumerate through all Devices. bFound = FALSE; DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (i=0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); ++i) { DWORD DataT; LPTSTR p,buffer = NULL; DWORD buffersize = 0; // We won't know the size of the HardwareID buffer until we call // this function. So call it with a null to begin with, and then // use the required buffer size to Alloc the nessicary space. // Keep calling we have success or an unknown failure. while (!SetupDiGetDeviceRegistryProperty( DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, &DataT, (PBYTE)buffer, buffersize, &buffersize)) { if (GetLastError() == ERROR_INVALID_DATA) { // May be a Legacy Device with no HardwareID. Continue. break; } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // We need to change the buffer size. if (buffer) { LocalFree(buffer); } buffer = (char *)LocalAlloc(LPTR,buffersize); } else { // Unknown Failure. str.Format("Error: SetupDiGetDeviceRegistryProperty unknown Failure"); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); goto cleanup_DeviceInfo; } } if (GetLastError() == ERROR_INVALID_DATA) { continue; } // Compare each entry in the buffer multi-sz list with our HardwareID. for (p=buffer; (*p) && (p < &buffer[buffersize]); p += lstrlen(p) + sizeof(TCHAR)) { // convert the string to lowercase strlwr(p); if (!_tcscmp(HardwareId,p)) { bFound = TRUE; break; } } if (buffer) { LocalFree(buffer); } if (bFound) { break; } } if (GetLastError() != NO_ERROR) { str.Format("Error: EnumDeviceInfo Failure"); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); } // Cleanup. cleanup_DeviceInfo: err = GetLastError(); SetupDiDestroyDeviceInfoList(DeviceInfoSet); SetLastError(err); return err == NO_ERROR; } BOOL InstallRootEnumeratedDriver(LPTSTR HardwareId, LPTSTR INFFile, PBOOL RebootRequired) { HDEVINFO DeviceInfoSet = 0; SP_DEVINFO_DATA DeviceInfoData; GUID ClassGUID; TCHAR ClassName[MAX_LEN]; DWORD err; CString str; // Use the INF File to extract the Class GUID. if (!SetupDiGetINFClass(INFFile,&ClassGUID,ClassName,sizeof(ClassName),0)) { str.Format("Error : SetupDiGetINFClass "); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); return FALSE; } // Create the container for the to-be-created Device Information Element. DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0); if(DeviceInfoSet == INVALID_HANDLE_VALUE) { str.Format("Error : SetupDiCreateDeviceInfoList"); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); return FALSE; } // Now create the element. // Use the Class GUID and Name from the INF file. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); if (!SetupDiCreateDeviceInfo(DeviceInfoSet, ClassName, &ClassGUID, NULL, 0, DICD_GENERATE_ID, &DeviceInfoData)) { str.Format("Error : SetupDiCreateDeviceInfo"); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); goto cleanup_DeviceInfo; } // Add the HardwareID to the Device's HardwareID property. if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, (LPBYTE)HardwareId, (lstrlen(HardwareId)+1+1)*sizeof(TCHAR))) { str.Format("Error : SetupDiSetDeviceRegistryProperty"); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); goto cleanup_DeviceInfo; } // Transform the registry element into an actual devnode // in the PnP HW tree. if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DeviceInfoSet, &DeviceInfoData)) { str.Format("Error : SetupDiCallClassInstaller"); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); goto cleanup_DeviceInfo; } // The element is now registered. We must explicitly remove the // device using DIF_REMOVE, if we encounter any failure from now on. // // Install the Driver. // if (!UpdateDriverForPlugAndPlayDevices(0, HardwareId, INFFile, INSTALLFLAG_FORCE, RebootRequired)) { DWORD err = GetLastError(); if (!SetupDiCallClassInstaller( DIF_REMOVE, DeviceInfoSet, &DeviceInfoData)) { //DisplayError(TEXT("CallClassInstaller(REMOVE)")); } SetLastError(err); } // Cleanup. cleanup_DeviceInfo: err = GetLastError(); SetupDiDestroyDeviceInfoList(DeviceInfoSet); SetLastError(err); return !(err == NO_ERROR); } //Install USB Driver with INF file, but must get the Hardware ID first BOOL InstallDriver() { BOOL RebootRequired = 0; CString str; // Get the HardwareID from INF file, must be first do it. if (!GetHardwareIDFromINF()) { return FALSE; } CString strInfFile(GetFilePath() + "\\iPOS_T700.inf"); char *inf_file = (LPSTR)(LPCTSTR)strInfFile; // Look to see if this device already exists. if (FindExistingDevice(HardwareID)) { // No Need to Create a Device Node, just call our API. if (!UpdateDriverForPlugAndPlayDevices(0, // No Window Handle HardwareID, // Hardware ID inf_file, // INF FileName INSTALLFLAG_FORCE, &RebootRequired)) { str.Format("Error : UpdateDriverForPlugAndPlayDevices"); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); return FALSE; } } else { if (GetLastError()!= ERROR_NO_MORE_ITEMS) { // An unknown failure from FindExistingDevice() str.Format("Error : An unknown failure from FindExistingDevice"); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); return FALSE; } // Driver Does not exist, Create and call the API. // HardwareID must be a multi-sz string, which HardwareID is. if (!InstallRootEnumeratedDriver(HardwareID, // HardwareID inf_file, // INF FileName &RebootRequired)) { str.Format("Error : InstallRootEnumeratedDriver"); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); return FALSE; } } return TRUE; } //Uninstall driver with Hardware ID BOOL UnInstallDriver() { HDEVINFO DeviceInfoSet; SP_DEVINFO_DATA DeviceInfoData; DWORD i,err; CString str; // Create a Device Information Set with Special devices. DeviceInfoSet = SetupDiGetClassDevs(NULL, // Special devices 0, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT ); // Special devices present on system if (DeviceInfoSet == INVALID_HANDLE_VALUE) { str.Format("GetClassDevs(Special Present Devices) Error"); AfxMessageBox(str, MB_OK | MB_ICONQUESTION); return FALSE; } // Enumerate through Devices. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (i=0;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++) { DWORD DataT; LPTSTR p,buffer = NULL; DWORD buffersize = 0; // We won't know the size of the HardwareID buffer until we call // this function. So call it with a null to begin with, and then // use the required buffer size to Alloc the nessicary space. // Keep calling we have success or an unknown failure. while (!SetupDiGetDeviceRegistryProperty( DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, &DataT, (PBYTE)buffer, buffersize, &buffersize)) { if (GetLastError() == ERROR_INVALID_DATA) { // May be a Legacy Device with no HardwareID. Continue. break; } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // We need to change the buffer size. if (buffer) { LocalFree(buffer); } buffer =(char *)LocalAlloc(LPTR,buffersize); } else { // Unknown Failure. goto cleanup_DeviceInfo; } } if (GetLastError() == ERROR_INVALID_DATA) continue; // Compare each entry in the buffer multi-sz list with our HardwareID. for ( p=buffer; *p&&(p<&buffer[buffersize]); p+=lstrlen(p)+sizeof(TCHAR)) { // convert the string to lowercase strlwr(p); if (!strcmp(HardwareID, p)) { // Worker function to remove device. if (!SetupDiCallClassInstaller(DIF_REMOVE, DeviceInfoSet, &DeviceInfoData)) { //_tprintf(TEXT("CallClassInstaller(REMOVE) error\n")); } break; } } if (buffer) { LocalFree(buffer); } } if ((GetLastError()!=NO_ERROR)&&(GetLastError()!=ERROR_NO_MORE_ITEMS)) { //_tprintf(TEXT("EnumDeviceInfo error")); } // Cleanup. cleanup_DeviceInfo: err = GetLastError(); SetupDiDestroyDeviceInfoList(DeviceInfoSet); SetLastError(err); return err == NO_ERROR; } void CUsb_Install_2KXPDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: Add your message handler code here if (m_pDlgProgress) { delete m_pDlgProgress; m_pDlgProgress = NULL; } } void CUsb_Install_2KXPDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default g_iPos += 10; m_pDlgProgress->m_ctrl_Progress.SetPos(g_iPos); if ((m_bFinishThread) && (g_iPos >= 80)) { m_pDlgProgress->m_ctrl_Progress.SetPos(100); int ret = 0; m_pDlgProgress->EndDialog(ret); KillTimer(m_nTimer); } CDialog::OnTimer(nIDEvent); } void CUsb_Install_2KXPDlg::OnClose() { // TODO: Add your message handler code here and/or call default if (m_pDlgProgress) { delete m_pDlgProgress; m_pDlgProgress = NULL; } CDialog::OnClose(); }