⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 install.cpp

📁 一个用VC开发的驱动程序安装卸载程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Install.cpp: implementation of the CInstall class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DriverInstall.h"
#include "Install.h"
#include <Winsvc.h>
#include <setupapi.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CInstall::CInstall()
{

}

CInstall::~CInstall()
{

}
/*
register pfc service
If the function succeeds, the return value is ERROR_SUCCESS.
If the function fails, the return value is another.
*/

DWORD CInstall::NTServiceRegistration(BOOL fRegister)
{
	DWORD dwRet = ERROR_SUCCESS;
	SC_HANDLE hManager = NULL;
	SC_HANDLE hService = NULL;
	hManager = OpenSCManager(NULL, NULL, GENERIC_READ|GENERIC_WRITE);
	if (hManager == NULL) 
	{
		dwRet = GetLastError();
		goto skip;
	}
	
	hService = OpenService(hManager, CDX_PFC_NAME, SERVICE_ALL_ACCESS|GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE);
	if (hService == NULL) 
	{
		dwRet = GetLastError();
		if (dwRet != ERROR_SERVICE_DOES_NOT_EXIST) 
		{
			goto skip;
		}
		
		dwRet = NO_ERROR;
	}
	
	if (fRegister) 
	{
		// Register service
		if (hService) 
		{
			// Update configuration
			if (ChangeServiceConfig(hService, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
				CDX_PFC_PATH, CDX_PFC_GROUP, NULL, NULL, NULL, NULL, CDX_PFC_DESCRIPTION) == FALSE) 
			{
				dwRet = GetLastError();
				if (dwRet == ERROR_SERVICE_MARKED_FOR_DELETE) 
				{
					// @@@@@ Signal they have to reboot
				}
				goto skip;
			}
			
			dwRet = NTLowerFilter(fRegister);
			RegDeleteValue(HKEY_LOCAL_MACHINE, CDX_PFC_LEGACY_GROUP);
		}else 
		{
			// Create new registration
			hService = CreateService(hManager, CDX_PFC_NAME, CDX_PFC_DESCRIPTION, SERVICE_ALL_ACCESS | GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
				SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
				CDX_PFC_PATH, CDX_PFC_GROUP, NULL, NULL, NULL, NULL);
			if (hService == NULL) 
			{
				dwRet = GetLastError();
				goto skip;
			}
			
			dwRet = NTLowerFilter(fRegister);
			RegDeleteValue(HKEY_LOCAL_MACHINE, CDX_PFC_LEGACY_GROUP);

		}
	}else 
	{
		if (hService) 
		{
			// Unregister service
			DeleteService(hService);
		}
		
		NTLowerFilter(fRegister);
		RegDeleteValue(HKEY_LOCAL_MACHINE, CDX_PFC_SERVICE);

	}
	
skip:;
	 if (hService) 
	 {
		 CloseServiceHandle(hService);
	 }
	 
	 if (hManager) 
	 {
		 CloseServiceHandle(hManager);
	 }
	 return (dwRet);
}
/*
Copy driver file to system32\drivers
*/
int CInstall::CopyDriverFile(char *src, const char *dst)
{
	BOOL 	retCp = 0;
	char szFileName[MAX_PATH];
	int  iLength;
	
	//get the path we are executing in
	iLength = GetModuleFileName(GetModuleHandle(NULL),
								(LPSTR)szFileName,
								MAX_PATH);
	
    for(int i = iLength; szFileName[i] != '\\'; i--);
    szFileName[i+1] = NULL;
	strcat(szFileName, src);
	retCp = CopyFile( szFileName, dst, FALSE);
	return(retCp);
}
/*
modify register
if fRegister == true, Add "PFC" filter
if fRegister == false, delete "PFC" filter

*/

