ULONG ProcessDotNetTrace( _In_ PASMPAGE_QUERY_CONTEXT Context ) { ULONG result; TRACEHANDLE traceHandle; EVENT_TRACE_LOGFILE logFile; memset(&logFile, 0, sizeof(EVENT_TRACE_LOGFILE)); logFile.LoggerName = DotNetLoggerName.Buffer; logFile.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD; logFile.BufferCallback = DotNetBufferCallback; logFile.EventRecordCallback = DotNetEventCallback; logFile.Context = Context; traceHandle = OpenTrace(&logFile); if (traceHandle == INVALID_PROCESSTRACE_HANDLE) return GetLastError(); Context->TraceHandleActive = 1; Context->TraceHandle = traceHandle; result = ProcessTrace(&traceHandle, 1, NULL, NULL); if (_InterlockedExchange(&Context->TraceHandleActive, 0) == 1) { CloseTrace(traceHandle); } return result; }
NTSTATUS EtpRundownEtwMonitorThreadStart( _In_ PVOID Parameter ) { EVENT_TRACE_LOGFILE logFile; TRACEHANDLE traceHandle; memset(&logFile, 0, sizeof(EVENT_TRACE_LOGFILE)); logFile.LoggerName = EtpRundownLoggerName.Buffer; logFile.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD; logFile.BufferCallback = EtpRundownEtwBufferCallback; logFile.EventRecordCallback = EtpRundownEtwEventCallback; logFile.Context = &traceHandle; traceHandle = OpenTrace(&logFile); if (traceHandle != INVALID_PROCESSTRACE_HANDLE) { ProcessTrace(&traceHandle, 1, NULL, NULL); if (traceHandle != 0) CloseTrace(traceHandle); } NtClose(EtpRundownEtwMonitorThreadHandle); EtpRundownEtwMonitorThreadHandle = NULL; return STATUS_SUCCESS; }
FORCEINLINE VOID StopTraceListening ( __in TRACEHANDLE SessionHandle, __inout PTRACE_PROPERTIES Properties, __in TRACEHANDLE ConsumingHandle ) { ControlTrace(SessionHandle, LOGGER_NAME, &Properties->TraceProperties, EVENT_TRACE_CONTROL_STOP); CloseTrace(ConsumingHandle); }
int __cdecl wmain(int argc, wchar_t* argv[]) { bool fPrintUsage = true; if (argc == 2) { if (!SetConsoleCtrlHandler([](_In_ DWORD) { _s_fIsEnding = true; return TRUE; }, TRUE /*Add*/)) { wprintf(L"Erm, looks like ctrl+c isn't going to exit cleanly."); } TRACEHANDLE hTrace = 0; // Open the session EVENT_TRACE_LOGFILE etlTrace = { 0 }; etlTrace.LoggerName = argv[1]; etlTrace.ProcessTraceMode = PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_REAL_TIME; etlTrace.EventRecordCallback = (PEVENT_RECORD_CALLBACK)&_HandleEvent; etlTrace.Context = &hTrace; hTrace = OpenTrace(&etlTrace); if (hTrace != INVALID_PROCESSTRACE_HANDLE) { TRACEHANDLE rghTrace[] = { hTrace }; ULONG ulProcessTrace = ProcessTrace(rghTrace, ARRAYSIZE(rghTrace), nullptr, nullptr); if (ulProcessTrace == ERROR_SUCCESS) { fPrintUsage = false; } else { wprintf(L"ProcessTrace failed. (%u)\r\n", ulProcessTrace); } if (!_s_fIsClosed) { CloseTrace(hTrace); _s_fIsClosed = true; } } else { wprintf(L"OpenTrace failed.\r\n"); } } if (fPrintUsage) { wprintf(USAGE); } }
NTSTATUS EtpEtwMonitorThreadStart( _In_ PVOID Parameter ) { ULONG result; EVENT_TRACE_LOGFILE logFile; TRACEHANDLE traceHandle; // See comment in EtEtwProcessesUpdatedCallback. if (WindowsVersion >= WINDOWS_8) EtUpdateProcessInformation(); memset(&logFile, 0, sizeof(EVENT_TRACE_LOGFILE)); logFile.LoggerName = EtpActualKernelLoggerName->Buffer; logFile.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD; logFile.BufferCallback = EtpEtwBufferCallback; logFile.EventRecordCallback = EtpEtwEventCallback; while (TRUE) { result = ERROR_SUCCESS; traceHandle = OpenTrace(&logFile); if (traceHandle != INVALID_PROCESSTRACE_HANDLE) { while (!EtpEtwExiting && (result = ProcessTrace(&traceHandle, 1, NULL, NULL)) == ERROR_SUCCESS) NOTHING; CloseTrace(traceHandle); } if (EtpEtwExiting) break; if (result == ERROR_WMI_INSTANCE_NOT_FOUND) { // The session was stopped by another program. Try to start it again. EtStartEtwSession(); } // Some error occurred, so sleep for a while before trying again. // Don't sleep if we just successfully started a session, though. if (!EtpEtwActive) Sleep(250); } return STATUS_SUCCESS; }
ULONG UpdateDotNetTraceInfoWithTimeout( _In_ PASMPAGE_QUERY_CONTEXT Context, _In_ BOOLEAN ClrV2, _In_opt_ PLARGE_INTEGER Timeout ) { HANDLE threadHandle; BOOLEAN timeout = FALSE; // ProcessDotNetTrace is not guaranteed to complete within any period of time, because // the target process might terminate before it writes the DCStartComplete_V1 event. // If the timeout is reached, the trace handle is closed, forcing ProcessTrace to stop // processing. Context->TraceClrV2 = ClrV2; Context->TraceResult = 0; Context->TraceHandleActive = 0; Context->TraceHandle = 0; threadHandle = PhCreateThread(0, UpdateDotNetTraceInfoThreadStart, Context); if (NtWaitForSingleObject(threadHandle, FALSE, Timeout) != STATUS_WAIT_0) { // Timeout has expired. Stop the trace processing if it's still active. // BUG: This assumes that the thread is in ProcessTrace. It might still be // setting up though! if (_InterlockedExchange(&Context->TraceHandleActive, 0) == 1) { CloseTrace(Context->TraceHandle); timeout = TRUE; } NtWaitForSingleObject(threadHandle, FALSE, NULL); } NtClose(threadHandle); if (timeout) return ERROR_TIMEOUT; return Context->TraceResult; }
bool ETW::Stop() { if (isActive) { ULONG controlTraceResult = ControlTrace(openedHandle, KERNEL_LOGGER_NAME, sessionProperties, EVENT_TRACE_CONTROL_STOP); // ERROR_CTX_CLOSE_PENDING(7007L): The call was successful. The ProcessTrace function will stop after it has processed all real-time events in its buffers (it will not receive any new events). // ERROR_BUSY(170L): Prior to Windows Vista, you cannot close the trace until the ProcessTrace function completes. // ERROR_INVALID_HANDLE(6L): One of the following is true: TraceHandle is NULL. TraceHandle is INVALID_HANDLE_VALUE. ULONG closeTraceStatus = CloseTrace(openedHandle); // Wait for ProcessThread to finish WaitForSingleObject(processThreadHandle, INFINITE); BOOL wasThreadClosed = CloseHandle(processThreadHandle); isActive = false; return wasThreadClosed && closeTraceStatus == ERROR_SUCCESS && controlTraceResult == ERROR_SUCCESS; } return false; }
~CTraceLog() { CloseTrace(); }
ULONG DecodeFile( __in PWSTR FileName, __inout PPROCESSING_CONTEXT LogContext ) /*++ Routine Description: The main initialization on processing the ETL file is done here. First, a handle to the specified trace (the ETL file in this case) is obtained, then an ETW Api call, ProcessTrace(), is made. ProcessTrace() will invoke the Buffer and Event callback functions after processing each buffer and event, respectively. In the end, CloseTrace() is called. Arguments: FileName - Supplies the name of the ETL file to be decoded. LogContext - Supplies the structure that persists contextual information across callbacks. Return Value: ERROR_SUCCESS - Success. Win32 error code - Calls to OpenTrace, ProcessTrace or CloseTrace failed. --*/ { ULONG Status; EVENT_TRACE_LOGFILE LogFile = {0}; TRACEHANDLE Handle; LogFile.LogFileName = FileName; LogFile.ProcessTraceMode |= PROCESS_TRACE_MODE_EVENT_RECORD; LogFile.EventRecordCallback = EventCallback; LogFile.BufferCallback = BufferCallback; LogFile.Context = (PVOID)LogContext; Handle = OpenTrace(&LogFile); if (Handle == INVALID_PROCESSTRACE_HANDLE) { Status = GetLastError(); wprintf(L"\nOpenTrace failed. Error code: %u.\n", Status); return Status; } Status = ProcessTrace(&Handle, 1, NULL, NULL); if (Status != ERROR_SUCCESS) { wprintf(L"\nProcessTrace failed. Error code: %u.\n", Status); } Status = CloseTrace(Handle); if (Status != ERROR_SUCCESS) { wprintf(L"\nCloseTrace failed. Error code: %u.\n", Status); } return Status; }
void TraceDone(void) { CloseTrace(); if (g_LogFile) { delete g_LogFile; g_LogFile = NULL; } }
VOID NTAPI DotNetEventCallback( _In_ PEVENT_RECORD EventRecord ) { PASMPAGE_QUERY_CONTEXT context = EventRecord->UserContext; PEVENT_HEADER eventHeader = &EventRecord->EventHeader; PEVENT_DESCRIPTOR eventDescriptor = &eventHeader->EventDescriptor; if (UlongToHandle(eventHeader->ProcessId) == context->ProcessId) { // .NET 4.0+ switch (eventDescriptor->Id) { case RuntimeInformationDCStart: { PRuntimeInformationRundown data = EventRecord->UserData; PDNA_NODE node; PPH_STRING startupFlagsString; PPH_STRING startupModeString; // Check for duplicates. if (FindClrNode(context, data->ClrInstanceID)) break; node = AddNode(context); node->Type = DNA_TYPE_CLR; node->u.Clr.ClrInstanceID = data->ClrInstanceID; node->u.Clr.DisplayName = PhFormatString(L"CLR v%u.%u.%u.%u", data->VMMajorVersion, data->VMMinorVersion, data->VMBuildNumber, data->VMQfeNumber); node->StructureText = node->u.Clr.DisplayName->sr; node->IdText = PhFormatString(L"%u", data->ClrInstanceID); startupFlagsString = FlagsToString(data->StartupFlags, StartupFlagsMap, sizeof(StartupFlagsMap)); startupModeString = FlagsToString(data->StartupMode, StartupModeMap, sizeof(StartupModeMap)); if (startupFlagsString->Length != 0 && startupModeString->Length != 0) { node->FlagsText = PhConcatStrings(3, startupFlagsString->Buffer, L", ", startupModeString->Buffer); PhDereferenceObject(startupFlagsString); PhDereferenceObject(startupModeString); } else if (startupFlagsString->Length != 0) { node->FlagsText = startupFlagsString; PhDereferenceObject(startupModeString); } else if (startupModeString->Length != 0) { node->FlagsText = startupModeString; PhDereferenceObject(startupFlagsString); } if (data->CommandLine[0]) node->PathText = PhCreateString(data->CommandLine); PhAddItemList(context->NodeRootList, node); } break; case AppDomainDCStart_V1: { PAppDomainLoadUnloadRundown_V1 data = EventRecord->UserData; SIZE_T appDomainNameLength; USHORT clrInstanceID; PDNA_NODE parentNode; PDNA_NODE node; appDomainNameLength = PhCountStringZ(data->AppDomainName) * sizeof(WCHAR); clrInstanceID = *(PUSHORT)((PCHAR)data + FIELD_OFFSET(AppDomainLoadUnloadRundown_V1, AppDomainName) + appDomainNameLength + sizeof(WCHAR) + sizeof(ULONG)); // Find the CLR node to add the AppDomain node to. parentNode = FindClrNode(context, clrInstanceID); if (parentNode) { // Check for duplicates. if (FindAppDomainNode(parentNode, data->AppDomainID)) break; node = AddNode(context); node->Type = DNA_TYPE_APPDOMAIN; node->u.AppDomain.AppDomainID = data->AppDomainID; node->u.AppDomain.DisplayName = PhConcatStrings2(L"AppDomain: ", data->AppDomainName); node->StructureText = node->u.AppDomain.DisplayName->sr; node->IdText = PhFormatString(L"%I64u", data->AppDomainID); node->FlagsText = FlagsToString(data->AppDomainFlags, AppDomainFlagsMap, sizeof(AppDomainFlagsMap)); PhAddItemList(parentNode->Children, node); } } break; case AssemblyDCStart_V1: { PAssemblyLoadUnloadRundown_V1 data = EventRecord->UserData; SIZE_T fullyQualifiedAssemblyNameLength; USHORT clrInstanceID; PDNA_NODE parentNode; PDNA_NODE node; PH_STRINGREF remainingPart; fullyQualifiedAssemblyNameLength = PhCountStringZ(data->FullyQualifiedAssemblyName) * sizeof(WCHAR); clrInstanceID = *(PUSHORT)((PCHAR)data + FIELD_OFFSET(AssemblyLoadUnloadRundown_V1, FullyQualifiedAssemblyName) + fullyQualifiedAssemblyNameLength + sizeof(WCHAR)); // Find the AppDomain node to add the Assembly node to. parentNode = FindClrNode(context, clrInstanceID); if (parentNode) parentNode = FindAppDomainNode(parentNode, data->AppDomainID); if (parentNode) { // Check for duplicates. if (FindAssemblyNode(parentNode, data->AssemblyID)) break; node = AddNode(context); node->Type = DNA_TYPE_ASSEMBLY; node->u.Assembly.AssemblyID = data->AssemblyID; node->u.Assembly.FullyQualifiedAssemblyName = PhCreateStringEx(data->FullyQualifiedAssemblyName, fullyQualifiedAssemblyNameLength); // Display only the assembly name, not the whole fully qualified name. if (!PhSplitStringRefAtChar(&node->u.Assembly.FullyQualifiedAssemblyName->sr, ',', &node->StructureText, &remainingPart)) node->StructureText = node->u.Assembly.FullyQualifiedAssemblyName->sr; node->IdText = PhFormatString(L"%I64u", data->AssemblyID); node->FlagsText = FlagsToString(data->AssemblyFlags, AssemblyFlagsMap, sizeof(AssemblyFlagsMap)); PhAddItemList(parentNode->Children, node); } } break; case ModuleDCStart_V1: { PModuleLoadUnloadRundown_V1 data = EventRecord->UserData; PWSTR moduleILPath; SIZE_T moduleILPathLength; PWSTR moduleNativePath; SIZE_T moduleNativePathLength; USHORT clrInstanceID; PDNA_NODE node; moduleILPath = data->ModuleILPath; moduleILPathLength = PhCountStringZ(moduleILPath) * sizeof(WCHAR); moduleNativePath = (PWSTR)((PCHAR)moduleILPath + moduleILPathLength + sizeof(WCHAR)); moduleNativePathLength = PhCountStringZ(moduleNativePath) * sizeof(WCHAR); clrInstanceID = *(PUSHORT)((PCHAR)moduleNativePath + moduleNativePathLength + sizeof(WCHAR)); // Find the Assembly node to set the path on. node = FindClrNode(context, clrInstanceID); if (node) node = FindAssemblyNode2(node, data->AssemblyID); if (node) { PhMoveReference(&node->PathText, PhCreateStringEx(moduleILPath, moduleILPathLength)); if (moduleNativePathLength != 0) PhMoveReference(&node->NativePathText, PhCreateStringEx(moduleNativePath, moduleNativePathLength)); } } break; case DCStartComplete_V1: { if (_InterlockedExchange(&context->TraceHandleActive, 0) == 1) { CloseTrace(context->TraceHandle); } } break; } // .NET 2.0 if (eventDescriptor->Id == 0) { switch (eventDescriptor->Opcode) { case CLR_MODULEDCSTART_OPCODE: { PModuleLoadUnloadRundown_V1 data = EventRecord->UserData; PWSTR moduleILPath; SIZE_T moduleILPathLength; PWSTR moduleNativePath; SIZE_T moduleNativePathLength; PDNA_NODE node; ULONG_PTR indexOfBackslash; ULONG_PTR indexOfLastDot; moduleILPath = data->ModuleILPath; moduleILPathLength = PhCountStringZ(moduleILPath) * sizeof(WCHAR); moduleNativePath = (PWSTR)((PCHAR)moduleILPath + moduleILPathLength + sizeof(WCHAR)); moduleNativePathLength = PhCountStringZ(moduleNativePath) * sizeof(WCHAR); if (context->ClrV2Node && (moduleILPathLength != 0 || moduleNativePathLength != 0)) { node = AddNode(context); node->Type = DNA_TYPE_ASSEMBLY; node->FlagsText = FlagsToString(data->ModuleFlags, ModuleFlagsMap, sizeof(ModuleFlagsMap)); node->PathText = PhCreateStringEx(moduleILPath, moduleILPathLength); if (moduleNativePathLength != 0) node->NativePathText = PhCreateStringEx(moduleNativePath, moduleNativePathLength); // Use the name between the last backslash and the last dot for the structure column text. // (E.g. C:\...\AcmeSoft.BigLib.dll -> AcmeSoft.BigLib) indexOfBackslash = PhFindLastCharInString(node->PathText, 0, '\\'); indexOfLastDot = PhFindLastCharInString(node->PathText, 0, '.'); if (indexOfBackslash != -1) { node->StructureText.Buffer = node->PathText->Buffer + indexOfBackslash + 1; if (indexOfLastDot != -1 && indexOfLastDot > indexOfBackslash) { node->StructureText.Length = (indexOfLastDot - indexOfBackslash - 1) * sizeof(WCHAR); } else { node->StructureText.Length = node->PathText->Length - indexOfBackslash * sizeof(WCHAR) - sizeof(WCHAR); } } else { node->StructureText = node->PathText->sr; } PhAddItemList(context->ClrV2Node->Children, node); } } break; case CLR_METHODDC_DCSTARTCOMPLETE_OPCODE: { if (_InterlockedExchange(&context->TraceHandleActive, 0) == 1) { CloseTrace(context->TraceHandle); } } break; } } } }
/* Runs the host editor. Another big use for this is to open sites * that are in your host list. */ int HostWindow(void) { int c; char cmd[256]; volatile BookmarkPtr toOpen; vsigproc_t si; int maxy, maxx; int lmaxy; si = (sigproc_t) (-1); if (gWinInit) { gHostListWin = NULL; gHostWin = NULL; gHostWin = newwin(LINES, COLS, 0, 0); if (gHostWin == NULL) return (-1); curs_set(0); cbreak(); /* Set the clear flag for the first update. */ wclear(gHostWin); keypad(gHostWin, TRUE); /* For arrow keys. */ #ifdef HAVE_NOTIMEOUT notimeout(gHostWin, TRUE); #endif #ifdef HAVE_SIGSETJMP if (sigsetjmp(gHostWinJmp, 1) == 0) { #else /* HAVE_SIGSETJMP */ if (setjmp(gHostWinJmp) == 0) { #endif /* HAVE_SIGSETJMP */ /* Gracefully cleanup the screen if the user ^C's. */ si = NcSignal(SIGINT, SigIntHostWin); /* Initialize the page start and select a host to be * the current one. */ gHostListWinStart = 0; gHilitedHost = 0; if (gNumBookmarks == 0) gCurHostListItem = NULL; else gCurHostListItem = &gBookmarkTable[gHilitedHost]; /* Initially, we don't want to connect to any site in * the host list. */ toOpen = NULL; getmaxyx(gHostWin, maxy, maxx); WAttr(gHostWin, kBold, 1); WAddCenteredStr(gHostWin, 0, "NcFTP Bookmark Editor"); WAttr(gHostWin, kBold, 0); DrawStrAt(gHostWin, 3, 2, "Open selected site: <enter>"); DrawStrAt(gHostWin, 4, 2, "Edit selected site: /ed"); DrawStrAt(gHostWin, 5, 2, "Delete selected site: /del"); DrawStrAt(gHostWin, 6, 2, "Duplicate selected site: /dup"); DrawStrAt(gHostWin, 7, 2, "Add a new site: /new"); DrawStrAt(gHostWin, 9, 2, "Up one: <u>"); DrawStrAt(gHostWin, 10, 2, "Down one: <d>"); DrawStrAt(gHostWin, 11, 2, "Previous page: <p>"); DrawStrAt(gHostWin, 12, 2, "Next page: <n>"); DrawStrAt(gHostWin, 14, 2, "Capital letters selects first"); DrawStrAt(gHostWin, 15, 2, " site starting with the letter."); DrawStrAt(gHostWin, 17, 2, "Exit the bookmark editor: <x>"); /* Initialize the scrolling host list window. */ if (maxx < 110) { gHostListWinWide = 0; gHostListWin = subwin( gHostWin, LINES - 7, 40, 3, COLS - 40 - 2 ); } else { gHostListWinWide = COLS - 42; gHostListWin = subwin( gHostWin, LINES - 7, gHostListWinWide, 3, 38 ); } if (gHostListWin == NULL) return (-1); lmaxy = getmaxy(gHostListWin); gHostListPageSize = lmaxy; DrawHostList(); wmove(gHostWin, maxy - 1, 0); UpdateHostWindows(1); for (;;) { c = HostWinGetKey(); if (gNeedToClearMsg) { wmove(gHostWin, maxy - 2, 0); wclrtoeol(gHostWin); wrefresh(gHostWin); } if ((c >= 'A') && (c <= 'Z')) { /* isupper can coredump if wgetch returns a meta key. */ HostWinZoomTo(c); } else if (c == '/') { /* Get an "extended" command. Sort of like vi's * :colon commands. */ HostWinGetStr(cmd, sizeof(cmd)); if (ISTREQ(cmd, "ed")) HostWinEdit(); else if (ISTREQ(cmd, "dup")) HostWinDup(); else if (ISTREQ(cmd, "del")) HostWinDelete(); else if (ISTREQ(cmd, "new")) HostWinNew(); else HostWinMsg("Invalid bookmark editor command."); } else switch(c) { case 10: /* ^J == newline */ goto enter; case 13: /* ^M == carriage return */ goto enter; #ifdef KEY_ENTER case KEY_ENTER: Trace(1, " [0x%04X, %s]\n", c, "ENTER"); #endif enter: if (gCurHostListItem == NULL) HostWinMsg("Nothing to open. Try 'open sitename' from the main screen."); else { toOpen = (BookmarkPtr) gCurHostListItem; goto done; } break; case kControl_L: UpdateHostWindows(1); break; case 'u': case 'k': /* vi up key */ case 'h': /* vi left key */ HostListLineUp(); break; #ifdef KEY_UP case KEY_UP: Trace(1, " [0x%04X, %s]\n", c, "UP"); HostListLineUp(); break; #endif #ifdef KEY_LEFT case KEY_LEFT: Trace(1, " [0x%04X, %s]\n", c, "LEFT"); HostListLineUp(); break; #endif case 'd': case 'j': /* vi down key */ case 'l': /* vi right key */ HostListLineDown(); break; #ifdef KEY_DOWN case KEY_DOWN: Trace(1, " [0x%04X, %s]\n", c, "DOWN"); HostListLineDown(); break; #endif #ifdef KEY_RIGHT case KEY_RIGHT: Trace(1, " [0x%04X, %s]\n", c, "RIGHT"); HostListLineDown(); break; #endif case 'p': HostListPageUp(); break; #ifdef KEY_PPAGE case KEY_PPAGE: Trace(1, " [0x%04X, %s]\n", c, "PPAGE"); HostListPageUp(); break; #endif case 'n': HostListPageDown(); break; #ifdef KEY_NPAGE case KEY_NPAGE: Trace(1, " [0x%04X, %s]\n", c, "NPAGE"); HostListPageDown(); break; #endif case 'x': case 'q': goto done; default: HostWinMsg("Invalid key."); Trace(1, " [0x%04X, %s]\n", c, "<invalid>"); break; } } } NcSignal(SIGINT, (FTPSigProc) SIG_IGN); done: if (gHostListWin != NULL) delwin(gHostListWin); if (gHostWin != NULL) delwin(gHostWin); gHostListWin = gHostWin = NULL; if (si != (sigproc_t) (-1)) NcSignal(SIGINT, si); if (toOpen != (BookmarkPtr) 0) { /* If the user selected a site to open, connect to it now. */ if (gStandAlone != 0) { LaunchNcFTP(toOpen->bookmarkName); /*NOTREACHED*/ Exit(0); } else if (gBookmarkSelectionFile != NULL) { WriteSelectedBMToFile(toOpen->bookmarkName); } return (kNoErr); } } return (kNoErr); } /* HostWindow */ main_void_return_t main(int argc, const char **argv) { int result; int argi; gStandAlone = 1; gBookmarkSelectionFile = NULL; InitUserInfo(); if (LoadBookmarkTable() < 0) { exit(7); } if (argc > 1) { /* The following hack is used by NcFTP * to get the number of columns without * having to link with curses/termcap. * This simplifies things since the * system may or may not have a good * curses implementation, and we don't * want to complicate NcFTP itself with * that. */ argi = 1; if (strcmp(argv[1], "--dimensions") == 0) { result = PrintDimensions(0); exit((result == 0) ? 0 : 1); } else if (strcmp(argv[1], "--dimensions-terse") == 0) { result = PrintDimensions(1); exit((result == 0) ? 0 : 1); } else if (strcmp(argv[1], "--debug") == 0) { SetDebug(1); argi++; } /* Requested that we were run from ncftp. */ gStandAlone = 0; if ((argc > argi) && (argv[argi][0] == '/')) gBookmarkSelectionFile = (const char *) argv[argi]; if (gNumBookmarks < 1) exit(7); } result = FTPInitLibrary(&gLib); if (result < 0) { (void) fprintf(stderr, "ncftp: init library error %d (%s).\n", result, FTPStrError(result)); exit(1); } result = FTPInitConnectionInfo(&gLib, &gConn, kDefaultFTPBufSize); if (result < 0) { (void) fprintf(stderr, "ncftp: init connection info error %d (%s).\n", result, FTPStrError(result)); exit(1); } if (gDebug > 0) OpenTrace(); InitPrefs(); LoadFirewallPrefs(0); LoadPrefs(); InitWindows(); Trace(1, "Terminal size is %d columns by %d rows.\n", gScreenWidth, gScreenHeight); HostWindow(); if (gDebug > 0) CloseTrace(); EndWin(); exit(0); } /* main */
static void WINAPI _HandleEvent(_In_ PEVENT_RECORD per) { if (!_s_fIsEnding) { PTRACE_EVENT_INFO ptei = nullptr; // Populate ptei. { DWORD cbEventInfo = 0; DWORD status = TdhGetEventInformation(per, 0, nullptr, nullptr, &cbEventInfo); if (ERROR_INSUFFICIENT_BUFFER == status) { ptei = (TRACE_EVENT_INFO*)malloc(cbEventInfo); if (ptei != nullptr) { status = TdhGetEventInformation(per, 0, nullptr, ptei, &cbEventInfo); if (status != ERROR_SUCCESS) { free(ptei); ptei = nullptr; } } } } // Timestamp { FILETIME ft; ft.dwHighDateTime = per->EventHeader.TimeStamp.HighPart; ft.dwLowDateTime = per->EventHeader.TimeStamp.LowPart; SYSTEMTIME st; FileTimeToSystemTime(&ft, &st); SystemTimeToTzSpecificLocalTime(nullptr, &st, &st); wchar_t wszDate[100]; GetDateFormatEx(LOCALE_NAME_INVARIANT, NULL, &st, L"yyyyy-MM-dd", wszDate, ARRAYSIZE(wszDate), nullptr); wchar_t wszTime[100]; GetTimeFormatEx(LOCALE_NAME_INVARIANT, NULL, &st, L"HH:mm:ss", wszTime, ARRAYSIZE(wszTime)); // yyyy-MM-dd HH:mm:ss:fffffff // Windows refuses to give us milliseconds for free, let alone fractions of milliseconds wprintf(L"%s ", wszDate); wprintf(L"%s", wszTime); wprintf(L".%07u, ", ft.dwLowDateTime % ((1000000000 /*nanoseconds per second*/) / (100 /* nanoseconds per interval */))); } // Thread ID wprintf(L"Thread %lu, ", per->EventHeader.ThreadId); // Provider name or GUID { const wchar_t* providerName = ptei ? TEI_PROVIDER_NAME(ptei) : nullptr; if (providerName != nullptr) { wprintf(L"%s, ", (BYTE*)ptei + ptei->ProviderNameOffset); } else { BSTR bstrGuid; if (SUCCEEDED(StringFromCLSID(per->EventHeader.ProviderId, &bstrGuid))) { wprintf(L"%s, ", bstrGuid); ::CoTaskMemFree(bstrGuid); } } } // Task name or id { const wchar_t* taskName = ptei ? TEI_TASK_NAME(ptei) : nullptr; if (taskName != nullptr) { wprintf(L"%s, ", taskName); } else { // printf converts 8-bit chars to 16-bit ints, in case you don't know wprintf(L"%hu, ", per->EventHeader.EventDescriptor.Task); } } // Event ID // wprintf(L"%hu, ", per->EventHeader.EventDescriptor.Id); // Activity ID //{ // BSTR bstrGuid; // if (SUCCEEDED(StringFromCLSID(per->EventHeader.ActivityId, &bstrGuid))) // { // wprintf(L"%s, ", bstrGuid); // ::CoTaskMemFree(bstrGuid); // } //} // Opcode name or ID { wchar_t* opcodeName = ptei ? TEI_OPCODE_NAME(ptei) : nullptr; if (opcodeName != nullptr) { wprintf(L"%s, ", (BYTE*)ptei + ptei->OpcodeNameOffset); } else { wprintf(L"%hu, ", per->EventHeader.EventDescriptor.Opcode); } } // Payload if (EVENT_HEADER_FLAG_STRING_ONLY == (per->EventHeader.Flags & EVENT_HEADER_FLAG_STRING_ONLY)) { wprintf(L"%s", (LPWSTR)per->UserData); } else { for (USHORT i = 0; i < ptei->TopLevelPropertyCount; i++) { DWORD status = PrintProperties(per, ptei, i, nullptr, 0); if (ERROR_SUCCESS != status) { wprintf(L"Printing top level properties failed."); } wprintf(L", "); } } // endl wprintf(L"\r\n"); // combat stdout buffering _flushall(); if (ptei != nullptr) { free(ptei); ptei = nullptr; } } else { if (!_s_fIsClosed) { CloseTrace(*((TRACEHANDLE*)per->UserContext)); _s_fIsClosed = true; } } }