From 7be71b206433c21c8eeb758a3a8b866f877f64bd Mon Sep 17 00:00:00 2001 From: James Yonan Date: Tue, 27 Oct 2015 20:09:26 -0600 Subject: [PATCH] Added Windows utility classes and methods: Win::Service -- A Windows Service wrapper. Win::LogFile -- a LogBase derivative that allows logging to a natively created and handled file. Win::module_name() -- Get the module name as a std::wstring. Win::module_name_utf8() -- Get the module name as a UTF-8 string. --- openvpn/win/logfile.hpp | 100 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 openvpn/win/logfile.hpp diff --git a/openvpn/win/logfile.hpp b/openvpn/win/logfile.hpp new file mode 100644 index 00000000..9159f186 --- /dev/null +++ b/openvpn/win/logfile.hpp @@ -0,0 +1,100 @@ +// OpenVPN -- An application to securely tunnel IP networks +// over a single port, with support for SSL/TLS-based +// session authentication and key exchange, +// packet encryption, packet authentication, and +// packet compression. +// +// Copyright (C) 2012-2015 OpenVPN Technologies, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License Version 3 +// as published by the Free Software Foundation. +// +// 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program in the COPYING file. +// If not, see . + +#ifndef OPENVPN_WIN_LOGFILE_H +#define OPENVPN_WIN_LOGFILE_H + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace openvpn { + namespace Win { + + class LogFile : public LogBase + { + public: + typedef RCPtr Ptr; + + LogFile(const std::string& fn, + const std::string& sddl_string, + bool append) + : log_handle(create_file(fn, sddl_string, append)), + log_context(this) + { + } + + virtual void log(const std::string& str) override + { + DWORD n_written; + const std::string line = date_time() + ' ' + str; + ::WriteFile(log_handle(), line.c_str(), line.length(), &n_written, NULL); + } + + private: + static ScopedHANDLE create_file(const std::string& fn, + const std::string& sddl_string, + bool append) + { + SecurityAttributes sa(sddl_string, true, "redirect_stdout_stderr"); + const std::wstring wfn = wstring::from_utf8(fn); + ScopedHANDLE file(::CreateFileW( + wfn.c_str(), + GENERIC_WRITE, + FILE_SHARE_READ, + &sa.sa, + append ? OPEN_ALWAYS : CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL)); + if (!file.defined()) + { + const Win::LastError err; + OPENVPN_THROW_EXCEPTION("Win::LogFile: failed to open " << fn << " : " << err.message()); + } + + // append to logfile? + if (append) + { + if (::SetFilePointer(file(), 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) + { + const Win::LastError err; + OPENVPN_THROW_EXCEPTION("Win::LogFile: cannot append to " << fn << " : " << err.message()); + } + } + return file; + } + + ScopedHANDLE log_handle; + Log::Context log_context; // must be initialized last + }; + + } +} + +#endif