You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1361 lines
38 KiB
1361 lines
38 KiB
/********************************************************************
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
PCH_Driver.CPP
|
|
|
|
Abstract:
|
|
WBEM provider class implementation for PCH_Driver class
|
|
|
|
Revision History:
|
|
|
|
Ghim-Sim Chua (gschua) 04/27/99
|
|
- Created
|
|
|
|
Brijesh Krishnaswami (brijeshk) 05/24/99
|
|
- added code for enumerating usermode drivers
|
|
- added code for enumerating msdos drivers
|
|
- added code for getting details on kernel mode drivers
|
|
********************************************************************/
|
|
|
|
#include "pchealth.h"
|
|
#include "PCH_Driver.h"
|
|
#include "drvdefs.h"
|
|
#include "shlwapi.h"
|
|
|
|
#define Not_VxD
|
|
#include <vxdldr.h> /* For DeviceInfo */
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// tracing stuff
|
|
|
|
#ifdef THIS_FILE
|
|
#undef THIS_FILE
|
|
#endif
|
|
static char __szTraceSourceFile[] = __FILE__;
|
|
#define THIS_FILE __szTraceSourceFile
|
|
#define TRACE_ID DCID_DRIVER
|
|
#define SYSTEM_INI_MAX 32767
|
|
|
|
CPCH_Driver MyPCH_DriverSet (PROVIDER_NAME_PCH_DRIVER, PCH_NAMESPACE) ;
|
|
void MakeSrchDirs(void);
|
|
|
|
static BOOL fThunkInit = FALSE;
|
|
|
|
TCHAR g_rgSrchDir[10][MAX_PATH];
|
|
UINT g_nSrchDir;
|
|
|
|
|
|
// Property names
|
|
//===============
|
|
const static WCHAR* pCategory = L"Category" ;
|
|
const static WCHAR* pTimeStamp = L"TimeStamp" ;
|
|
const static WCHAR* pChange = L"Change" ;
|
|
const static WCHAR* pDate = L"Date" ;
|
|
const static WCHAR* pDescription = L"Description" ;
|
|
const static WCHAR* pLoadedFrom = L"LoadedFrom" ;
|
|
const static WCHAR* pManufacturer = L"Manufacturer" ;
|
|
const static WCHAR* pName = L"Name" ;
|
|
const static WCHAR* pPartOf = L"PartOf" ;
|
|
const static WCHAR* pPath = L"Path" ;
|
|
const static WCHAR* pSize = L"Size" ;
|
|
const static WCHAR* pType = L"Type" ;
|
|
const static WCHAR* pVersion = L"Version" ;
|
|
|
|
// Device names
|
|
//=============
|
|
LPSTR c_rgpszDevice[] = {
|
|
"device",
|
|
"display",
|
|
"mouse",
|
|
"keyboard",
|
|
"network",
|
|
"ebios",
|
|
"fastdisk",
|
|
"transport",
|
|
"netcard",
|
|
"netcard3",
|
|
"netmisc",
|
|
"secondnet",
|
|
NULL
|
|
};
|
|
|
|
// IO Subsystem extensions
|
|
//========================
|
|
LPSTR c_rgptszDrvExt[] = {
|
|
".DRV",
|
|
".MPD",
|
|
".PDR",
|
|
".VXD",
|
|
NULL
|
|
};
|
|
|
|
// Registry key names
|
|
//===================
|
|
LPCTSTR c_rgptszConfig[] = {
|
|
TEXT("DevLoader"),
|
|
TEXT("Contention"),
|
|
TEXT("Enumerator"),
|
|
TEXT("Driver"),
|
|
TEXT("PortDriver"),
|
|
TEXT("DeviceVxDs"),
|
|
TEXT("vdd"),
|
|
TEXT("minivdd"),
|
|
NULL
|
|
};
|
|
|
|
// Known VxDs
|
|
//===========
|
|
LPCTSTR astrKnownVxDs[] = {
|
|
"VMM",
|
|
"VPOWERD",
|
|
"ENABLE",
|
|
"VKD",
|
|
"VFLATD",
|
|
"BIOS",
|
|
"VDD",
|
|
"VMOUSE",
|
|
"EBIOS",
|
|
"VSHARE",
|
|
"VWIN32",
|
|
"VFBACKUP",
|
|
"VCOMM",
|
|
"COMBUFF",
|
|
"VCD",
|
|
"VPD",
|
|
"IFSMGR",
|
|
"IOS",
|
|
"SPOOLER",
|
|
"VFAT",
|
|
"VCACHE",
|
|
"VCOND",
|
|
"VCDFSD",
|
|
"INT13",
|
|
"VXDLDR",
|
|
"VDEF",
|
|
"PAGEFILE",
|
|
"CONFIGMG",
|
|
"VMD",
|
|
"DOSNET",
|
|
"VPICD",
|
|
"VTD",
|
|
"REBOOT",
|
|
"VDMAD",
|
|
"VSD",
|
|
"V86MMGR",
|
|
"PAGESWAP",
|
|
"DOSMGR",
|
|
"VMPOLL",
|
|
"SHELL",
|
|
"PARITY",
|
|
"BIOSXLAT",
|
|
"VMCPD",
|
|
"VTDAPI",
|
|
"PERF",
|
|
"NTKERN",
|
|
"SDVXD",
|
|
NULL
|
|
};
|
|
|
|
// Known VxD Description
|
|
//======================
|
|
LPCTSTR astrKnownVxDsDesc[] = {
|
|
"Virtual Machine Manager",
|
|
"Advanced Power Management driver",
|
|
"Accessibility driver",
|
|
"Keyboard driver",
|
|
"Linear aperture video driver",
|
|
"Plug and Play BIOS driver",
|
|
"Display driver",
|
|
"Mouse driver",
|
|
"Extended BIOS driver",
|
|
"File sharing driver",
|
|
"Win32 subsystem driver",
|
|
"Floppy backup helper driver",
|
|
"Communications port Plug and Play driver",
|
|
"Communications buffer driver",
|
|
"Communications port driver",
|
|
"Printer driver",
|
|
"File system manager",
|
|
"I/O Supervisor",
|
|
"Print spooler",
|
|
"FAT filesystem driver",
|
|
"Cache manager",
|
|
"Console subsystem driver",
|
|
"CD-ROM filesystem driver",
|
|
"BIOS hard disk emulation driver",
|
|
"Dynamic device driver loader",
|
|
"Default filesystem driver",
|
|
"Swapfile driver",
|
|
"Configuration manager",
|
|
"Windows 3.1-compatible mouse driver",
|
|
"Windows 3.1-compatible network helper driver",
|
|
"Hardware interrupt manager",
|
|
"Timer device driver",
|
|
"Ctrl+Alt+Del manager",
|
|
"Direct Memory Access controller driver",
|
|
"Speaker driver",
|
|
"MS-DOS memory manager",
|
|
"Swapfile manager",
|
|
"MS-DOS emulation manager",
|
|
"System idle-time driver",
|
|
"Shell device driver",
|
|
"Memory parity driver",
|
|
"BIOS emulation driver",
|
|
"Math coprocessor driver",
|
|
"Multimedia timer driver",
|
|
"System Monitor data collection driver",
|
|
"Windows Driver Model",
|
|
"SmartDrive",
|
|
NULL
|
|
};
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CPCH_Driver::EnumerateInstances
|
|
*
|
|
* DESCRIPTION : Returns all the instances of this class.
|
|
*
|
|
* INPUTS : A pointer to the MethodContext for communication with WinMgmt.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::CreateInstanceEnumAsync. Note that the following
|
|
* flags are handled by (and filtered out by) WinMgmt:
|
|
* WBEM_FLAG_DEEP
|
|
* WBEM_FLAG_SHALLOW
|
|
* WBEM_FLAG_RETURN_IMMEDIATELY
|
|
* WBEM_FLAG_FORWARD_ONLY
|
|
* WBEM_FLAG_BIDIRECTIONAL
|
|
*
|
|
* RETURNS : WBEM_S_NO_ERROR if successful
|
|
*
|
|
* COMMENTS : TO DO: All instances on the machine should be returned here.
|
|
* If there are no instances, return WBEM_S_NO_ERROR.
|
|
* It is not an error to have no instances.
|
|
*
|
|
*****************************************************************************/
|
|
HRESULT CPCH_Driver::EnumerateInstances(
|
|
MethodContext* pMethodContext,
|
|
long lFlags
|
|
)
|
|
{
|
|
TraceFunctEnter("CPCH_Driver::AddDriverKernelList");
|
|
HRESULT hRes = WBEM_S_NO_ERROR;
|
|
CComVariant varValue;
|
|
|
|
//
|
|
// Get the date and time
|
|
SYSTEMTIME stUTCTime;
|
|
GetSystemTime(&stUTCTime);
|
|
|
|
// if thunk init is already done, don't initialize again
|
|
if (!fThunkInit)
|
|
{
|
|
ThunkInit();
|
|
fThunkInit = TRUE;
|
|
}
|
|
|
|
|
|
// Enumerate Kernel Drivers
|
|
MakeSrchDirs();
|
|
GetDriverKernel();
|
|
DRIVER_KERNEL *pDrvKer = m_pDriverKernel;
|
|
DRIVER_KERNEL *pDelDrvKer;
|
|
while(pDrvKer)
|
|
{
|
|
// Create a new instance
|
|
CInstancePtr pInstance(CreateNewInstance(pMethodContext), false);
|
|
|
|
// Set the timestamp
|
|
if (!pInstance->SetDateTime(pTimeStamp, WBEMTime(stUTCTime)))
|
|
ErrorTrace(TRACE_ID, "SetDateTime on Timestamp Field failed.");
|
|
|
|
// Set the category
|
|
if (!pInstance->SetCHString(pCategory, "Kernel"))
|
|
ErrorTrace(TRACE_ID, "SetVariant on Category Field failed.");
|
|
|
|
// Set the name
|
|
if (_tcslen(pDrvKer->strDriver))
|
|
{
|
|
varValue = pDrvKer->strDriver;
|
|
if (!pInstance->SetVariant(pName, varValue))
|
|
ErrorTrace(TRACE_ID, "SetVariant on Name Field failed.");
|
|
}
|
|
|
|
// Set the path
|
|
if (_tcslen(pDrvKer->strLikelyPath))
|
|
{
|
|
varValue = pDrvKer->strLikelyPath;
|
|
if (!pInstance->SetVariant(pPath, varValue))
|
|
ErrorTrace(TRACE_ID, "SetVariant on Path Field failed.");
|
|
}
|
|
|
|
|
|
// set file description, version, partof
|
|
CComBSTR filename = pDrvKer->strLikelyPath;
|
|
SetFileVersionInfo(filename, pInstance);
|
|
|
|
// Set the Description - overwrite with well-known description if available
|
|
if (_tcslen(pDrvKer->strDescription))
|
|
{
|
|
varValue = pDrvKer->strDescription;
|
|
if (!pInstance->SetVariant(pDescription, varValue))
|
|
ErrorTrace(TRACE_ID, "SetVariant on Description Field failed.");
|
|
}
|
|
|
|
// Set the LoadedFrom
|
|
if (_tcslen(pDrvKer->strLoadedFrom))
|
|
{
|
|
varValue = pDrvKer->strLoadedFrom;
|
|
if (!pInstance->SetVariant(pLoadedFrom, varValue))
|
|
ErrorTrace(TRACE_ID, "SetVariant on LoadedFrom Field failed.");
|
|
}
|
|
|
|
// Commit this
|
|
hRes = pInstance->Commit();
|
|
if (FAILED(hRes))
|
|
ErrorTrace(TRACE_ID, "Commit on Instance failed.");
|
|
|
|
// advance and delete the record
|
|
pDelDrvKer = pDrvKer;
|
|
pDrvKer = pDrvKer->next;
|
|
delete (pDelDrvKer);
|
|
}
|
|
|
|
// get usermode drivers
|
|
// create instances, and cleanup list
|
|
GetDriverUserMode();
|
|
ParseUserModeList(pMethodContext);
|
|
|
|
// get msdos drivers
|
|
// create instances, and cleanup list
|
|
GetDriverMSDos();
|
|
ParseMSDosList(pMethodContext);
|
|
|
|
TraceFunctLeave();
|
|
return hRes;
|
|
}
|
|
|
|
|
|
HRESULT CPCH_Driver::AddDriverKernelList(LPTSTR strDriverList, LPTSTR strLoadedFrom)
|
|
{
|
|
TraceFunctEnter("CPCH_Driver::AddDriverKernelList");
|
|
|
|
// Break driver list up into tokens
|
|
LPTSTR strDriverName;
|
|
int nStrLen;
|
|
int nPos;
|
|
|
|
while ((strDriverName = Token_Find(&strDriverList)) != 0)
|
|
{
|
|
// Got the first token
|
|
// See if the first character is '*', if so remove it.
|
|
if(strDriverName[0] == _T('*'))
|
|
{
|
|
strDriverName++;
|
|
}
|
|
// Allocate new element
|
|
DRIVER_KERNEL *pNewKernel = new DRIVER_KERNEL;
|
|
if (!pNewKernel)
|
|
{
|
|
ErrorTrace(TRACE_ID, "Out of memory while calling new DRIVER_KERNEL");
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
// Zero out all memory
|
|
ZeroMemory(pNewKernel, sizeof(DRIVER_KERNEL));
|
|
|
|
// Check if we have a path by seeing if filename is same as the driver name
|
|
LPTSTR strFilename = PathFindFileName(strDriverName);
|
|
|
|
// copy name
|
|
_tcscpy(pNewKernel->strDriver, strFilename);
|
|
|
|
// terminate name at the extension
|
|
*PathFindExtension(pNewKernel->strDriver) = 0;
|
|
|
|
// check for duplicates
|
|
DRIVER_KERNEL *pDrvKerLoop = m_pDriverKernel;
|
|
BOOL bDup = FALSE;
|
|
while(pDrvKerLoop)
|
|
{
|
|
if (!_tcsicmp(pDrvKerLoop->strDriver, pNewKernel->strDriver))
|
|
{
|
|
bDup = TRUE;
|
|
break;
|
|
}
|
|
pDrvKerLoop = pDrvKerLoop->next;
|
|
}
|
|
|
|
// if duplicate, delete it, otherwise store it in linked list
|
|
if (bDup)
|
|
{
|
|
delete pNewKernel;
|
|
}
|
|
else
|
|
{
|
|
// Copy Loaded From
|
|
_tcscpy(pNewKernel->strLoadedFrom, strLoadedFrom);
|
|
|
|
// Copy Path
|
|
_tcscpy(pNewKernel->strLikelyPath, strDriverName);
|
|
|
|
// check if it is a well known VxD and copy the description
|
|
for(int iVxDIndex = 0; astrKnownVxDs[iVxDIndex]; iVxDIndex++)
|
|
if (!_tcsicmp(astrKnownVxDs[iVxDIndex], pNewKernel->strDriver))
|
|
_tcscpy(pNewKernel->strDescription, astrKnownVxDsDesc[iVxDIndex]);
|
|
|
|
// Add it to the list
|
|
pNewKernel->next = m_pDriverKernel;
|
|
m_pDriverKernel = pNewKernel;
|
|
}
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CPCH_Driver::GetDriverKernel()
|
|
{
|
|
TraceFunctEnter("CPCH_Driver::GetDriverKernel");
|
|
|
|
// Init WinDir
|
|
TCHAR strWinDir[MAX_PATH];
|
|
GetWindowsDirectory(strWinDir, MAX_PATH);
|
|
|
|
// init head of list
|
|
m_pDriverKernel = NULL;
|
|
|
|
// Add vmm driver
|
|
TCHAR strVmmPath[MAX_PATH];
|
|
TCHAR strVmmFilePath[MAX_PATH];
|
|
PathCombine(strVmmPath, strWinDir, "VMM32");
|
|
PathCombine(strVmmFilePath, strVmmPath, "vmm.vxd");
|
|
AddDriverKernelList(strVmmFilePath, "Registry");
|
|
|
|
// Add debugging drivers
|
|
AddDriverKernelList("wdeb386.exe", "Debugger");
|
|
AddDriverKernelList("debugcmd.vxd", "Debugger");
|
|
|
|
// Add winsock drivers
|
|
AddDriverKernelList("wsock.vxd", "Winsock");
|
|
AddDriverKernelList("vdhcp.386", "Winsock");
|
|
|
|
// Add WINMM drivers
|
|
AddDriverKernelList("mmdevldr.vxd", "Plug and Play");
|
|
|
|
// AddDriverKernelList("===HKLM_System_CurrentControlSet_Services_VxD_AFVXD===", "Registry");
|
|
|
|
// Add HKLM\System\CurrentControlSet\Services\VxD\AFVXD
|
|
AddRegDriverList(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\AFVXD");
|
|
|
|
// AddDriverKernelList("===HKLM_System_CurrentControlSet_Services_VxD_Winsock===", "Registry");
|
|
|
|
// Add HKLM\System\CurrentControlSet\Services\VxD\Winsock
|
|
AddRegDriverList(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\Winsock");
|
|
|
|
// AddDriverKernelList("===HKLM_System_CurrentControlSet_Services_Class===", "Registry");
|
|
|
|
// Add HKLM\System\CurrentControlSet\Services\Class
|
|
GetRegDriver("System\\CurrentControlSet\\Services\\Class");
|
|
|
|
// AddDriverKernelList("===HKLM_System_CurrentControlSet_Services_Class_Display===", "Registry");
|
|
|
|
// Add HKLM\System\CurrentControlSet\Services\Class\Display
|
|
GetRegDriver("System\\CurrentControlSet\\Services\\Class\\Display");
|
|
|
|
// AddDriverKernelList("===SYSTEM_INI===", "Registry");
|
|
|
|
// Add system.ini drivers
|
|
GetSystemINIDriver();
|
|
|
|
// AddDriverKernelList("===IOSubSystem===", "Registry");
|
|
|
|
// Add IO Subsystem drivers
|
|
GetIOSubsysDriver();
|
|
|
|
// AddDriverKernelList("===HKLM_System_CurrentControlSet_Services_VxD===", "Registry");
|
|
|
|
// Add HKLM\System\CurrentControlSet\Services\VxD
|
|
GetServicesVxD();
|
|
|
|
// Collect additional driver information from MSISYS or DrWatson
|
|
GetMSISYSVxD();
|
|
|
|
// Now that we've collected all the drivers, collect each driver's information
|
|
GetKernelDriverInfo();
|
|
|
|
TraceFunctLeave();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
BOOL
|
|
Drivers_PathFileExists(LPTSTR ptszBuf, LPCTSTR ptszPath, LPCTSTR ptszFile)
|
|
{
|
|
PathCombine(ptszBuf, ptszPath, ptszFile);
|
|
return PathFileExists(ptszBuf);
|
|
}
|
|
|
|
|
|
void
|
|
MakeSrchDirs(void)
|
|
{
|
|
TCHAR tszPath[3];
|
|
LPTSTR pszDir;
|
|
UINT ctchPath;
|
|
LPTSTR ptsz;
|
|
LPTSTR pTmp;
|
|
int i = 0;
|
|
|
|
// look in windows dir
|
|
GetWindowsDirectory(g_rgSrchDir[0], MAX_PATH);
|
|
|
|
// look in windows\vmm32
|
|
PathCombine(g_rgSrchDir[1], g_rgSrchDir[0], TEXT("VMM32"));
|
|
|
|
// look in system dir
|
|
GetSystemDirectory(g_rgSrchDir[2], MAX_PATH);
|
|
|
|
// look in boot dir
|
|
RMIREGS reg;
|
|
reg.ax = 0x3305;
|
|
reg.dl = 3; // assume C: in case of error
|
|
Int86x(0x21, ®);
|
|
wsprintf(g_rgSrchDir[3], "%c:\\", reg.dl + '@');
|
|
|
|
// look in dirs specified in path variable
|
|
i = 4;
|
|
pszDir = NULL;
|
|
// get size of path string
|
|
ctchPath = GetEnvironmentVariable(TEXT("PATH"), tszPath, 1);
|
|
pTmp = ptsz = new TCHAR[ctchPath+1];
|
|
if (ptsz)
|
|
{
|
|
GetEnvironmentVariable(TEXT("PATH"), ptsz, ctchPath);
|
|
while ((pszDir = Token_Find(&ptsz)) != 0)
|
|
{
|
|
lstrcpy(g_rgSrchDir[i++],pszDir);
|
|
}
|
|
delete [] pTmp;
|
|
}
|
|
|
|
g_nSrchDir = i-1;
|
|
}
|
|
|
|
|
|
HRESULT CPCH_Driver::GetKernelDriverInfo()
|
|
{
|
|
int i;
|
|
|
|
TraceFunctEnter("CPCH_Driver::GetKernelDriverInfo");
|
|
|
|
/*
|
|
* Search order :
|
|
*
|
|
* 1. If extension is ".386" look in Windows directory.
|
|
* 2. Look in System directory.
|
|
* 3. Look in directory Windows was launched from.
|
|
* (We'll assume Root directory.)
|
|
* 4. Then look on the path.
|
|
*
|
|
* If the file doesn't have an extension, use ".vxd".
|
|
*
|
|
* BUGBUG -- this is a hack; need to look for .386 too
|
|
*/
|
|
|
|
DRIVER_KERNEL *pDKLoop;
|
|
pDKLoop = m_pDriverKernel;
|
|
|
|
while(pDKLoop)
|
|
{
|
|
TCHAR szFile[MAX_PATH] = TEXT("");
|
|
LPTSTR szExtension = NULL;
|
|
|
|
if (PathFileExists(pDKLoop->strLikelyPath))
|
|
{
|
|
goto havefile;
|
|
}
|
|
|
|
lstrcpy(szFile, pDKLoop->strLikelyPath);
|
|
for (i=0; i<g_nSrchDir; i++)
|
|
{
|
|
if (Drivers_PathFileExists(pDKLoop->strLikelyPath, g_rgSrchDir[i], szFile))
|
|
{
|
|
goto havefile;
|
|
}
|
|
|
|
szExtension = PathFindExtension(pDKLoop->strLikelyPath);
|
|
|
|
// no extension?
|
|
if (!_tcslen(szExtension))
|
|
{
|
|
// try .VXD
|
|
lstrcat(szFile, TEXT(".VXD"));
|
|
if (Drivers_PathFileExists(pDKLoop->strLikelyPath, g_rgSrchDir[i], szFile))
|
|
{
|
|
goto havefile;
|
|
}
|
|
|
|
// try .386
|
|
lstrcpy(szFile, pDKLoop->strLikelyPath);
|
|
lstrcat(szFile, TEXT(".386"));
|
|
if (Drivers_PathFileExists(pDKLoop->strLikelyPath, g_rgSrchDir[i], szFile))
|
|
{
|
|
goto havefile;
|
|
}
|
|
}
|
|
}
|
|
|
|
// no path
|
|
lstrcpy(pDKLoop->strLikelyPath, TEXT(""));
|
|
|
|
havefile:
|
|
pDKLoop = pDKLoop->next;
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
HRESULT CPCH_Driver::GetSystemINIDriver()
|
|
{
|
|
TraceFunctEnter("CPCH_Driver::GetSystemINIDriver");
|
|
|
|
TCHAR str386Enh[SYSTEM_INI_MAX];
|
|
LPTSTR strLine;
|
|
int iLineLen;
|
|
|
|
// Get the section 386Enh in system.ini
|
|
GetPrivateProfileSection(TEXT("386Enh"), str386Enh, SYSTEM_INI_MAX, TEXT("system.ini"));
|
|
|
|
// For each line in the 386Enh section
|
|
for (strLine = str386Enh; (iLineLen = _tcslen(strLine)) != 0; strLine += iLineLen + 1)
|
|
{
|
|
// Get the value after the '=' char
|
|
LPTSTR strValue = _tcschr(strLine, '=');
|
|
|
|
if (strValue)
|
|
{
|
|
// Terminate the string at the '=' char
|
|
*strValue = '\0';
|
|
|
|
// Look to see if device corresponds to any of the listed devices
|
|
for (int iDeviceNames = 0; c_rgpszDevice[iDeviceNames]; iDeviceNames++)
|
|
{
|
|
// if it is listed, add to the driver list
|
|
if (_tcsicmp(c_rgpszDevice[iDeviceNames], strLine) == 0)
|
|
{
|
|
AddDriverKernelList(strValue + 1, "system.ini");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CPCH_Driver::GetIOSubsysDriver()
|
|
{
|
|
TraceFunctEnter("CPCH_Driver::GetIOSubsysDriver");
|
|
|
|
TCHAR strSystemDir[MAX_PATH];
|
|
TCHAR strIOSubSys[MAX_PATH];
|
|
TCHAR strIOSubSysWildcard[MAX_PATH];
|
|
TCHAR strFullPath[MAX_PATH];
|
|
TCHAR strDir[MAX_PATH];
|
|
|
|
HANDLE hfd;
|
|
WIN32_FIND_DATA wfd;
|
|
|
|
// get the system directory
|
|
if (!GetSystemDirectory(strSystemDir, MAX_PATH))
|
|
{
|
|
ErrorTrace(TRACE_ID, "Error while calling GetSystemDirectory");
|
|
goto EndIO;
|
|
}
|
|
|
|
// combine paths to IO Subsystem
|
|
PathCombine(strIOSubSys, strSystemDir, "IOSUBSYS");
|
|
PathCombine(strIOSubSysWildcard, strIOSubSys, "*.*");
|
|
|
|
// enumerate all files in IO Subsystem
|
|
hfd = FindFirstFile(strIOSubSysWildcard, &wfd);
|
|
|
|
if (hfd != INVALID_HANDLE_VALUE)
|
|
do
|
|
{
|
|
// add file it it has one of the extensions in c_rgptszDrvExt
|
|
LPTSTR strExt = PathFindExtension(wfd.cFileName);
|
|
for (int iExt = 0; c_rgptszDrvExt[iExt]; iExt++) {
|
|
if (_tcsicmp(strExt, c_rgptszDrvExt[iExt]) == 0) {
|
|
PathCombine(strFullPath, strIOSubSys, wfd.cFileName);
|
|
AddDriverKernelList(strFullPath, "I/O subsystem");
|
|
break;
|
|
}
|
|
}
|
|
} while (FindNextFile(hfd, &wfd));
|
|
FindClose(hfd);
|
|
|
|
EndIO:
|
|
TraceFunctLeave();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CPCH_Driver::GetServicesVxD()
|
|
{
|
|
TraceFunctEnter("CPCH_Driver::GetServicesVxD");
|
|
|
|
TCHAR strStaticVxd[MAX_PATH];
|
|
DWORD dwLen = MAX_PATH;
|
|
HKEY hkMain;
|
|
|
|
// Open the key in registry
|
|
if (RegOpenKey(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD", &hkMain) == ERROR_SUCCESS)
|
|
{
|
|
TCHAR strValue[MAX_PATH];
|
|
|
|
// Enum all the keys in the subkey
|
|
for (int iEnumSubKey = 0; RegEnumKey(hkMain, iEnumSubKey, strValue, MAX_PATH) == ERROR_SUCCESS; iEnumSubKey++)
|
|
{
|
|
HKEY hkSub;
|
|
|
|
// Open the subkey
|
|
if (RegOpenKey(hkMain, strValue, &hkSub) == ERROR_SUCCESS)
|
|
{
|
|
// examine the StaticVxD value
|
|
dwLen = MAX_PATH;
|
|
if (RegQueryValueEx(hkSub, "StaticVxD", 0, 0, (LPBYTE)strStaticVxd, &dwLen) == ERROR_SUCCESS)
|
|
AddDriverKernelList(strStaticVxd, "Registry");
|
|
|
|
// close the key
|
|
RegCloseKey(hkSub);
|
|
}
|
|
}
|
|
// close the key
|
|
RegCloseKey(hkMain);
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CPCH_Driver::GetMSISYSVxD()
|
|
{
|
|
TraceFunctEnter("CPCH_Driver::GetMSISYSVxD");
|
|
|
|
HANDLE hVxDHandle = INVALID_HANDLE_VALUE;
|
|
|
|
// try looking for MSISYS.VXD
|
|
hVxDHandle = CreateFile("\\\\.\\MSISYS.VXD", 0, 0, 0, 0, FILE_ATTRIBUTE_NORMAL, 0);
|
|
if (hVxDHandle == INVALID_HANDLE_VALUE)
|
|
{
|
|
// try looking for DRWATSON.VXD
|
|
hVxDHandle = CreateFile("\\\\.\\DRWATSON.VXD", 0, 0, 0, 0, FILE_ATTRIBUTE_NORMAL, 0);
|
|
if (hVxDHandle == INVALID_HANDLE_VALUE)
|
|
{
|
|
ErrorTrace(TRACE_ID, "Error in opening MSISYS.VXD or DRWATSON.VXD");
|
|
goto EndAddVxD;
|
|
}
|
|
}
|
|
|
|
// Call into VxD to get additional information
|
|
struct DeviceInfo* pDeviceInfo;
|
|
DWORD cbRc;
|
|
if (DeviceIoControl(hVxDHandle, IOCTL_GETVXDLIST, 0, 0, &pDeviceInfo, sizeof(pDeviceInfo), &cbRc, 0))
|
|
{
|
|
while (pDeviceInfo
|
|
&& !IsBadReadPtr(pDeviceInfo, sizeof(*pDeviceInfo))
|
|
&& pDeviceInfo->DI_Signature == 0x444C5658)
|
|
{
|
|
if (pDeviceInfo->DI_DDB == (LPVOID)1)
|
|
AddDriverKernelList(pDeviceInfo->DI_ModuleName, "UNKNOWN");
|
|
pDeviceInfo = pDeviceInfo->DI_Next;
|
|
}
|
|
}
|
|
|
|
EndAddVxD:
|
|
if (hVxDHandle != INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseHandle(hVxDHandle);
|
|
}
|
|
TraceFunctLeave();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CPCH_Driver::GetRegDriver(LPTSTR strSubKey)
|
|
{
|
|
TraceFunctEnter("CPCH_Driver::GetRegDriver");
|
|
|
|
TCHAR strStaticVxd[MAX_PATH];
|
|
DWORD dwLen = MAX_PATH;
|
|
HKEY hkMain;
|
|
|
|
// Open the key in registry
|
|
if (RegOpenKey(HKEY_LOCAL_MACHINE, strSubKey, &hkMain) == ERROR_SUCCESS)
|
|
{
|
|
TCHAR strValue[MAX_PATH];
|
|
|
|
// Enum all the keys in the subkey
|
|
for (int iEnumSubKey = 0; RegEnumKey(hkMain, iEnumSubKey, strValue, MAX_PATH) == ERROR_SUCCESS; iEnumSubKey++)
|
|
{
|
|
HKEY hkSub;
|
|
|
|
// Open the subkey
|
|
if (RegOpenKey(hkMain, strValue, &hkSub) == ERROR_SUCCESS)
|
|
{
|
|
TCHAR strSubValue[MAX_PATH];
|
|
|
|
// Enum all the subkeys in the subkey
|
|
for (int iEnumSubSubKey = 0; RegEnumKey(hkSub, iEnumSubSubKey, strSubValue, MAX_PATH) == ERROR_SUCCESS; iEnumSubSubKey++)
|
|
{
|
|
HKEY hkSubSub;
|
|
|
|
// Open the subsubkey
|
|
if (RegOpenKey(hkSub, strSubValue, &hkSubSub) == ERROR_SUCCESS)
|
|
{
|
|
// examine the values in subkey
|
|
AddRegDriverConfigList(hkSubSub);
|
|
}
|
|
// close the key
|
|
RegCloseKey(hkSubSub);
|
|
}
|
|
// close the key
|
|
RegCloseKey(hkSub);
|
|
}
|
|
}
|
|
// close the key
|
|
RegCloseKey(hkMain);
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CPCH_Driver::AddRegDriverConfigList(HKEY hk)
|
|
{
|
|
TraceFunctEnter("CPCH_Driver::AddRegDriverConfigList");
|
|
for (int iCount = 0; c_rgptszConfig[iCount]; iCount++)
|
|
{
|
|
TCHAR strValue[MAX_PATH];
|
|
DWORD dwCount = MAX_PATH;
|
|
|
|
|
|
if (RegQueryValueEx(hk, c_rgptszConfig[iCount], 0, 0, (LPBYTE)strValue, &dwCount) == ERROR_SUCCESS)
|
|
{
|
|
/*
|
|
if(strValue[0] == '*')
|
|
{
|
|
nStrLen = _tcslen(strValue);
|
|
for(nPos = 1; nPos < nStrLen ; nPos++)
|
|
{
|
|
strValue[nPos-1] = strValue[nPos];
|
|
}
|
|
}
|
|
*/
|
|
AddDriverKernelList(strValue, "Plug and Play");
|
|
}
|
|
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CPCH_Driver::AddRegDriverList(HKEY hKeyMain, LPTSTR strSubKey)
|
|
{
|
|
TraceFunctEnter("CPCH_Driver::AddRegDriverList");
|
|
HKEY hKey;
|
|
|
|
// Open key in registry
|
|
if (RegOpenKey(hKeyMain, strSubKey, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
// enumerate all values
|
|
for (int iValue = 0; ; iValue++)
|
|
{
|
|
TCHAR strValue[MAX_PATH];
|
|
TCHAR strKey[MAX_PATH];
|
|
DWORD ctchRc = MAX_PATH;
|
|
DWORD cbRc = MAX_PATH;
|
|
LONG lResult;
|
|
|
|
lResult = RegEnumValue(hKey, iValue, strKey, &ctchRc, 0, 0, (LPBYTE)strValue, &cbRc);
|
|
|
|
if (lResult == ERROR_SUCCESS)
|
|
{
|
|
if (strKey[0])
|
|
AddDriverKernelList(strValue, "Registry");
|
|
}
|
|
else
|
|
if (lResult != ERROR_MORE_DATA)
|
|
break;
|
|
}
|
|
// close the key
|
|
RegCloseKey(hKeyMain);
|
|
}
|
|
else
|
|
ErrorTrace(TRACE_ID, "RegOpenKey failed");
|
|
|
|
TraceFunctLeave();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// get list of MSDos drivers
|
|
HRESULT
|
|
CPCH_Driver::GetDriverMSDos()
|
|
{
|
|
VXDINFO vi;
|
|
VXDOUT vo;
|
|
HANDLE hVxD = INVALID_HANDLE_VALUE;
|
|
ULONG cbRc;
|
|
PBYTE pbSysVars = NULL;
|
|
WORD wTemp = 0;
|
|
BOOL fRc = FALSE;
|
|
|
|
TraceFunctEnter("CPCH_DRIVER::GetDriverMSDos");
|
|
|
|
// open handle to vxd
|
|
hVxD = CreateFile(TEXT("\\\\.\\MSISYS.VXD"), 0, 0, 0, 0, FILE_FLAG_DELETE_ON_CLOSE, 0);
|
|
if (hVxD == INVALID_HANDLE_VALUE)
|
|
{
|
|
ErrorTrace(TRACE_ID, "Cannot open VxD");
|
|
goto exit;
|
|
}
|
|
|
|
// get high linear address of system VM
|
|
// ask msisys.vxd for this
|
|
vo.dwHighLinear = 0;
|
|
fRc = DeviceIoControl(hVxD,
|
|
IOCTL_CONNECT,
|
|
&vi,
|
|
sizeof(vi),
|
|
&vo,
|
|
sizeof(vo),
|
|
&cbRc,
|
|
0);
|
|
|
|
if (fRc && vo.dwHighLinear)
|
|
{
|
|
RMIREGS reg;
|
|
|
|
// Get list of driver lists
|
|
reg.ax = 0x5200;
|
|
if (Int86x(0x21, ®) == 0)
|
|
{
|
|
pbSysVars = (PBYTE) pvAddPvCb(vo.dwHighLinear,
|
|
reg.es * 16 + reg.bx);
|
|
|
|
// Build the list of drivers in conventional memory.
|
|
wTemp = PUN(WORD, pbSysVars[-2]);
|
|
|
|
DosMem_WalkArena(wTemp, vo.dwHighLinear);
|
|
|
|
// Build the list of drivers in UMBs.
|
|
wTemp = PUN(WORD, pbSysVars[0x66]);
|
|
if (wTemp != 0xFFFF)
|
|
{
|
|
DosMem_WalkArena(wTemp, vo.dwHighLinear);
|
|
}
|
|
|
|
// Remove KRNL386 and its ilk to prune away non-TSR apps.
|
|
DosMem_CleanArena(vo.dwHighLinear);
|
|
}
|
|
}
|
|
|
|
exit:
|
|
TraceFunctLeave();
|
|
if (hVxD)
|
|
{
|
|
CloseHandle(hVxD);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
// get list of user mode drivers
|
|
HRESULT
|
|
CPCH_Driver::GetDriverUserMode()
|
|
{
|
|
BOOL fRc;
|
|
WORD hDriver;
|
|
DRIVERINFOSTRUCT16 dis;
|
|
|
|
TraceFunctEnter("CPCH_Driver::GetDriverUserMode");
|
|
|
|
dis.length = sizeof(dis);
|
|
|
|
hDriver = 0;
|
|
|
|
// walk through list of 16-bit drivers
|
|
while ((hDriver = GetNextDriver16(hDriver,
|
|
GND_FIRSTINSTANCEONLY)) != 0)
|
|
{
|
|
if (GetDriverInfo16(hDriver, &dis))
|
|
{
|
|
WORD wVer;
|
|
DWORD dwMajor;
|
|
DWORD dwMinor;
|
|
TCHAR szTemp[MAX_PATH];
|
|
DRIVER_USER_MODE* pDriver = new DRIVER_USER_MODE;
|
|
|
|
if (!pDriver)
|
|
{
|
|
ErrorTrace(TRACE_ID,"Cannot allocate memory");
|
|
goto exit;
|
|
}
|
|
|
|
if (GetModuleFileName16(dis.hModule,
|
|
pDriver->strPath,
|
|
cA(pDriver->strPath)))
|
|
{
|
|
lstrcpyn(pDriver->strDriver,
|
|
dis.szAliasName,
|
|
cA(pDriver->strDriver));
|
|
|
|
wVer = GetExpWinVer16(dis.hModule);
|
|
dwMajor = HIBYTE(wVer);
|
|
dwMinor = LOBYTE(wVer);
|
|
wsprintf(pDriver->strType,
|
|
TEXT("%d.%d"),
|
|
dwMajor,
|
|
dwMinor % 10 ? dwMinor : dwMinor / 10);
|
|
|
|
// append to driver list
|
|
m_DriverUserModeList.push_back(pDriver);
|
|
}
|
|
else
|
|
{
|
|
delete pDriver;
|
|
ErrorTrace(TRACE_ID, "GetModuleFileName16 failed");
|
|
}
|
|
}
|
|
}
|
|
|
|
exit:
|
|
TraceFunctLeave();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// walk arena and create list of drivers
|
|
void
|
|
CPCH_Driver::DosMem_WalkArena(WORD segStart, DWORD dwHighLinear)
|
|
{
|
|
WORD segStop = 0;
|
|
WORD seg = segStart;
|
|
TCHAR szTemp[MAX_PATH]="";
|
|
|
|
TraceFunctEnter("DosMem_WalkArena");
|
|
|
|
do
|
|
{
|
|
PARENA par = (PARENA) (dwHighLinear + seg * 16);
|
|
|
|
seg++;
|
|
|
|
// Remember the stop point if we've found it.
|
|
if (par->bType == 'Z')
|
|
{
|
|
segStop = (WORD)(seg + par->csegSize);
|
|
}
|
|
|
|
|
|
// If it's owned by itself, then it's a program or driver.
|
|
// We know a bit more about the DOS memory subtypes.
|
|
// This can change in principle (since most people don't
|
|
// know about it, and we changed it in Win95, so obviously
|
|
// it isn't compatibility-constrained).
|
|
if (par->segOwner == seg)
|
|
{
|
|
DRIVER_MS_DOS* pDriver = NULL;
|
|
|
|
if (par->bType == 'M' || par->bType == 'D' || par->bType == 'Z')
|
|
{
|
|
|
|
pDriver = new DRIVER_MS_DOS;
|
|
|
|
if (!pDriver)
|
|
{
|
|
ErrorTrace(TRACE_ID, "Cannot allocate memory");
|
|
goto exit;
|
|
}
|
|
|
|
lstrcpyn(pDriver->strName, par->rgchOwner, 9);
|
|
pDriver->seg = seg;
|
|
m_DriverMSDosList.push_back(pDriver);
|
|
}
|
|
}
|
|
|
|
|
|
// If it's owned by 8 and rgchOwner is "SD", then it's
|
|
// "system data" and contains subobjects. Else, it's a
|
|
// normal arena that we step over.
|
|
segStart = seg;
|
|
if (par->segOwner == 8 && PUN(WORD, par->rgchOwner) == 0x4453)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
seg = (WORD)(seg + par->csegSize);
|
|
}
|
|
|
|
if (seg < segStart)
|
|
{
|
|
break;
|
|
}
|
|
|
|
} while (seg != segStop);
|
|
|
|
exit:
|
|
TraceFunctLeave();
|
|
}
|
|
|
|
|
|
// Remove the items that are apps and not TSRs.
|
|
// Done by locating KRNL386, and then walking the parent chain until
|
|
// we find an app that is its own parent.
|
|
void
|
|
CPCH_Driver::DosMem_CleanArena(DWORD dwHighLinear)
|
|
{
|
|
std::list<DRIVER_MS_DOS*>::iterator it = m_DriverMSDosList.begin();
|
|
std::list<DRIVER_MS_DOS*>::iterator it2;
|
|
WORD seg, segParent;
|
|
PBYTE ppsp;
|
|
|
|
TraceFunctEnter("CPCH_Driver::DosMem_CleanArena");
|
|
|
|
while (it != m_DriverMSDosList.end())
|
|
{
|
|
if ((*it) && _tcsstr((*it)->strName,TEXT("KRNL386")))
|
|
{
|
|
break;
|
|
}
|
|
it++;
|
|
}
|
|
|
|
// cannot find KRNL386?
|
|
if (it == m_DriverMSDosList.end() || !(*it))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
// traverse list in reverse order
|
|
do
|
|
{
|
|
seg = (*it)->seg;
|
|
ppsp = (PBYTE) (dwHighLinear + seg * 16);
|
|
m_DriverMSDosList.erase(it);
|
|
it--;
|
|
|
|
segParent = PUN(WORD, ppsp[0x16]);
|
|
if (seg == segParent) // Found the top. Stop
|
|
{
|
|
break;
|
|
}
|
|
|
|
// find parent
|
|
for (it2 = m_DriverMSDosList.begin(); it2 != m_DriverMSDosList.end(); it2++)
|
|
{
|
|
if ((*it2) && (*it2)->seg == segParent)
|
|
{
|
|
it = it2;
|
|
break;
|
|
}
|
|
}
|
|
if (it2 == m_DriverMSDosList.end()) // parent not found
|
|
{
|
|
break;
|
|
}
|
|
} while (it != m_DriverMSDosList.begin() && (*it));
|
|
|
|
exit:
|
|
TraceFunctLeave();
|
|
}
|
|
|
|
|
|
void CPCH_Driver::SetFileVersionInfo(CComBSTR filename, CInstance *pInstance)
|
|
{
|
|
CFileVersionInfo fvi;
|
|
|
|
TraceFunctEnter("CPCH_Driver::SetFileVersionInfo");
|
|
|
|
CComPtr<IWbemClassObject> pFileObj;
|
|
if (SUCCEEDED(GetCIMDataFile(filename, &pFileObj)))
|
|
{
|
|
CopyProperty(pFileObj, L"Version", pInstance, pVersion);
|
|
CopyProperty(pFileObj, L"FileSize", pInstance, pSize);
|
|
CopyProperty(pFileObj, L"CreationDate", pInstance, pDate);
|
|
CopyProperty(pFileObj, L"Manufacturer", pInstance, pManufacturer);
|
|
}
|
|
|
|
if (SUCCEEDED(fvi.QueryFile(filename)))
|
|
{
|
|
if (!pInstance->SetCHString(pDescription, fvi.GetDescription()))
|
|
ErrorTrace(TRACE_ID, "SetCHString on description field failed.");
|
|
|
|
if (!pInstance->SetCHString(pPartOf, fvi.GetProduct()))
|
|
ErrorTrace(TRACE_ID, "SetCHString on partof field failed.");
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
}
|
|
|
|
|
|
// step through user mode driver list and create instances
|
|
HRESULT
|
|
CPCH_Driver::ParseUserModeList(
|
|
MethodContext* pMethodContext
|
|
)
|
|
{
|
|
HRESULT hRes = WBEM_S_NO_ERROR;
|
|
std::list<DRIVER_USER_MODE* >::iterator it = m_DriverUserModeList.begin();
|
|
|
|
TraceFunctEnter("CPCH_Driver::ParseUserModeList");
|
|
|
|
while (it != m_DriverUserModeList.end() && (SUCCEEDED(hRes)))
|
|
{
|
|
DRIVER_USER_MODE* pUMDrv = *it;
|
|
|
|
if (!pUMDrv)
|
|
{
|
|
ErrorTrace(TRACE_ID, "Null driver node in list");
|
|
continue;
|
|
}
|
|
|
|
SYSTEMTIME stUTCTime;
|
|
GetSystemTime(&stUTCTime);
|
|
|
|
// Create a new instance based on the passed-in MethodContext
|
|
CInstancePtr pInstance(CreateNewInstance(pMethodContext), false);
|
|
|
|
if (!pInstance->SetDateTime(pTimeStamp, WBEMTime(stUTCTime)))
|
|
{
|
|
ErrorTrace(TRACE_ID, "SetDateTime on Timestamp Field failed.");
|
|
}
|
|
if (!pInstance->SetCHString(pChange, L"Snapshot"))
|
|
{
|
|
ErrorTrace(TRACE_ID, "SetCHString on Change Field failed.");
|
|
}
|
|
|
|
// set category
|
|
if (!pInstance->SetCHString(pCategory, L"UserMode"))
|
|
{
|
|
ErrorTrace(TRACE_ID, "SetCHString on Change Field failed.");
|
|
}
|
|
|
|
// set driver name
|
|
if (!pInstance->SetCHString(pName, pUMDrv->strDriver))
|
|
{
|
|
ErrorTrace(TRACE_ID, "SetCHString on Name Field failed.");
|
|
}
|
|
|
|
// set path
|
|
if (!pInstance->SetCHString(pPath, pUMDrv->strPath))
|
|
{
|
|
ErrorTrace(TRACE_ID, "SetCHString on Path Field failed.");
|
|
}
|
|
|
|
// set type
|
|
if (!pInstance->SetCHString(pType, pUMDrv->strType))
|
|
{
|
|
ErrorTrace(TRACE_ID, "SetCHString on Type Field failed.");
|
|
}
|
|
|
|
|
|
// get version info
|
|
CFileVersionInfo fvi;
|
|
CComBSTR filename = pUMDrv->strPath;
|
|
SetFileVersionInfo(filename,pInstance);
|
|
hRes = pInstance->Commit();
|
|
if (FAILED(hRes))
|
|
{
|
|
ErrorTrace(TRACE_ID, "Commit on Instance failed.");
|
|
}
|
|
|
|
// delete the node
|
|
delete pUMDrv;
|
|
pUMDrv = NULL;
|
|
it = m_DriverUserModeList.erase(it);
|
|
}
|
|
TraceFunctLeave();
|
|
return hRes;
|
|
}
|
|
|
|
|
|
// step through ms-dos driver list and create instances
|
|
HRESULT
|
|
CPCH_Driver::ParseMSDosList(
|
|
MethodContext* pMethodContext
|
|
)
|
|
{
|
|
HRESULT hRes = WBEM_S_NO_ERROR;
|
|
std::list<DRIVER_MS_DOS* >::iterator it = m_DriverMSDosList.begin();
|
|
|
|
TraceFunctEnter("CPCH_Driver::ParseMSDosList");
|
|
|
|
while (it != m_DriverMSDosList.end() && (SUCCEEDED(hRes)))
|
|
{
|
|
DRIVER_MS_DOS* pMSDrv = *it;
|
|
|
|
if (!pMSDrv)
|
|
{
|
|
ErrorTrace(TRACE_ID, "Null driver node in list");
|
|
continue;
|
|
}
|
|
|
|
SYSTEMTIME stUTCTime;
|
|
GetSystemTime(&stUTCTime);
|
|
|
|
|
|
// Create a new instance based on the passed-in MethodContext
|
|
CInstancePtr pInstance(CreateNewInstance(pMethodContext), false);
|
|
|
|
if (!pInstance->SetDateTime(pTimeStamp, WBEMTime(stUTCTime)))
|
|
{
|
|
ErrorTrace(TRACE_ID, "SetDateTime on Timestamp Field failed.");
|
|
}
|
|
|
|
if (!pInstance->SetCHString(pChange, L"Snapshot"))
|
|
{
|
|
ErrorTrace(TRACE_ID, "SetCHString on Change Field failed.");
|
|
}
|
|
|
|
// set category
|
|
if (!pInstance->SetCHString(pCategory, L"MSDOS"))
|
|
{
|
|
ErrorTrace(TRACE_ID, "SetCHString on Change Field failed.");
|
|
}
|
|
|
|
// set driver name
|
|
if (!pInstance->SetCHString(pName, pMSDrv->strName))
|
|
{
|
|
ErrorTrace(TRACE_ID, "SetCHString on Name Field failed.");
|
|
}
|
|
|
|
// set type to "Device Driver"
|
|
if (!pInstance->SetCHString(pType, L"Device Driver"))
|
|
{
|
|
ErrorTrace(TRACE_ID, "SetCHString on Type Field failed.");
|
|
}
|
|
|
|
hRes = pInstance->Commit();
|
|
if (FAILED(hRes))
|
|
{
|
|
ErrorTrace(TRACE_ID, "Commit on Instance failed.");
|
|
}
|
|
|
|
// delete the node
|
|
delete pMSDrv;
|
|
pMSDrv = NULL;
|
|
it = m_DriverMSDosList.erase(it);
|
|
}
|
|
TraceFunctLeave();
|
|
return hRes;
|
|
}
|