DWORD CInstall::NTLowerFilter(BOOL fRegister)
{
	HKEY hKey;
	BYTE abBuf[512];
	DWORD dwRet;
	
	dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, CDX_PFC_CLASS_ID, 0, KEY_READ | KEY_WRITE, &hKey);
	if (dwRet == ERROR_SUCCESS)
	{
		DWORD dwSize = sizeof(abBuf) - 8;
		
		dwRet = RegQueryValueEx(hKey, CDX_PFC_FILTER, NULL, NULL, abBuf, &dwSize);
		if (dwRet == ERROR_FILE_NOT_FOUND) 
		{
			// The key doesn't exist: treat this case as the key is empty
			dwSize = 0;
			dwRet = ERROR_SUCCESS;
		}
		
		if (dwRet == ERROR_SUCCESS) 
		{
			DWORD dwItems = 0;
			BOOL fZero = TRUE;
			LPTSTR pszStart, pszEnd, pszPfcStart, pszPfcEnd, pszTmp, pszChar;
			
			// Set up pointers to the new string
			pszStart = (LPTSTR)abBuf;
			pszEnd = (LPTSTR)(abBuf + dwSize);
			pszPfcStart = pszPfcEnd = NULL;
			
			// Parse the string to make sure it is properly terminated
			for (pszTmp = pszStart; pszTmp < pszEnd; pszTmp = _tcsinc(pszTmp)) {
				if (_tcsnextc(pszTmp)) 
				{
					if (fZero) 
					{
						// Beginning of a new item
						dwItems++;
						fZero = FALSE;
					}
				}else 
				{
					if (fZero) 
					{
						// Second zero
						break;
					}
					
					fZero = TRUE;
				}
			}
			
			if (pszTmp >= pszEnd && fZero == FALSE) 
			{
				// Key not terminated
				*pszTmp = 0;
				pszTmp = _tcsinc(pszTmp);
			}
			
			pszEnd = pszTmp;
			dwSize = (DWORD)pszEnd - (DWORD)pszStart; 
			
			// Zero out remaining buffer
			memset(pszEnd, 0, sizeof(abBuf) - dwSize);
			
			//
			// Here we removed the second zero (or added the first) at the end and we have the number of items
			//
			
			// Hack necessary to search and, if found, remove the "_" invalid EasyCD Creator filter ----------------------------------
			for (pszTmp = pszStart; pszTmp < pszEnd; pszTmp = _tcsinc(pszTmp)) 
			{
				pszChar = pszTmp;
				
				if (pszChar == pszStart || _tcsnextc(_tcsdec(pszStart, pszChar)) == 0) 
				{
					if (_tcsnextc(pszChar) == _T('_')) 
					{
						pszChar = _tcsinc(pszChar);
						if (_tcsnextc(pszChar) == 0) 
						{
							// Remove "_" filter
							pszChar = _tcsinc(pszChar);
							
							dwItems--;
							dwSize -= (DWORD)pszChar - (DWORD)pszTmp;
							memmove(pszTmp, pszChar, (DWORD)pszEnd - (DWORD)pszChar);
							pszEnd = (LPTSTR)(abBuf + dwSize);
							// Zero out remaining buffer
							memset(pszEnd, 0, sizeof(abBuf) - dwSize);
							break;
						}
					}
				}
			}
			// -----------------------------------------------------------------------------------------------------------------------
			
			// Search for the "Pfc" entry
			for (pszTmp = pszStart; pszTmp < pszEnd; pszTmp = _tcsinc(pszTmp)) 
			{
				pszChar = pszTmp;
				
				if (pszChar == pszStart || _tcsnextc(_tcsdec(pszStart, pszChar)) == 0) 
				{
					if (_tcsnextc(pszChar) == _T('p') || _tcsnextc(pszChar) == _T('P')) 
					{
						pszChar = _tcsinc(pszChar);
						if (_tcsnextc(pszChar) == _T('f') || _tcsnextc(pszChar) == _T('F')) 
						{
							pszChar = _tcsinc(pszChar);
							if (_tcsnextc(pszChar) == _T('c') || _tcsnextc(pszChar) == _T('C')) 
							{
								pszChar = _tcsinc(pszChar);
								if (_tcsnextc(pszChar) == 0) 
								{
									pszPfcStart = pszTmp;
									pszPfcEnd = _tcsinc(pszChar);
									break;
								}
							}
						}
					}
				}
			}
			
			if (fRegister && pszPfcStart == NULL) 
			{
				// Add "PFC" filter
				DWORD dwLen = (_tcslen(_T("Pfc")) + 1) * sizeof(TCHAR);
				
				dwItems++;
				memmove(abBuf + dwLen, abBuf, dwSize);
				_tcscpy(pszStart, _T("Pfc"));
				dwSize += dwLen;
				pszEnd = (LPTSTR)(abBuf + dwSize);
			}else if (fRegister == FALSE && pszPfcStart) 
			{
				// Remove "PFC" filter
				dwItems--;
				dwSize -= (DWORD)pszPfcEnd - (DWORD)pszPfcStart;
				memmove(pszPfcStart, pszPfcEnd, (DWORD)pszEnd - (DWORD)pszPfcEnd);
				pszEnd = (LPTSTR)(abBuf + dwSize);
			}
			
			if (dwItems == 0) 
			{
				// Delete key if any
				RegDeleteValue(hKey, CDX_PFC_FILTER);
			}else 
			{
				// Add 2nd zero at the end
				*pszEnd = 0;
				pszEnd = _tcsinc(pszEnd);
				dwSize = (DWORD)pszEnd - (DWORD)pszStart;
				
				// Write key  
				dwRet = RegSetValueEx(hKey, CDX_PFC_FILTER, 0, REG_MULTI_SZ, abBuf, dwSize);
			}
    }
    RegCloseKey(hKey);
  }
  return (dwRet);
}
/*
Install pfc driver
If the function succeeds, the return value is TRUE.
If the function fails, the return value is FALSE.
*/
BOOL CInstall::PFCInstall()
{
	char 	sysdir[MAX_PATH];
	CString sDesVal;
	GetWindowsDirectory(sysdir, MAX_PATH);
	sDesVal = sysdir;
	if (sDesVal.GetLength() > 3) sDesVal += "\\";
	sDesVal += CDX_PFC_PATH;
	CopyDriverFile(CDX_PFC_FILE, (LPCSTR)sDesVal);
	if (NTServiceRegistration(TRUE) != ERROR_SUCCESS)
	{
		return FALSE;
	}
	return TRUE;
}

