Created
April 17, 2016 12:09
-
-
Save egtra/a33b6cf167dfb7611bef7f30329ba17d to your computer and use it in GitHub Desktop.
"netsh trace start caputre=yes traceFile=D:\packet.etl"の再現
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| Copyright © 2016 Egtra | |
| This program is free software: you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation, either version 3 of the License, or | |
| (at your option) any later version. | |
| This program is distributed in the hope that it will be useful, | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| */ | |
| #define UNICODE | |
| #define _UNICODE | |
| #include <iostream> | |
| #include <string> | |
| #include <cstdlib> | |
| #include <cstdint> | |
| #include <ctime> | |
| #include <windows.h> | |
| #include <lmcons.h> | |
| #include <winevt.h> | |
| #include <netcfgx.h> | |
| #include <evntrace.h> | |
| #include <comdef.h> | |
| #include <atlbase.h> | |
| #include <atlutil.h> | |
| #pragma comment(lib, "rpcrt4.lib") | |
| using namespace std::literals; | |
| HRESULT OutputErrorMessgae(_In_ PCWSTR functionName, HRESULT hr) | |
| { | |
| std::wclog << functionName << '\n'; | |
| std::wclog << std::showbase << std::hex << hr << '\n'; | |
| std::wclog << ATL::AtlGetErrorDescription(hr).GetString() << std::endl; | |
| return hr; | |
| } | |
| HRESULT OutputLastError(_In_ PCWSTR functionName) | |
| { | |
| auto hr = ATL::AtlHresultFromLastError(); | |
| return OutputErrorMessgae(functionName, hr); | |
| } | |
| void ExitIfErrorHResult(_In_ PCWSTR functionName, HRESULT hr) | |
| { | |
| if (FAILED(hr)) | |
| { | |
| std::quick_exit(OutputErrorMessgae(functionName, hr)); | |
| } | |
| } | |
| void ExitIfErrorWin32(_In_ PCWSTR functionName, DWORD e) | |
| { | |
| ExitIfErrorHResult(functionName, HRESULT_FROM_WIN32(e)); | |
| } | |
| _COM_SMARTPTR_TYPEDEF(INetCfg, __uuidof(INetCfg)); | |
| _COM_SMARTPTR_TYPEDEF(INetCfgLock, __uuidof(INetCfgLock)); | |
| _COM_SMARTPTR_TYPEDEF(INetCfgComponent, __uuidof(INetCfgComponent)); | |
| _COM_SMARTPTR_TYPEDEF(INetCfgComponentBindings, __uuidof(INetCfgComponentBindings)); | |
| _COM_SMARTPTR_TYPEDEF(IEnumNetCfgBindingPath, __uuidof(IEnumNetCfgBindingPath)); | |
| _COM_SMARTPTR_TYPEDEF(INetCfgBindingPath, __uuidof(INetCfgBindingPath)); | |
| int wmain() | |
| { | |
| std::locale l(std::locale::classic(), "", std::locale::ctype); | |
| std::wcout.imbue(l); | |
| std::wclog.imbue(l); | |
| HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); | |
| ExitIfErrorHResult(L"CoInitializeEx", hr); | |
| DWORD result; | |
| HKEY hkSession; | |
| HKEY hkParameters; | |
| result = RegCreateKeyEx( | |
| HKEY_CURRENT_USER, | |
| LR"(System\CurrentControlSet\Control\NetTrace\Session)", | |
| 0, | |
| nullptr, | |
| REG_OPTION_NON_VOLATILE, | |
| KEY_WRITE, | |
| nullptr, | |
| &hkSession, | |
| nullptr); | |
| ExitIfErrorWin32(L"RegOpenKeyEx (Session)", result); | |
| result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, LR"(System\CurrentControlSet\Services\NdisCap\Parameters)", 0, KEY_WRITE, &hkParameters); | |
| ExitIfErrorWin32(L"RegOpenKeyEx (Parameters)", result); | |
| auto hscm = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT); | |
| auto hsc = OpenService(hscm, L"ndiscap", SERVICE_START | SERVICE_CHANGE_CONFIG); | |
| result = StartService(hsc, 0, nullptr); | |
| //result = ChangeServiceConfig(hsc, SERVICE_KERNEL_DRIVER, SERVICE_SYSTEM_START, SERVICE_NO_CHANGE, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); | |
| DWORD refCount = 1; | |
| result = RegSetValueEx(hkParameters, L"RefCount", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&refCount), sizeof refCount); | |
| ExitIfErrorWin32(L"RegSetValueEx(RefCount)", result); | |
| DWORD captureMode = 0; | |
| result = RegSetValueEx(hkParameters, L"CaptureMode", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&captureMode), sizeof captureMode); | |
| ExitIfErrorWin32(L"RegSetValueEx(CaptureMode)", result); | |
| INetCfgPtr nc(CLSID_CNetCfg, nullptr, CLSCTX_SERVER); | |
| INetCfgLockPtr lock = nc; | |
| hr = lock->AcquireWriteLock(5000, L"Sample app (ndiscap-netsh)", nullptr); | |
| ExitIfErrorHResult(L"INetCfgLock::AcquireWriteLock", hr); | |
| if (hr != S_OK) | |
| { | |
| std::wclog << "Locked" << std::endl; | |
| std::quick_exit(1); | |
| } | |
| hr = nc->Initialize(nullptr); | |
| ExitIfErrorHResult(L"INetCfg::Initialize", hr); | |
| INetCfgComponentPtr ndisCap; | |
| hr = nc->FindComponent(L"ms_ndiscap", &ndisCap); | |
| ExitIfErrorHResult(L"INetCfg::FindComponent", hr); | |
| INetCfgComponentBindingsPtr b = ndisCap; | |
| IEnumNetCfgBindingPathPtr enumBindingPath; | |
| hr = b->EnumBindingPaths(EBP_BELOW, &enumBindingPath); | |
| ExitIfErrorHResult(L"INetCfgComponentBindings::EnumBindingPaths", hr); | |
| INetCfgBindingPathPtr bindingPath; | |
| ULONG fetched; | |
| while (enumBindingPath->Next(1, &bindingPath, &fetched) == S_OK) | |
| { | |
| // netshでは、先にIsEnabledを確認している | |
| hr = bindingPath->Enable(TRUE); | |
| ExitIfErrorHResult(L"INetCfgBindingPath::Enable", hr); | |
| } | |
| hr = nc->Apply(); | |
| ExitIfErrorHResult(L"INetCfg::Apply", hr); | |
| DWORD value = 1; | |
| result = RegSetValueEx(hkSession, L"CaptureEnabled", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof value); | |
| ExitIfErrorWin32(L"RegSetValueEx(CaptureEnabled)", result); | |
| hr = lock->ReleaseWriteLock(); | |
| WCHAR computerName[16]{}; | |
| DWORD computerNameSize = ARRAYSIZE(computerName); | |
| GetComputerName(computerName, &computerNameSize); | |
| WCHAR userName[UNLEN + 1]{}; | |
| DWORD userNameSize = ARRAYSIZE(userName); | |
| GetUserName(userName, &userNameSize); | |
| std::wstring sessionName = L"NetTrace-"s + computerName + L'-' + userName; | |
| std::wcout << sessionName << std::endl; | |
| auto logFileName = LR"(D:\packet.etl)"; | |
| TRACEHANDLE th; | |
| union | |
| { | |
| char buffer[1024]; | |
| EVENT_TRACE_PROPERTIES etp; | |
| }; | |
| memset(buffer, 0, sizeof buffer); | |
| etp.Wnode.BufferSize = sizeof etp + sizeof(WCHAR) * (sessionName.size() + 1 + wcslen(logFileName) + 1); | |
| etp.Wnode.ClientContext = 2; // Query perfomance counter | |
| etp.Wnode.Flags = WNODE_FLAG_TRACED_GUID; | |
| etp.BufferSize = 128; | |
| etp.MaximumBuffers = 128; | |
| etp.MaximumFileSize = 250; | |
| etp.LogFileMode = EVENT_TRACE_FILE_MODE_CIRCULAR | EVENT_TRACE_FLAG_DEBUG_EVENTS | EVENT_TRACE_REAL_TIME_MODE; | |
| etp.LogFileNameOffset = sizeof etp + sizeof(WCHAR) * (sessionName.size() + 1); | |
| etp.LoggerNameOffset = sizeof etp; // 120 | |
| wmemcpy((PWSTR)(buffer + etp.LogFileNameOffset), logFileName, wcslen(logFileName) + 1); | |
| wmemcpy((PWSTR)(buffer + etp.LoggerNameOffset), sessionName.c_str(), sessionName.size() + 1); | |
| result = StartTrace(&th, sessionName.c_str(), &etp); | |
| ExitIfErrorWin32(L"StartTrace", HRESULT_FROM_WIN32(result)); | |
| struct __declspec(uuid("{83ed54f0-4d48-4e45-b16e-726ffd1fa4af}")) Microsoft_Windows_Networking_Correlation; | |
| struct __declspec(uuid("{2ed6006e-4729-4609-b423-3ee7bcd678ef}")) Microsoft_Windows_NDIS_PacketCapture; | |
| ENABLE_TRACE_PARAMETERS params{}; | |
| params.Version = ENABLE_TRACE_PARAMETERS_VERSION; | |
| result = EnableTraceEx2(th, &__uuidof(Microsoft_Windows_Networking_Correlation), EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_NONE, 7, 0, 0, ¶ms); | |
| ExitIfErrorWin32(L"EnableTraceEx2(Microsoft-Windows-Networking-Correlation)", result); | |
| params.Version = ENABLE_TRACE_PARAMETERS_VERSION; | |
| result = EnableTraceEx2(th, &__uuidof(Microsoft_Windows_NDIS_PacketCapture), EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_INFORMATION, 0, 0, 0, ¶ms); | |
| ExitIfErrorWin32(L"EnableTraceEx2(Microsoft-Windows-NDIS-PacketCapture)", result); | |
| value = 0; | |
| result = RegSetValueEx(hkSession, L"ReportEnabled", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof value); | |
| ExitIfErrorWin32(L"RegSetValueEx(ReportEnabled)", result); | |
| value = 1; | |
| result = RegSetValueEx(hkSession, L"MiniReportEnabled", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof value); | |
| ExitIfErrorWin32(L"RegSetValueEx(MiniReportEnabled)", result); | |
| result = RegSetValueEx(hkSession, L"CorrelateEnabled", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof value); | |
| ExitIfErrorWin32(L"RegSetValueEx(CorrelateEnabled)", result); | |
| result = RegSetValueEx(hkSession, L"PerfMergeEnabled", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof value); | |
| ExitIfErrorWin32(L"RegSetValueEx(PerfMergeEnabled)", result); | |
| GUID sessionId{}; | |
| UuidCreateSequential(&sessionId); | |
| WCHAR sessionIdString[39]{}; | |
| StringFromGUID2(sessionId, sessionIdString, ARRAYSIZE(sessionIdString)); | |
| result = RegSetValueEx(hkSession, L"SessionId", 0, REG_SZ, reinterpret_cast<const BYTE*>(&sessionIdString), sizeof sessionIdString); | |
| ExitIfErrorWin32(L"RegSetValueEx(SessionId)", result); | |
| auto startTime = static_cast<std::uint64_t>(std::time(nullptr)); | |
| result = RegSetValueEx(hkSession, L"StartTime", 0, REG_QWORD, reinterpret_cast<const BYTE*>(&startTime), sizeof startTime); | |
| ExitIfErrorWin32(L"RegSetValueEx(StartTime)", result); | |
| hr = nc->Uninitialize(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment