[26230] in CVS-changelog-for-Kerberos-V5

home help back first fref pref prev next nref lref last post

svn rev #25570: trunk/src/windows/leash/

daemon@ATHENA.MIT.EDU (tlyu@mit.edu)
Mon Dec 12 15:46:27 2011

Date: Mon, 12 Dec 2011 15:46:24 -0500
From: tlyu@mit.edu
Message-Id: <201112122046.pBCKkODb006113@drugstore.mit.edu>
To: cvs-krb5@mit.edu
Reply-To: krbdev@mit.edu
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: cvs-krb5-bounces@mit.edu

http://src.mit.edu/fisheye/changelog/krb5/?cs=25570
Commit By: tlyu
Log Message:
ticket: 7050
subject: kfw leash: add -console option to create console for debug output

Signed-off-by: Kevin Wasserman <kevin.wasserman@painless-security.com>


Changed Files:
U   trunk/src/windows/leash/Leash.cpp
U   trunk/src/windows/leash/Makefile.in
A   trunk/src/windows/leash/out2con.cpp
A   trunk/src/windows/leash/out2con.h
Modified: trunk/src/windows/leash/Leash.cpp
===================================================================
--- trunk/src/windows/leash/Leash.cpp	2011-12-12 20:46:20 UTC (rev 25569)
+++ trunk/src/windows/leash/Leash.cpp	2011-12-12 20:46:24 UTC (rev 25570)
@@ -26,6 +26,7 @@
 #include "mitwhich.h"
 #include <leasherr.h>
 #include "lglobals.h"
+#include "out2con.h"
 #include <krb5.h>
 #include <com_err.h>
 
@@ -305,6 +306,11 @@
             {
                 autoInit = TRUE;
             }