/*
uninstall pfc driver
*/
BOOL CInstall::UnInstallPFC()
{
	char szDir[MAX_PATH];
	CString sDesVal;
	GetWindowsDirectory(szDir, MAX_PATH);
	sDesVal = szDir;
	if (sDesVal.GetLength() > 3) sDesVal += "\\";
	sDesVal += CDX_PFC_PATH;

	if (NTServiceRegistration(FALSE) != ERROR_SUCCESS)
	{
		return FALSE;
	}
	return DeleteFile(sDesVal);
}

/*
get status of bootdisk driver 
if install return 1;
if unstall return 0;
if error return -1;
*/
int CInstall::CheckBootDiskInstall()
{
	int		iRet;
	HKEY	hKey = NULL;
	LONG	lResult;
	DWORD	dwType;
	DWORD	dwNum;
	DWORD	dwSize = 4;
	DWORD	i;
	BYTE	szDriverID[32];
	CString sVal;
	char *p;
	lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_BOOTDISK_ENUM, 0, KEY_READ, &hKey);
	if (lResult != ERROR_SUCCESS)
	{
		return 0;
	}
	lResult = RegQueryValueEx(hKey, "Count", NULL, &dwType, (BYTE*)&dwNum, &dwSize);
	if (lResult != ERROR_SUCCESS)
	{
		iRet = -1;
		goto EXIT;
	}
	if (dwNum == 0)
	{
		iRet = 0;
		goto EXIT;
	}
	for(i = 0; i < dwNum; i++)
	{
		sVal.Format("%u", i);
		dwSize = 32;
		lResult = RegQueryValueEx(hKey, sVal, NULL, &dwType, szDriverID, &dwSize);
		if (lResult != ERROR_SUCCESS)
		{
			iRet = -1;//error
			goto EXIT;
		}

		m_sDeviceID = szDriverID;
		p = strupr((char *)szDriverID);

		if (memcmp(p, REG_ROOT_SYSTEM, 11) == 0)
		{
			iRet = 1;//install
			goto EXIT;
		}
	}
	iRet = 0;//no install
EXIT:
	if (hKey != NULL)
	{
		RegCloseKey(hKey);
	}
	return iRet;
}
/*
Install bootdisk.sys driver from BootDisk.inf
If the function succeeds, the return value is TRUE.
If the function fails, the return value is FALSE.
*/

BOOL CInstall::BootDiskInstall()
{
	BOOL					bResult = TRUE;
	HDEVINFO				hDevInfo = NULL;
	GUID					guid;
	CString					sFullPath;
	char					szPath[MAX_PATH];
	char					szClassName[32];
	char					szDeviceID[255];
	DWORD					dwNameSize;
	SP_DEVINFO_DATA			spDevInfo;
	SP_DRVINFO_DATA			spDrvInfo;
	SP_DEVINSTALL_PARAMS	spDevPar;
	BOOL					fBuildList = FALSE;
	int						iInstall = CheckBootDiskInstall();
	if (iInstall == -1)
	{
		return FALSE;
	}else if (iInstall == 1)
	{
		return TRUE;
	}
	GetModuleFileName(NULL, szPath, MAX_PATH);
	sFullPath = szPath;
	sFullPath = sFullPath.Left(sFullPath.ReverseFind('\\') + 1);
	sFullPath += BOOTDISK_INF;
	if (!SetupDiGetINFClass(sFullPath, &guid, szClassName, 32, &dwNameSize))
	{
		return FALSE;
	}

	hDevInfo = SetupDiCreateDeviceInfoList(&guid, NULL);
	if (hDevInfo == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
	memset(&spDevInfo, 0, sizeof(SP_DEVINFO_DATA));
	spDevInfo.cbSize = sizeof(SP_DEVINFO_DATA);
	spDevInfo.ClassGuid = guid;
	
	if (!SetupDiCreateDeviceInfo(hDevInfo, szClassName, &guid, NULL, NULL, DICD_GENERATE_ID, &spDevInfo))
	{
		bResult = FALSE;
		goto EXIT;
	}

//	DIF_REGISTERDEVICE 
	if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDevInfo, &spDevInfo))
	{
		bResult = FALSE;
		goto EXIT;
	}

	memset(&spDevPar, 0, sizeof(SP_DEVINSTALL_PARAMS));
	spDevPar.cbSize		= sizeof(SP_DEVINSTALL_PARAMS);
	spDevPar.Flags		= DI_QUIETINSTALL | DI_ENUMSINGLEINF | DI_FORCECOPY | DI_INF_IS_SORTED;
	spDevPar.FlagsEx	= DI_FLAGSEX_ALLOWEXCLUDEDDRVS;
	spDevPar.hwndParent = NULL;
	strcpy (spDevPar.DriverPath, sFullPath);

	if (!SetupDiSetDeviceInstallParams(hDevInfo, &spDevInfo, &spDevPar))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -