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.

1051 lines
36 KiB

  1. // vchk.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #pragma hdrstop
  5. #include "vchk.h"
  6. #include "allowed.h"
  7. #include "ilimpchk.h"
  8. //#include <devguid.h>
  9. #include <setupapi.h>
  10. //#include <regstr.h>
  11. #include <cfgmgr32.h>
  12. #ifdef _DEBUG
  13. #define new DEBUG_NEW
  14. #undef THIS_FILE
  15. static char THIS_FILE[] = __FILE__;
  16. #endif
  17. using namespace std;
  18. //////////////////////////////////////////////////////////////////////////////
  19. //#define VCHK_TRACE_ON 1
  20. #ifdef VCHK_TRACE_ON
  21. const char* VchkTraceGetName(const char* szName)
  22. {
  23. const char* szLastSeg = szName;
  24. const char* szSlash = strchr(szName, '\\');
  25. while (szSlash) {
  26. ++szSlash;
  27. szLastSeg = szSlash;
  28. szSlash = strchr(szSlash, '\\');
  29. }
  30. return szLastSeg;
  31. }
  32. #define VCHK_TRACE(x) {cerr << " [" << VchkTraceGetName(__FILE__) << ":" << __LINE__ << "] " << x;}
  33. #else
  34. #define VCHK_TRACE(x)
  35. #endif
  36. /////////////////////////////////////////////////////////////////////////////
  37. // Enumerates display devices
  38. typedef class CDisplayDeviceEnum {
  39. public:
  40. static bool IsDigitsOnly(const char* sz);
  41. CDisplayDeviceEnum();
  42. ~CDisplayDeviceEnum() {free(Buffer);}
  43. bool IsValid() const {return bValid;}
  44. bool Next();
  45. CString GetMiniportPath();
  46. DWORD GetDeviceId() {return iEnum;}
  47. DWORD GetLastError() {return dwLastError;}
  48. const char* GetLastErrorStr() {return szLastError;}
  49. void MarkDevice(DISPLAY_DEVICE& r_DisplayDevice);
  50. void UnmarkDevice();
  51. bool IsMarkedDevice();
  52. private:
  53. static const GUID const displayClassGUID;
  54. BYTE* Buffer;
  55. size_t BufferSize;
  56. bool bValid;
  57. DWORD iEnum;
  58. HDEVINFO hDevInfo;
  59. SP_DEVINFO_DATA DeviceInfoData;
  60. HKEY hMarkedKey;
  61. DWORD dwLastError;
  62. const char* szLastError;
  63. bool ReallocBuffer(size_t NewSize)
  64. {
  65. if (NewSize > BufferSize) {
  66. void* p = realloc(Buffer, NewSize);
  67. if (!p) return false;
  68. Buffer = (PBYTE)p;
  69. BufferSize = NewSize;
  70. }
  71. return true;
  72. }
  73. void MarkKey(HKEY hKey);
  74. void UnmarkKey();
  75. bool IsMarkedDEVINST(DEVINST DevInst);
  76. } typedef_CDisplayDeviceEnum;
  77. /////////////////////////////////////////////////////////////////////////////
  78. // CDisplayDeviceEnum implementation
  79. /////////////////////////////////////////////////////////////////////////////
  80. // CDisplayDeviceEnum::IsDigitsOnly
  81. bool CDisplayDeviceEnum::IsDigitsOnly(const char* sz)
  82. {
  83. if (!sz || !*sz) return false;
  84. while (('0' <= *sz) && (*sz <= '9')) ++sz;
  85. return !*sz;
  86. }
  87. /////////////////////////////////////////////////////////////////////////////
  88. // CDisplayDeviceEnum constants
  89. const GUID const CDisplayDeviceEnum::displayClassGUID =
  90. {0x4d36e968L, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
  91. /////////////////////////////////////////////////////////////////////////////
  92. // CDisplayDeviceEnum constructor
  93. CDisplayDeviceEnum::CDisplayDeviceEnum() :
  94. bValid(true),
  95. Buffer(NULL),
  96. BufferSize(0),
  97. iEnum(0),
  98. hDevInfo(INVALID_HANDLE_VALUE),
  99. hMarkedKey(NULL),
  100. dwLastError(0),
  101. szLastError(NULL)
  102. {
  103. ZeroMemory(&DeviceInfoData, sizeof(DeviceInfoData));
  104. DeviceInfoData.cbSize = sizeof(DeviceInfoData);
  105. ReallocBuffer(MAX_PATH + 1);
  106. // Get Device Info Set for display class GUID
  107. hDevInfo = SetupDiGetClassDevs(&displayClassGUID, // class guid
  108. NULL, // Enumerator
  109. NULL, // top level window
  110. DIGCF_PRESENT);
  111. if (hDevInfo != INVALID_HANDLE_VALUE) {
  112. Next();
  113. } else {
  114. dwLastError = GetLastError();
  115. szLastError = "SetupDiGetClassDevs failure";
  116. bValid = false;
  117. }
  118. }
  119. /////////////////////////////////////////////////////////////////////////////
  120. // CDisplayDeviceEnum::Next() - gets next device into scope
  121. bool CDisplayDeviceEnum::Next()
  122. {
  123. if (!bValid) return false;
  124. // get device info for the device in the Device Info Set at index iEnum
  125. if (SetupDiEnumDeviceInfo(hDevInfo, // device info set
  126. iEnum, // member index
  127. &DeviceInfoData)) // Device Info data
  128. {
  129. ++iEnum;
  130. } else {
  131. dwLastError = GetLastError();
  132. szLastError = "SetupDiEnumDeviceInfo failure";
  133. bValid = false;
  134. }
  135. return bValid;
  136. }
  137. /////////////////////////////////////////////////////////////////////////////
  138. // CDisplayDeviceEnum::GetMiniportPath() - gets miniport of current device
  139. CString CDisplayDeviceEnum::GetMiniportPath()
  140. {
  141. DWORD BufferSizeNeeded = BufferSize;
  142. DWORD DataT;
  143. // Get Registry Information for the Device
  144. // First time through is to find out how much memory we need to allocate.
  145. // Second time actually gives us the information we want.
  146. while (!SetupDiGetDeviceRegistryProperty(hDevInfo, // device info set
  147. &DeviceInfoData, // info for the device we want to retrieve
  148. SPDRP_SERVICE, // Specify that we want the service name
  149. &DataT,
  150. Buffer, // this should return the service name
  151. BufferSizeNeeded,
  152. &BufferSizeNeeded))
  153. {
  154. DWORD dwError = GetLastError();
  155. if (dwError == ERROR_INSUFFICIENT_BUFFER) {
  156. if (ReallocBuffer(BufferSizeNeeded)) continue;
  157. szLastError = "Not enough memory";
  158. } else {
  159. szLastError = "SetupDiGetDeviceRegistryProperty failure";
  160. }
  161. dwLastError = dwError;
  162. bValid = false;
  163. return CString();
  164. }
  165. // get miniport path
  166. CString sRegPath("System\\CurrentControlSet\\Services\\");
  167. sRegPath += (LPCSTR)Buffer;
  168. // open the services key, find the service, and get the image path
  169. HKEY hkService;
  170. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  171. (LPCSTR)sRegPath,
  172. 0,
  173. KEY_READ,
  174. &hkService) != ERROR_SUCCESS)
  175. {
  176. dwLastError = GetLastError();
  177. szLastError = "RegOpenKeyEx failure";
  178. bValid = false;
  179. return CString();
  180. }
  181. if (!ReallocBuffer(MAX_PATH)) {
  182. dwLastError = -1;
  183. szLastError = "Not enough memory";
  184. bValid = false;
  185. return CString();
  186. }
  187. DWORD cb = BufferSize;
  188. ZeroMemory(Buffer, cb);
  189. if (RegQueryValueEx(hkService,
  190. "ImagePath",
  191. NULL,
  192. NULL,
  193. (LPBYTE)Buffer,
  194. &cb) != ERROR_SUCCESS)
  195. {
  196. dwLastError = GetLastError();
  197. szLastError = "RegQueryValueEx failure";
  198. bValid = false;
  199. return CString();
  200. }
  201. return CString((const char*)Buffer);
  202. }
  203. /////////////////////////////////////////////////////////////////////////////
  204. // CDisplayDeviceEnum::MarkDevice(DISPLAY_DEVICE&)
  205. //
  206. // XXX olegk (it is really XXX level of hack)
  207. // we will mark the child monitor subkey and than will be searching for
  208. // children with marked keys later in IsMarkedDevice()
  209. //
  210. void CDisplayDeviceEnum::MarkDevice(DISPLAY_DEVICE& r_DisplayDevice)
  211. {
  212. if (hMarkedKey) UnmarkDevice();
  213. VCHK_TRACE("-------- Marking Device ----------\n");
  214. VCHK_TRACE("ID : " << r_DisplayDevice.DeviceID << endl);
  215. VCHK_TRACE("Key : " << r_DisplayDevice.DeviceKey << endl);
  216. VCHK_TRACE("Name : " << r_DisplayDevice.DeviceName << endl);
  217. VCHK_TRACE("String : " << r_DisplayDevice.DeviceString << endl);
  218. DISPLAY_DEVICE MonitorInfo;
  219. MonitorInfo.cb = sizeof(MonitorInfo);
  220. if (!EnumDisplayDevices(r_DisplayDevice.DeviceName, 0, &MonitorInfo, 0)) {
  221. VCHK_TRACE("Can't get monitor info for " <<
  222. r_DisplayDevice.DeviceString << ' ' <<
  223. r_DisplayDevice.DeviceName << endl);
  224. return;
  225. }
  226. CString sKey;
  227. // XXX olegk - Assume that all device keys are under HKEY_LOCAL_MACHINE
  228. {
  229. const CHAR szMachineRegPath[] = "\\REGISTRY\\Machine\\";
  230. if (_strnicmp(szMachineRegPath,
  231. MonitorInfo.DeviceKey,
  232. sizeof(szMachineRegPath) - 1))
  233. {
  234. dwLastError = DWORD(-1);
  235. szLastError = "Invalid registry path (must be under HKEY_LOCAL_MACHINE)";
  236. VCHK_TRACE("Invalid registry path " << MonitorInfo.DeviceKey << endl);
  237. return;
  238. }
  239. sKey = (LPCSTR)(MonitorInfo.DeviceKey) + sizeof(szMachineRegPath) - 1;
  240. }
  241. HKEY hKey;
  242. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  243. (LPCSTR)sKey,
  244. 0,
  245. KEY_READ,
  246. &hKey) != ERROR_SUCCESS)
  247. {
  248. // Do nothing - no service will be found
  249. DWORD dwError = GetLastError();
  250. VCHK_TRACE("RegOpenKeyEx failure " << dwError << " : " << r_DisplayDevice.DeviceKey << endl);
  251. return;
  252. }
  253. VCHK_TRACE("Marked Key: " << (LPCSTR)sKey << endl);
  254. MarkKey(hKey);
  255. }
  256. /////////////////////////////////////////////////////////////////////////////
  257. // CDisplayDeviceEnum::UnmarkDevice(DISPLAY_DEVICE&)
  258. void CDisplayDeviceEnum::UnmarkDevice()
  259. {
  260. UnmarkKey();
  261. }
  262. /////////////////////////////////////////////////////////////////////////////
  263. // CDisplayDeviceEnum::IsMarkedDevice()
  264. bool CDisplayDeviceEnum::IsMarkedDevice()
  265. {
  266. const size_t nMaxLevel = 10; // XXX olegk - I can't imagine more than 3 but...
  267. DEVINST DevInstStack[nMaxLevel];
  268. size_t nLevel = 0;
  269. if (CM_Get_Child(&DevInstStack[nLevel], DeviceInfoData.DevInst, 0) != CR_SUCCESS) return false;
  270. while (!IsMarkedDEVINST(DevInstStack[nLevel])) {
  271. if ((nLevel < nMaxLevel) &&
  272. (CM_Get_Child(&DevInstStack[nLevel + 1],
  273. DevInstStack[nLevel],
  274. 0) == CR_SUCCESS))
  275. {
  276. ++nLevel;
  277. continue;
  278. }
  279. while (CM_Get_Sibling(&DevInstStack[nLevel], DevInstStack[nLevel], 0) != CR_SUCCESS) {
  280. if (!nLevel) return false; // End of search (no marker have been found)
  281. --nLevel;
  282. }
  283. }
  284. return true;
  285. }
  286. /////////////////////////////////////////////////////////////////////////////
  287. // CDisplayDeviceEnum::MarkKey(...)
  288. void CDisplayDeviceEnum::MarkKey(HKEY hKey)
  289. {
  290. UnmarkKey();
  291. hMarkedKey = hKey;
  292. }
  293. /////////////////////////////////////////////////////////////////////////////
  294. // CDisplayDeviceEnum::UnmarkKey(...)
  295. void CDisplayDeviceEnum::UnmarkKey()
  296. {
  297. if (!hMarkedKey) return;
  298. RegCloseKey(hMarkedKey);
  299. hMarkedKey = NULL;
  300. }
  301. /////////////////////////////////////////////////////////////////////////////
  302. // CDisplayDeviceEnum::IsMarkedDEVINST(...)
  303. bool CDisplayDeviceEnum::IsMarkedDEVINST(DEVINST DevInst)
  304. {
  305. bool bIsMarked = false;
  306. HKEY hKey;
  307. if (CM_Open_DevNode_Key(DevInst,
  308. KEY_READ, // IN REGSAM samDesired,
  309. 0, // IN ULONG ulHardwareProfile,
  310. RegDisposition_OpenExisting,
  311. &hKey, //OUT PHKEY phkDevice,
  312. CM_REGISTRY_SOFTWARE) == CR_SUCCESS)
  313. {
  314. extern bool IsTheSameRegKey(HKEY, HKEY);
  315. bIsMarked = IsTheSameRegKey(hMarkedKey, hKey);
  316. RegCloseKey(hKey);
  317. }
  318. return bIsMarked;
  319. }
  320. /////////////////////////////////////////////////////////////////////////////
  321. // The one and only application object
  322. void
  323. CDrvchkApp::PrintOut (LPCSTR str)
  324. {
  325. if (m_logf)
  326. fprintf (m_logf, "%s", str);
  327. else
  328. cerr << str;
  329. }
  330. void
  331. CDrvchkApp::PrintOut (unsigned num)
  332. {
  333. if (m_logf)
  334. fprintf (m_logf, "%u", num);
  335. else
  336. cerr << num;
  337. }
  338. inline
  339. void
  340. CDrvchkApp::ListOut (LPCSTR str)
  341. {
  342. if (m_listf)
  343. fprintf (m_listf, "%s", str);
  344. }
  345. void
  346. CDrvchkApp::ListOut (unsigned num)
  347. {
  348. if (m_listf)
  349. fprintf (m_listf, "%u", num);
  350. }
  351. ModulesAndImports allowed_modules;
  352. ModulesAndImports allowed_imports;
  353. ModulesAndImports known_illegal;
  354. ModulesAndImports illegal_msgs;
  355. void SetCurrentModule(const char* szModule)
  356. {
  357. allowed_imports.SetModule(szModule);
  358. illegal_msgs.SetModule(szModule);
  359. known_illegal.SetModule(szModule);
  360. }
  361. #define VCHK_WARN known_illegal.AddImport
  362. #define VCHK_FAIL illegal_msgs.AddImport
  363. #define VCHK_ALLOW allowed_imports.AddImport
  364. void BuildInAllowedAndIllegal (void)
  365. {
  366. SetCurrentModule("HAL.DLL");
  367. VCHK_FAIL ("HalAllocateCommonBuffer", "use VideoPortAllocateCommonBuffer");
  368. VCHK_FAIL ("HalFreeCommonBuffer", "use VideoPortFreeCommonBuffer");
  369. VCHK_WARN ("HalGetAdapter", "obsolete; see DDK manual");
  370. VCHK_WARN ("HalGetBusData", "obsolete; see DDK manual");
  371. VCHK_WARN ("HalGetBusDataByOffset");
  372. VCHK_WARN ("HalSetBusData", "obsolete; see DDK manual");
  373. VCHK_WARN ("HalSetBusDataByOffset");
  374. VCHK_WARN ("HalTranslateBusAddress");
  375. VCHK_FAIL ("KeGetCurrentIrql", "use VideoPortGetCurrentIrql");
  376. VCHK_FAIL ("KeQueryPerformanceCounter", "use VideoPortQueryPerformanceCounter");
  377. VCHK_FAIL ("KfAcquireSpinLock", "use VideoPortAcquireSpinLock");
  378. VCHK_FAIL ("KfReleaseSpinLock", "use VideoPortReleaseSpinLock");
  379. VCHK_FAIL ("READ_PORT_ULONG", "use VideoPortReadPortUlong");
  380. VCHK_FAIL ("WRITE_PORT_ULONG", "use VideoPortWritePortUlong");
  381. SetCurrentModule ("NTOSKRNL.EXE");
  382. VCHK_ALLOW ("_except_handler3");
  383. VCHK_FAIL ("ExAllocatePool", "use VideoPortAllocatePool");
  384. VCHK_FAIL ("ExAllocatePoolWithTag", "use VideoPortAllocatePool");
  385. VCHK_FAIL ("ExFreePool", "use VideoPortFreePool");
  386. VCHK_FAIL ("ExFreePoolWithTag", "use VideoPortFreePool");
  387. VCHK_WARN ("ExIsProcessorFeaturePresent");
  388. VCHK_WARN ("ExQueueWorkItem");
  389. VCHK_WARN ("IoAllocateMdl");
  390. VCHK_WARN ("IoCreateNotificationEvent");
  391. VCHK_WARN ("IoCreateSynchronizationEvent");
  392. VCHK_WARN ("IoFreeMdl");
  393. VCHK_WARN ("IoGetCurrentProcess");
  394. VCHK_FAIL ("IoReportDetectedDevice");
  395. VCHK_FAIL ("IoReportResourceForDetection");
  396. VCHK_WARN ("KeCancelTimer");
  397. VCHK_FAIL ("KeClearEvent", "use VideoPortClearEvent");
  398. VCHK_FAIL ("KeDelayExecutionThread", "use VideoPortStallExecution");
  399. VCHK_FAIL ("KeInitializeDpc", "use VideoPortQueueDpc");
  400. VCHK_FAIL ("KeInitializeSpinLock", "use VideoPortXxxSpinLockXxx");
  401. VCHK_WARN ("KeInitializeTimer");
  402. VCHK_WARN ("KeInitializeTimerEx");
  403. VCHK_FAIL ("KeInsertQueueDpc", "use VideoPortQueueDpc");
  404. VCHK_WARN ("KeQuerySystemTime");
  405. VCHK_WARN ("KeRestoreFloatingPointState");
  406. VCHK_WARN ("KeSaveFloatingPointState");
  407. VCHK_FAIL ("KeSetEvent", "use VideoPortSetEvent");
  408. VCHK_WARN ("KeSetTimer");
  409. VCHK_WARN ("KeSetTimerEx");
  410. VCHK_FAIL ("MmAllocateContiguousMemory", "use VideoPortAllocateContiguousMemory");
  411. VCHK_WARN ("MmAllocateNonCachedMemory");
  412. VCHK_WARN ("MmBuildMdlForNonPagedPool");
  413. VCHK_WARN ("MmFreeContiguousMemory");
  414. VCHK_WARN ("MmFreeNonCachedMemory");
  415. VCHK_WARN ("MmGetPhysicalAddress");
  416. VCHK_WARN ("MmIsAddressValid");
  417. VCHK_WARN ("MmMapIoSpace");
  418. VCHK_WARN ("MmMapLockedPages");
  419. VCHK_WARN ("MmMapLockedPagesSpecifyCache");
  420. VCHK_WARN ("MmProbeAndLockPages");
  421. VCHK_WARN ("MmQuerySystemSize");
  422. VCHK_WARN ("MmUnlockPages");
  423. VCHK_WARN ("MmUnmapIoSpace");
  424. VCHK_WARN ("MmUnmapLockedPages");
  425. VCHK_WARN ("ObReferenceObjectByHandle");
  426. VCHK_WARN ("PsGetCurrentProcessId");
  427. VCHK_WARN ("PsGetVersion");
  428. VCHK_FAIL ("READ_REGISTER_UCHAR", "use VideoPortReadRegisterUchar");
  429. VCHK_WARN ("RtlAnsiStringToUnicodeString");
  430. VCHK_WARN ("RtlAppendUnicodeStringToString");
  431. VCHK_WARN ("RtlCheckRegistryKey");
  432. VCHK_WARN ("RtlCompareMemory");
  433. VCHK_WARN ("RtlCopyUnicodeString");
  434. VCHK_WARN ("RtlCreateRegistryKey");
  435. VCHK_WARN ("RtlFreeAnsiString");
  436. VCHK_WARN ("RtlFreeUnicodeString");
  437. VCHK_WARN ("RtlInitAnsiString");
  438. VCHK_WARN ("RtlInitUnicodeString");
  439. VCHK_WARN ("RtlIntegerToUnicodeString");
  440. VCHK_WARN ("RtlQueryRegistryValues");
  441. VCHK_WARN ("RtlTimeToTimeFields");
  442. VCHK_WARN ("RtlUnicodeStringToAnsiString");
  443. VCHK_WARN ("RtlUnicodeToMultiByteN");
  444. VCHK_WARN ("RtlUnwind");
  445. VCHK_WARN ("RtlWriteRegistryValue");
  446. VCHK_FAIL ("wcslen", "link to libcntpr.lib instead");
  447. VCHK_FAIL ("WRITE_REGISTER_UCHAR", "use VideoPortWriteRegisterUchar");
  448. VCHK_FAIL ("WRITE_REGISTER_USHORT", "use VideoPortWriteRegisterUshort");
  449. VCHK_WARN ("ZwClose");
  450. VCHK_WARN ("ZwCreateFile");
  451. VCHK_WARN ("ZwEnumerateValueKey");
  452. VCHK_WARN ("ZwMapViewOfSection");
  453. VCHK_WARN ("ZwOpenKey");
  454. VCHK_WARN ("ZwOpenSection");
  455. VCHK_WARN ("ZwQueryValueKey");
  456. VCHK_WARN ("ZwSetSystemInformation");
  457. VCHK_WARN ("ZwUnmapViewOfSection");
  458. VCHK_WARN ("ZwWriteFile");
  459. }
  460. /////////////////////////////////////////////////////////////////////////////
  461. // main
  462. int __cdecl _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  463. {
  464. int nRetCode = 0;
  465. // initialize MFC and print and error on failure
  466. if (AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
  467. {
  468. CDrvchkApp theApp;
  469. theApp.InitInstance ();
  470. }
  471. return nRetCode;
  472. }
  473. /////////////////////////////////////////////////////////////////////////////
  474. // CDrvchkApp construction
  475. CDrvchkApp::CDrvchkApp() :
  476. m_logf(NULL),
  477. m_listf(NULL),
  478. m_drv_name ("")
  479. {
  480. // TODO: add construction code here,
  481. // Place all significant initialization in InitInstance
  482. }
  483. /////////////////////////////////////////////////////////////////////////////
  484. // The one and only CDrvchkApp object
  485. void
  486. CommandLine::ParseParam( LPCTSTR lpszParam, BOOL bFlag, BOOL bLast )
  487. {
  488. if (m_parse_error != parseOK)
  489. return;
  490. CString param (lpszParam);
  491. if (bFlag) {
  492. param.MakeUpper();
  493. if ((param==CString("?")) || (param == CString("HELP")) || (param == CString("H"))) {
  494. m_parse_error = parseHelp;
  495. } else if ((param==CString("?IMP")) || (param==CString("IMP?"))) {
  496. m_parse_error = parseHelpImports;
  497. } else if (m_last_flag.GetLength() && m_first_param) {
  498. m_parse_error = parseError;
  499. m_error_msg = CString("Flag ") + m_last_flag + CString(" requires a parameter.");
  500. } else if ((param==CString("LOG")) || (param==CString("DRV")) || (param==CString("MON")) ||
  501. (param==CString("LIST")) || (param==CString("LST")) || (param==CString("LS")) ||
  502. (param==CString("LIS")) || (param==CString("ALLOW"))) {
  503. if (bLast) {
  504. m_parse_error = parseError;
  505. m_error_msg = CString("Flag ") + param + CString(" requires a parameter.");
  506. } else {
  507. m_last_flag = param;
  508. m_first_param = TRUE;
  509. }
  510. } else {
  511. m_last_flag = CString();
  512. m_parse_error = parseError;
  513. m_error_msg = CString("Invalid flag: ") + param;
  514. }
  515. } else {
  516. if (m_last_flag==CString("ALLOW")) {
  517. m_first_param = FALSE;
  518. int nSplit = param.Find('!');
  519. if (nSplit != -1) {
  520. CString module = param.Left(nSplit);
  521. CString import = param.Mid(nSplit + 1);
  522. if (module.GetLength() && import.GetLength()) {
  523. allowed_imports.SetModule(module);
  524. allowed_imports.AddImport(import, "allowed by command line");
  525. } else {
  526. m_parse_error = parseError;
  527. m_error_msg = CString("Bad parameter format for flag: ") + m_last_flag;
  528. }
  529. } else {
  530. allowed_modules.SetModule(param);
  531. }
  532. } else if (m_last_flag==CString("DRV")) {
  533. if (m_monitor >= 1) {
  534. m_error_msg = "bad command line: Conflicting flags MON and DRV";
  535. m_parse_error = parseError;
  536. }
  537. m_drv_fname = param;
  538. m_last_flag="";
  539. } else if (m_last_flag==CString("LOG")) {
  540. m_log_fname = param;
  541. m_last_flag="";
  542. } else if (m_last_flag==CString("LIST") ||
  543. m_last_flag==CString("LST") ||
  544. m_last_flag==CString("LIS") ||
  545. m_last_flag==CString("LS")) {
  546. m_list_fname = param;
  547. m_last_flag="";
  548. } else if (m_last_flag==CString("MON")) {
  549. if ((param.GetLength()==1) &&
  550. (((LPCSTR)param)[0] >= '1') &&
  551. (((LPCSTR)param)[0] <= '9'))
  552. {
  553. if (m_drv_fname.GetLength()) {
  554. m_error_msg = "bad command line: Conflicting flags MON and DRV";
  555. m_parse_error = parseError;
  556. }
  557. char c = ((LPCSTR)param)[0];
  558. m_monitor = c - '0';
  559. } else {
  560. m_error_msg = "bad command line: MON flag has invalid parameter";
  561. m_parse_error = parseError;
  562. }
  563. m_last_flag="";
  564. } else {
  565. m_parse_error = parseError;
  566. m_error_msg = CString("Wrong parameter: ") + param;
  567. m_last_flag="";
  568. }
  569. }
  570. if (bLast) {
  571. if (m_last_flag==CString("LOG") || m_last_flag==CString("DRV")) {
  572. m_parse_error = parseError;
  573. m_error_msg = CString("Flag ") + m_last_flag + CString(" requires a parameter.");
  574. }
  575. }
  576. }
  577. /////////////////////////////////////////////////////////////////////////////
  578. // CDrvchkApp initialization
  579. const char* szHelp =
  580. "Copyright (C) Microsoft Corporation. All rights reserved.\n"
  581. "\n"
  582. "usage: vchk [-?] [-LOG logfile] [-DRV drvname | -MON id] [-LIST listname]\n"
  583. " [-ALLOW module[!import] [module[!import]] ...]\n"
  584. "\n"
  585. "where: -? displays this help\n"
  586. " -IMP? dumps imports tables that check performed against\n"
  587. " -LOG specifies output file name (if file already exists then new data\n"
  588. " will be appended to it)\n"
  589. " -DRV specifies the full name of the driver's binary to check\n"
  590. " -MON specifies 1-based numeric id of the display adapter to check\n"
  591. " -LIST specifies the file for summary (if file already exists then new\n"
  592. " data will be appended to it)\n"
  593. " -ALLOW specifies allowed imports\n"
  594. " module: name of allowed module (if no import specified then all\n"
  595. " imports from the module will be allowed)\n"
  596. " import: specific import name\n"
  597. "\n"
  598. " if neither -MON nor -DRV switches used then all currently active video\n"
  599. " drivers will be checked\n"
  600. "\n"
  601. "Example:\n"
  602. " vchk -log c:\\log.out -list con -allow HAL.DLL!HalGetBusData VIDEOPORT.SYS\n";
  603. BOOL CDrvchkApp::InitInstance()
  604. {
  605. // Standard initialization
  606. // If you are not using these features and wish to reduce the size
  607. m_os_ver_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  608. GetVersionEx (&m_os_ver_info);
  609. if (m_os_ver_info.dwPlatformId != VER_PLATFORM_WIN32_NT) { // doesn't work on Win9x
  610. PrintOut ("warning: unsupported OS (Win9x), nothing done.\n");
  611. return FALSE;
  612. }
  613. //if (m_os_ver_info.dwMajorVersion != 5) { // doesn't work on NT version prior to Win2K
  614. if (m_os_ver_info.dwMajorVersion < 5) { // XXX olegk - will it work in the future????
  615. PrintOut ("warning: unsupported OS (");
  616. PrintOut (m_os_ver_info.dwMajorVersion);
  617. PrintOut (".");
  618. PrintOut (m_os_ver_info.dwMinorVersion);
  619. PrintOut ("): nothing done.\n");
  620. return FALSE;
  621. }
  622. ParseCommandLine (m_cmd_line);
  623. BuildInAllowedAndIllegal();
  624. if (m_cmd_line.m_log_fname.GetLength()) {
  625. m_logf = fopen (m_cmd_line.m_log_fname, "a+");
  626. if (!m_logf) m_logf = fopen (m_cmd_line.m_log_fname, "a");
  627. }
  628. if (m_cmd_line.m_list_fname.GetLength()) {
  629. m_listf = fopen (m_cmd_line.m_list_fname, "a+");
  630. if (!m_listf) m_listf = fopen (m_cmd_line.m_list_fname, "a");
  631. }
  632. switch (m_cmd_line.m_parse_error) {
  633. case CommandLine::parseOK: {
  634. int device_num = m_cmd_line.m_monitor;
  635. if (m_cmd_line.m_drv_fname.GetLength()) {
  636. ChkDriver (m_cmd_line.m_drv_fname);
  637. } else {
  638. DWORD cbData = 0;
  639. DEVMODE dmCurrent;
  640. TCHAR szDeviceDescription[10000];
  641. TCHAR szImagePath[MAX_PATH + 1];
  642. TCHAR szVarImagePath[MAX_PATH + 1];
  643. TCHAR szExpImagePath[MAX_PATH + 1];
  644. DISPLAY_DEVICE DisplayDevice, *pDisplayDevice = NULL;
  645. CString dev_desc_CtrlSet;
  646. int nNonMirroringDevice = 0;
  647. //
  648. // Find non mirroring display device #device_num if needed
  649. //
  650. if (device_num >= 1) {
  651. ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
  652. DisplayDevice.cb = sizeof(DisplayDevice);
  653. DWORD i, nNonMirrorDev;
  654. for (i = 0, nNonMirrorDev = 0; EnumDisplayDevices(NULL, i, &DisplayDevice, 0); ++i) {
  655. if (DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) continue; // skip mirroring drivers
  656. if (device_num == ++nNonMirroringDevice) {
  657. pDisplayDevice = &DisplayDevice;
  658. break;
  659. }
  660. }
  661. if (!pDisplayDevice) {
  662. PrintOut ("error: cannot find video service\n");
  663. break;
  664. }
  665. }
  666. //
  667. // Let's find all the video drivers that are installed in the system
  668. //
  669. CDisplayDeviceEnum DevEnum;
  670. bool bDevFound = false;
  671. if (pDisplayDevice) DevEnum.MarkDevice(*pDisplayDevice);
  672. while (DevEnum.IsValid()) {
  673. if (!pDisplayDevice || DevEnum.IsMarkedDevice()) {
  674. bDevFound = true;
  675. CString sMiniportPath = DevEnum.GetMiniportPath();
  676. if (!sMiniportPath.GetLength()) {
  677. sprintf (szDeviceDescription, "error: cannot find video service #%d\n", DevEnum.GetDeviceId());
  678. PrintOut (szDeviceDescription);
  679. VCHK_TRACE("error: " << szDeviceDescription <<
  680. "\n " << DevEnum.GetLastError() << " " << DevEnum.GetLastErrorStr() << endl)
  681. break;
  682. }
  683. sprintf (szVarImagePath, "%%WINDIR%%\\%s", (LPCSTR)sMiniportPath);
  684. ExpandEnvironmentStrings (szVarImagePath, szExpImagePath, MAX_PATH);
  685. VCHK_TRACE("Checking miniport " << szExpImagePath << endl)
  686. ChkDriver (szExpImagePath);
  687. }
  688. DevEnum.Next();
  689. }
  690. if (!bDevFound) PrintOut ("error: cannot find video service\n");
  691. } // look for system drivers
  692. } // parseOK
  693. break;
  694. case CommandLine::parseHelp: {
  695. CString Filename, Version, Description, Copyright;
  696. {
  697. CHAR szModuleName[MAX_PATH + 1];
  698. ZeroMemory(szModuleName, sizeof(szModuleName));
  699. if (GetModuleFileName(m_hInstance, szModuleName, MAX_PATH)) {
  700. DWORD dw = 0;
  701. DWORD dwVerLen = GetFileVersionInfoSize(szModuleName, &dw);
  702. if (dwVerLen) {
  703. PBYTE Buffer = (PBYTE)malloc(dwVerLen + 1);
  704. PVOID pValue;
  705. if (Buffer &&
  706. GetFileVersionInfo(szModuleName, dw, dwVerLen, Buffer))
  707. {
  708. UINT ValLen;
  709. if (VerQueryValue(Buffer, "\\StringFileInfo\\000004B0\\OriginalFilename", &pValue, &ValLen)); {
  710. Filename = CString((LPCSTR)pValue, ValLen);
  711. }
  712. if (VerQueryValue(Buffer, "\\StringFileInfo\\000004b0\\ProductVersion", &pValue, &ValLen));
  713. Version = CString((LPCSTR)pValue, ValLen);
  714. if (VerQueryValue(Buffer, "\\StringFileInfo\\000004b0\\FileDescription", &pValue, &ValLen));
  715. Description = CString((LPCSTR)pValue, ValLen);
  716. }
  717. free(Buffer);
  718. }
  719. }
  720. }
  721. cout << endl << (Filename.GetLength() ? (LPCSTR)Filename : "VCHK.EXE!");
  722. if (Version.GetLength()) cout << " " << (LPCSTR)Version;
  723. if (Description.GetLength()) cout << ": " << (LPCSTR)Description;
  724. cout << endl;
  725. cout << szHelp;
  726. } // parseHelp
  727. break;
  728. case CommandLine::parseHelpImports: {
  729. BuildInAllowedAndIllegal();
  730. cout << "\n--- Illegal imports (errors) --------------\n\n";
  731. illegal_msgs.Dump(cout);
  732. cout << "\n--- Known illegal imports (warnings) ------\n\n";
  733. known_illegal.Dump(cout);
  734. cout << "\n--- Allowed imports -----------------------\n\n";
  735. allowed_imports.Dump(cout);
  736. cout << "\n--- Allowed modules -----------------------\n\n";
  737. allowed_modules.Dump(cout);
  738. } // parseHelpImports
  739. break;
  740. default:
  741. PrintOut ("error: ");
  742. PrintOut (m_cmd_line.m_error_msg.GetLength() ? (LPCSTR)m_cmd_line.m_error_msg : "unknown failure");
  743. PrintOut ("\nUse vchk -? for help.\n");
  744. } // switch
  745. if (m_logf)
  746. fclose (m_logf);
  747. m_logf = NULL;
  748. if (m_listf)
  749. fclose (m_listf);
  750. m_listf = NULL;
  751. return TRUE;
  752. }
  753. void CDrvchkApp::ChkDriver (CString drv_name)
  754. {
  755. m_drv_name = drv_name;
  756. cerr << (LPCSTR)m_drv_name << endl;
  757. if (!InitIllegalImportsSearch (m_drv_name, "INIT")) {
  758. PrintOut ("error: can't perform check in ");
  759. PrintOut (m_drv_name);
  760. PrintOut (", check the name and path please\n");
  761. } else if (CheckDriverAndPrintResults ()) {
  762. PrintOut ("success: no illegal imports in ");
  763. PrintOut (m_drv_name);
  764. PrintOut ("\n");
  765. }
  766. }
  767. BOOL CDrvchkApp::CheckDriverAndPrintResults ()
  768. {
  769. Names Modules = CheckSectionsForImports ();
  770. if (!Modules.Ptr) {
  771. PrintOut ("error: cannot retrieve import information from ");
  772. PrintOut (m_drv_name);
  773. PrintOut ("\n");
  774. return FALSE;
  775. }
  776. int errors_found = 0;
  777. int warnings_found = 0;
  778. bool bad_data = false;
  779. for (int i=0;
  780. i<Modules.Num;
  781. Modules.Ptr = GetNextName(Modules.Ptr), i++) {
  782. Names Imports = GetImportsList (Modules.Ptr);
  783. if (!Imports.Num) {
  784. bad_data = true;
  785. break;
  786. }
  787. VCHK_TRACE("Checking " << (LPCSTR)Modules.Ptr << endl)
  788. CString module_name (Modules.Ptr);
  789. module_name.MakeUpper();
  790. if (allowed_modules.IsModule(module_name)) {
  791. //
  792. // The whole module is allowed, no errors on any import
  793. // from this module.
  794. //
  795. VCHK_TRACE("Allowed module " << (LPCSTR)module_name << endl)
  796. continue;
  797. }
  798. BOOL KnownIllegals = known_illegal.IsModule(module_name);
  799. if (KnownIllegals) {
  800. VCHK_TRACE("Known Illegals from " << (LPCSTR)module_name << endl)
  801. }
  802. BOOL IllegalMsgs = illegal_msgs.IsModule(module_name);
  803. if (IllegalMsgs) {
  804. VCHK_TRACE("Illegal Imports from " << (LPCSTR)module_name << endl)
  805. }
  806. BOOL AllowedImports = allowed_imports.IsModule(module_name);
  807. if (AllowedImports) {
  808. VCHK_TRACE("Allowed Imports from " << (LPCSTR)module_name << endl)
  809. }
  810. LPSTR ImportsPtr = Imports.Ptr;
  811. for (int j=0;
  812. j<Imports.Num;
  813. Imports.Ptr = GetNextName (Imports.Ptr), j++) {
  814. if (allowed_imports.Lookup(Imports.Ptr)) continue;
  815. CString msg = "";
  816. CString ImportFnName = module_name +
  817. CString("!") +
  818. CString(Imports.Ptr);
  819. if (KnownIllegals && known_illegal.Lookup(Imports.Ptr, msg)) {
  820. PrintOut ("warning: ");
  821. ++warnings_found;
  822. } else if (AllowedImports && allowed_imports.Lookup(Imports.Ptr)) {
  823. continue; // Ignore allowed import
  824. } else if (IllegalMsgs && illegal_msgs.Lookup(Imports.Ptr, msg)) {
  825. PrintOut ("error: ");
  826. ++errors_found;
  827. } else {
  828. PrintOut ("warning: "); // Default case; now we make it warning too, but keep it
  829. ++warnings_found; // a separate case for very probable future changes.
  830. }
  831. PrintOut (m_drv_name);
  832. PrintOut (": ");
  833. PrintOut (ImportFnName);
  834. if (msg.GetLength()) {
  835. PrintOut (" -- ");
  836. PrintOut (msg);
  837. }
  838. PrintOut ("\n");
  839. }
  840. if (ImportsPtr) HeapFree (GetProcessHeap(), 0, ImportsPtr);
  841. }
  842. CString drv_bin_name;
  843. for (int i=m_drv_name.GetLength()-1; i>=0; i--) {
  844. if (m_drv_name.GetAt(i)=='\\') {
  845. drv_bin_name = ((LPCSTR)m_drv_name) + i + 1;
  846. break;
  847. }
  848. }
  849. BOOL skip_it = FALSE;
  850. if (m_drv_name.Find("\\wdm\\") != -1) {
  851. skip_it = TRUE;
  852. }
  853. char buf[256];
  854. if (skip_it) {
  855. sprintf (buf, "SKIP WDM:");
  856. } else if (bad_data) {
  857. sprintf (buf, "WRONG_BINARY:");
  858. } else if (errors_found!=0) {
  859. sprintf (buf, "ERRORS: ");
  860. } else if (warnings_found!=0) {
  861. sprintf (buf, "WARNINGS:");
  862. } else {
  863. sprintf (buf, "SUCCESS:");
  864. }
  865. ListOut (buf);
  866. sprintf (buf, "\t%3d errors\t%3d warnings\t%s\n", errors_found, warnings_found, (LPCSTR)drv_bin_name);
  867. ListOut (buf);
  868. return (errors_found==0);
  869. }