+            else if (0 == stricmp(optionParam+1, "console") ||
+                     0 == stricmp(optionParam+1, "c"))
+            {
+                CreateConsoleEcho();
+            }
             else
             {
                 MessageBox(hMsg,
@@ -312,6 +318,7 @@
                             "'-renew' or '-r' to perform ticket renewal (and exit)\n"
                             "'-destroy' or '-d' to perform ticket destruction (and exit)\n"
                             "'-autoinit' or '-a' to perform automatic ticket initialization\n"
+                            "'-console' or '-c' to attach a console for debugging\n"
                             "'-ms2mit' or '-import' or '-m' to perform ticket importation (and exit)",
                            "Leash Error", MB_OK);
                 return FALSE;

Modified: trunk/src/windows/leash/Makefile.in
===================================================================
--- trunk/src/windows/leash/Makefile.in	2011-12-12 20:46:20 UTC (rev 25569)
+++ trunk/src/windows/leash/Makefile.in	2011-12-12 20:46:24 UTC (rev 25570)
@@ -45,6 +45,7 @@
 	$(OUTPRE)LeashView.obj \
 	$(OUTPRE)lglobals.obj \
 	$(OUTPRE)MainFrm.obj \
+	$(OUTPRE)out2con.obj \
 	$(OUTPRE)StdAfx.obj \
 	$(OUTPRE)AfsProperties.obj \
 	$(OUTPRE)VSroutines.obj \

Added: trunk/src/windows/leash/out2con.cpp
===================================================================
--- trunk/src/windows/leash/out2con.cpp	                        (rev 0)
+++ trunk/src/windows/leash/out2con.cpp	2011-12-12 20:46:24 UTC (rev 25570)
@@ -0,0 +1,126 @@
+#include "out2con.h"
+
+#include <windows.h>
+#include <stdio.h>
+#include <io.h>
+
+class ConsoleEcho
+{
+public:
+    ConsoleEcho();
+    ~ConsoleEcho();
+
+private:
+    DWORD ThreadLoop();
+
+    static DWORD WINAPI ThreadFunc(void* param);
+
+    FILE m_originalStdout;
+    int m_stdoutfd;
+    int m_pipefd;
+    HANDLE m_hReadPipe, m_hWritePipe;
+    HANDLE m_hThread;
+
+    static const int BUFSIZE=512;
+};
+
+
+ConsoleEcho *
+CreateConsoleEcho()
+{
+    return new ConsoleEcho;
+}
+
+void
+DestroyConsoleEcho(ConsoleEcho *echo)
+{
+    delete echo;
+}
+
+
+DWORD WINAPI ConsoleEcho::ThreadFunc(void* param)
+{
+    return ((ConsoleEcho*)(param))->ThreadLoop();
+}
+
+
+DWORD ConsoleEcho::ThreadLoop()
+{
+    DWORD dwRead, dwWritten;
+    CHAR chBuf[BUFSIZE];
+    BOOL bSuccess = FALSE;
+    // Note that the following does not work when running in the msvc2010
+    // debugger with redirected output; you still get the redirected file
+    // handle, not the console:
+    //HANDLE hConsoleStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
+    // This seems to be more reliable:
+    HANDLE hConsoleStdOut = CreateFile("CONOUT$",
+                                       GENERIC_WRITE,
+                                       FILE_SHARE_WRITE,
+                                       NULL, OPEN_EXISTING, 0, 0);
+    for (;;) {
+        // read from redirected stdout
+        bSuccess = ReadFile(m_hReadPipe, chBuf, BUFSIZE, &dwRead, NULL);
+        if (!bSuccess || (dwRead == 0))
+            break;
+
+        // write to console
+        WriteFile(hConsoleStdOut, chBuf, dwRead, &dwWritten, NULL);
+        // also write to original stdout
+        if (m_stdoutfd>=0) {
+            _write(m_stdoutfd, chBuf, dwRead);
+            // _commit() causes assert if m_stdoutfd is a device (e.g., console or NUL).
+            if (!_isatty(m_stdoutfd))
+                _commit(m_stdoutfd);
+        }
+    }
+    CloseHandle(hConsoleStdOut);
+    return 0;
+}
+
+ConsoleEcho::ConsoleEcho()
+{
+    // setup console
+    AllocConsole();
+    // create pipe
+    CreatePipe(&m_hReadPipe, &m_hWritePipe, NULL, 0);
+    // save original stdout to preserve commandline-specified redirection
+    m_stdoutfd = _fileno(stdout);
+    // and copy the whole damn FILE structure so we can restore it
+    // when we're done.  I don't know any other way to restore the
+    // crazy windows gui default '-2' filedesc stdout.
+    m_originalStdout = *stdout;
+    // hook up the write end of our pipe to stdout
+    m_pipefd = _open_osfhandle((intptr_t)m_hWritePipe, 0);
+    // take our os file handle and allocate a crt FILE for it
+    FILE* fp = _fdopen(m_pipefd, "w");
+    // copy to stdout
+    *stdout = *fp;
+    // now slam the allocated FILE's _flag to zero to mark it as free without
+    // actually closing the os file handle and pipe
+    fp->_flag = 0;
+
+    // disable buffering
+    setvbuf(stdout, NULL, _IONBF, 0);
+
+    // Create a thread to process our pipe, forwarding output
+    // to both the console and the original stdout
+    m_hThread = CreateThread(NULL, 0, &ThreadFunc, this, 0, NULL);
+}
+
+ConsoleEcho::~ConsoleEcho()
+{
+    // fclose() unfortunately immediately invalidates the read pipe before the
+    // pipe thread has a chance to flush it, so don't do that.
+    //fclose(stdout);
+
+    // instead, just slam the original stdout
+    *stdout = m_originalStdout;
+    //printf("Safe to printf now and no longer echoed to console.\n");
+    // Close write pipe
+    _close(m_pipefd);
+    // and wait here for pipe thread to exit
+    WaitForSingleObject(m_hThread, 1000);
+    // now close read pipe as well
+    CloseHandle(m_hReadPipe);
+}

Added: trunk/src/windows/leash/out2con.h
===================================================================
--- trunk/src/windows/leash/out2con.h	                        (rev 0)
+++ trunk/src/windows/leash/out2con.h	2011-12-12 20:46:24 UTC (rev 25570)
@@ -0,0 +1,38 @@
+#ifndef OUT2CON_H
+#define OUT2CON_H
+
+/* Call CreateConsoleEcho() to create a console and begin echoing stdout to it.
+ * The original stream (if any) will still receive output from stdout.
+ * Call DestroyConsoleEcho() to stop echoing stdout to the console.
+ * The original stream continues to receive stdout.
+ *
+ * WARNING: it is not safe to use stdout from another thread during
+ *          CreateConsoleEcho() or DestroyConsoleEcho()
+ */
+
+class ConsoleEcho;
+
+ConsoleEcho *
+CreateConsoleEcho();
+
+void
+DestroyConsoleEcho(ConsoleEcho *consoleEcho);
+
+// Convenience class to automatically echo to console within a scope
+class AutoConsoleEcho
+{
+public:
+    AutoConsoleEcho() : m_echo(CreateConsoleEcho())
+    {
+    }
+
+    ~AutoConsoleEcho()
+    {
+        DestroyConsoleEcho(m_echo);
+    }
+private:
+    ConsoleEcho* m_echo;
+};
+
+
+#endif

_______________________________________________
cvs-krb5 mailing list
cvs-krb5@mit.edu
https://mailman.mit.edu/mailman/listinfo/cvs-krb5

home help back first fref pref prev next nref lref last post