BOOLEAN EtGpuMonitorInitialization(VOID) { //@@ gdi32.dll and setupapi.dll 함수 후킹으로 함수 address 획득. /*if (PhGetIntegerSetting(SETTING_NAME_ENABLE_GPU_MONITOR) && WindowsVersion >= WINDOWS_7) {*/ HMODULE gdi32Handle; HMODULE setupapiHandle; if (gdi32Handle = GetModuleHandle(L"gdi32.dll")) { D3DKMTOpenAdapterFromDeviceName_I = (PVOID)GetProcAddress(gdi32Handle, "D3DKMTOpenAdapterFromDeviceName"); D3DKMTCloseAdapter_I = (PVOID)GetProcAddress(gdi32Handle, "D3DKMTCloseAdapter"); D3DKMTQueryStatistics_I = (PVOID)GetProcAddress(gdi32Handle, "D3DKMTQueryStatistics"); /*if (D3DKMTOpenAdapterFromDeviceName_I == NULL) printf("failed got D3DKMTDeviceName_l addr \n"); else printf("success got D3DKMTDeviceName_l addr %x \n", D3DKMTOpenAdapterFromDeviceName_I);*/ } if (setupapiHandle = LoadLibrary(L"setupapi.dll")) { SetupDiGetClassDevsW_I = (PVOID)GetProcAddress(setupapiHandle, "SetupDiGetClassDevsW"); SetupDiDestroyDeviceInfoList_I = (PVOID)GetProcAddress(setupapiHandle, "SetupDiDestroyDeviceInfoList"); SetupDiEnumDeviceInterfaces_I = (PVOID)GetProcAddress(setupapiHandle, "SetupDiEnumDeviceInterfaces"); SetupDiGetDeviceInterfaceDetailW_I = (PVOID)GetProcAddress(setupapiHandle, "SetupDiGetDeviceInterfaceDetailW"); SetupDiGetDeviceRegistryPropertyW_I = (PVOID)GetProcAddress(setupapiHandle, "SetupDiGetDeviceRegistryPropertyW"); } if ( D3DKMTOpenAdapterFromDeviceName_I && D3DKMTCloseAdapter_I && D3DKMTQueryStatistics_I && SetupDiGetClassDevsW_I && SetupDiDestroyDeviceInfoList_I && SetupDiEnumDeviceInterfaces_I && SetupDiGetDeviceInterfaceDetailW_I ) { EtpGpuAdapterList = PhCreateList(4); //@@ D3DStatistics 초기화 및 D3DStatistics에서 gpu adapter list를 받아옮. if (EtpInitializeD3DStatistics() && EtpGpuAdapterList->Count != 0) return TRUE; } return FALSE; }
VOID EtGpuMonitorInitialization( VOID ) { if (PhGetIntegerSetting(SETTING_NAME_ENABLE_GPU_MONITOR)) { EtpGpuAdapterList = PhCreateList(4); if (EtpInitializeD3DStatistics()) EtGpuEnabled = TRUE; } if (EtGpuEnabled) { ULONG sampleCount; ULONG i; ULONG j; PPH_STRING bitmapString; D3DKMT_QUERYSTATISTICS queryStatistics; sampleCount = PhGetIntegerSetting(L"SampleCount"); PhInitializeCircularBuffer_FLOAT(&EtGpuNodeHistory, sampleCount); PhInitializeCircularBuffer_ULONG(&EtMaxGpuNodeHistory, sampleCount); PhInitializeCircularBuffer_FLOAT(&EtMaxGpuNodeUsageHistory, sampleCount); PhInitializeCircularBuffer_ULONG(&EtGpuDedicatedHistory, sampleCount); PhInitializeCircularBuffer_ULONG(&EtGpuSharedHistory, sampleCount); EtGpuNodesTotalRunningTimeDelta = PhAllocate(sizeof(PH_UINT64_DELTA) * EtGpuTotalNodeCount); memset(EtGpuNodesTotalRunningTimeDelta, 0, sizeof(PH_UINT64_DELTA) * EtGpuTotalNodeCount); EtGpuNodesHistory = PhAllocate(sizeof(PH_CIRCULAR_BUFFER_FLOAT) * EtGpuTotalNodeCount); for (i = 0; i < EtGpuTotalNodeCount; i++) { PhInitializeCircularBuffer_FLOAT(&EtGpuNodesHistory[i], sampleCount); } PhRegisterCallback( &PhProcessesUpdatedEvent, EtGpuProcessesUpdatedCallback, NULL, &ProcessesUpdatedCallbackRegistration ); // Load the node bitmap. bitmapString = PhGetStringSetting(SETTING_NAME_GPU_NODE_BITMAP); if (!(bitmapString->Length & 3) && bitmapString->Length / 4 <= BYTES_NEEDED_FOR_BITS(EtGpuTotalNodeCount)) { PhHexStringToBuffer(&bitmapString->sr, (PUCHAR)EtGpuNodeBitMapBuffer); EtGpuNodeBitMapBitsSet = RtlNumberOfSetBits(&EtGpuNodeBitMap); } PhDereferenceObject(bitmapString); // Fix up the node bitmap if the current node count differs from what we've seen. if (EtGpuTotalNodeCount != PhGetIntegerSetting(SETTING_NAME_GPU_LAST_NODE_COUNT)) { ULONG maxContextSwitch = 0; ULONG maxContextSwitchNodeIndex = 0; RtlClearAllBits(&EtGpuNodeBitMap); EtGpuNodeBitMapBitsSet = 0; for (i = 0; i < EtpGpuAdapterList->Count; i++) { PETP_GPU_ADAPTER gpuAdapter = EtpGpuAdapterList->Items[i]; for (j = 0; j < gpuAdapter->NodeCount; j++) { memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS)); queryStatistics.Type = D3DKMT_QUERYSTATISTICS_NODE; queryStatistics.AdapterLuid = gpuAdapter->AdapterLuid; queryStatistics.QueryNode.NodeId = j; if (NT_SUCCESS(D3DKMTQueryStatistics(&queryStatistics))) { // The numbers below are quite arbitrary. if (queryStatistics.QueryResult.NodeInformation.GlobalInformation.RunningTime.QuadPart != 0 && queryStatistics.QueryResult.NodeInformation.GlobalInformation.ContextSwitch > 10000) { RtlSetBits(&EtGpuNodeBitMap, gpuAdapter->FirstNodeIndex + j, 1); EtGpuNodeBitMapBitsSet++; } if (maxContextSwitch < queryStatistics.QueryResult.NodeInformation.GlobalInformation.ContextSwitch) { maxContextSwitch = queryStatistics.QueryResult.NodeInformation.GlobalInformation.ContextSwitch; maxContextSwitchNodeIndex = gpuAdapter->FirstNodeIndex + j; } } } } // Just in case if (EtGpuNodeBitMapBitsSet == 0) { RtlSetBits(&EtGpuNodeBitMap, maxContextSwitchNodeIndex, 1); EtGpuNodeBitMapBitsSet = 1; } PhSetIntegerSetting(SETTING_NAME_GPU_LAST_NODE_COUNT, EtGpuTotalNodeCount); } } }