Leaked source code of windows server 2003
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

  1. /********************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. PCH_Driver.CPP
  5. Abstract:
  6. WBEM provider class implementation for PCH_Driver class
  7. Revision History:
  8. Ghim-Sim Chua (gschua) 04/27/99
  9. - Created
  10. Brijesh Krishnaswami (brijeshk) 05/24/99
  11. - added code for enumerating usermode drivers
  12. - added code for enumerating msdos drivers
  13. - added code for getting details on kernel mode drivers
  14. ********************************************************************/
  15. #include "pchealth.h"
  16. #include "PCH_Driver.h"
  17. #include "drvdefs.h"
  18. #include "shlwapi.h"
  19. #define Not_VxD
  20. #include <vxdldr.h> /* For DeviceInfo */
  21. /////////////////////////////////////////////////////////////////////////////
  22. // tracing stuff
  23. #ifdef THIS_FILE
  24. #undef THIS_FILE
  25. #endif
  26. static char __szTraceSourceFile[] = __FILE__;
  27. #define THIS_FILE __szTraceSourceFile
  28. #define TRACE_ID DCID_DRIVER
  29. #define SYSTEM_INI_MAX 32767
  30. CPCH_Driver MyPCH_DriverSet (PROVIDER_NAME_PCH_DRIVER, PCH_NAMESPACE) ;
  31. void MakeSrchDirs(void);
  32. static BOOL fThunkInit = FALSE;
  33. TCHAR g_rgSrchDir[10][MAX_PATH];
  34. UINT g_nSrchDir;
  35. // Property names
  36. //===============
  37. const static WCHAR* pCategory = L"Category" ;
  38. const static WCHAR* pTimeStamp = L"TimeStamp" ;
  39. const static WCHAR* pChange = L"Change" ;
  40. const static WCHAR* pDate = L"Date" ;
  41. const static WCHAR* pDescription = L"Description" ;
  42. const static WCHAR* pLoadedFrom = L"LoadedFrom" ;
  43. const static WCHAR* pManufacturer = L"Manufacturer" ;
  44. const static WCHAR* pName = L"Name" ;
  45. const static WCHAR* pPartOf = L"PartOf" ;
  46. const static WCHAR* pPath = L"Path" ;
  47. const static WCHAR* pSize = L"Size" ;
  48. const static WCHAR* pType = L"Type" ;
  49. const static WCHAR* pVersion = L"Version" ;
  50. // Device names
  51. //=============
  52. LPSTR c_rgpszDevice[] = {
  53. "device",
  54. "display",
  55. "mouse",
  56. "keyboard",
  57. "network",
  58. "ebios",
  59. "fastdisk",
  60. "transport",
  61. "netcard",
  62. "netcard3",
  63. "netmisc",
  64. "secondnet",
  65. NULL
  66. };
  67. // IO Subsystem extensions
  68. //========================
  69. LPSTR c_rgptszDrvExt[] = {
  70. ".DRV",
  71. ".MPD",
  72. ".PDR",
  73. ".VXD",
  74. NULL
  75. };
  76. // Registry key names
  77. //===================
  78. LPCTSTR c_rgptszConfig[] = {
  79. TEXT("DevLoader"),
  80. TEXT("Contention"),
  81. TEXT("Enumerator"),
  82. TEXT("Driver"),
  83. TEXT("PortDriver"),
  84. TEXT("DeviceVxDs"),
  85. TEXT("vdd"),
  86. TEXT("minivdd"),
  87. NULL
  88. };
  89. // Known VxDs
  90. //===========
  91. LPCTSTR astrKnownVxDs[] = {
  92. "VMM",
  93. "VPOWERD",
  94. "ENABLE",
  95. "VKD",
  96. "VFLATD",
  97. "BIOS",
  98. "VDD",
  99. "VMOUSE",
  100. "EBIOS",
  101. "VSHARE",
  102. "VWIN32",
  103. "VFBACKUP",
  104. "VCOMM",
  105. "COMBUFF",
  106. "VCD",
  107. "VPD",
  108. "IFSMGR",
  109. "IOS",
  110. "SPOOLER",
  111. "VFAT",
  112. "VCACHE",
  113. "VCOND",
  114. "VCDFSD",
  115. "INT13",
  116. "VXDLDR",
  117. "VDEF",
  118. "PAGEFILE",
  119. "CONFIGMG",
  120. "VMD",
  121. "DOSNET",
  122. "VPICD",
  123. "VTD",
  124. "REBOOT",
  125. "VDMAD",
  126. "VSD",
  127. "V86MMGR",
  128. "PAGESWAP",
  129. "DOSMGR",
  130. "VMPOLL",
  131. "SHELL",
  132. "PARITY",
  133. "BIOSXLAT",
  134. "VMCPD",
  135. "VTDAPI",
  136. "PERF",
  137. "NTKERN",
  138. "SDVXD",
  139. NULL
  140. };
  141. // Known VxD Description
  142. //======================
  143. LPCTSTR astrKnownVxDsDesc[] = {
  144. "Virtual Machine Manager",
  145. "Advanced Power Management driver",
  146. "Accessibility driver",
  147. "Keyboard driver",
  148. "Linear aperture video driver",
  149. "Plug and Play BIOS driver",
  150. "Display driver",
  151. "Mouse driver",
  152. "Extended BIOS driver",
  153. "File sharing driver",
  154. "Win32 subsystem driver",
  155. "Floppy backup helper driver",
  156. "Communications port Plug and Play driver",
  157. "Communications buffer driver",
  158. "Communications port driver",
  159. "Printer driver",
  160. "File system manager",
  161. "I/O Supervisor",
  162. "Print spooler",
  163. "FAT filesystem driver",
  164. "Cache manager",
  165. "Console subsystem driver",
  166. "CD-ROM filesystem driver",
  167. "BIOS hard disk emulation driver",
  168. "Dynamic device driver loader",
  169. "Default filesystem driver",
  170. "Swapfile driver",
  171. "Configuration manager",
  172. "Windows 3.1-compatible mouse driver",
  173. "Windows 3.1-compatible network helper driver",
  174. "Hardware interrupt manager",
  175. "Timer device driver",
  176. "Ctrl+Alt+Del manager",
  177. "Direct Memory Access controller driver",
  178. "Speaker driver",
  179. "MS-DOS memory manager",
  180. "Swapfile manager",
  181. "MS-DOS emulation manager",
  182. "System idle-time driver",
  183. "Shell device driver",
  184. "Memory parity driver",
  185. "BIOS emulation driver",
  186. "Math coprocessor driver",
  187. "Multimedia timer driver",
  188. "System Monitor data collection driver",
  189. "Windows Driver Model",
  190. "SmartDrive",
  191. NULL
  192. };
  193. /*****************************************************************************
  194. *
  195. * FUNCTION : CPCH_Driver::EnumerateInstances
  196. *
  197. * DESCRIPTION : Returns all the instances of this class.
  198. *
  199. * INPUTS : A pointer to the MethodContext for communication with WinMgmt.
  200. * A long that contains the flags described in
  201. * IWbemServices::CreateInstanceEnumAsync. Note that the following
  202. * flags are handled by (and filtered out by) WinMgmt:
  203. * WBEM_FLAG_DEEP
  204. * WBEM_FLAG_SHALLOW
  205. * WBEM_FLAG_RETURN_IMMEDIATELY
  206. * WBEM_FLAG_FORWARD_ONLY
  207. * WBEM_FLAG_BIDIRECTIONAL
  208. *
  209. * RETURNS : WBEM_S_NO_ERROR if successful
  210. *
  211. * COMMENTS : TO DO: All instances on the machine should be returned here.
  212. * If there are no instances, return WBEM_S_NO_ERROR.
  213. * It is not an error to have no instances.
  214. *
  215. *****************************************************************************/
  216. HRESULT CPCH_Driver::EnumerateInstances(
  217. MethodContext* pMethodContext,
  218. long lFlags
  219. )
  220. {
  221. TraceFunctEnter("CPCH_Driver::AddDriverKernelList");
  222. HRESULT hRes = WBEM_S_NO_ERROR;
  223. CComVariant varValue;
  224. //
  225. // Get the date and time
  226. SYSTEMTIME stUTCTime;
  227. GetSystemTime(&stUTCTime);
  228. // if thunk init is already done, don't initialize again
  229. if (!fThunkInit)
  230. {
  231. ThunkInit();
  232. fThunkInit = TRUE;
  233. }
  234. // Enumerate Kernel Drivers
  235. MakeSrchDirs();
  236. GetDriverKernel();
  237. DRIVER_KERNEL *pDrvKer = m_pDriverKernel;
  238. DRIVER_KERNEL *pDelDrvKer;
  239. while(pDrvKer)
  240. {
  241. // Create a new instance
  242. CInstancePtr pInstance(CreateNewInstance(pMethodContext), false);
  243. // Set the timestamp
  244. if (!pInstance->SetDateTime(pTimeStamp, WBEMTime(stUTCTime)))
  245. ErrorTrace(TRACE_ID, "SetDateTime on Timestamp Field failed.");
  246. // Set the category
  247. if (!pInstance->SetCHString(pCategory, "Kernel"))
  248. ErrorTrace(TRACE_ID, "SetVariant on Category Field failed.");
  249. // Set the name
  250. if (_tcslen(pDrvKer->strDriver))
  251. {
  252. varValue = pDrvKer->strDriver;
  253. if (!pInstance->SetVariant(pName, varValue))
  254. ErrorTrace(TRACE_ID, "SetVariant on Name Field failed.");
  255. }
  256. // Set the path
  257. if (_tcslen(pDrvKer->strLikelyPath))
  258. {
  259. varValue = pDrvKer->strLikelyPath;
  260. if (!pInstance->SetVariant(pPath, varValue))
  261. ErrorTrace(TRACE_ID, "SetVariant on Path Field failed.");
  262. }
  263. // set file description, version, partof
  264. CComBSTR filename = pDrvKer->strLikelyPath;
  265. SetFileVersionInfo(filename, pInstance);
  266. // Set the Description - overwrite with well-known description if available
  267. if (_tcslen(pDrvKer->strDescription))
  268. {
  269. varValue = pDrvKer->strDescription;
  270. if (!pInstance->SetVariant(pDescription, varValue))
  271. ErrorTrace(TRACE_ID, "SetVariant on Description Field failed.");
  272. }
  273. // Set the LoadedFrom
  274. if (_tcslen(pDrvKer->strLoadedFrom))
  275. {
  276. varValue = pDrvKer->strLoadedFrom;
  277. if (!pInstance->SetVariant(pLoadedFrom, varValue))
  278. ErrorTrace(TRACE_ID, "SetVariant on LoadedFrom Field failed.");
  279. }
  280. // Commit this
  281. hRes = pInstance->Commit();
  282. if (FAILED(hRes))
  283. ErrorTrace(TRACE_ID, "Commit on Instance failed.");
  284. // advance and delete the record
  285. pDelDrvKer = pDrvKer;
  286. pDrvKer = pDrvKer->next;
  287. delete (pDelDrvKer);
  288. }
  289. // get usermode drivers
  290. // create instances, and cleanup list
  291. GetDriverUserMode();
  292. ParseUserModeList(pMethodContext);
  293. // get msdos drivers
  294. // create instances, and cleanup list
  295. GetDriverMSDos();
  296. ParseMSDosList(pMethodContext);
  297. TraceFunctLeave();
  298. return hRes;
  299. }
  300. HRESULT CPCH_Driver::AddDriverKernelList(LPTSTR strDriverList, LPTSTR strLoadedFrom)
  301. {
  302. TraceFunctEnter("CPCH_Driver::AddDriverKernelList");
  303. // Break driver list up into tokens
  304. LPTSTR strDriverName;
  305. int nStrLen;
  306. int nPos;
  307. while ((strDriverName = Token_Find(&strDriverList)) != 0)
  308. {
  309. // Got the first token
  310. // See if the first character is '*', if so remove it.
  311. if(strDriverName[0] == _T('*'))
  312. {
  313. strDriverName++;
  314. }
  315. // Allocate new element
  316. DRIVER_KERNEL *pNewKernel = new DRIVER_KERNEL;
  317. if (!pNewKernel)
  318. {
  319. ErrorTrace(TRACE_ID, "Out of memory while calling new DRIVER_KERNEL");
  320. return WBEM_E_OUT_OF_MEMORY;
  321. }
  322. // Zero out all memory
  323. ZeroMemory(pNewKernel, sizeof(DRIVER_KERNEL));
  324. // Check if we have a path by seeing if filename is same as the driver name
  325. LPTSTR strFilename = PathFindFileName(strDriverName);
  326. // copy name
  327. _tcscpy(pNewKernel->strDriver, strFilename);
  328. // terminate name at the extension
  329. *PathFindExtension(pNewKernel->strDriver) = 0;
  330. // check for duplicates
  331. DRIVER_KERNEL *pDrvKerLoop = m_pDriverKernel;
  332. BOOL bDup = FALSE;
  333. while(pDrvKerLoop)
  334. {
  335. if (!_tcsicmp(pDrvKerLoop->strDriver, pNewKernel->strDriver))
  336. {
  337. bDup = TRUE;
  338. break;
  339. }
  340. pDrvKerLoop = pDrvKerLoop->next;
  341. }
  342. // if duplicate, delete it, otherwise store it in linked list
  343. if (bDup)
  344. {
  345. delete pNewKernel;
  346. }
  347. else
  348. {
  349. // Copy Loaded From
  350. _tcscpy(pNewKernel->strLoadedFrom, strLoadedFrom);
  351. // Copy Path
  352. _tcscpy(pNewKernel->strLikelyPath, strDriverName);
  353. // check if it is a well known VxD and copy the description
  354. for(int iVxDIndex = 0; astrKnownVxDs[iVxDIndex]; iVxDIndex++)
  355. if (!_tcsicmp(astrKnownVxDs[iVxDIndex], pNewKernel->strDriver))
  356. _tcscpy(pNewKernel->strDescription, astrKnownVxDsDesc[iVxDIndex]);
  357. // Add it to the list
  358. pNewKernel->next = m_pDriverKernel;
  359. m_pDriverKernel = pNewKernel;
  360. }
  361. }
  362. TraceFunctLeave();
  363. return S_OK;
  364. }
  365. HRESULT CPCH_Driver::GetDriverKernel()
  366. {
  367. TraceFunctEnter("CPCH_Driver::GetDriverKernel");
  368. // Init WinDir
  369. TCHAR strWinDir[MAX_PATH];
  370. GetWindowsDirectory(strWinDir, MAX_PATH);
  371. // init head of list
  372. m_pDriverKernel = NULL;
  373. // Add vmm driver
  374. TCHAR strVmmPath[MAX_PATH];
  375. TCHAR strVmmFilePath[MAX_PATH];
  376. PathCombine(strVmmPath, strWinDir, "VMM32");
  377. PathCombine(strVmmFilePath, strVmmPath, "vmm.vxd");
  378. AddDriverKernelList(strVmmFilePath, "Registry");
  379. // Add debugging drivers
  380. AddDriverKernelList("wdeb386.exe", "Debugger");
  381. AddDriverKernelList("debugcmd.vxd", "Debugger");
  382. // Add winsock drivers
  383. AddDriverKernelList("wsock.vxd", "Winsock");
  384. AddDriverKernelList("vdhcp.386", "Winsock");
  385. // Add WINMM drivers
  386. AddDriverKernelList("mmdevldr.vxd", "Plug and Play");
  387. // AddDriverKernelList("===HKLM_System_CurrentControlSet_Services_VxD_AFVXD===", "Registry");
  388. // Add HKLM\System\CurrentControlSet\Services\VxD\AFVXD
  389. AddRegDriverList(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\AFVXD");
  390. // AddDriverKernelList("===HKLM_System_CurrentControlSet_Services_VxD_Winsock===", "Registry");
  391. // Add HKLM\System\CurrentControlSet\Services\VxD\Winsock
  392. AddRegDriverList(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\Winsock");
  393. // AddDriverKernelList("===HKLM_System_CurrentControlSet_Services_Class===", "Registry");
  394. // Add HKLM\System\CurrentControlSet\Services\Class
  395. GetRegDriver("System\\CurrentControlSet\\Services\\Class");
  396. // AddDriverKernelList("===HKLM_System_CurrentControlSet_Services_Class_Display===", "Registry");
  397. // Add HKLM\System\CurrentControlSet\Services\Class\Display
  398. GetRegDriver("System\\CurrentControlSet\\Services\\Class\\Display");
  399. // AddDriverKernelList("===SYSTEM_INI===", "Registry");
  400. // Add system.ini drivers
  401. GetSystemINIDriver();
  402. // AddDriverKernelList("===IOSubSystem===", "Registry");
  403. // Add IO Subsystem drivers
  404. GetIOSubsysDriver();
  405. // AddDriverKernelList("===HKLM_System_CurrentControlSet_Services_VxD===", "Registry");
  406. // Add HKLM\System\CurrentControlSet\Services\VxD
  407. GetServicesVxD();
  408. // Collect additional driver information from MSISYS or DrWatson
  409. GetMSISYSVxD();
  410. // Now that we've collected all the drivers, collect each driver's information
  411. GetKernelDriverInfo();
  412. TraceFunctLeave();
  413. return S_OK;
  414. }
  415. BOOL
  416. Drivers_PathFileExists(LPTSTR ptszBuf, LPCTSTR ptszPath, LPCTSTR ptszFile)
  417. {
  418. PathCombine(ptszBuf, ptszPath, ptszFile);
  419. return PathFileExists(ptszBuf);
  420. }
  421. void
  422. MakeSrchDirs(void)
  423. {
  424. TCHAR tszPath[3];
  425. LPTSTR pszDir;
  426. UINT ctchPath;
  427. LPTSTR ptsz;
  428. LPTSTR pTmp;
  429. int i = 0;
  430. // look in windows dir
  431. GetWindowsDirectory(g_rgSrchDir[0], MAX_PATH);
  432. // look in windows\vmm32
  433. PathCombine(g_rgSrchDir[1], g_rgSrchDir[0], TEXT("VMM32"));
  434. // look in system dir
  435. GetSystemDirectory(g_rgSrchDir[2], MAX_PATH);
  436. // look in boot dir
  437. RMIREGS reg;
  438. reg.ax = 0x3305;
  439. reg.dl = 3; // assume C: in case of error
  440. Int86x(0x21, &reg);
  441. wsprintf(g_rgSrchDir[3], "%c:\\", reg.dl + '@');
  442. // look in dirs specified in path variable
  443. i = 4;
  444. pszDir = NULL;
  445. // get size of path string
  446. ctchPath = GetEnvironmentVariable(TEXT("PATH"), tszPath, 1);
  447. pTmp = ptsz = new TCHAR[ctchPath+1];
  448. if (ptsz)
  449. {
  450. GetEnvironmentVariable(TEXT("PATH"), ptsz, ctchPath);
  451. while ((pszDir = Token_Find(&ptsz)) != 0)
  452. {
  453. lstrcpy(g_rgSrchDir[i++],pszDir);
  454. }
  455. delete [] pTmp;
  456. }
  457. g_nSrchDir = i-1;
  458. }
  459. HRESULT CPCH_Driver::GetKernelDriverInfo()
  460. {
  461. int i;
  462. TraceFunctEnter("CPCH_Driver::GetKernelDriverInfo");
  463. /*
  464. * Search order :
  465. *
  466. * 1. If extension is ".386" look in Windows directory.
  467. * 2. Look in System directory.
  468. * 3. Look in directory Windows was launched from.
  469. * (We'll assume Root directory.)
  470. * 4. Then look on the path.
  471. *
  472. * If the file doesn't have an extension, use ".vxd".
  473. *
  474. * BUGBUG -- this is a hack; need to look for .386 too
  475. */
  476. DRIVER_KERNEL *pDKLoop;
  477. pDKLoop = m_pDriverKernel;
  478. while(pDKLoop)
  479. {
  480. TCHAR szFile[MAX_PATH] = TEXT("");
  481. LPTSTR szExtension = NULL;
  482. if (PathFileExists(pDKLoop->strLikelyPath))
  483. {
  484. goto havefile;
  485. }
  486. lstrcpy(szFile, pDKLoop->strLikelyPath);
  487. for (i=0; i<g_nSrchDir; i++)
  488. {
  489. if (Drivers_PathFileExists(pDKLoop->strLikelyPath, g_rgSrchDir[i], szFile))
  490. {
  491. goto havefile;
  492. }
  493. szExtension = PathFindExtension(pDKLoop->strLikelyPath);
  494. // no extension?
  495. if (!_tcslen(szExtension))
  496. {
  497. // try .VXD
  498. lstrcat(szFile, TEXT(".VXD"));
  499. if (Drivers_PathFileExists(pDKLoop->strLikelyPath, g_rgSrchDir[i], szFile))
  500. {
  501. goto havefile;
  502. }
  503. // try .386
  504. lstrcpy(szFile, pDKLoop->strLikelyPath);
  505. lstrcat(szFile, TEXT(".386"));
  506. if (Drivers_PathFileExists(pDKLoop->strLikelyPath, g_rgSrchDir[i], szFile))
  507. {
  508. goto havefile;
  509. }
  510. }
  511. }
  512. // no path
  513. lstrcpy(pDKLoop->strLikelyPath, TEXT(""));
  514. havefile:
  515. pDKLoop = pDKLoop->next;
  516. }
  517. TraceFunctLeave();
  518. return S_OK;
  519. }
  520. HRESULT CPCH_Driver::GetSystemINIDriver()
  521. {
  522. TraceFunctEnter("CPCH_Driver::GetSystemINIDriver");
  523. TCHAR str386Enh[SYSTEM_INI_MAX];
  524. LPTSTR strLine;
  525. int iLineLen;
  526. // Get the section 386Enh in system.ini
  527. GetPrivateProfileSection(TEXT("386Enh"), str386Enh, SYSTEM_INI_MAX, TEXT("system.ini"));
  528. // For each line in the 386Enh section
  529. for (strLine = str386Enh; (iLineLen = _tcslen(strLine)) != 0; strLine += iLineLen + 1)
  530. {
  531. // Get the value after the '=' char
  532. LPTSTR strValue = _tcschr(strLine, '=');
  533. if (strValue)
  534. {
  535. // Terminate the string at the '=' char
  536. *strValue = '\0';
  537. // Look to see if device corresponds to any of the listed devices
  538. for (int iDeviceNames = 0; c_rgpszDevice[iDeviceNames]; iDeviceNames++)
  539. {
  540. // if it is listed, add to the driver list
  541. if (_tcsicmp(c_rgpszDevice[iDeviceNames], strLine) == 0)
  542. {
  543. AddDriverKernelList(strValue + 1, "system.ini");
  544. }
  545. }
  546. }
  547. }
  548. TraceFunctLeave();
  549. return S_OK;
  550. }
  551. HRESULT CPCH_Driver::GetIOSubsysDriver()
  552. {
  553. TraceFunctEnter("CPCH_Driver::GetIOSubsysDriver");
  554. TCHAR strSystemDir[MAX_PATH];
  555. TCHAR strIOSubSys[MAX_PATH];
  556. TCHAR strIOSubSysWildcard[MAX_PATH];
  557. TCHAR strFullPath[MAX_PATH];
  558. TCHAR strDir[MAX_PATH];
  559. HANDLE hfd;
  560. WIN32_FIND_DATA wfd;
  561. // get the system directory
  562. if (!GetSystemDirectory(strSystemDir, MAX_PATH))
  563. {
  564. ErrorTrace(TRACE_ID, "Error while calling GetSystemDirectory");
  565. goto EndIO;
  566. }
  567. // combine paths to IO Subsystem
  568. PathCombine(strIOSubSys, strSystemDir, "IOSUBSYS");
  569. PathCombine(strIOSubSysWildcard, strIOSubSys, "*.*");
  570. // enumerate all files in IO Subsystem
  571. hfd = FindFirstFile(strIOSubSysWildcard, &wfd);
  572. if (hfd != INVALID_HANDLE_VALUE)
  573. do
  574. {
  575. // add file it it has one of the extensions in c_rgptszDrvExt
  576. LPTSTR strExt = PathFindExtension(wfd.cFileName);
  577. for (int iExt = 0; c_rgptszDrvExt[iExt]; iExt++) {
  578. if (_tcsicmp(strExt, c_rgptszDrvExt[iExt]) == 0) {
  579. PathCombine(strFullPath, strIOSubSys, wfd.cFileName);
  580. AddDriverKernelList(strFullPath, "I/O subsystem");
  581. break;
  582. }
  583. }
  584. } while (FindNextFile(hfd, &wfd));
  585. FindClose(hfd);
  586. EndIO:
  587. TraceFunctLeave();
  588. return S_OK;
  589. }
  590. HRESULT CPCH_Driver::GetServicesVxD()
  591. {
  592. TraceFunctEnter("CPCH_Driver::GetServicesVxD");
  593. TCHAR strStaticVxd[MAX_PATH];
  594. DWORD dwLen = MAX_PATH;
  595. HKEY hkMain;
  596. // Open the key in registry
  597. if (RegOpenKey(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD", &hkMain) == ERROR_SUCCESS)
  598. {
  599. TCHAR strValue[MAX_PATH];
  600. // Enum all the keys in the subkey
  601. for (int iEnumSubKey = 0; RegEnumKey(hkMain, iEnumSubKey, strValue, MAX_PATH) == ERROR_SUCCESS; iEnumSubKey++)
  602. {
  603. HKEY hkSub;
  604. // Open the subkey
  605. if (RegOpenKey(hkMain, strValue, &hkSub) == ERROR_SUCCESS)
  606. {
  607. // examine the StaticVxD value
  608. dwLen = MAX_PATH;
  609. if (RegQueryValueEx(hkSub, "StaticVxD", 0, 0, (LPBYTE)strStaticVxd, &dwLen) == ERROR_SUCCESS)
  610. AddDriverKernelList(strStaticVxd, "Registry");
  611. // close the key
  612. RegCloseKey(hkSub);
  613. }
  614. }
  615. // close the key
  616. RegCloseKey(hkMain);
  617. }
  618. TraceFunctLeave();
  619. return S_OK;
  620. }
  621. HRESULT CPCH_Driver::GetMSISYSVxD()
  622. {
  623. TraceFunctEnter("CPCH_Driver::GetMSISYSVxD");
  624. HANDLE hVxDHandle = INVALID_HANDLE_VALUE;
  625. // try looking for MSISYS.VXD
  626. hVxDHandle = CreateFile("\\\\.\\MSISYS.VXD", 0, 0, 0, 0, FILE_ATTRIBUTE_NORMAL, 0);
  627. if (hVxDHandle == INVALID_HANDLE_VALUE)
  628. {
  629. // try looking for DRWATSON.VXD
  630. hVxDHandle = CreateFile("\\\\.\\DRWATSON.VXD", 0, 0, 0, 0, FILE_ATTRIBUTE_NORMAL, 0);
  631. if (hVxDHandle == INVALID_HANDLE_VALUE)
  632. {
  633. ErrorTrace(TRACE_ID, "Error in opening MSISYS.VXD or DRWATSON.VXD");
  634. goto EndAddVxD;
  635. }
  636. }
  637. // Call into VxD to get additional information
  638. struct DeviceInfo* pDeviceInfo;
  639. DWORD cbRc;
  640. if (DeviceIoControl(hVxDHandle, IOCTL_GETVXDLIST, 0, 0, &pDeviceInfo, sizeof(pDeviceInfo), &cbRc, 0))
  641. {
  642. while (pDeviceInfo
  643. && !IsBadReadPtr(pDeviceInfo, sizeof(*pDeviceInfo))
  644. && pDeviceInfo->DI_Signature == 0x444C5658)
  645. {
  646. if (pDeviceInfo->DI_DDB == (LPVOID)1)
  647. AddDriverKernelList(pDeviceInfo->DI_ModuleName, "UNKNOWN");
  648. pDeviceInfo = pDeviceInfo->DI_Next;
  649. }
  650. }
  651. EndAddVxD:
  652. if (hVxDHandle != INVALID_HANDLE_VALUE)
  653. {
  654. CloseHandle(hVxDHandle);
  655. }
  656. TraceFunctLeave();
  657. return S_OK;
  658. }
  659. HRESULT CPCH_Driver::GetRegDriver(LPTSTR strSubKey)
  660. {
  661. TraceFunctEnter("CPCH_Driver::GetRegDriver");
  662. TCHAR strStaticVxd[MAX_PATH];
  663. DWORD dwLen = MAX_PATH;
  664. HKEY hkMain;
  665. // Open the key in registry
  666. if (RegOpenKey(HKEY_LOCAL_MACHINE, strSubKey, &hkMain) == ERROR_SUCCESS)
  667. {
  668. TCHAR strValue[MAX_PATH];
  669. // Enum all the keys in the subkey
  670. for (int iEnumSubKey = 0; RegEnumKey(hkMain, iEnumSubKey, strValue, MAX_PATH) == ERROR_SUCCESS; iEnumSubKey++)
  671. {
  672. HKEY hkSub;
  673. // Open the subkey
  674. if (RegOpenKey(hkMain, strValue, &hkSub) == ERROR_SUCCESS)
  675. {
  676. TCHAR strSubValue[MAX_PATH];
  677. // Enum all the subkeys in the subkey
  678. for (int iEnumSubSubKey = 0; RegEnumKey(hkSub, iEnumSubSubKey, strSubValue, MAX_PATH) == ERROR_SUCCESS; iEnumSubSubKey++)
  679. {
  680. HKEY hkSubSub;
  681. // Open the subsubkey
  682. if (RegOpenKey(hkSub, strSubValue, &hkSubSub) == ERROR_SUCCESS)
  683. {
  684. // examine the values in subkey
  685. AddRegDriverConfigList(hkSubSub);
  686. }
  687. // close the key
  688. RegCloseKey(hkSubSub);
  689. }
  690. // close the key
  691. RegCloseKey(hkSub);
  692. }
  693. }
  694. // close the key
  695. RegCloseKey(hkMain);
  696. }
  697. TraceFunctLeave();
  698. return S_OK;
  699. }
  700. HRESULT CPCH_Driver::AddRegDriverConfigList(HKEY hk)
  701. {
  702. TraceFunctEnter("CPCH_Driver::AddRegDriverConfigList");
  703. for (int iCount = 0; c_rgptszConfig[iCount]; iCount++)
  704. {
  705. TCHAR strValue[MAX_PATH];
  706. DWORD dwCount = MAX_PATH;
  707. if (RegQueryValueEx(hk, c_rgptszConfig[iCount], 0, 0, (LPBYTE)strValue, &dwCount) == ERROR_SUCCESS)
  708. {
  709. /*
  710. if(strValue[0] == '*')
  711. {
  712. nStrLen = _tcslen(strValue);
  713. for(nPos = 1; nPos < nStrLen ; nPos++)
  714. {
  715. strValue[nPos-1] = strValue[nPos];
  716. }
  717. }
  718. */
  719. AddDriverKernelList(strValue, "Plug and Play");
  720. }
  721. }
  722. TraceFunctLeave();
  723. return S_OK;
  724. }
  725. HRESULT CPCH_Driver::AddRegDriverList(HKEY hKeyMain, LPTSTR strSubKey)
  726. {
  727. TraceFunctEnter("CPCH_Driver::AddRegDriverList");
  728. HKEY hKey;
  729. // Open key in registry
  730. if (RegOpenKey(hKeyMain, strSubKey, &hKey) == ERROR_SUCCESS)
  731. {
  732. // enumerate all values
  733. for (int iValue = 0; ; iValue++)
  734. {
  735. TCHAR strValue[MAX_PATH];
  736. TCHAR strKey[MAX_PATH];
  737. DWORD ctchRc = MAX_PATH;
  738. DWORD cbRc = MAX_PATH;
  739. LONG lResult;
  740. lResult = RegEnumValue(hKey, iValue, strKey, &ctchRc, 0, 0, (LPBYTE)strValue, &cbRc);
  741. if (lResult == ERROR_SUCCESS)
  742. {
  743. if (strKey[0])
  744. AddDriverKernelList(strValue, "Registry");
  745. }
  746. else
  747. if (lResult != ERROR_MORE_DATA)
  748. break;
  749. }
  750. // close the key
  751. RegCloseKey(hKeyMain);
  752. }
  753. else
  754. ErrorTrace(TRACE_ID, "RegOpenKey failed");
  755. TraceFunctLeave();
  756. return S_OK;
  757. }
  758. // get list of MSDos drivers
  759. HRESULT
  760. CPCH_Driver::GetDriverMSDos()
  761. {
  762. VXDINFO vi;
  763. VXDOUT vo;
  764. HANDLE hVxD = INVALID_HANDLE_VALUE;
  765. ULONG cbRc;
  766. PBYTE pbSysVars = NULL;
  767. WORD wTemp = 0;
  768. BOOL fRc = FALSE;
  769. TraceFunctEnter("CPCH_DRIVER::GetDriverMSDos");
  770. // open handle to vxd
  771. hVxD = CreateFile(TEXT("\\\\.\\MSISYS.VXD"), 0, 0, 0, 0, FILE_FLAG_DELETE_ON_CLOSE, 0);
  772. if (hVxD == INVALID_HANDLE_VALUE)
  773. {
  774. ErrorTrace(TRACE_ID, "Cannot open VxD");
  775. goto exit;
  776. }
  777. // get high linear address of system VM
  778. // ask msisys.vxd for this
  779. vo.dwHighLinear = 0;
  780. fRc = DeviceIoControl(hVxD,
  781. IOCTL_CONNECT,
  782. &vi,
  783. sizeof(vi),
  784. &vo,
  785. sizeof(vo),
  786. &cbRc,
  787. 0);
  788. if (fRc && vo.dwHighLinear)
  789. {
  790. RMIREGS reg;
  791. // Get list of driver lists
  792. reg.ax = 0x5200;
  793. if (Int86x(0x21, &reg) == 0)
  794. {
  795. pbSysVars = (PBYTE) pvAddPvCb(vo.dwHighLinear,
  796. reg.es * 16 + reg.bx);
  797. // Build the list of drivers in conventional memory.
  798. wTemp = PUN(WORD, pbSysVars[-2]);
  799. DosMem_WalkArena(wTemp, vo.dwHighLinear);
  800. // Build the list of drivers in UMBs.
  801. wTemp = PUN(WORD, pbSysVars[0x66]);
  802. if (wTemp != 0xFFFF)
  803. {
  804. DosMem_WalkArena(wTemp, vo.dwHighLinear);
  805. }
  806. // Remove KRNL386 and its ilk to prune away non-TSR apps.
  807. DosMem_CleanArena(vo.dwHighLinear);
  808. }
  809. }
  810. exit:
  811. TraceFunctLeave();
  812. if (hVxD)
  813. {
  814. CloseHandle(hVxD);
  815. }
  816. return S_OK;
  817. }
  818. // get list of user mode drivers
  819. HRESULT
  820. CPCH_Driver::GetDriverUserMode()
  821. {
  822. BOOL fRc;
  823. WORD hDriver;
  824. DRIVERINFOSTRUCT16 dis;
  825. TraceFunctEnter("CPCH_Driver::GetDriverUserMode");
  826. dis.length = sizeof(dis);
  827. hDriver = 0;
  828. // walk through list of 16-bit drivers
  829. while ((hDriver = GetNextDriver16(hDriver,
  830. GND_FIRSTINSTANCEONLY)) != 0)
  831. {
  832. if (GetDriverInfo16(hDriver, &dis))
  833. {
  834. WORD wVer;
  835. DWORD dwMajor;
  836. DWORD dwMinor;
  837. TCHAR szTemp[MAX_PATH];
  838. DRIVER_USER_MODE* pDriver = new DRIVER_USER_MODE;
  839. if (!pDriver)
  840. {
  841. ErrorTrace(TRACE_ID,"Cannot allocate memory");
  842. goto exit;
  843. }
  844. if (GetModuleFileName16(dis.hModule,
  845. pDriver->strPath,
  846. cA(pDriver->strPath)))
  847. {
  848. lstrcpyn(pDriver->strDriver,
  849. dis.szAliasName,
  850. cA(pDriver->strDriver));
  851. wVer = GetExpWinVer16(dis.hModule);
  852. dwMajor = HIBYTE(wVer);
  853. dwMinor = LOBYTE(wVer);
  854. wsprintf(pDriver->strType,
  855. TEXT("%d.%d"),
  856. dwMajor,
  857. dwMinor % 10 ? dwMinor : dwMinor / 10);
  858. // append to driver list
  859. m_DriverUserModeList.push_back(pDriver);
  860. }
  861. else
  862. {
  863. delete pDriver;
  864. ErrorTrace(TRACE_ID, "GetModuleFileName16 failed");
  865. }
  866. }
  867. }
  868. exit:
  869. TraceFunctLeave();
  870. return S_OK;
  871. }
  872. // walk arena and create list of drivers
  873. void
  874. CPCH_Driver::DosMem_WalkArena(WORD segStart, DWORD dwHighLinear)
  875. {
  876. WORD segStop = 0;
  877. WORD seg = segStart;
  878. TCHAR szTemp[MAX_PATH]="";
  879. TraceFunctEnter("DosMem_WalkArena");
  880. do
  881. {
  882. PARENA par = (PARENA) (dwHighLinear + seg * 16);
  883. seg++;
  884. // Remember the stop point if we've found it.
  885. if (par->bType == 'Z')
  886. {
  887. segStop = (WORD)(seg + par->csegSize);
  888. }
  889. // If it's owned by itself, then it's a program or driver.
  890. // We know a bit more about the DOS memory subtypes.
  891. // This can change in principle (since most people don't
  892. // know about it, and we changed it in Win95, so obviously
  893. // it isn't compatibility-constrained).
  894. if (par->segOwner == seg)
  895. {
  896. DRIVER_MS_DOS* pDriver = NULL;
  897. if (par->bType == 'M' || par->bType == 'D' || par->bType == 'Z')
  898. {
  899. pDriver = new DRIVER_MS_DOS;
  900. if (!pDriver)
  901. {
  902. ErrorTrace(TRACE_ID, "Cannot allocate memory");
  903. goto exit;
  904. }
  905. lstrcpyn(pDriver->strName, par->rgchOwner, 9);
  906. pDriver->seg = seg;
  907. m_DriverMSDosList.push_back(pDriver);
  908. }
  909. }
  910. // If it's owned by 8 and rgchOwner is "SD", then it's
  911. // "system data" and contains subobjects. Else, it's a
  912. // normal arena that we step over.
  913. segStart = seg;
  914. if (par->segOwner == 8 && PUN(WORD, par->rgchOwner) == 0x4453)
  915. {
  916. }
  917. else
  918. {
  919. seg = (WORD)(seg + par->csegSize);
  920. }
  921. if (seg < segStart)
  922. {
  923. break;
  924. }
  925. } while (seg != segStop);
  926. exit:
  927. TraceFunctLeave();
  928. }
  929. // Remove the items that are apps and not TSRs.
  930. // Done by locating KRNL386, and then walking the parent chain until
  931. // we find an app that is its own parent.
  932. void
  933. CPCH_Driver::DosMem_CleanArena(DWORD dwHighLinear)
  934. {
  935. std::list<DRIVER_MS_DOS*>::iterator it = m_DriverMSDosList.begin();
  936. std::list<DRIVER_MS_DOS*>::iterator it2;
  937. WORD seg, segParent;
  938. PBYTE ppsp;
  939. TraceFunctEnter("CPCH_Driver::DosMem_CleanArena");
  940. while (it != m_DriverMSDosList.end())
  941. {
  942. if ((*it) && _tcsstr((*it)->strName,TEXT("KRNL386")))
  943. {
  944. break;
  945. }
  946. it++;
  947. }
  948. // cannot find KRNL386?
  949. if (it == m_DriverMSDosList.end() || !(*it))
  950. {
  951. goto exit;
  952. }
  953. // traverse list in reverse order
  954. do
  955. {
  956. seg = (*it)->seg;
  957. ppsp = (PBYTE) (dwHighLinear + seg * 16);
  958. m_DriverMSDosList.erase(it);
  959. it--;
  960. segParent = PUN(WORD, ppsp[0x16]);
  961. if (seg == segParent) // Found the top. Stop
  962. {
  963. break;
  964. }
  965. // find parent
  966. for (it2 = m_DriverMSDosList.begin(); it2 != m_DriverMSDosList.end(); it2++)
  967. {
  968. if ((*it2) && (*it2)->seg == segParent)
  969. {
  970. it = it2;
  971. break;
  972. }
  973. }
  974. if (it2 == m_DriverMSDosList.end()) // parent not found
  975. {
  976. break;
  977. }
  978. } while (it != m_DriverMSDosList.begin() && (*it));
  979. exit:
  980. TraceFunctLeave();
  981. }
  982. void CPCH_Driver::SetFileVersionInfo(CComBSTR filename, CInstance *pInstance)
  983. {
  984. CFileVersionInfo fvi;
  985. TraceFunctEnter("CPCH_Driver::SetFileVersionInfo");
  986. CComPtr<IWbemClassObject> pFileObj;
  987. if (SUCCEEDED(GetCIMDataFile(filename, &pFileObj)))
  988. {
  989. CopyProperty(pFileObj, L"Version", pInstance, pVersion);
  990. CopyProperty(pFileObj, L"FileSize", pInstance, pSize);
  991. CopyProperty(pFileObj, L"CreationDate", pInstance, pDate);
  992. CopyProperty(pFileObj, L"Manufacturer", pInstance, pManufacturer);
  993. }
  994. if (SUCCEEDED(fvi.QueryFile(filename)))
  995. {
  996. if (!pInstance->SetCHString(pDescription, fvi.GetDescription()))
  997. ErrorTrace(TRACE_ID, "SetCHString on description field failed.");
  998. if (!pInstance->SetCHString(pPartOf, fvi.GetProduct()))
  999. ErrorTrace(TRACE_ID, "SetCHString on partof field failed.");
  1000. }
  1001. TraceFunctLeave();
  1002. }
  1003. // step through user mode driver list and create instances
  1004. HRESULT
  1005. CPCH_Driver::ParseUserModeList(
  1006. MethodContext* pMethodContext
  1007. )
  1008. {
  1009. HRESULT hRes = WBEM_S_NO_ERROR;
  1010. std::list<DRIVER_USER_MODE* >::iterator it = m_DriverUserModeList.begin();
  1011. TraceFunctEnter("CPCH_Driver::ParseUserModeList");
  1012. while (it != m_DriverUserModeList.end() && (SUCCEEDED(hRes)))
  1013. {
  1014. DRIVER_USER_MODE* pUMDrv = *it;
  1015. if (!pUMDrv)
  1016. {
  1017. ErrorTrace(TRACE_ID, "Null driver node in list");
  1018. continue;
  1019. }
  1020. SYSTEMTIME stUTCTime;
  1021. GetSystemTime(&stUTCTime);
  1022. // Create a new instance based on the passed-in MethodContext
  1023. CInstancePtr pInstance(CreateNewInstance(pMethodContext), false);
  1024. if (!pInstance->SetDateTime(pTimeStamp, WBEMTime(stUTCTime)))
  1025. {
  1026. ErrorTrace(TRACE_ID, "SetDateTime on Timestamp Field failed.");
  1027. }
  1028. if (!pInstance->SetCHString(pChange, L"Snapshot"))
  1029. {
  1030. ErrorTrace(TRACE_ID, "SetCHString on Change Field failed.");
  1031. }
  1032. // set category
  1033. if (!pInstance->SetCHString(pCategory, L"UserMode"))
  1034. {
  1035. ErrorTrace(TRACE_ID, "SetCHString on Change Field failed.");
  1036. }
  1037. // set driver name
  1038. if (!pInstance->SetCHString(pName, pUMDrv->strDriver))
  1039. {
  1040. ErrorTrace(TRACE_ID, "SetCHString on Name Field failed.");
  1041. }
  1042. // set path
  1043. if (!pInstance->SetCHString(pPath, pUMDrv->strPath))
  1044. {
  1045. ErrorTrace(TRACE_ID, "SetCHString on Path Field failed.");
  1046. }
  1047. // set type
  1048. if (!pInstance->SetCHString(pType, pUMDrv->strType))
  1049. {
  1050. ErrorTrace(TRACE_ID, "SetCHString on Type Field failed.");
  1051. }
  1052. // get version info
  1053. CFileVersionInfo fvi;
  1054. CComBSTR filename = pUMDrv->strPath;
  1055. SetFileVersionInfo(filename,pInstance);
  1056. hRes = pInstance->Commit();
  1057. if (FAILED(hRes))
  1058. {
  1059. ErrorTrace(TRACE_ID, "Commit on Instance failed.");
  1060. }
  1061. // delete the node
  1062. delete pUMDrv;
  1063. pUMDrv = NULL;
  1064. it = m_DriverUserModeList.erase(it);
  1065. }
  1066. TraceFunctLeave();
  1067. return hRes;
  1068. }
  1069. // step through ms-dos driver list and create instances
  1070. HRESULT
  1071. CPCH_Driver::ParseMSDosList(
  1072. MethodContext* pMethodContext
  1073. )
  1074. {
  1075. HRESULT hRes = WBEM_S_NO_ERROR;
  1076. std::list<DRIVER_MS_DOS* >::iterator it = m_DriverMSDosList.begin();
  1077. TraceFunctEnter("CPCH_Driver::ParseMSDosList");
  1078. while (it != m_DriverMSDosList.end() && (SUCCEEDED(hRes)))
  1079. {
  1080. DRIVER_MS_DOS* pMSDrv = *it;
  1081. if (!pMSDrv)
  1082. {
  1083. ErrorTrace(TRACE_ID, "Null driver node in list");
  1084. continue;
  1085. }
  1086. SYSTEMTIME stUTCTime;
  1087. GetSystemTime(&stUTCTime);
  1088. // Create a new instance based on the passed-in MethodContext
  1089. CInstancePtr pInstance(CreateNewInstance(pMethodContext), false);
  1090. if (!pInstance->SetDateTime(pTimeStamp, WBEMTime(stUTCTime)))
  1091. {
  1092. ErrorTrace(TRACE_ID, "SetDateTime on Timestamp Field failed.");
  1093. }
  1094. if (!pInstance->SetCHString(pChange, L"Snapshot"))
  1095. {
  1096. ErrorTrace(TRACE_ID, "SetCHString on Change Field failed.");
  1097. }
  1098. // set category
  1099. if (!pInstance->SetCHString(pCategory, L"MSDOS"))
  1100. {
  1101. ErrorTrace(TRACE_ID, "SetCHString on Change Field failed.");
  1102. }
  1103. // set driver name
  1104. if (!pInstance->SetCHString(pName, pMSDrv->strName))
  1105. {
  1106. ErrorTrace(TRACE_ID, "SetCHString on Name Field failed.");
  1107. }
  1108. // set type to "Device Driver"
  1109. if (!pInstance->SetCHString(pType, L"Device Driver"))
  1110. {
  1111. ErrorTrace(TRACE_ID, "SetCHString on Type Field failed.");
  1112. }
  1113. hRes = pInstance->Commit();
  1114. if (FAILED(hRes))
  1115. {
  1116. ErrorTrace(TRACE_ID, "Commit on Instance failed.");
  1117. }
  1118. // delete the node
  1119. delete pMSDrv;
  1120. pMSDrv = NULL;
  1121. it = m_DriverMSDosList.erase(it);
  1122. }
  1123. TraceFunctLeave();
  1124. return hRes;
  1125. }