// vchk.cpp : Defines the entry point for the console application. // #include "stdafx.h" #pragma hdrstop #include "vchk.h" #include "allowed.h" #include "ilimpchk.h" //#include #include //#include #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif using namespace std; ////////////////////////////////////////////////////////////////////////////// //#define VCHK_TRACE_ON 1 #ifdef VCHK_TRACE_ON const char* VchkTraceGetName(const char* szName) { const char* szLastSeg = szName; const char* szSlash = strchr(szName, '\\'); while (szSlash) { ++szSlash; szLastSeg = szSlash; szSlash = strchr(szSlash, '\\'); } return szLastSeg; } #define VCHK_TRACE(x) {cerr << " [" << VchkTraceGetName(__FILE__) << ":" << __LINE__ << "] " << x;} #else #define VCHK_TRACE(x) #endif ///////////////////////////////////////////////////////////////////////////// // Enumerates display devices typedef class CDisplayDeviceEnum { public: static bool IsDigitsOnly(const char* sz); CDisplayDeviceEnum(); ~CDisplayDeviceEnum() {free(Buffer);} bool IsValid() const {return bValid;} bool Next(); CString GetMiniportPath(); DWORD GetDeviceId() {return iEnum;} DWORD GetLastError() {return dwLastError;} const char* GetLastErrorStr() {return szLastError;} void MarkDevice(DISPLAY_DEVICE& r_DisplayDevice); void UnmarkDevice(); bool IsMarkedDevice(); private: static const GUID const displayClassGUID; BYTE* Buffer; size_t BufferSize; bool bValid; DWORD iEnum; HDEVINFO hDevInfo; SP_DEVINFO_DATA DeviceInfoData; HKEY hMarkedKey; DWORD dwLastError; const char* szLastError; bool ReallocBuffer(size_t NewSize) { if (NewSize > BufferSize) { void* p = realloc(Buffer, NewSize); if (!p) return false; Buffer = (PBYTE)p; BufferSize = NewSize; } return true; } void MarkKey(HKEY hKey); void UnmarkKey(); bool IsMarkedDEVINST(DEVINST DevInst); } typedef_CDisplayDeviceEnum; ///////////////////////////////////////////////////////////////////////////// // CDisplayDeviceEnum implementation ///////////////////////////////////////////////////////////////////////////// // CDisplayDeviceEnum::IsDigitsOnly bool CDisplayDeviceEnum::IsDigitsOnly(const char* sz) { if (!sz || !*sz) return false; while (('0' <= *sz) && (*sz <= '9')) ++sz; return !*sz; } ///////////////////////////////////////////////////////////////////////////// // CDisplayDeviceEnum constants const GUID const CDisplayDeviceEnum::displayClassGUID = {0x4d36e968L, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}; ///////////////////////////////////////////////////////////////////////////// // CDisplayDeviceEnum constructor CDisplayDeviceEnum::CDisplayDeviceEnum() : bValid(true), Buffer(NULL), BufferSize(0), iEnum(0), hDevInfo(INVALID_HANDLE_VALUE), hMarkedKey(NULL), dwLastError(0), szLastError(NULL) { ZeroMemory(&DeviceInfoData, sizeof(DeviceInfoData)); DeviceInfoData.cbSize = sizeof(DeviceInfoData); ReallocBuffer(MAX_PATH + 1); // Get Device Info Set for display class GUID hDevInfo = SetupDiGetClassDevs(&displayClassGUID, // class guid NULL, // Enumerator NULL, // top level window DIGCF_PRESENT); if (hDevInfo != INVALID_HANDLE_VALUE) { Next(); } else { dwLastError = GetLastError(); szLastError = "SetupDiGetClassDevs failure"; bValid = false; } } ///////////////////////////////////////////////////////////////////////////// // CDisplayDeviceEnum::Next() - gets next device into scope bool CDisplayDeviceEnum::Next() { if (!bValid) return false; // get device info for the device in the Device Info Set at index iEnum if (SetupDiEnumDeviceInfo(hDevInfo, // device info set iEnum, // member index &DeviceInfoData)) // Device Info data { ++iEnum; } else { dwLastError = GetLastError(); szLastError = "SetupDiEnumDeviceInfo failure"; bValid = false; } return bValid; } ///////////////////////////////////////////////////////////////////////////// // CDisplayDeviceEnum::GetMiniportPath() - gets miniport of current device CString CDisplayDeviceEnum::GetMiniportPath() { DWORD BufferSizeNeeded = BufferSize; DWORD DataT; // Get Registry Information for the Device // First time through is to find out how much memory we need to allocate. // Second time actually gives us the information we want. while (!SetupDiGetDeviceRegistryProperty(hDevInfo, // device info set &DeviceInfoData, // info for the device we want to retrieve SPDRP_SERVICE, // Specify that we want the service name &DataT, Buffer, // this should return the service name BufferSizeNeeded, &BufferSizeNeeded)) { DWORD dwError = GetLastError(); if (dwError == ERROR_INSUFFICIENT_BUFFER) { if (ReallocBuffer(BufferSizeNeeded)) continue; szLastError = "Not enough memory"; } else { szLastError = "SetupDiGetDeviceRegistryProperty failure"; } dwLastError = dwError; bValid = false; return CString(); } // get miniport path CString sRegPath("System\\CurrentControlSet\\Services\\"); sRegPath += (LPCSTR)Buffer; // open the services key, find the service, and get the image path HKEY hkService; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)sRegPath, 0, KEY_READ, &hkService) != ERROR_SUCCESS) { dwLastError = GetLastError(); szLastError = "RegOpenKeyEx failure"; bValid = false; return CString(); } if (!ReallocBuffer(MAX_PATH)) { dwLastError = -1; szLastError = "Not enough memory"; bValid = false; return CString(); } DWORD cb = BufferSize; ZeroMemory(Buffer, cb); if (RegQueryValueEx(hkService, "ImagePath", NULL, NULL, (LPBYTE)Buffer, &cb) != ERROR_SUCCESS) { dwLastError = GetLastError(); szLastError = "RegQueryValueEx failure"; bValid = false; return CString(); } return CString((const char*)Buffer); } ///////////////////////////////////////////////////////////////////////////// // CDisplayDeviceEnum::MarkDevice(DISPLAY_DEVICE&) // // XXX olegk (it is really XXX level of hack) // we will mark the child monitor subkey and than will be searching for // children with marked keys later in IsMarkedDevice() // void CDisplayDeviceEnum::MarkDevice(DISPLAY_DEVICE& r_DisplayDevice) { if (hMarkedKey) UnmarkDevice(); VCHK_TRACE("-------- Marking Device ----------\n"); VCHK_TRACE("ID : " << r_DisplayDevice.DeviceID << endl); VCHK_TRACE("Key : " << r_DisplayDevice.DeviceKey << endl); VCHK_TRACE("Name : " << r_DisplayDevice.DeviceName << endl); VCHK_TRACE("String : " << r_DisplayDevice.DeviceString << endl); DISPLAY_DEVICE MonitorInfo; MonitorInfo.cb = sizeof(MonitorInfo); if (!EnumDisplayDevices(r_DisplayDevice.DeviceName, 0, &MonitorInfo, 0)) { VCHK_TRACE("Can't get monitor info for " << r_DisplayDevice.DeviceString << ' ' << r_DisplayDevice.DeviceName << endl); return; } CString sKey; // XXX olegk - Assume that all device keys are under HKEY_LOCAL_MACHINE { const CHAR szMachineRegPath[] = "\\REGISTRY\\Machine\\"; if (_strnicmp(szMachineRegPath, MonitorInfo.DeviceKey, sizeof(szMachineRegPath) - 1)) { dwLastError = DWORD(-1); szLastError = "Invalid registry path (must be under HKEY_LOCAL_MACHINE)"; VCHK_TRACE("Invalid registry path " << MonitorInfo.DeviceKey << endl); return; } sKey = (LPCSTR)(MonitorInfo.DeviceKey) + sizeof(szMachineRegPath) - 1; } HKEY hKey; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)sKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS) { // Do nothing - no service will be found DWORD dwError = GetLastError(); VCHK_TRACE("RegOpenKeyEx failure " << dwError << " : " << r_DisplayDevice.DeviceKey << endl); return; } VCHK_TRACE("Marked Key: " << (LPCSTR)sKey << endl); MarkKey(hKey); } ///////////////////////////////////////////////////////////////////////////// // CDisplayDeviceEnum::UnmarkDevice(DISPLAY_DEVICE&) void CDisplayDeviceEnum::UnmarkDevice() { UnmarkKey(); } ///////////////////////////////////////////////////////////////////////////// // CDisplayDeviceEnum::IsMarkedDevice() bool CDisplayDeviceEnum::IsMarkedDevice() { const size_t nMaxLevel = 10; // XXX olegk - I can't imagine more than 3 but... DEVINST DevInstStack[nMaxLevel]; size_t nLevel = 0; if (CM_Get_Child(&DevInstStack[nLevel], DeviceInfoData.DevInst, 0) != CR_SUCCESS) return false; while (!IsMarkedDEVINST(DevInstStack[nLevel])) { if ((nLevel < nMaxLevel) && (CM_Get_Child(&DevInstStack[nLevel + 1], DevInstStack[nLevel], 0) == CR_SUCCESS)) { ++nLevel; continue; } while (CM_Get_Sibling(&DevInstStack[nLevel], DevInstStack[nLevel], 0) != CR_SUCCESS) { if (!nLevel) return false; // End of search (no marker have been found) --nLevel; } } return true; } ///////////////////////////////////////////////////////////////////////////// // CDisplayDeviceEnum::MarkKey(...) void CDisplayDeviceEnum::MarkKey(HKEY hKey) { UnmarkKey(); hMarkedKey = hKey; } ///////////////////////////////////////////////////////////////////////////// // CDisplayDeviceEnum::UnmarkKey(...) void CDisplayDeviceEnum::UnmarkKey() { if (!hMarkedKey) return; RegCloseKey(hMarkedKey); hMarkedKey = NULL; } ///////////////////////////////////////////////////////////////////////////// // CDisplayDeviceEnum::IsMarkedDEVINST(...) bool CDisplayDeviceEnum::IsMarkedDEVINST(DEVINST DevInst) { bool bIsMarked = false; HKEY hKey; if (CM_Open_DevNode_Key(DevInst, KEY_READ, // IN REGSAM samDesired, 0, // IN ULONG ulHardwareProfile, RegDisposition_OpenExisting, &hKey, //OUT PHKEY phkDevice, CM_REGISTRY_SOFTWARE) == CR_SUCCESS) { extern bool IsTheSameRegKey(HKEY, HKEY); bIsMarked = IsTheSameRegKey(hMarkedKey, hKey); RegCloseKey(hKey); } return bIsMarked; } ///////////////////////////////////////////////////////////////////////////// // The one and only application object void CDrvchkApp::PrintOut (LPCSTR str) { if (m_logf) fprintf (m_logf, "%s", str); else cerr << str; } void CDrvchkApp::PrintOut (unsigned num) { if (m_logf) fprintf (m_logf, "%u", num); else cerr << num; } inline void CDrvchkApp::ListOut (LPCSTR str) { if (m_listf) fprintf (m_listf, "%s", str); } void CDrvchkApp::ListOut (unsigned num) { if (m_listf) fprintf (m_listf, "%u", num); } ModulesAndImports allowed_modules; ModulesAndImports allowed_imports; ModulesAndImports known_illegal; ModulesAndImports illegal_msgs; void SetCurrentModule(const char* szModule) { allowed_imports.SetModule(szModule); illegal_msgs.SetModule(szModule); known_illegal.SetModule(szModule); } #define VCHK_WARN known_illegal.AddImport #define VCHK_FAIL illegal_msgs.AddImport #define VCHK_ALLOW allowed_imports.AddImport void BuildInAllowedAndIllegal (void) { SetCurrentModule("HAL.DLL"); VCHK_FAIL ("HalAllocateCommonBuffer", "use VideoPortAllocateCommonBuffer"); VCHK_FAIL ("HalFreeCommonBuffer", "use VideoPortFreeCommonBuffer"); VCHK_WARN ("HalGetAdapter", "obsolete; see DDK manual"); VCHK_WARN ("HalGetBusData", "obsolete; see DDK manual"); VCHK_WARN ("HalGetBusDataByOffset"); VCHK_WARN ("HalSetBusData", "obsolete; see DDK manual"); VCHK_WARN ("HalSetBusDataByOffset"); VCHK_WARN ("HalTranslateBusAddress"); VCHK_FAIL ("KeGetCurrentIrql", "use VideoPortGetCurrentIrql"); VCHK_FAIL ("KeQueryPerformanceCounter", "use VideoPortQueryPerformanceCounter"); VCHK_FAIL ("KfAcquireSpinLock", "use VideoPortAcquireSpinLock"); VCHK_FAIL ("KfReleaseSpinLock", "use VideoPortReleaseSpinLock"); VCHK_FAIL ("READ_PORT_ULONG", "use VideoPortReadPortUlong"); VCHK_FAIL ("WRITE_PORT_ULONG", "use VideoPortWritePortUlong"); SetCurrentModule ("NTOSKRNL.EXE"); VCHK_ALLOW ("_except_handler3"); VCHK_FAIL ("ExAllocatePool", "use VideoPortAllocatePool"); VCHK_FAIL ("ExAllocatePoolWithTag", "use VideoPortAllocatePool"); VCHK_FAIL ("ExFreePool", "use VideoPortFreePool"); VCHK_FAIL ("ExFreePoolWithTag", "use VideoPortFreePool"); VCHK_WARN ("ExIsProcessorFeaturePresent"); VCHK_WARN ("ExQueueWorkItem"); VCHK_WARN ("IoAllocateMdl"); VCHK_WARN ("IoCreateNotificationEvent"); VCHK_WARN ("IoCreateSynchronizationEvent"); VCHK_WARN ("IoFreeMdl"); VCHK_WARN ("IoGetCurrentProcess"); VCHK_FAIL ("IoReportDetectedDevice"); VCHK_FAIL ("IoReportResourceForDetection"); VCHK_WARN ("KeCancelTimer"); VCHK_FAIL ("KeClearEvent", "use VideoPortClearEvent"); VCHK_FAIL ("KeDelayExecutionThread", "use VideoPortStallExecution"); VCHK_FAIL ("KeInitializeDpc", "use VideoPortQueueDpc"); VCHK_FAIL ("KeInitializeSpinLock", "use VideoPortXxxSpinLockXxx"); VCHK_WARN ("KeInitializeTimer"); VCHK_WARN ("KeInitializeTimerEx"); VCHK_FAIL ("KeInsertQueueDpc", "use VideoPortQueueDpc"); VCHK_WARN ("KeQuerySystemTime"); VCHK_WARN ("KeRestoreFloatingPointState"); VCHK_WARN ("KeSaveFloatingPointState"); VCHK_FAIL ("KeSetEvent", "use VideoPortSetEvent"); VCHK_WARN ("KeSetTimer"); VCHK_WARN ("KeSetTimerEx"); VCHK_FAIL ("MmAllocateContiguousMemory", "use VideoPortAllocateContiguousMemory"); VCHK_WARN ("MmAllocateNonCachedMemory"); VCHK_WARN ("MmBuildMdlForNonPagedPool"); VCHK_WARN ("MmFreeContiguousMemory"); VCHK_WARN ("MmFreeNonCachedMemory"); VCHK_WARN ("MmGetPhysicalAddress"); VCHK_WARN ("MmIsAddressValid"); VCHK_WARN ("MmMapIoSpace"); VCHK_WARN ("MmMapLockedPages"); VCHK_WARN ("MmMapLockedPagesSpecifyCache"); VCHK_WARN ("MmProbeAndLockPages"); VCHK_WARN ("MmQuerySystemSize"); VCHK_WARN ("MmUnlockPages"); VCHK_WARN ("MmUnmapIoSpace"); VCHK_WARN ("MmUnmapLockedPages"); VCHK_WARN ("ObReferenceObjectByHandle"); VCHK_WARN ("PsGetCurrentProcessId"); VCHK_WARN ("PsGetVersion"); VCHK_FAIL ("READ_REGISTER_UCHAR", "use VideoPortReadRegisterUchar"); VCHK_WARN ("RtlAnsiStringToUnicodeString"); VCHK_WARN ("RtlAppendUnicodeStringToString"); VCHK_WARN ("RtlCheckRegistryKey"); VCHK_WARN ("RtlCompareMemory"); VCHK_WARN ("RtlCopyUnicodeString"); VCHK_WARN ("RtlCreateRegistryKey"); VCHK_WARN ("RtlFreeAnsiString"); VCHK_WARN ("RtlFreeUnicodeString"); VCHK_WARN ("RtlInitAnsiString"); VCHK_WARN ("RtlInitUnicodeString"); VCHK_WARN ("RtlIntegerToUnicodeString"); VCHK_WARN ("RtlQueryRegistryValues"); VCHK_WARN ("RtlTimeToTimeFields"); VCHK_WARN ("RtlUnicodeStringToAnsiString"); VCHK_WARN ("RtlUnicodeToMultiByteN"); VCHK_WARN ("RtlUnwind"); VCHK_WARN ("RtlWriteRegistryValue"); VCHK_FAIL ("wcslen", "link to libcntpr.lib instead"); VCHK_FAIL ("WRITE_REGISTER_UCHAR", "use VideoPortWriteRegisterUchar"); VCHK_FAIL ("WRITE_REGISTER_USHORT", "use VideoPortWriteRegisterUshort"); VCHK_WARN ("ZwClose"); VCHK_WARN ("ZwCreateFile"); VCHK_WARN ("ZwEnumerateValueKey"); VCHK_WARN ("ZwMapViewOfSection"); VCHK_WARN ("ZwOpenKey"); VCHK_WARN ("ZwOpenSection"); VCHK_WARN ("ZwQueryValueKey"); VCHK_WARN ("ZwSetSystemInformation"); VCHK_WARN ("ZwUnmapViewOfSection"); VCHK_WARN ("ZwWriteFile"); } ///////////////////////////////////////////////////////////////////////////// // main int __cdecl _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; // initialize MFC and print and error on failure if (AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { CDrvchkApp theApp; theApp.InitInstance (); } return nRetCode; } ///////////////////////////////////////////////////////////////////////////// // CDrvchkApp construction CDrvchkApp::CDrvchkApp() : m_logf(NULL), m_listf(NULL), m_drv_name ("") { // TODO: add construction code here, // Place all significant initialization in InitInstance } ///////////////////////////////////////////////////////////////////////////// // The one and only CDrvchkApp object void CommandLine::ParseParam( LPCTSTR lpszParam, BOOL bFlag, BOOL bLast ) { if (m_parse_error != parseOK) return; CString param (lpszParam); if (bFlag) { param.MakeUpper(); if ((param==CString("?")) || (param == CString("HELP")) || (param == CString("H"))) { m_parse_error = parseHelp; } else if ((param==CString("?IMP")) || (param==CString("IMP?"))) { m_parse_error = parseHelpImports; } else if (m_last_flag.GetLength() && m_first_param) { m_parse_error = parseError; m_error_msg = CString("Flag ") + m_last_flag + CString(" requires a parameter."); } else if ((param==CString("LOG")) || (param==CString("DRV")) || (param==CString("MON")) || (param==CString("LIST")) || (param==CString("LST")) || (param==CString("LS")) || (param==CString("LIS")) || (param==CString("ALLOW"))) { if (bLast) { m_parse_error = parseError; m_error_msg = CString("Flag ") + param + CString(" requires a parameter."); } else { m_last_flag = param; m_first_param = TRUE; } } else { m_last_flag = CString(); m_parse_error = parseError; m_error_msg = CString("Invalid flag: ") + param; } } else { if (m_last_flag==CString("ALLOW")) { m_first_param = FALSE; int nSplit = param.Find('!'); if (nSplit != -1) { CString module = param.Left(nSplit); CString import = param.Mid(nSplit + 1); if (module.GetLength() && import.GetLength()) { allowed_imports.SetModule(module); allowed_imports.AddImport(import, "allowed by command line"); } else { m_parse_error = parseError; m_error_msg = CString("Bad parameter format for flag: ") + m_last_flag; } } else { allowed_modules.SetModule(param); } } else if (m_last_flag==CString("DRV")) { if (m_monitor >= 1) { m_error_msg = "bad command line: Conflicting flags MON and DRV"; m_parse_error = parseError; } m_drv_fname = param; m_last_flag=""; } else if (m_last_flag==CString("LOG")) { m_log_fname = param; m_last_flag=""; } else if (m_last_flag==CString("LIST") || m_last_flag==CString("LST") || m_last_flag==CString("LIS") || m_last_flag==CString("LS")) { m_list_fname = param; m_last_flag=""; } else if (m_last_flag==CString("MON")) { if ((param.GetLength()==1) && (((LPCSTR)param)[0] >= '1') && (((LPCSTR)param)[0] <= '9')) { if (m_drv_fname.GetLength()) { m_error_msg = "bad command line: Conflicting flags MON and DRV"; m_parse_error = parseError; } char c = ((LPCSTR)param)[0]; m_monitor = c - '0'; } else { m_error_msg = "bad command line: MON flag has invalid parameter"; m_parse_error = parseError; } m_last_flag=""; } else { m_parse_error = parseError; m_error_msg = CString("Wrong parameter: ") + param; m_last_flag=""; } } if (bLast) { if (m_last_flag==CString("LOG") || m_last_flag==CString("DRV")) { m_parse_error = parseError; m_error_msg = CString("Flag ") + m_last_flag + CString(" requires a parameter."); } } } ///////////////////////////////////////////////////////////////////////////// // CDrvchkApp initialization const char* szHelp = "Copyright (C) Microsoft Corporation. All rights reserved.\n" "\n" "usage: vchk [-?] [-LOG logfile] [-DRV drvname | -MON id] [-LIST listname]\n" " [-ALLOW module[!import] [module[!import]] ...]\n" "\n" "where: -? displays this help\n" " -IMP? dumps imports tables that check performed against\n" " -LOG specifies output file name (if file already exists then new data\n" " will be appended to it)\n" " -DRV specifies the full name of the driver's binary to check\n" " -MON specifies 1-based numeric id of the display adapter to check\n" " -LIST specifies the file for summary (if file already exists then new\n" " data will be appended to it)\n" " -ALLOW specifies allowed imports\n" " module: name of allowed module (if no import specified then all\n" " imports from the module will be allowed)\n" " import: specific import name\n" "\n" " if neither -MON nor -DRV switches used then all currently active video\n" " drivers will be checked\n" "\n" "Example:\n" " vchk -log c:\\log.out -list con -allow HAL.DLL!HalGetBusData VIDEOPORT.SYS\n"; BOOL CDrvchkApp::InitInstance() { // Standard initialization // If you are not using these features and wish to reduce the size m_os_ver_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx (&m_os_ver_info); if (m_os_ver_info.dwPlatformId != VER_PLATFORM_WIN32_NT) { // doesn't work on Win9x PrintOut ("warning: unsupported OS (Win9x), nothing done.\n"); return FALSE; } //if (m_os_ver_info.dwMajorVersion != 5) { // doesn't work on NT version prior to Win2K if (m_os_ver_info.dwMajorVersion < 5) { // XXX olegk - will it work in the future???? PrintOut ("warning: unsupported OS ("); PrintOut (m_os_ver_info.dwMajorVersion); PrintOut ("."); PrintOut (m_os_ver_info.dwMinorVersion); PrintOut ("): nothing done.\n"); return FALSE; } ParseCommandLine (m_cmd_line); BuildInAllowedAndIllegal(); if (m_cmd_line.m_log_fname.GetLength()) { m_logf = fopen (m_cmd_line.m_log_fname, "a+"); if (!m_logf) m_logf = fopen (m_cmd_line.m_log_fname, "a"); } if (m_cmd_line.m_list_fname.GetLength()) { m_listf = fopen (m_cmd_line.m_list_fname, "a+"); if (!m_listf) m_listf = fopen (m_cmd_line.m_list_fname, "a"); } switch (m_cmd_line.m_parse_error) { case CommandLine::parseOK: { int device_num = m_cmd_line.m_monitor; if (m_cmd_line.m_drv_fname.GetLength()) { ChkDriver (m_cmd_line.m_drv_fname); } else { DWORD cbData = 0; DEVMODE dmCurrent; TCHAR szDeviceDescription[10000]; TCHAR szImagePath[MAX_PATH + 1]; TCHAR szVarImagePath[MAX_PATH + 1]; TCHAR szExpImagePath[MAX_PATH + 1]; DISPLAY_DEVICE DisplayDevice, *pDisplayDevice = NULL; CString dev_desc_CtrlSet; int nNonMirroringDevice = 0; // // Find non mirroring display device #device_num if needed // if (device_num >= 1) { ZeroMemory(&DisplayDevice, sizeof(DisplayDevice)); DisplayDevice.cb = sizeof(DisplayDevice); DWORD i, nNonMirrorDev; for (i = 0, nNonMirrorDev = 0; EnumDisplayDevices(NULL, i, &DisplayDevice, 0); ++i) { if (DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) continue; // skip mirroring drivers if (device_num == ++nNonMirroringDevice) { pDisplayDevice = &DisplayDevice; break; } } if (!pDisplayDevice) { PrintOut ("error: cannot find video service\n"); break; } } // // Let's find all the video drivers that are installed in the system // CDisplayDeviceEnum DevEnum; bool bDevFound = false; if (pDisplayDevice) DevEnum.MarkDevice(*pDisplayDevice); while (DevEnum.IsValid()) { if (!pDisplayDevice || DevEnum.IsMarkedDevice()) { bDevFound = true; CString sMiniportPath = DevEnum.GetMiniportPath(); if (!sMiniportPath.GetLength()) { sprintf (szDeviceDescription, "error: cannot find video service #%d\n", DevEnum.GetDeviceId()); PrintOut (szDeviceDescription); VCHK_TRACE("error: " << szDeviceDescription << "\n " << DevEnum.GetLastError() << " " << DevEnum.GetLastErrorStr() << endl) break; } sprintf (szVarImagePath, "%%WINDIR%%\\%s", (LPCSTR)sMiniportPath); ExpandEnvironmentStrings (szVarImagePath, szExpImagePath, MAX_PATH); VCHK_TRACE("Checking miniport " << szExpImagePath << endl) ChkDriver (szExpImagePath); } DevEnum.Next(); } if (!bDevFound) PrintOut ("error: cannot find video service\n"); } // look for system drivers } // parseOK break; case CommandLine::parseHelp: { CString Filename, Version, Description, Copyright; { CHAR szModuleName[MAX_PATH + 1]; ZeroMemory(szModuleName, sizeof(szModuleName)); if (GetModuleFileName(m_hInstance, szModuleName, MAX_PATH)) { DWORD dw = 0; DWORD dwVerLen = GetFileVersionInfoSize(szModuleName, &dw); if (dwVerLen) { PBYTE Buffer = (PBYTE)malloc(dwVerLen + 1); PVOID pValue; if (Buffer && GetFileVersionInfo(szModuleName, dw, dwVerLen, Buffer)) { UINT ValLen; if (VerQueryValue(Buffer, "\\StringFileInfo\\000004B0\\OriginalFilename", &pValue, &ValLen)); { Filename = CString((LPCSTR)pValue, ValLen); } if (VerQueryValue(Buffer, "\\StringFileInfo\\000004b0\\ProductVersion", &pValue, &ValLen)); Version = CString((LPCSTR)pValue, ValLen); if (VerQueryValue(Buffer, "\\StringFileInfo\\000004b0\\FileDescription", &pValue, &ValLen)); Description = CString((LPCSTR)pValue, ValLen); } free(Buffer); } } } cout << endl << (Filename.GetLength() ? (LPCSTR)Filename : "VCHK.EXE!"); if (Version.GetLength()) cout << " " << (LPCSTR)Version; if (Description.GetLength()) cout << ": " << (LPCSTR)Description; cout << endl; cout << szHelp; } // parseHelp break; case CommandLine::parseHelpImports: { BuildInAllowedAndIllegal(); cout << "\n--- Illegal imports (errors) --------------\n\n"; illegal_msgs.Dump(cout); cout << "\n--- Known illegal imports (warnings) ------\n\n"; known_illegal.Dump(cout); cout << "\n--- Allowed imports -----------------------\n\n"; allowed_imports.Dump(cout); cout << "\n--- Allowed modules -----------------------\n\n"; allowed_modules.Dump(cout); } // parseHelpImports break; default: PrintOut ("error: "); PrintOut (m_cmd_line.m_error_msg.GetLength() ? (LPCSTR)m_cmd_line.m_error_msg : "unknown failure"); PrintOut ("\nUse vchk -? for help.\n"); } // switch if (m_logf) fclose (m_logf); m_logf = NULL; if (m_listf) fclose (m_listf); m_listf = NULL; return TRUE; } void CDrvchkApp::ChkDriver (CString drv_name) { m_drv_name = drv_name; cerr << (LPCSTR)m_drv_name << endl; if (!InitIllegalImportsSearch (m_drv_name, "INIT")) { PrintOut ("error: can't perform check in "); PrintOut (m_drv_name); PrintOut (", check the name and path please\n"); } else if (CheckDriverAndPrintResults ()) { PrintOut ("success: no illegal imports in "); PrintOut (m_drv_name); PrintOut ("\n"); } } BOOL CDrvchkApp::CheckDriverAndPrintResults () { Names Modules = CheckSectionsForImports (); if (!Modules.Ptr) { PrintOut ("error: cannot retrieve import information from "); PrintOut (m_drv_name); PrintOut ("\n"); return FALSE; } int errors_found = 0; int warnings_found = 0; bool bad_data = false; for (int i=0; i=0; i--) { if (m_drv_name.GetAt(i)=='\\') { drv_bin_name = ((LPCSTR)m_drv_name) + i + 1; break; } } BOOL skip_it = FALSE; if (m_drv_name.Find("\\wdm\\") != -1) { skip_it = TRUE; } char buf[256]; if (skip_it) { sprintf (buf, "SKIP WDM:"); } else if (bad_data) { sprintf (buf, "WRONG_BINARY:"); } else if (errors_found!=0) { sprintf (buf, "ERRORS: "); } else if (warnings_found!=0) { sprintf (buf, "WARNINGS:"); } else { sprintf (buf, "SUCCESS:"); } ListOut (buf); sprintf (buf, "\t%3d errors\t%3d warnings\t%s\n", errors_found, warnings_found, (LPCSTR)drv_bin_name); ListOut (buf); return (errors_found==0); }