📄 install.cpp
字号:
// 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 + -