From 0b1bba36f8ea0f6949f745e35eb64f6468b42db4 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sat, 7 May 2016 14:55:19 -0700 Subject: [PATCH] dll: FspIsInteractive, FspServiceLog, FspServiceLogV --- inc/winfsp/winfsp.h | 3 +++ src/dll/service.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index 75bd629b..b6aab291 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -876,6 +876,9 @@ FSP_API VOID FspServiceRequestTime(FSP_SERVICE *Service, ULONG Time); FSP_API VOID FspServiceSetExitCode(FSP_SERVICE *Service, ULONG ExitCode); FSP_API NTSTATUS FspServiceRun(FSP_SERVICE *Service); FSP_API VOID FspServiceStop(FSP_SERVICE *Service); +FSP_API BOOLEAN FspServiceIsInteractive(VOID); +FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...); +FSP_API VOID FspServiceLogV(ULONG Type, PWSTR Format, va_list ap); /* * Utility diff --git a/src/dll/service.c b/src/dll/service.c index b60bac65..8ff68824 100644 --- a/src/dll/service.c +++ b/src/dll/service.c @@ -432,3 +432,64 @@ static BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType) return TRUE; } } + +FSP_API BOOLEAN FspServiceIsInteractive(VOID) +{ + /* + * Modeled after System.Environment.UserInteractive. + * See http://referencesource.microsoft.com/#mscorlib/system/environment.cs,947ad026e7cb830c + */ + static HWINSTA ProcessWindowStation; + static BOOLEAN IsInteractive; + HWINSTA CurrentWindowStation; + USEROBJECTFLAGS Flags; + + CurrentWindowStation = GetProcessWindowStation(); + if (0 != CurrentWindowStation && ProcessWindowStation != CurrentWindowStation) + { + if (GetUserObjectInformationW(CurrentWindowStation, UOI_FLAGS, &Flags, sizeof Flags, 0)) + IsInteractive = 0 != (Flags.dwFlags & WSF_VISIBLE); + ProcessWindowStation = CurrentWindowStation; + } + return IsInteractive; +} + +FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...) +{ + va_list ap; + + va_start(ap, Format); + FspServiceLogV(Type, Format, ap); + va_end(ap); +} + +FSP_API VOID FspServiceLogV(ULONG Type, PWSTR Format, va_list ap) +{ + if (FspServiceIsInteractive()) + { + WCHAR BufW[1024]; + /* wvsprintfW is only safe with a 1024 WCHAR buffer */ + PSTR BufA; + DWORD Length; + + wvsprintfW(BufW, Format, ap); + BufW[(sizeof BufW / sizeof BufW[0]) - 1] = L'\0'; + + Length = lstrlenW(BufW); + BufA = MemAlloc(Length * 3); + if (0 != BufA) + { + Length = WideCharToMultiByte(CP_UTF8, 0, BufW, Length, BufA, sizeof BufA, 0, 0); + if (0 < Length) + { + if (Length > sizeof BufA - 1) + Length = sizeof BufA - 1; + BufA[Length++] = '\n'; + WriteFile(GetStdHandle(STD_ERROR_HANDLE), BufA, Length, &Length, 0); + } + MemFree(BufA); + } + } + else + FspEventLogV(Type, Format, ap); +}