Windows CCAPI snapshot. Should build & pass ping test
authorKevin Koch <kpkoch@mit.edu>
Tue, 22 Jan 2008 19:14:04 +0000 (19:14 +0000)
committerKevin Koch <kpkoch@mit.edu>
Tue, 22 Jan 2008 19:14:04 +0000 (19:14 +0000)
TargetVersion: 1.7
Component: krb5-libs
Ticket: 5594

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20203 dc483132-0cff-0310-8789-dd5450dbe970

51 files changed:
src/ccapi/common/win/OldCC/autolock.hxx [new file with mode: 0644]
src/ccapi/common/win/OldCC/ccutil.cxx [new file with mode: 0644]
src/ccapi/common/win/OldCC/ccutil.def [new file with mode: 0644]
src/ccapi/common/win/OldCC/ccutils.c [new file with mode: 0644]
src/ccapi/common/win/OldCC/ccutils.h [new file with mode: 0644]
src/ccapi/common/win/OldCC/init.cxx [new file with mode: 0644]
src/ccapi/common/win/OldCC/init.hxx [new file with mode: 0644]
src/ccapi/common/win/OldCC/name.h [new file with mode: 0644]
src/ccapi/common/win/OldCC/opts.cxx [new file with mode: 0644]
src/ccapi/common/win/OldCC/opts.hxx [new file with mode: 0644]
src/ccapi/common/win/OldCC/secure.cxx [new file with mode: 0644]
src/ccapi/common/win/OldCC/secure.hxx [new file with mode: 0644]
src/ccapi/common/win/OldCC/util.cxx [new file with mode: 0644]
src/ccapi/common/win/OldCC/util.h [new file with mode: 0644]
src/ccapi/common/win/cci_os_debugging.c [new file with mode: 0644]
src/ccapi/common/win/cci_os_identifier.c [new file with mode: 0644]
src/ccapi/common/win/ccs_reply.Acf [new file with mode: 0644]
src/ccapi/common/win/ccs_reply.Idl [new file with mode: 0644]
src/ccapi/common/win/ccs_request.Acf [new file with mode: 0644]
src/ccapi/common/win/ccs_request.idl [new file with mode: 0644]
src/ccapi/common/win/tls.c [new file with mode: 0644]
src/ccapi/common/win/tls.h [new file with mode: 0644]
src/ccapi/common/win/win-utils.c [new file with mode: 0644]
src/ccapi/common/win/win-utils.h [new file with mode: 0644]
src/ccapi/lib/win/Makefile [new file with mode: 0644]
src/ccapi/lib/win/OldCC/ccapi.h [new file with mode: 0644]
src/ccapi/lib/win/OldCC/client.cxx [new file with mode: 0644]
src/ccapi/lib/win/OldCC/client.h [new file with mode: 0644]
src/ccapi/lib/win/OldCC/rpc.cxx [new file with mode: 0644]
src/ccapi/lib/win/WINCCAPI.sln [new file with mode: 0644]
src/ccapi/lib/win/WINCCAPI.vcproj [new file with mode: 0644]
src/ccapi/lib/win/ccapi.def [new file with mode: 0644]
src/ccapi/lib/win/ccapi_os_ipc.cxx [new file with mode: 0644]
src/ccapi/lib/win/ccs_reply_proc.c [new file with mode: 0644]
src/ccapi/lib/win/dllmain.cxx [new file with mode: 0644]
src/ccapi/lib/win/dllmain.h [new file with mode: 0644]
src/ccapi/server/win/Makefile [new file with mode: 0644]
src/ccapi/server/win/Server.sln [new file with mode: 0644]
src/ccapi/server/win/Server.vcproj [new file with mode: 0644]
src/ccapi/server/win/WorkItem.cpp [new file with mode: 0644]
src/ccapi/server/win/WorkQueue.cpp [new file with mode: 0644]
src/ccapi/server/win/WorkQueue.h [new file with mode: 0644]
src/ccapi/server/win/ccs_os_pipe.c [new file with mode: 0644]
src/ccapi/server/win/ccs_os_server.cpp [new file with mode: 0644]
src/ccapi/server/win/ccs_request_proc.c [new file with mode: 0644]
src/ccapi/server/win/ccs_win_pipe.c [new file with mode: 0644]
src/ccapi/server/win/ccs_win_pipe.h [new file with mode: 0644]
src/ccapi/server/win/workitem.h [new file with mode: 0644]
src/ccapi/test/Makefile.w32 [new file with mode: 0644]
src/ccapi/test/pingtest.c [new file with mode: 0644]
src/ccapi/test/simple_lock_test.c

diff --git a/src/ccapi/common/win/OldCC/autolock.hxx b/src/ccapi/common/win/OldCC/autolock.hxx
new file mode 100644 (file)
index 0000000..9fc7595
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+\r
+   Copyright (C) 1998 Danilo Almeida.  All rights reserved.\r
+\r
+   automatic stack-based locking object\r
+\r
+   This file is part of FIFS (Framework for Implementing File Systems). \r
+\r
+   This software is distributed with NO WARRANTY OF ANY KIND.  No\r
+   author or distributor accepts any responsibility for the\r
+   consequences of using it, or for whether it serves any particular\r
+   purpose or works at all, unless he or she says so in writing.\r
+   Refer to the included modified Alladin Free Public License (the\r
+   "License") for full details.\r
+\r
+   Every copy of this software must include a copy of the License, in\r
+   a plain ASCII text file named COPYING.  The License grants you the\r
+   right to copy, modify and redistribute this software, but only\r
+   under certain conditions described in the License.  Among other\r
+   things, the License requires that the copyright notice and this\r
+   notice be preserved on all copies.\r
+\r
+*/\r
+\r
+#ifndef __AUTOLOCK_HXX__\r
+#define __AUTOLOCK_HXX__\r
+\r
+#include <windows.h>\r
+\r
+class CcOsLock {\r
+    CRITICAL_SECTION cs;\r
+    bool valid;\r
+public:\r
+    CcOsLock()      {InitializeCriticalSection(&cs);   valid = true; }\r
+    ~CcOsLock()     {DeleteCriticalSection(&cs);       valid = false;}\r
+    void lock()     {if (valid) EnterCriticalSection(&cs);}\r
+    void unlock()   {if (valid) LeaveCriticalSection(&cs);}\r
+#if 0\r
+    bool trylock()  {return valid ? (TryEnterCriticalSection(&cs) ? true : false)\r
+                                  : false; }\r
+#endif\r
+};\r
+\r
+class CcAutoLock {\r
+    CcOsLock& m_lock;\r
+public:\r
+    static void Start(CcAutoLock*& a, CcOsLock& lock) { a = new CcAutoLock(lock); };\r
+    static void Stop (CcAutoLock*& a) { delete a; a = 0; };\r
+    CcAutoLock(CcOsLock& lock):m_lock(lock) { m_lock.lock(); }\r
+    ~CcAutoLock() { m_lock.unlock(); }\r
+};\r
+\r
+#endif /* __AUTOLOCK_HXX */\r
diff --git a/src/ccapi/common/win/OldCC/ccutil.cxx b/src/ccapi/common/win/OldCC/ccutil.cxx
new file mode 100644 (file)
index 0000000..e5e5bae
--- /dev/null
@@ -0,0 +1,187 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+#include "init.hxx"\r
+#include "secure.hxx"\r
+\r
+extern "C" {\r
+#include "cci_debugging.h"\r
+    }\r
+\r
+\r
+CcOsLock Init::s_lock;\r
+DWORD Init::s_refcount = 0;\r
+DWORD Init::s_error = ERROR_INVALID_HANDLE;\r
+bool Init::s_init = false;\r
+Init::InitInfo Init::s_info = { 0 };\r
+HINSTANCE Init::s_hRpcDll = 0;\r
+\r
+#define INIT "INIT: "\r
+\r
+static\r
+void\r
+ShowInfo(\r
+    Init::InitInfo& info\r
+    );\r
+\r
+DWORD\r
+Init::Info(\r
+    InitInfo& info\r
+    )\r
+{\r
+    // This funciton will not do automatic initialization.\r
+    CcAutoLock AL(s_lock);\r
+    if (!s_init) {\r
+        memset(&info, 0, sizeof(info));\r
+        return s_error ? s_error : ERROR_INVALID_HANDLE;\r
+    } else {\r
+        info = s_info;\r
+        return 0;\r
+    }\r
+}\r
+\r
+DWORD\r
+Init::Initialize() {\r
+    CcAutoLock AL(s_lock);\r
+    cci_debug_printf("%s s_init:%d", __FUNCTION__, s_init);\r
+    if (s_init) {\r
+        s_refcount++;\r
+        return 0;\r
+        }\r
+    SecureClient s;\r
+    DWORD status = 0;\r
+    OSVERSIONINFO osvi;\r
+    BOOL isSupportedVersion = FALSE;\r
+    memset(&s_info, 0, sizeof(s_info));\r
+    memset(&osvi, 0, sizeof(osvi));\r
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
+\r
+    status = !GetVersionEx(&osvi);       // Returns a boolean.  Invert to 0 is OK.\r
+\r
+    if (!status) {\r
+        switch(osvi.dwPlatformId) {\r
+        case VER_PLATFORM_WIN32_WINDOWS:\r
+            s_info.isNT = FALSE;\r
+            isSupportedVersion = TRUE;\r
+            break;\r
+        case VER_PLATFORM_WIN32_NT:\r
+            s_info.isNT = TRUE;\r
+            isSupportedVersion = TRUE;\r
+            break;\r
+        case VER_PLATFORM_WIN32s:\r
+        default:\r
+            s_info.isNT = FALSE;\r
+            break;\r
+            }\r
+    \r
+        if (!isSupportedVersion) {\r
+            cci_debug_printf("%s Trying to run on an unsupported version of Windows", __FUNCTION__);\r
+            status  = 1;\r
+            }\r
+        }\r
+\r
+    if (!status) {status  = !s_info.isNT;}\r
+\r
+    if (!status) {status = !(s_hRpcDll = LoadLibrary(TEXT("rpcrt4.dll")));}\r
+\r
+    if (!status) {\r
+        s_info.fRpcBindingSetAuthInfoEx = (FP_RpcBindingSetAuthInfoEx)\r
+            GetProcAddress(s_hRpcDll, TEXT(FN_RpcBindingSetAuthInfoEx));\r
+        if (!s_info.fRpcBindingSetAuthInfoEx) {\r
+            cci_debug_printf("  Running on NT but could not find RpcBindinSetAuthInfoEx");\r
+            status = 1;\r
+            }\r
+        }\r
+    \r
+    if (!status) {\r
+        s_info.fRpcServerRegisterIfEx = (FP_RpcServerRegisterIfEx)\r
+            GetProcAddress(s_hRpcDll, TEXT(FN_RpcServerRegisterIfEx));\r
+        if (!s_info.fRpcServerRegisterIfEx) {\r
+            cci_debug_printf("  Running on NT but could not find RpcServerRegisterIfEx");\r
+            status = 1;\r
+            }\r
+        }\r
+\r
+    if (!status) {\r
+        status = SecureClient::Attach();\r
+        if (status) {\r
+            cci_debug_printf("  SecureClient::Attach() failed (%u)", status);\r
+            }\r
+        }\r
+\r
+    if (status) {\r
+        memset(&s_info, 0, sizeof(s_info));\r
+        if (s_hRpcDll) {\r
+            FreeLibrary(s_hRpcDll);\r
+            s_hRpcDll = 0;\r
+        }\r
+        cci_debug_printf("  Init::Attach() failed (%u)", status);\r
+    } else {\r
+        s_refcount++;\r
+        s_init = true;\r
+        ShowInfo(s_info);\r
+    }\r
+    s_error = status;\r
+    return status;\r
+}\r
+\r
+DWORD\r
+Init::Cleanup(\r
+    )\r
+{\r
+    CcAutoLock AL(s_lock);\r
+    s_refcount--;\r
+    if (s_refcount) return 0;\r
+    if (!s_init) return 0;\r
+    DWORD error = 0;\r
+    if (s_hRpcDll) {\r
+        FreeLibrary(s_hRpcDll);\r
+        s_hRpcDll = 0;\r
+    }\r
+    error = SecureClient::Detach();\r
+    memset(&s_info, 0, sizeof(s_info));\r
+    s_init = false;\r
+    s_error = 0;\r
+    if (error) {\r
+        cci_debug_printf("  Init::Detach() had an error (%u)", error);\r
+        }\r
+    return error;\r
+}\r
+\r
+static\r
+void\r
+ShowInfo(\r
+    Init::InitInfo& info\r
+    )\r
+{\r
+    if (info.isNT) {\r
+        cci_debug_printf("  Running on Windows NT using secure mode");\r
+    } else {\r
+        cci_debug_printf("  Running insecurely on non-NT Windows");\r
+    }\r
+    return;\r
+}\r
diff --git a/src/ccapi/common/win/OldCC/ccutil.def b/src/ccapi/common/win/OldCC/ccutil.def
new file mode 100644 (file)
index 0000000..a187c80
--- /dev/null
@@ -0,0 +1,5 @@
+;LIBRARY               COMERR32\r
+HEAPSIZE       8192\r
+\r
+EXPORTS\r
+    
\ No newline at end of file
diff --git a/src/ccapi/common/win/OldCC/ccutils.c b/src/ccapi/common/win/OldCC/ccutils.c
new file mode 100644 (file)
index 0000000..1db00b4
--- /dev/null
@@ -0,0 +1,136 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+\r
+#include "cci_debugging.h"\r
+#include "util.h"\r
+\r
+BOOL isNT() {\r
+    OSVERSIONINFO osvi;\r
+    DWORD   status              = 0;\r
+    BOOL    bSupportedVersion   = FALSE;\r
+    BOOL    bIsNT               = FALSE;\r
+\r
+    memset(&osvi, 0, sizeof(osvi));\r
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
+\r
+    status = !GetVersionEx(&osvi);       // Returns a boolean.  Invert to 0 is OK.\r
+\r
+    if (!status) {\r
+        switch(osvi.dwPlatformId) {\r
+        case VER_PLATFORM_WIN32_WINDOWS:\r
+            bIsNT = FALSE;\r
+            bSupportedVersion = TRUE;\r
+            break;\r
+        case VER_PLATFORM_WIN32_NT:\r
+            bIsNT = TRUE;\r
+            bSupportedVersion = TRUE;\r
+            break;\r
+        case VER_PLATFORM_WIN32s:\r
+        default:\r
+            bIsNT = FALSE;\r
+            break;\r
+            }\r
+    \r
+        if (!bSupportedVersion) {\r
+            cci_debug_printf("%s Running on an unsupported version of Windows", __FUNCTION__);\r
+            status  = 1;\r
+            }\r
+        }\r
+\r
+    return (!status && bIsNT && bSupportedVersion);\r
+    }\r
+\r
+char*   allocEventName(char* uuid_string, char* suffix) {\r
+    LPSTR       event_name      = NULL;\r
+    cc_int32    err             = ccNoError;\r
+\r
+    event_name = malloc(strlen(uuid_string) + strlen(suffix) + 3);\r
+    if (!event_name) err = cci_check_error(ccErrNoMem);\r
+\r
+    if (!err) {\r
+        strcpy(event_name, uuid_string);\r
+        strcat(event_name, "_");\r
+        strcat(event_name, suffix);\r
+        }\r
+\r
+    return event_name;\r
+    }\r
+\r
+HANDLE createThreadEvent(char* uuid, char* suffix) {\r
+    LPSTR                   event_name  = NULL;\r
+    HANDLE                  hEvent      = NULL;\r
+    PSECURITY_ATTRIBUTES    psa         = 0;        // Everything having to do with\r
+    SECURITY_ATTRIBUTES     sa          = { 0 };    // sa, psa, security is copied\r
+    DWORD                   status      = 0;        // from the previous implementation.\r
+\r
+    psa = isNT() ? &sa : 0;\r
+\r
+    if (isNT()) {\r
+        sa.nLength = sizeof(sa);\r
+        status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor);\r
+        cci_check_error(status);\r
+        }\r
+\r
+    if (!status) {\r
+        event_name = allocEventName(uuid, suffix);\r
+        if (!event_name) status = cci_check_error(ccErrNoMem);\r
+        }\r
+    cci_debug_printf("%s event_name:%s", __FUNCTION__, event_name);\r
+    \r
+    if (!status) {\r
+        hEvent = CreateEvent(psa, FALSE, FALSE, event_name);\r
+        if (!hEvent)     status = cci_check_error(GetLastError());\r
+        }\r
+\r
+    if (!status) ResetEvent(hEvent);\r
+\r
+    \r
+    if (event_name) free(event_name);\r
+    if (isNT())     free(sa.lpSecurityDescriptor);\r
+\r
+    return hEvent;\r
+    }\r
+\r
+HANDLE openThreadEvent(char* uuid, char* suffix) {\r
+    LPSTR   event_name  = NULL;\r
+    HANDLE  hEvent      = NULL;\r
+    DWORD   status      = 0;\r
+\r
+    event_name = allocEventName(uuid, suffix);\r
+    if (!event_name) status = cci_check_error(ccErrNoMem);\r
+    cci_debug_printf("%s event_name:%s", __FUNCTION__, event_name);\r
+\r
+    if (!status) {\r
+        hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name);\r
+        if (!hEvent) status = cci_check_error(GetLastError());\r
+        }\r
+\r
+    if (event_name) free(event_name);\r
+\r
+    return hEvent;\r
+    }
\ No newline at end of file
diff --git a/src/ccapi/common/win/OldCC/ccutils.h b/src/ccapi/common/win/OldCC/ccutils.h
new file mode 100644 (file)
index 0000000..77cafb1
--- /dev/null
@@ -0,0 +1,49 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef __CCUTILS_H__\r
+#define __CCUTILS_H__\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+#if 0\r
+}\r
+#endif\r
+\r
+#define REPLY_SUFFIX    (char*)"reply"\r
+#define LISTEN_SUFFIX   (char*)"listen"\r
+\r
+BOOL    isNT();\r
+char*   allocEventName   (char* uuid, char* suffix);\r
+HANDLE  createThreadEvent(char* uuid, char* suffix);\r
+HANDLE  openThreadEvent  (char* uuid, char* suffix);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* __CCUTILS_H__ */\r
diff --git a/src/ccapi/common/win/OldCC/init.cxx b/src/ccapi/common/win/OldCC/init.cxx
new file mode 100644 (file)
index 0000000..af93722
--- /dev/null
@@ -0,0 +1,187 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+#include "init.hxx"\r
+#include "secure.hxx"\r
+\r
+extern "C" {\r
+#include "cci_debugging.h"\r
+    }\r
+\r
+\r
+CcOsLock Init::s_lock;\r
+DWORD Init::s_refcount = 0;\r
+DWORD Init::s_error = ERROR_INVALID_HANDLE;\r
+bool Init::s_init = false;\r
+Init::InitInfo Init::s_info = { 0 };\r
+HINSTANCE Init::s_hRpcDll = 0;\r
+\r
+#define INIT "INIT: "\r
+\r
+static\r
+void\r
+ShowInfo(\r
+    Init::InitInfo& info\r
+    );\r
+\r
+DWORD\r
+Init::Info(\r
+    InitInfo& info\r
+    )\r
+{\r
+    // This funciton will not do automatic initialization.\r
+    CcAutoLock AL(s_lock);\r
+    if (!s_init) {\r
+        memset(&info, 0, sizeof(info));\r
+        return s_error ? s_error : ERROR_INVALID_HANDLE;\r
+    } else {\r
+        info = s_info;\r
+        return 0;\r
+    }\r
+}\r
+\r
+DWORD\r
+Init::Initialize() {\r
+    CcAutoLock AL(s_lock);\r
+//    cci_debug_printf("%s s_init:%d", __FUNCTION__, s_init);\r
+    if (s_init) {\r
+        s_refcount++;\r
+        return 0;\r
+        }\r
+    SecureClient s;\r
+    DWORD status = 0;\r
+    OSVERSIONINFO osvi;\r
+    BOOL isSupportedVersion = FALSE;\r
+    memset(&s_info, 0, sizeof(s_info));\r
+    memset(&osvi, 0, sizeof(osvi));\r
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
+\r
+    status = !GetVersionEx(&osvi);       // Returns a boolean.  Invert to 0 is OK.\r
+\r
+    if (!status) {\r
+        switch(osvi.dwPlatformId) {\r
+        case VER_PLATFORM_WIN32_WINDOWS:\r
+            s_info.isNT = FALSE;\r
+            isSupportedVersion = TRUE;\r
+            break;\r
+        case VER_PLATFORM_WIN32_NT:\r
+            s_info.isNT = TRUE;\r
+            isSupportedVersion = TRUE;\r
+            break;\r
+        case VER_PLATFORM_WIN32s:\r
+        default:\r
+            s_info.isNT = FALSE;\r
+            break;\r
+            }\r
+    \r
+        if (!isSupportedVersion) {\r
+            cci_debug_printf("%s Trying to run on an unsupported version of Windows", __FUNCTION__);\r
+            status  = 1;\r
+            }\r
+        }\r
+\r
+    if (!status) {status  = !s_info.isNT;}\r
+\r
+    if (!status) {status = !(s_hRpcDll = LoadLibrary(TEXT("rpcrt4.dll")));}\r
+\r
+    if (!status) {\r
+        s_info.fRpcBindingSetAuthInfoEx = (FP_RpcBindingSetAuthInfoEx)\r
+            GetProcAddress(s_hRpcDll, TEXT(FN_RpcBindingSetAuthInfoEx));\r
+        if (!s_info.fRpcBindingSetAuthInfoEx) {\r
+            cci_debug_printf("  Running on NT but could not find RpcBindinSetAuthInfoEx");\r
+            status = 1;\r
+            }\r
+        }\r
+    \r
+    if (!status) {\r
+        s_info.fRpcServerRegisterIfEx = (FP_RpcServerRegisterIfEx)\r
+            GetProcAddress(s_hRpcDll, TEXT(FN_RpcServerRegisterIfEx));\r
+        if (!s_info.fRpcServerRegisterIfEx) {\r
+            cci_debug_printf("  Running on NT but could not find RpcServerRegisterIfEx");\r
+            status = 1;\r
+            }\r
+        }\r
+\r
+    if (!status) {\r
+        status = SecureClient::Attach();\r
+        if (status) {\r
+            cci_debug_printf("  SecureClient::Attach() failed (%u)", status);\r
+            }\r
+        }\r
+\r
+    if (status) {\r
+        memset(&s_info, 0, sizeof(s_info));\r
+        if (s_hRpcDll) {\r
+            FreeLibrary(s_hRpcDll);\r
+            s_hRpcDll = 0;\r
+        }\r
+        cci_debug_printf("  Init::Attach() failed (%u)", status);\r
+    } else {\r
+        s_refcount++;\r
+        s_init = true;\r
+        ShowInfo(s_info);\r
+    }\r
+    s_error = status;\r
+    return status;\r
+}\r
+\r
+DWORD\r
+Init::Cleanup(\r
+    )\r
+{\r
+    CcAutoLock AL(s_lock);\r
+    s_refcount--;\r
+    if (s_refcount) return 0;\r
+    if (!s_init) return 0;\r
+    DWORD error = 0;\r
+    if (s_hRpcDll) {\r
+        FreeLibrary(s_hRpcDll);\r
+        s_hRpcDll = 0;\r
+    }\r
+    error = SecureClient::Detach();\r
+    memset(&s_info, 0, sizeof(s_info));\r
+    s_init = false;\r
+    s_error = 0;\r
+    if (error) {\r
+        cci_debug_printf("  Init::Detach() had an error (%u)", error);\r
+        }\r
+    return error;\r
+}\r
+\r
+static\r
+void\r
+ShowInfo(\r
+    Init::InitInfo& info\r
+    )\r
+{\r
+    if (info.isNT) {\r
+        cci_debug_printf("  Running on Windows NT using secure mode");\r
+    } else {\r
+        cci_debug_printf("  Running insecurely on non-NT Windows");\r
+    }\r
+    return;\r
+}\r
diff --git a/src/ccapi/common/win/OldCC/init.hxx b/src/ccapi/common/win/OldCC/init.hxx
new file mode 100644 (file)
index 0000000..f50db77
--- /dev/null
@@ -0,0 +1,102 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#pragma once\r
+#include "autolock.hxx"\r
+#include <rpc.h>\r
+\r
+typedef RPC_STATUS (RPC_ENTRY *FP_RpcBindingSetAuthInfoExA)(\r
+    IN RPC_BINDING_HANDLE Binding,\r
+    IN unsigned char __RPC_FAR * ServerPrincName,\r
+    IN unsigned long AuthnLevel,\r
+    IN unsigned long AuthnSvc,\r
+    IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL\r
+    IN unsigned long AuthzSvc,\r
+    IN RPC_SECURITY_QOS *SecurityQos OPTIONAL\r
+    );\r
+\r
+typedef RPC_STATUS (RPC_ENTRY *FP_RpcBindingSetAuthInfoExW)(\r
+    IN RPC_BINDING_HANDLE Binding,\r
+    IN unsigned short __RPC_FAR * ServerPrincName,\r
+    IN unsigned long AuthnLevel,\r
+    IN unsigned long AuthnSvc,\r
+    IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL\r
+    IN unsigned long AuthzSvc, OPTIONAL\r
+    IN RPC_SECURITY_QOS *SecurityQOS\r
+    );\r
+\r
+typedef RPC_STATUS (RPC_ENTRY *FP_RpcServerRegisterIfEx)(\r
+    IN RPC_IF_HANDLE IfSpec,\r
+    IN UUID __RPC_FAR * MgrTypeUuid,\r
+    IN RPC_MGR_EPV __RPC_FAR * MgrEpv,\r
+    IN unsigned int Flags,\r
+    IN unsigned int MaxCalls,\r
+    IN RPC_IF_CALLBACK_FN __RPC_FAR *IfCallback\r
+    );\r
+\r
+#ifdef UNICODE\r
+#define FP_RpcBindingSetAuthInfoEx FP_RpcBindingSetAuthInfoExW\r
+#define FN_RpcBindingSetAuthInfoEx "RpcBindingSetAuthInfoExW"\r
+#else\r
+#define FP_RpcBindingSetAuthInfoEx FP_RpcBindingSetAuthInfoExA\r
+#define FN_RpcBindingSetAuthInfoEx "RpcBindingSetAuthInfoExA"\r
+#endif\r
+\r
+#define FN_RpcServerRegisterIfEx   "RpcServerRegisterIfEx"\r
+\r
+class Init\r
+{\r
+public:\r
+    struct InitInfo {\r
+        BOOL isNT;\r
+        FP_RpcBindingSetAuthInfoEx fRpcBindingSetAuthInfoEx;\r
+        FP_RpcServerRegisterIfEx fRpcServerRegisterIfEx;\r
+    };\r
+\r
+    static DWORD Initialize();\r
+    static DWORD Cleanup();\r
+    static DWORD Info(InitInfo& info);\r
+\r
+    static bool Initialized() { return s_init; }\r
+\r
+private:\r
+    static CcOsLock s_lock;\r
+    static DWORD s_refcount;\r
+    static DWORD s_error;\r
+    static bool s_init;\r
+    static InitInfo s_info;\r
+    static HINSTANCE s_hRpcDll;\r
+};\r
+\r
+#define INIT_INIT_EX(trap, error) \\r
+do \\r
+{ \\r
+    if (!Init::Initialized()) \\r
+    { \\r
+        DWORD rc = Init::Initialize(); \\r
+        if (rc) return (trap) ? (error) : rc; \\r
+    } \\r
+} while(0)\r
diff --git a/src/ccapi/common/win/OldCC/name.h b/src/ccapi/common/win/OldCC/name.h
new file mode 100644 (file)
index 0000000..e0172d6
--- /dev/null
@@ -0,0 +1,38 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#pragma once\r
+\r
+#ifdef _WIN64\r
+#define CCAPI_MODULE "krbcc64"\r
+#else\r
+#define CCAPI_MODULE "krbcc32"\r
+#endif\r
+#define CCAPI_DLL CCAPI_MODULE ".dll"\r
+#define CCAPI_EXE CCAPI_MODULE "s.exe"\r
+\r
+#define CCAPI_DLL   "ccapi.dll"\r
+#define CCAPI_EXE   "ccapiserver.exe"
\ No newline at end of file
diff --git a/src/ccapi/common/win/OldCC/opts.cxx b/src/ccapi/common/win/OldCC/opts.cxx
new file mode 100644 (file)
index 0000000..c6a40d6
--- /dev/null
@@ -0,0 +1,188 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <opts.hxx>\r
+\r
+#if 0\r
+const struct Opts*\r
+GetOpts(\r
+    )\r
+{\r
+    bool done = false;\r
+    struct Opts* o;\r
+    if (!(o = new Opts))\r
+        goto cleanup;\r
+    if (!(o->pszString = new char[lstrlenA(opts.pszString) + 1]))\r
+        goto cleanup;\r
+    if (!(o->pszEndpoint = new char[lstrlenA(opts.pszEndpoint) + 1]))\r
+        goto cleanup;\r
+    strcpy(o->pszString, opts.pszString);\r
+    strcpy(o->pszEndpoint, opts.pszEndpoint);\r
+    done = true;\r
+ cleanup:\r
+    if (!done) {\r
+        FreeOpts(o);\r
+        o = 0;\r
+    }\r
+    return o;\r
+}\r
+\r
+void\r
+FreeOpts(\r
+    struct Opts* o\r
+    )\r
+{\r
+    if (o) {\r
+        if (o->pszString)\r
+            delete [] o->pszString;\r
+        if (o->pszEndpoint)\r
+            delete [] o->pszEndpoint;\r
+        delete o;\r
+    }\r
+}\r
+#endif\r
+\r
+bool\r
+ParseOpts::IsValidOpt(\r
+    char ch\r
+    )\r
+{\r
+    return (m_ValidOpts[ch % 256] != 0);\r
+}\r
+\r
+void\r
+ParseOpts::PrintOpt(\r
+    char ch,\r
+    char* text\r
+    )\r
+{\r
+    if (IsValidOpt(ch))\r
+        fprintf(stderr, "  -%c %s\n", ch, text);\r
+}\r
+\r
+void\r
+ParseOpts::UsageOpts(\r
+    char * program,\r
+    int code\r
+    )\r
+{\r
+    fprintf(stderr, "Usage: %s [options]\n", program);\r
+    PrintOpt('k', "stop server");\r
+#ifdef CCAPI_TEST_OPTIONS\r
+    PrintOpt('s', "string");\r
+    PrintOpt('e', "endpoint");\r
+    PrintOpt('m', "maxcalls");\r
+    PrintOpt('n', "mincalls");\r
+    PrintOpt('f', "flag_wait_op");\r
+    PrintOpt('u', "unprotected");\r
+    PrintOpt('b', "use security callback");\r
+#endif\r
+    PrintOpt('c', "output debug info to console");\r
+    exit(code);\r
+}\r
+\r
+void\r
+ParseOpts::SetValidOpts(\r
+    char* valid_opts\r
+    )\r
+{\r
+    memset(m_ValidOpts, 0, sizeof(m_ValidOpts));\r
+    char *p = valid_opts;\r
+    for (p = valid_opts; *p; p++) {\r
+        m_ValidOpts[*p % sizeof(m_ValidOpts)] = 1;\r
+    }\r
+}\r
+\r
+void\r
+ParseOpts::Parse(\r
+    Opts& opts,\r
+    int argc,\r
+    char **argv\r
+    )\r
+{\r
+    int i;\r
+    for (i = 1; i < argc; i++) {\r
+        if ((*argv[i] == '-') || (*argv[i] == '/')) {\r
+            char ch = tolower(*(argv[i]+1));\r
+            if (!IsValidOpt(ch))\r
+                UsageOpts(argv[0]);\r
+            switch (ch) {\r
+            case 'k':\r
+                opts.bShutdown = TRUE;\r
+                break;\r
+#ifdef CCAPI_TEST_OPTIONS\r
+            case 's':\r
+                opts.pszString = argv[++i];\r
+                break;\r
+            case 'e':\r
+                opts.pszEndpoint = argv[++i];\r
+                break;\r
+            case 'm':\r
+                opts.cMaxCalls = (unsigned int) atoi(argv[++i]);\r
+                break;\r
+            case 'n':\r
+                opts.cMinCalls = (unsigned int) atoi(argv[++i]);\r
+                break;\r
+            case 'f':\r
+                opts.fDontWait = (unsigned int) atoi(argv[++i]);\r
+                break;\r
+            case 'u':\r
+                opts.bDontProtect = TRUE;\r
+                break;\r
+            case 'b':\r
+                opts.bSecCallback = TRUE;\r
+                break;\r
+#endif\r
+            case 'c':\r
+                opts.bConsole = TRUE;\r
+                break;\r
+            case 'h':\r
+            case '?':\r
+            default:\r
+                UsageOpts(argv[0]);\r
+            }\r
+        }\r
+        else\r
+            UsageOpts(argv[0]);\r
+    }\r
+\r
+}\r
+\r
+ParseOpts::ParseOpts(char* valid_opts)\r
+{\r
+    SetValidOpts(valid_opts);\r
+}\r
+\r
+ParseOpts::ParseOpts()\r
+{\r
+}\r
+\r
+ParseOpts::~ParseOpts()\r
+{\r
+}\r
diff --git a/src/ccapi/common/win/OldCC/opts.hxx b/src/ccapi/common/win/OldCC/opts.hxx
new file mode 100644 (file)
index 0000000..1732ceb
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#pragma once\r
+\r
+class ParseOpts\r
+{\r
+public:\r
+    struct Opts {\r
+        char* pszString;\r
+        char* pszEndpoint;\r
+        unsigned int cMinCalls;\r
+        unsigned int cMaxCalls;\r
+        unsigned int fDontWait;\r
+        bool bDontProtect;\r
+        bool bShutdown;\r
+        bool bSecCallback;\r
+        bool bConsole;\r
+    };\r
+\r
+    ParseOpts(char* valid_opts);\r
+    ParseOpts();\r
+    ~ParseOpts();\r
+    void SetValidOpts(char* valid_opts);\r
+    void Parse(Opts& opts, int argc, char **argv);\r
+\r
+private:\r
+    bool IsValidOpt(char ch);\r
+    void PrintOpt(char ch, char* text);\r
+    void UsageOpts(char* program, int code = 0);\r
+\r
+    char m_ValidOpts[256];\r
+};\r
diff --git a/src/ccapi/common/win/OldCC/secure.cxx b/src/ccapi/common/win/OldCC/secure.cxx
new file mode 100644 (file)
index 0000000..a32235f
--- /dev/null
@@ -0,0 +1,161 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+#include "secure.hxx"\r
+\r
+extern "C" {\r
+#include "cci_debugging.h"\r
+    }\r
+\r
+CcOsLock SecureClient::s_lock;\r
+DWORD SecureClient::s_refcount = 0;\r
+DWORD SecureClient::s_error = 0;\r
+HANDLE SecureClient::s_hToken = 0;\r
+\r
+#include "util.h"\r
+\r
+#define SC "SecureClient::"\r
+\r
+DWORD\r
+SecureClient::Attach(\r
+    )\r
+{\r
+    CcAutoLock AL(s_lock);\r
+    if (s_hToken) {\r
+        s_refcount++;\r
+        return 0;\r
+    }\r
+    if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, \r
+                         &s_hToken)) {\r
+        s_refcount++;\r
+        s_error = 0;\r
+    } else {\r
+        s_hToken = 0;\r
+        s_error = GetLastError();\r
+    }\r
+    return s_error;\r
+}\r
+\r
+DWORD\r
+SecureClient::Detach(\r
+    )\r
+{\r
+    CcAutoLock AL(s_lock);\r
+    s_refcount--;\r
+    if (s_refcount) return 0;\r
+    if (!s_hToken) return 0;\r
+    DWORD error = 0;\r
+    if (!CloseHandle(s_hToken))\r
+        error = GetLastError();\r
+    s_hToken = 0;\r
+    s_error = 0;\r
+    return error;\r
+}\r
+\r
+DWORD SecureClient::Token(HANDLE& hToken) {\r
+    // This function will not do automatic initialization.\r
+    CcAutoLock AL(s_lock);\r
+    hToken = 0;\r
+    if (!s_hToken) {\r
+        cci_debug_printf("%s no process token initialized (%u)", __FUNCTION__, s_error);\r
+        return s_error ? s_error : ERROR_INVALID_HANDLE;\r
+        } \r
+    else {\r
+        DWORD status = 0;\r
+        if (!DuplicateHandle(GetCurrentProcess(), s_hToken, \r
+                             GetCurrentProcess(), &hToken, 0, FALSE, \r
+                             DUPLICATE_SAME_ACCESS)) {\r
+            status = GetLastError();\r
+            cci_debug_printf("  Could not duplicate handle (%u)", status);\r
+            }\r
+        return status;\r
+        }\r
+    }\r
+\r
+void\r
+SecureClient::Start(SecureClient*& s) {\r
+    s = new SecureClient;\r
+}\r
+\r
+void\r
+SecureClient::Stop(SecureClient*& s) {\r
+    delete s;\r
+    s = 0;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+\r
+/* This constructor turns off impersonation.\r
+ * It is OK for OpenThreadToken to return an error -- that just means impersonation\r
+ * is off.\r
+ */\r
+SecureClient::SecureClient():\r
+    m_Error(0),\r
+    m_hToken(0),\r
+    m_NeedRestore(false) {\r
+\r
+    HANDLE hThread = GetCurrentThread();\r
+    HANDLE hThDuplicate;\r
+    \r
+    int status  = DuplicateHandle(  GetCurrentProcess(),\r
+                                    hThread,\r
+                                    GetCurrentProcess(),\r
+                                    &hThDuplicate,\r
+                                    TOKEN_ALL_ACCESS,\r
+                                    FALSE,\r
+                                    0);\r
+    if (!status) return;\r
+\r
+    if (!OpenThreadToken(hThDuplicate, TOKEN_ALL_ACCESS, FALSE, &m_hToken)) {\r
+        m_Error = GetLastError();\r
+        return;\r
+        }\r
+    if (SetThreadToken(&hThDuplicate, NULL)) {\r
+        m_NeedRestore = true;\r
+    } else {\r
+        m_Error = GetLastError();\r
+        }\r
+    CloseHandle(hThDuplicate);\r
+    }\r
+\r
+SecureClient::~SecureClient() {\r
+    if (m_NeedRestore) {\r
+        HANDLE hThread = GetCurrentThread();\r
+        if (!SetThreadToken(&hThread, m_hToken)) {\r
+            m_Error = cci_check_error(GetLastError());\r
+            }\r
+        }\r
+    if (m_hToken) {\r
+        if (!CloseHandle(m_hToken)) {\r
+            m_Error = cci_check_error(GetLastError());\r
+            }\r
+        }\r
+    }\r
+\r
+DWORD SecureClient::Error() {\r
+    return m_Error;\r
+    }
\ No newline at end of file
diff --git a/src/ccapi/common/win/OldCC/secure.hxx b/src/ccapi/common/win/OldCC/secure.hxx
new file mode 100644 (file)
index 0000000..009e36c
--- /dev/null
@@ -0,0 +1,60 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#pragma once\r
+\r
+#include <windows.h>\r
+#include "autolock.hxx"\r
+\r
+class SecureClient\r
+{\r
+public:\r
+    static DWORD Attach();\r
+    static DWORD Detach();\r
+    static DWORD Token(HANDLE& hToken);\r
+    static void Start(SecureClient*& s);\r
+    static void Stop(SecureClient*& s);\r
+\r
+#if 0\r
+    static DWORD CheckImpersonation();\r
+    static bool IsImp();\r
+    static DWORD DuplicateImpAsPrimary(HANDLE& hPrimary);\r
+#endif\r
+\r
+    SecureClient();\r
+    ~SecureClient();\r
+    DWORD Error();\r
+\r
+private:\r
+    static CcOsLock s_lock;\r
+    static DWORD s_refcount;\r
+    static DWORD s_error;\r
+    static HANDLE s_hToken;\r
+\r
+    DWORD m_Error;\r
+    HANDLE m_hToken;\r
+    bool m_NeedRestore;\r
+};\r
diff --git a/src/ccapi/common/win/OldCC/util.cxx b/src/ccapi/common/win/OldCC/util.cxx
new file mode 100644 (file)
index 0000000..62b204b
--- /dev/null
@@ -0,0 +1,519 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+#include <stdio.h>  // for _snprintf\r
+\r
+#include "util.h"\r
+#include "secure.hxx"\r
+\r
+extern "C" {\r
+#include "cci_debugging.h"\r
+#include "ccutils.h"\r
+    }\r
+\r
+\r
+\r
+void* malloc_alloc_p(size_t size) {\r
+    return malloc(size);\r
+    }\r
+\r
+void free_alloc_p(void *pptr) {\r
+    void **real_pptr = (void**)pptr;\r
+    if (*real_pptr) {\r
+        free(*real_pptr);\r
+        *real_pptr = 0;\r
+        }\r
+    }\r
+\r
+extern "C" DWORD alloc_textual_sid(\r
+    PSID pSid,          // binary Sid\r
+    LPSTR *pTextualSid  // buffer for Textual representaion of Sid\r
+    ) {\r
+    PSID_IDENTIFIER_AUTHORITY psia;\r
+    DWORD dwSubAuthorities;\r
+    DWORD dwSidRev = SID_REVISION;\r
+    DWORD dwCounter;\r
+    DWORD dwSidSize;\r
+\r
+    *pTextualSid = 0;\r
+\r
+    //\r
+    // test if Sid passed in is valid\r
+    //\r
+    if(!IsValidSid(pSid)) return ERROR_INVALID_PARAMETER;\r
+\r
+    // obtain SidIdentifierAuthority\r
+    psia = GetSidIdentifierAuthority(pSid);\r
\r
+    // obtain sidsubauthority count\r
+    dwSubAuthorities =* GetSidSubAuthorityCount(pSid);\r
\r
+    //\r
+    // compute buffer length\r
+    // S-SID_REVISION- + identifierauthority- + subauthorities- + NULL\r
+    //\r
+    dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);\r
+    *pTextualSid = (LPSTR)malloc_alloc_p(dwSidSize);\r
+    if (!*pTextualSid)\r
+        return GetLastError();\r
+\r
+    LPSTR TextualSid = *pTextualSid;\r
+\r
+    //\r
+    // prepare S-SID_REVISION-\r
+    //\r
+    wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev );\r
\r
+    //\r
+    // prepare SidIdentifierAuthority\r
+    //\r
+    if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )\r
+    {\r
+        wsprintf(TextualSid + lstrlen(TextualSid),\r
+                 TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),\r
+                 (USHORT)psia->Value[0],\r
+                 (USHORT)psia->Value[1],\r
+                 (USHORT)psia->Value[2],\r
+                 (USHORT)psia->Value[3],\r
+                 (USHORT)psia->Value[4],\r
+                 (USHORT)psia->Value[5]);\r
+    }\r
+    else\r
+    {\r
+        wsprintf(TextualSid + lstrlen(TextualSid), TEXT("%lu"),\r
+                 (ULONG)(psia->Value[5]      )   +\r
+                 (ULONG)(psia->Value[4] <<  8)   +\r
+                 (ULONG)(psia->Value[3] << 16)   +\r
+                 (ULONG)(psia->Value[2] << 24)   );\r
+    }\r
\r
+    //\r
+    // loop through SidSubAuthorities\r
+    //\r
+    for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)\r
+    {\r
+        wsprintf(TextualSid + lstrlen(TextualSid), TEXT("-%lu"),\r
+                 *GetSidSubAuthority(pSid, dwCounter) );\r
+    }\r
+    return 0;\r
+}\r
+\r
+DWORD alloc_token_user(HANDLE hToken, PTOKEN_USER *pptu) {\r
+    DWORD status = 0;\r
+    DWORD size = 0;\r
+    *pptu = 0;\r
+\r
+    GetTokenInformation(hToken, TokenUser, *pptu, 0, &size);\r
+    if (size == 0) status = GetLastError();\r
+\r
+    if (!status) {\r
+        if (!(*pptu = (PTOKEN_USER)malloc_alloc_p(size)))\r
+            status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!GetTokenInformation(hToken, TokenUser, *pptu, size, &size))\r
+            status = GetLastError();\r
+        }\r
+\r
+    if (status && *pptu) {\r
+        free_alloc_p(pptu);\r
+        }\r
+    return status;\r
+    }\r
+\r
+DWORD\r
+alloc_username(\r
+    PSID Sid,\r
+    LPSTR* pname,\r
+    LPSTR* pdomain = 0\r
+    )\r
+{\r
+    DWORD status = 0;\r
+    DWORD name_len = 0;\r
+    DWORD domain_len = 0;\r
+    SID_NAME_USE snu;\r
+    LPSTR name = 0;\r
+    LPSTR domain = 0;\r
+\r
+    *pname = 0;\r
+    if (pdomain) *pdomain = 0;\r
+\r
+    LookupAccountSidA(NULL, Sid, 0, &name_len, 0, &domain_len, &snu);\r
+    if ((name_len == 0) || (domain_len == 0)) status = GetLastError();\r
+\r
+    if (!status) {\r
+        if (!(name = (LPSTR)malloc_alloc_p(name_len))) status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!(domain = (LPSTR)malloc_alloc_p(domain_len))) status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!LookupAccountSidA(NULL, Sid, name, &name_len, domain, &domain_len, &snu)) status = GetLastError();\r
+        }\r
+\r
+    if (status) {\r
+        if (name)   free_alloc_p(&name);\r
+        if (domain) free_alloc_p(&domain);\r
+        } \r
+    else {\r
+        if (pdomain) {\r
+            *pname = name;\r
+            *pdomain = domain;\r
+            } \r
+        else {\r
+            DWORD size = name_len + domain_len + 1;\r
+            *pname = (LPSTR)malloc_alloc_p(size);\r
+            if (!*pname) status = GetLastError();\r
+            else _snprintf(*pname, size, "%s\\%s", name, domain);\r
+            }\r
+        }\r
+    return status;\r
+    }\r
+\r
+DWORD get_authentication_id(HANDLE hToken, LUID* pAuthId) {\r
+    TOKEN_STATISTICS ts;\r
+    DWORD len;\r
+\r
+    if (!GetTokenInformation(hToken, TokenStatistics, &ts, sizeof(ts), &len))\r
+        return GetLastError();\r
+    *pAuthId = ts.AuthenticationId;\r
+    return 0;\r
+    }\r
+\r
+DWORD\r
+alloc_name_9x(\r
+    LPSTR* pname,\r
+    LPSTR postfix\r
+    )\r
+{\r
+    char prefix[] = "krbcc";\r
+    DWORD len = (sizeof(prefix) - 1) + 1 + strlen(postfix) + 1;\r
+\r
+    *pname = (LPSTR)malloc_alloc_p(len);\r
+    if (!*pname) return GetLastError();\r
+    _snprintf(*pname, len, "%s.%s", prefix, postfix);\r
+    return 0;\r
+}\r
+\r
+DWORD alloc_name_NT(LPSTR* pname, LPSTR postfix) {\r
+    DWORD status = 0;\r
+    HANDLE hToken = 0;\r
+    LUID auth_id;\r
+#ifdef _DEBUG\r
+    PTOKEN_USER ptu = 0;\r
+    LPSTR name = 0;\r
+    LPSTR domain = 0;\r
+    LPSTR sid = 0;\r
+#endif\r
+    char prefix[] = "krbcc";\r
+    // Play it safe and say 3 characters are needed per 8 bits (byte).\r
+    // Note that 20 characters are needed for a 64-bit number in\r
+    // decimal (plus one for the string termination.\r
+    // and include room for sessionId.\r
+    char lid[3*sizeof(LUID)+1+5];\r
+    DWORD sessionId;\r
+    DWORD len = 0;\r
+\r
+    *pname = 0;\r
+\r
+    status = SecureClient::Token(hToken);\r
+\r
+    if (!status) {\r
+        status = get_authentication_id(hToken, &auth_id);\r
+        }\r
+\r
+    if (!status) {\r
+        if (!ProcessIdToSessionId(GetCurrentProcessId(), &sessionId))\r
+               sessionId = 0;\r
+        }\r
+\r
+#ifdef _DEBUG\r
+    if (!status) {status = alloc_token_user(hToken, &ptu);}\r
+    if (!status) {status = alloc_username(ptu->User.Sid, &name, &domain);}\r
+    if (!status) {status = alloc_textual_sid(ptu->User.Sid, &sid);}\r
+#endif\r
+\r
+    if (!status) {\r
+        _snprintf(lid, sizeof(lid), "%I64u.%u", auth_id, sessionId);\r
+        lid[sizeof(lid)-1] = 0; // be safe\r
+\r
+        len = (sizeof(prefix) - 1) + 1 + strlen(lid) + 1 + strlen(postfix) + 1;\r
+        *pname = (LPSTR)malloc_alloc_p(len);\r
+        if (!*pname) status = GetLastError();\r
+        }\r
+\r
+    //\r
+    // We used to allocate a name of the form:\r
+    // "prefix.domain.name.sid.lid.postfix" (usually under 80\r
+    // characters, depending on username).  However, XP thought this\r
+    // was "invalid" (too long?) for some reason.\r
+    //\r
+    // Therefore, we now use "prefix.lid.postfix"\r
+    // and for Terminal server we use "prefix.lid.sessionId.postfix"\r
+    //\r
+\r
+    if (!status) {\r
+        _snprintf(*pname, len, "%s.%s.%s", prefix, lid, postfix);\r
+        }\r
+\r
+#ifdef _DEBUG\r
+    if (sid)\r
+        free_alloc_p(&sid);\r
+    if (name)\r
+        free_alloc_p(&name);\r
+    if (domain)\r
+        free_alloc_p(&domain);\r
+    if (ptu)\r
+        free_alloc_p(&ptu);\r
+#endif\r
+    if (hToken && hToken != INVALID_HANDLE_VALUE)\r
+        CloseHandle(hToken);\r
+    if (status && *pname)\r
+        free_alloc_p(pname);\r
+    return status;\r
+}\r
+\r
+extern "C" DWORD alloc_name(LPSTR* pname, LPSTR postfix, BOOL isNT) {\r
+    return isNT ? alloc_name_NT(pname, postfix) : \r
+        alloc_name_9x(pname, postfix);\r
+    }\r
+\r
+extern "C" DWORD alloc_own_security_descriptor_NT(PSECURITY_DESCRIPTOR* ppsd) {\r
+    DWORD status = 0;\r
+    HANDLE hToken = 0;\r
+    PTOKEN_USER ptu = 0;\r
+    PSID pSid = 0;\r
+    PACL pAcl = 0;\r
+    DWORD size = 0;\r
+    SECURITY_DESCRIPTOR sd;\r
+\r
+    *ppsd = 0;\r
+\r
+    if (!status) {status = SecureClient::Token(hToken);}\r
+\r
+    // Get SID:\r
+    if (!status) {status = alloc_token_user(hToken, &ptu);}\r
+\r
+    if (!status) {\r
+        size = GetLengthSid(ptu->User.Sid);\r
+        pSid = (PSID) malloc_alloc_p(size);\r
+        if (!pSid) status = GetLastError();\r
+        }\r
+    if (!status) {\r
+        if (!CopySid(size, pSid, ptu->User.Sid)) status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        // Prepare ACL:\r
+        size = sizeof(ACL);\r
+        // Add an ACE:\r
+        size += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSid);\r
+        pAcl = (PACL) malloc_alloc_p(size);\r
+        if (!pAcl) status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!InitializeAcl(pAcl, size, ACL_REVISION)) status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pSid)) status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        // Prepare SD itself:\r
+        if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!SetSecurityDescriptorOwner(&sd, pSid, FALSE)) status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!IsValidSecurityDescriptor(&sd)) status = ERROR_INVALID_PARAMETER;\r
+        }\r
+\r
+    if (!status) {\r
+        // We now have a SD.  Let's copy it.\r
+        {\r
+            // This should not succeed.  Instead it should give us the size.\r
+            BOOL ok = MakeSelfRelativeSD(&sd, 0, &size);\r
+            }\r
+        if (size == 0) status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        *ppsd = (PSECURITY_DESCRIPTOR) malloc_alloc_p(size);\r
+        if (!*ppsd) status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!MakeSelfRelativeSD(&sd, *ppsd, &size)) status = GetLastError();\r
+        }\r
+\r
+    if (ptu)                free_alloc_p(&ptu);\r
+    if (pSid)               free_alloc_p(&pSid);\r
+    if (pAcl)               free_alloc_p(&pAcl);\r
+    if (hToken && hToken != INVALID_HANDLE_VALUE)   CloseHandle(hToken);\r
+    if (status && *ppsd)    free_alloc_p(ppsd);\r
+    return status;\r
+}\r
+\r
+DWORD\r
+alloc_module_file_name(\r
+    char* module,\r
+    char** pname\r
+    )\r
+{\r
+    const DWORD max = 8192;\r
+    DWORD status = 0;\r
+    DWORD got = 0;\r
+    DWORD size = 512; // use low number to test...\r
+    HMODULE h = 0;\r
+    BOOL ok = FALSE;\r
+    char* name = 0;\r
+\r
+    if (!pname)\r
+        return ERROR_INVALID_PARAMETER;\r
+    *pname = 0;\r
+\r
+    h = GetModuleHandle(module);\r
+\r
+    if (!h) return GetLastError();\r
+\r
+    // We assume size < max and size > 0\r
+    while (!status && !ok) {\r
+        if (size > max) {\r
+            // XXX - Assert?\r
+            status = ERROR_INVALID_DATA;\r
+            continue;\r
+        }\r
+        if (name) free_alloc_p(&name);\r
+        name = (char*)malloc_alloc_p(size + 1);\r
+        if (!name) {\r
+            status = ERROR_NOT_ENOUGH_MEMORY;\r
+            continue;\r
+        }\r
+        name[size] = 0;\r
+        got = GetModuleFileName(h, name, size);\r
+        if (!got) {\r
+            status = GetLastError();\r
+            // sanity check:\r
+            if (!status) {\r
+                // XXX - print nasty message...assert?\r
+                status = ERROR_INVALID_DATA;\r
+            }\r
+            continue;\r
+        }\r
+        // To know we're ok, we need to verify that what we got\r
+        // was bigger than GetModuleSize thought it got.\r
+        ok = got && (got < size) && !name[got];\r
+        size *= 2;\r
+    }\r
+    if (status && name)\r
+        free_alloc_p(&name);\r
+    else\r
+        *pname = name;\r
+    return status;\r
+}\r
+\r
+DWORD\r
+alloc_module_dir_name(\r
+    char* module,\r
+    char** pname\r
+    )\r
+{\r
+    DWORD status = alloc_module_file_name(module, pname);\r
+    if (!status) {\r
+        char* name = *pname;\r
+        char* p = name + strlen(name);\r
+        while ((p >= name) && (*p != '\\') && (*p != '/')) p--;\r
+        if (p < name) {\r
+            free_alloc_p(pname);\r
+            status = ERROR_INVALID_DATA;\r
+        } else {\r
+            *p = 0;\r
+        }\r
+    }\r
+    return status;\r
+}\r
+\r
+DWORD\r
+alloc_module_dir_name_with_file(\r
+    char* module,\r
+    char* file,\r
+    char** pname\r
+    )\r
+{\r
+    DWORD status = alloc_module_dir_name(module, pname);\r
+    if (!status) {\r
+        char* name = *pname;\r
+        size_t name_size = strlen(name);\r
+        size_t size = name_size + 1 + strlen(file) + 1;\r
+        char* result = (char*)malloc_alloc_p(size);\r
+        if (!result) {\r
+            status = ERROR_NOT_ENOUGH_MEMORY;\r
+            free_alloc_p(pname);\r
+        } else {\r
+            strcpy(result, name);\r
+            result[name_size] = '\\';\r
+            strcpy(result + name_size + 1, file);\r
+            free_alloc_p(pname);\r
+            *pname = result;\r
+        }\r
+    }\r
+    return status;\r
+}\r
+\r
+DWORD alloc_cmdline_2_args(char* prog,\r
+                           char* arg1,\r
+                           char* arg2,\r
+                           char** pname) {\r
+    DWORD   status  = 0;\r
+    size_t  size    = strlen(prog) + strlen(arg1) + strlen(arg2) + 4;\r
+    char*   result  = (char*)malloc_alloc_p(size);\r
+    if (!result) {\r
+        status = ERROR_NOT_ENOUGH_MEMORY;\r
+        } \r
+    else {\r
+        strcpy(result, prog);\r
+        strcat(result, " ");\r
+        strcat(result, arg1);\r
+        strcat(result, " ");\r
+        strcat(result, arg2);\r
+        *pname = result;\r
+        }\r
+    cci_debug_printf("%s made <%s>", __FUNCTION__, result);\r
+    return status;\r
+    }\r
diff --git a/src/ccapi/common/win/OldCC/util.h b/src/ccapi/common/win/OldCC/util.h
new file mode 100644 (file)
index 0000000..a51858c
--- /dev/null
@@ -0,0 +1,89 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef __UTIL_H__\r
+#define __UTIL_H__\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+#if 0\r
+}\r
+#endif\r
+\r
+BOOL isNT();\r
+\r
+void*\r
+user_allocate(\r
+    size_t size\r
+    );\r
+\r
+void\r
+user_free(\r
+    void* ptr\r
+    );\r
+\r
+void\r
+free_alloc_p(\r
+    void* pptr\r
+    );\r
+\r
+DWORD\r
+alloc_name(\r
+    LPSTR* pname,\r
+    LPSTR postfix,\r
+    BOOL isNT\r
+    );\r
+\r
+DWORD\r
+alloc_own_security_descriptor_NT(\r
+    PSECURITY_DESCRIPTOR* ppsd\r
+    );\r
+\r
+DWORD\r
+alloc_module_dir_name(\r
+    char* module,\r
+    char** pname\r
+    );\r
+\r
+DWORD\r
+alloc_module_dir_name_with_file(\r
+    char* module,\r
+    char* file,\r
+    char** pname\r
+    );\r
+\r
+DWORD alloc_cmdline_2_args(\r
+    char* prog,\r
+    char* arg1,\r
+    char* arg2,\r
+    char** pname);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* __UTIL_H__ */\r
diff --git a/src/ccapi/common/win/cci_os_debugging.c b/src/ccapi/common/win/cci_os_debugging.c
new file mode 100644 (file)
index 0000000..f1fbb28
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <stdio.h> \r
+#include <stdarg.h>\r
+\r
+#include "cci_os_debugging.h"\r
+#include "win-utils.h"\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+void cci_os_debug_vprintf (const char *in_format, va_list in_args) {\r
+    printf  ( "%s %ld ", timestamp(), GetCurrentThreadId() );\r
+    vprintf ( in_format, in_args );\r
+    printf  ( "\n" );\r
+    }\r
diff --git a/src/ccapi/common/win/cci_os_identifier.c b/src/ccapi/common/win/cci_os_identifier.c
new file mode 100644 (file)
index 0000000..7b44fe3
--- /dev/null
@@ -0,0 +1,58 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include "cci_common.h"\r
+#include "cci_os_identifier.h"\r
+\r
+#include <rpc.h>\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 cci_os_identifier_new_uuid (cci_uuid_string_t *out_uuid_string) {\r
+    cc_int32        err = ccNoError;\r
+    UUID            uuid;\r
+    char*           uuidStringTemp;\r
+\r
+    err = UuidCreate(&uuid);\r
+\r
+    if (!err) {\r
+        err = UuidToString(&uuid, &uuidStringTemp);\r
+        }\r
+\r
+    if (!err) {\r
+        *out_uuid_string = malloc(1+strlen(uuidStringTemp));\r
+\r
+        if (*out_uuid_string) {\r
+            strcpy(*out_uuid_string, uuidStringTemp);\r
+            }\r
+\r
+        RpcStringFree(&uuidStringTemp);\r
+        }\r
+\r
+    cci_debug_printf("cci_os_identifier_new_uuid returning %s", *out_uuid_string);\r
+\r
+    return cci_check_error (err);\r
+    }
\ No newline at end of file
diff --git a/src/ccapi/common/win/ccs_reply.Acf b/src/ccapi/common/win/ccs_reply.Acf
new file mode 100644 (file)
index 0000000..89e8abe
--- /dev/null
@@ -0,0 +1,31 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+[implicit_handle(handle_t ccs_reply_IfHandle)]\r
+\r
+interface ccs_reply {\r
+    [async] ccapi_listen();\r
+    }\r
diff --git a/src/ccapi/common/win/ccs_reply.Idl b/src/ccapi/common/win/ccs_reply.Idl
new file mode 100644 (file)
index 0000000..4c6f6f3
--- /dev/null
@@ -0,0 +1,60 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+[ uuid (6E3B5060-CA46-1067-B31A-00DD010662DA),\r
+  version(1.0),\r
+  pointer_default(unique)\r
+]\r
+\r
+/* This interface sends a cci_stream via rpc.\r
+ */\r
+\r
+interface ccs_reply {\r
+    const long HSIZE = sizeof(void*);\r
+\r
+/* The reply from the server to a request from the client: */\r
+void ccs_rpc_request_reply(\r
+    [in]                    const long              rpcmsg,         /* Message type */\r
+    [in, size_is(HSIZE)]    const char              tsphandle[],\r
+    [in, string]            const char*             uuid,\r
+    [in]                    const long              srvStartTime,   /* Server Start Time */\r
+    [in]                    const long              cbIn,           /* Length of buffer */\r
+    [in,  size_is(cbIn)]    const unsigned char     chIn[],         /* Data buffer */\r
+    [out]                   long*                   status );       /* Return code */\r
+\r
+void ccs_rpc_connect_reply(\r
+    [in]                    const long      rpcmsg,         /* Message type */\r
+    [in, size_is(HSIZE)]    const char      tsphandle[],\r
+    [in, string]            const char*     uuid,\r
+    [in]                    const long      srvStartTime,   /* Server Start Time */\r
+    [out]                   long*           status );       /* Return code */\r
+\r
+void ccapi_listen(\r
+    handle_t                hBinding,   \r
+    [in]                    const long rpcmsg,              /* Message type */\r
+    [out]                   long* status );                 /* Return code */\r
+\r
+    }\r
diff --git a/src/ccapi/common/win/ccs_request.Acf b/src/ccapi/common/win/ccs_request.Acf
new file mode 100644 (file)
index 0000000..853a152
--- /dev/null
@@ -0,0 +1,31 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+[implicit_handle(handle_t ccs_request_IfHandle)]\r
+interface ccs_request\r
+{\r
+\r
+}\r
diff --git a/src/ccapi/common/win/ccs_request.idl b/src/ccapi/common/win/ccs_request.idl
new file mode 100644 (file)
index 0000000..bd69314
--- /dev/null
@@ -0,0 +1,58 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+[ uuid (906B0CE0-C70B-1067-B317-00DD010662DA),\r
+  version(1.0),\r
+  pointer_default(unique)\r
+]\r
+\r
+interface ccs_request {\r
+\r
+typedef char CC_CHAR;\r
+typedef unsigned char CC_UCHAR;\r
+typedef int CC_INT32;\r
+typedef unsigned int CC_UINT32;\r
+\r
+const long HSIZE = sizeof(void*);\r
+\r
+void ccs_rpc_request(\r
+    [in]                        const long  rpcmsg,         /* Message type */\r
+    [in, size_is(HSIZE)]        const char  tsphandle[],\r
+    [in,  string]               const char* pszUUID,        /* Requestor's UUID */\r
+    [in]                        const long  lenRequest,     /* Length of buffer */\r
+    [in,  size_is(lenRequest)]  const char* pszRequest,     /* Data buffer */\r
+    [in]                        const long  serverStartTime,/* Which server session we're talking to */\r
+    [out]                       long*       status );       /* Return code */\r
+\r
+void ccs_rpc_connect(\r
+    [in]                        const long  rpcmsg,         /* Message type */\r
+    [in, size_is(HSIZE)]        const char  tsphandle[],\r
+    [in,  string]               const char* pszUUID,        /* Requestor's UUID */\r
+    [out]                       long*       status );       /* Return code */\r
+\r
+CC_UINT32 ccs_authenticate(\r
+    [in, string]                const CC_CHAR* name );\r
+}\r
diff --git a/src/ccapi/common/win/tls.c b/src/ccapi/common/win/tls.c
new file mode 100644 (file)
index 0000000..411d709
--- /dev/null
@@ -0,0 +1,71 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include "string.h"\r
+\r
+#include "tls.h"\r
+\r
+struct tspdata* new_tspdata(char* uuid, time_t sst) {\r
+    struct tspdata* p   = (struct tspdata*)malloc(sizeof(struct tspdata));\r
+    if (p) {\r
+        memset(p, 0, sizeof(struct tspdata));\r
+        p->_sst = sst;\r
+        if (uuid) {strncpy(p->_uuid, uuid, UUID_SIZE-1);}\r
+        }\r
+    return p;\r
+    }\r
+\r
+void delete_tspdata(struct tspdata* p) {\r
+    if (p)          free(p);\r
+    }\r
+\r
+void tspdata_setUUID(struct tspdata* p, unsigned char __RPC_FAR* uuidString) {\r
+    strncpy(p->_uuid, uuidString, UUID_SIZE-1);\r
+    };\r
+\r
+void         tspdata_setConnected (struct tspdata* p, BOOL b)           {p->_CCAPI_Connected = b;}\r
+\r
+void         tspdata_setReplyEvent(struct tspdata* p, HANDLE h)         {p->_replyEvent = h;}\r
+\r
+void         tspdata_setRpcAState (struct tspdata* p, RPC_ASYNC_STATE* rpcState) {\r
+    p->_rpcState = rpcState;}\r
+\r
+void         tspdata_setSST       (struct tspdata* p, time_t t)         {p->_sst = t;}\r
+\r
+void         tspdata_setStream    (struct tspdata* p, cci_stream_t s)   {p->_stream = s;}\r
+\r
+\r
+BOOL         tspdata_getConnected (struct tspdata* p)         {return p->_CCAPI_Connected;}\r
+\r
+HANDLE       tspdata_getReplyEvent(struct tspdata* p)         {return p->_replyEvent;}\r
+\r
+time_t       tspdata_getSST       (const struct tspdata* p)   {return p->_sst;}\r
+\r
+cci_stream_t tspdata_getStream    (const struct tspdata* p)   {return p->_stream;}\r
+\r
+char*        tspdata_getUUID      (const struct tspdata* p)   {return p->_uuid;}\r
+\r
+RPC_ASYNC_STATE* tspdata_getRpcAState (const struct tspdata* p)   {return p->_rpcState;}\r
diff --git a/src/ccapi/common/win/tls.h b/src/ccapi/common/win/tls.h
new file mode 100644 (file)
index 0000000..b18705e
--- /dev/null
@@ -0,0 +1,70 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+/* Thread local storage for client threads. */\r
+\r
+#ifndef _tls_h\r
+#define _tls_h\r
+\r
+#include "windows.h"\r
+#include "time.h"\r
+\r
+#include "cci_stream.h"\r
+\r
+#define UUID_SIZE   128\r
+\r
+/* The client code can be run in any client thread.  The thread-specific data\r
+   is defined here.\r
+ */\r
+\r
+struct tspdata {\r
+    BOOL                _CCAPI_Connected;\r
+    RPC_ASYNC_STATE*    _rpcState;\r
+    HANDLE              _replyEvent;\r
+    time_t              _sst;\r
+    cci_stream_t        _stream;\r
+    char                _uuid[UUID_SIZE];\r
+    };\r
+\r
+struct tspdata* new_tspdata          (char* uuid, time_t sst);\r
+void            delete_tspdata       (struct tspdata* p);\r
+\r
+void            tspdata_setConnected (struct tspdata* p, BOOL b);\r
+void            tspdata_setReplyEvent(struct tspdata* p, HANDLE h);\r
+void            tspdata_setRpcAState (struct tspdata* p, RPC_ASYNC_STATE* rpcState);\r
+void            tspdata_setSST       (struct tspdata* p, time_t t);\r
+void            tspdata_setStream    (struct tspdata* p, cci_stream_t s);\r
+void            tspdata_setUUID      (struct tspdata* p, unsigned char __RPC_FAR* uuidString);\r
+HANDLE          tspdata_getReplyEvent(const struct tspdata* p);\r
+\r
+BOOL             tspdata_getConnected(const struct tspdata* p);\r
+RPC_ASYNC_STATE* tspdata_getRpcAState(const struct tspdata* p);\r
+time_t           tspdata_getSST      (const struct tspdata* p);\r
+cci_stream_t     tspdata_getStream   (const struct tspdata* p);\r
+char*            tspdata_getUUID     (const struct tspdata* p);\r
+\r
+\r
+#endif _tls_h\r
diff --git a/src/ccapi/common/win/win-utils.c b/src/ccapi/common/win/win-utils.c
new file mode 100644 (file)
index 0000000..c082142
--- /dev/null
@@ -0,0 +1,66 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <time.h>\r
+#include "windows.h"\r
+\r
+#include "win-utils.h"\r
+#include "cci_debugging.h"\r
+\r
+#pragma warning (disable : 4996)\r
+\r
+#define UUID_SIZE   128\r
+\r
+char*           clientPrefix        = "CCAPI_CLIENT_";\r
+char*           serverPrefix        = "CCS_LISTEN_";\r
+unsigned char*  pszProtocolSequence = "ncalrpc";\r
+\r
+#define         MAX_TIMESTAMP   40\r
+char            _ts[MAX_TIMESTAMP];\r
+\r
+char* clientEndpoint(const char* UUID) {\r
+    char* _clientEndpoint   = (char*)malloc(strlen(UUID) + strlen(clientPrefix) + 2);\r
+    strcpy(_clientEndpoint, clientPrefix);\r
+    strncat(_clientEndpoint, UUID, UUID_SIZE);\r
+//    cci_debug_printf("%s returning %s", __FUNCTION__, _clientEndpoint);\r
+    return _clientEndpoint;\r
+    }       \r
+\r
+char* serverEndpoint(const char* user) {\r
+    char* _serverEndpoint   = (char*)malloc(strlen(user) + strlen(serverPrefix) + 2);\r
+    strcpy(_serverEndpoint, serverPrefix);\r
+    strncat(_serverEndpoint, user, UUID_SIZE);\r
+    return _serverEndpoint;\r
+    }       \r
+\r
+char* timestamp() {\r
+    SYSTEMTIME  _stime;\r
+    GetSystemTime(&_stime);\r
+    GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &_stime, "HH:mm:ss", _ts, sizeof(_ts)-1);\r
+    return _ts;\r
+    }
\ No newline at end of file
diff --git a/src/ccapi/common/win/win-utils.h b/src/ccapi/common/win/win-utils.h
new file mode 100644 (file)
index 0000000..97226e9
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef _win_utils_h\r
+#define _win_utils_h\r
+\r
+#ifndef TRUE\r
+#define TRUE    (1==1)\r
+#endif\r
+\r
+#ifndef FALSE\r
+#define FALSE   (1==0)\r
+#endif\r
+\r
+static enum ccapiMsgType {\r
+    CCMSG_INVALID   = 0,\r
+    CCMSG_CONNECT,\r
+    CCMSG_REQUEST,\r
+    CCMSG_CONNECT_REPLY,\r
+    CCMSG_REQUEST_REPLY,\r
+    CCMSG_DISCONNECT,\r
+    CCMSG_LISTEN,\r
+    CCMSG_PING\r
+    };\r
+\r
+char*                   clientEndpoint(const char* UUID);\r
+char*                   serverEndpoint(const char* UUID);\r
+extern unsigned char*   pszProtocolSequence;\r
+\r
+char* timestamp();\r
+\r
+#endif // _win_utils_h
\ No newline at end of file
diff --git a/src/ccapi/lib/win/Makefile b/src/ccapi/lib/win/Makefile
new file mode 100644 (file)
index 0000000..4bdd98d
--- /dev/null
@@ -0,0 +1,116 @@
+!include <Win32.Mak>\r
+\r
+# . is ...\pismere\athena\auth\krb5\src\ccapi\lib\win\r
+CCAPI = ..\..\r
+CO      = $(CCAPI)\common\r
+COWIN   = $(CCAPI)\common\win\r
+CCUTIL  = $(CCAPI)\common\win\OldCC             \r
+LIBDIR  = $(CCAPI)\lib\r
+LIBWIN  = $(LIBDIR)\win\r
+K5SRC   = $(CCAPI)\..\r
+POSIX   = $(K5SRC)\lib\krb5\posix\r
+OLDCC   = $(LIBWIN)\OldCC\r
+\r
+INC     = -I.. -I$(CO) -I$(COWIN) -I$(K5SRC)\include -I..\..\..\util\et -I$(OLDCC) \\r
+    -I$(LIBWIN) -I$(CCUTIL)\r
+MIDLI   = /I $(K5SRC)\include /I. /I$(COWIN) /I$(CO) \r
+\r
+!if "$(CPU)" == "i386"\r
+cflags = $(cflags) /EHsc /MDd -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 \\r
+$(INC) -D_CRT_SECURE_NO_WARNINGS\r
+!else\r
+cflags = $(cflags) /W3 -D_CRTAPI1= -D_CRTAPI2= $(INC)\r
+!endif\r
+\r
+!if "$(PREPROCESS)" == "P"\r
+cflags = $(cflags) -P\r
+!endif\r
+\r
+all : ccapi.dll\r
+\r
+common = cci_array_internal.obj cci_cred_union.obj cci_debugging.obj cci_identifier.obj \\r
+    cci_message.obj cci_stream.obj \r
+    \r
+commonwin = cci_os_debugging.obj \\r
+            cci_os_identifier.obj \\r
+            tls.obj \\r
+            win-utils.obj\r
+\r
+dll =   ccapi_ccache.obj \\r
+        ccapi_ccache_iterator.obj \\r
+        ccapi_context.obj \\r
+        ccapi_context_change_time.obj \\r
+        ccapi_credentials.obj \\r
+        ccapi_credentials_iterator.obj \\r
+        ccapi_ipc.obj \\r
+        ccapi_string.obj \r
+\r
+dllwin =    ccs_reply_s.obj \\r
+            ccs_reply_proc.obj \\r
+            ccs_request_c.obj            \r
+            \r
+dllwincxx = ccapi_os_ipc.obj \\r
+            dllmain.obj\r
+            \r
+oldcc   =   client.obj \\r
+            rpc.obj \r
+            \r
+utils   =   ccutils.obj\r
+\r
+utilscxx =  init.obj \\r
+            secure.obj \\r
+            util.obj\r
+\r
+\r
+linkobjs = $(common) $(commonwin) $(dll) $(dllwin) $(dllwincxx) $(oldcc) $(utils) $(utilscxx)\r
+\r
+#includes = \r
+\r
+# Main program:\r
+ccapi.dll : $(linkobjs) ccapi.def\r
+    $(link) $(linkdebug) $(conflags) -out:ccapi.dll /DEF:ccapi.def /implib:ccapi.lib $(dlllflags) \\r
+        $(linkobjs) rpcrt4.lib kernel32.lib user32.lib $(conlibsdll) \r
+\r
+\r
+ccs_request.h ccs_request_c.c ccs_request_s.c : $(COWIN)\ccs_request.idl $(COWIN)\ccs_request.acf\r
+    midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(cc) -cpp_opt "-E" \\r
+    $(COWIN)\ccs_request.idl\r
+\r
+ccs_reply.h   ccs_reply_c.c   ccs_reply_s.c   : $(COWIN)\ccs_reply.idl   $(COWIN)\ccs_reply.acf\r
+    midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(cc) -cpp_opt "-E" -I. -I$(COWIN) \\r
+    $(COWIN)\ccs_reply.idl\r
+\r
+$(common) : $(CO)\$*.c\r
+   $(cc) $(cdebug) $(cflags) $(cvarsdll) $(CO)\$*.c\r
+\r
+$(commonwin) : $(COWIN)\$*.c\r
+   $(cc) $(cdebug) $(cflags) $(cvarsdll) $(COWIN)\$*.c\r
+\r
+$(dll) : $(LIBDIR)\$*.c\r
+   $(cc) $(cdebug) $(cflags) $(cvarsdll) $(LIBDIR)\$*.c\r
+\r
+$(dllwin) : $*.c ccs_reply.h ccs_request.h\r
+   $(cc) $(cdebug) $(cflags) $(cvarsdll) $(LIBWIN)\$*.c\r
+\r
+$(dllwincxx) : $*.cxx ccs_reply.h ccs_request.h\r
+   $(cc) $(cdebug) $(cflags) $(cvarsdll) $(LIBWIN)\$*.cxx\r
+\r
+$(oldcc) : $(OLDCC)\$*.cxx\r
+   $(cc) $(cdebug) $(cflags) $(cvarsdll) $(OLDCC)\$*.cxx\r
+\r
+$(utils) : $(CCUTIL)\$*.c\r
+   $(cc) $(cdebug) $(cflags) $(cvarsdll) $(CCUTIL)\$*.c\r
+\r
+$(utilscxx) : $(CCUTIL)\$*.cxx\r
+   $(cc) $(cdebug) $(cflags) $(cvarsdll) $(CCUTIL)\$*.cxx\r
+\r
+\r
+\r
+# Clean up everything\r
+cleanall : clean\r
+    -del *.dll\r
+\r
+# Clean up everything but the .EXEs\r
+clean :\r
+    -del *.obj\r
+    -del *.map\r
diff --git a/src/ccapi/lib/win/OldCC/ccapi.h b/src/ccapi/lib/win/OldCC/ccapi.h
new file mode 100644 (file)
index 0000000..65a72ed
--- /dev/null
@@ -0,0 +1,284 @@
+\r
+\r
+/* this ALWAYS GENERATED file contains the definitions for the interfaces */\r
+\r
+\r
+ /* File created by MIDL compiler version 6.00.0366 */\r
+/* at Fri Nov 30 10:06:16 2007\r
+ */\r
+/* Compiler settings for ccapi.idl:\r
+    Oic, W1, Zp8, env=Win32 (32b run)\r
+    protocol : dce , ms_ext, c_ext, oldnames\r
+    error checks: allocation ref bounds_check enum stub_data \r
+    VC __declspec() decoration level: \r
+         __declspec(uuid()), __declspec(selectany), __declspec(novtable)\r
+         DECLSPEC_UUID(), MIDL_INTERFACE()\r
+*/\r
+//@@MIDL_FILE_HEADING(  )\r
+\r
+#pragma warning( disable: 4049 )  /* more than 64k source lines */\r
+\r
+\r
+/* verify that the <rpcndr.h> version is high enough to compile this file*/\r
+#ifndef __REQUIRED_RPCNDR_H_VERSION__\r
+#define __REQUIRED_RPCNDR_H_VERSION__ 440\r
+#endif\r
+\r
+#include "rpc.h"\r
+#include "rpcndr.h"\r
+\r
+#ifndef __ccapi_h__\r
+#define __ccapi_h__\r
+\r
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)\r
+#pragma once\r
+#endif\r
+\r
+/* Forward Declarations */ \r
+\r
+#ifdef __cplusplus\r
+extern "C"{\r
+#endif \r
+\r
+void * __RPC_USER MIDL_user_allocate(size_t);\r
+void __RPC_USER MIDL_user_free( void * ); \r
+\r
+#ifndef __ccapi_INTERFACE_DEFINED__\r
+#define __ccapi_INTERFACE_DEFINED__\r
+\r
+/* interface ccapi */\r
+/* [implicit_handle][unique][version][uuid] */ \r
+\r
+typedef /* [context_handle] */ struct opaque_handle_CTX *HCTX;\r
+\r
+typedef /* [context_handle] */ struct opaque_handle_CACHE *HCACHE;\r
+\r
+typedef /* [context_handle] */ struct opaque_handle_CACHE_ITER *HCACHE_ITER;\r
+\r
+typedef /* [context_handle] */ struct opaque_handle_CRED_ITER *HCRED_ITER;\r
+\r
+typedef unsigned char CC_CHAR;\r
+\r
+typedef unsigned char CC_UCHAR;\r
+\r
+typedef int CC_INT32;\r
+\r
+typedef unsigned int CC_UINT32;\r
+\r
+typedef CC_INT32 CC_TIME_T;\r
+\r
+\r
+enum __MIDL_ccapi_0001\r
+    {  STK_AFS = 0,\r
+       STK_DES = 1\r
+    } ;\r
+\r
+enum __MIDL_ccapi_0002\r
+    {  CC_API_VER_1    = 1,\r
+       CC_API_VER_2    = 2\r
+    } ;\r
+\r
+enum __MIDL_ccapi_0003\r
+    {  KRB_NAME_SZ     = 40,\r
+       KRB_INSTANCE_SZ = 40,\r
+       KRB_REALM_SZ    = 40,\r
+       MAX_V4_CRED_LEN = 1250\r
+    } ;\r
+typedef struct _NC_INFO\r
+    {\r
+    /* [string] */ CC_CHAR *name;\r
+    /* [string] */ CC_CHAR *principal;\r
+    CC_INT32 vers;\r
+    }  NC_INFO;\r
+\r
+typedef struct _NC_INFO_LIST\r
+    {\r
+    CC_UINT32 length;\r
+    /* [size_is] */ NC_INFO *info;\r
+    }  NC_INFO_LIST;\r
+\r
+typedef struct _V4_CRED\r
+    {\r
+    CC_UCHAR kversion;\r
+    CC_CHAR principal[ 41 ];\r
+    CC_CHAR principal_instance[ 41 ];\r
+    CC_CHAR service[ 41 ];\r
+    CC_CHAR service_instance[ 41 ];\r
+    CC_CHAR realm[ 41 ];\r
+    CC_UCHAR session_key[ 8 ];\r
+    CC_INT32 kvno;\r
+    CC_INT32 str_to_key;\r
+    CC_INT32 issue_date;\r
+    CC_INT32 lifetime;\r
+    CC_UINT32 address;\r
+    CC_INT32 ticket_sz;\r
+    CC_UCHAR ticket[ 1250 ];\r
+    }  V4_CRED;\r
+\r
+typedef struct _CC_DATA\r
+    {\r
+    CC_UINT32 type;\r
+    CC_UINT32 length;\r
+    /* [size_is] */ CC_UCHAR *data;\r
+    }  CC_DATA;\r
+\r
+typedef struct _CC_DATA_LIST\r
+    {\r
+    CC_UINT32 count;\r
+    /* [size_is] */ CC_DATA *data;\r
+    }  CC_DATA_LIST;\r
+\r
+typedef struct _V5_CRED\r
+    {\r
+    /* [string] */ CC_CHAR *client;\r
+    /* [string] */ CC_CHAR *server;\r
+    CC_DATA keyblock;\r
+    CC_TIME_T authtime;\r
+    CC_TIME_T starttime;\r
+    CC_TIME_T endtime;\r
+    CC_TIME_T renew_till;\r
+    CC_UINT32 is_skey;\r
+    CC_UINT32 ticket_flags;\r
+    CC_DATA_LIST addresses;\r
+    CC_DATA ticket;\r
+    CC_DATA second_ticket;\r
+    CC_DATA_LIST authdata;\r
+    }  V5_CRED;\r
+\r
+typedef /* [switch_type] */ union _CRED_PTR_UNION\r
+    {\r
+    /* [case()] */ V4_CRED *pV4Cred;\r
+    /* [case()] */ V5_CRED *pV5Cred;\r
+    }  CRED_PTR_UNION;\r
+\r
+typedef struct _CRED_UNION\r
+    {\r
+    CC_INT32 cred_type;\r
+    /* [switch_is] */ CRED_PTR_UNION cred;\r
+    }  CRED_UNION;\r
+\r
+CC_INT32 rcc_initialize( \r
+    /* [out] */ HCTX *pctx);\r
+\r
+CC_INT32 rcc_shutdown( \r
+    /* [out][in] */ HCTX *pctx);\r
+\r
+CC_INT32 rcc_get_change_time( \r
+    /* [in] */ HCTX ctx,\r
+    /* [out] */ CC_TIME_T *time);\r
+\r
+CC_INT32 rcc_create( \r
+    /* [in] */ HCTX ctx,\r
+    /* [string][in] */ const CC_CHAR *name,\r
+    /* [string][in] */ const CC_CHAR *principal,\r
+    /* [in] */ CC_INT32 vers,\r
+    /* [in] */ CC_UINT32 flags,\r
+    /* [out] */ HCACHE *pcache);\r
+\r
+CC_INT32 rcc_open( \r
+    /* [in] */ HCTX ctx,\r
+    /* [string][in] */ const CC_CHAR *name,\r
+    /* [in] */ CC_INT32 vers,\r
+    /* [in] */ CC_UINT32 flags,\r
+    /* [out] */ HCACHE *pcache);\r
+\r
+CC_INT32 rcc_close( \r
+    /* [out][in] */ HCACHE *pcache);\r
+\r
+CC_INT32 rcc_destroy( \r
+    /* [out][in] */ HCACHE *pcache);\r
+\r
+CC_INT32 rcc_seq_fetch_NCs_begin( \r
+    /* [in] */ HCTX ctx,\r
+    /* [out] */ HCACHE_ITER *piter);\r
+\r
+CC_INT32 rcc_seq_fetch_NCs_end( \r
+    /* [out][in] */ HCACHE_ITER *piter);\r
+\r
+CC_INT32 rcc_seq_fetch_NCs_next( \r
+    /* [in] */ HCACHE_ITER iter,\r
+    /* [out] */ HCACHE *pcache);\r
+\r
+CC_INT32 rcc_seq_fetch_NCs( \r
+    /* [in] */ HCTX ctx,\r
+    /* [out][in] */ HCACHE_ITER *piter,\r
+    /* [out] */ HCACHE *pcache);\r
+\r
+CC_INT32 rcc_get_NC_info( \r
+    /* [in] */ HCTX ctx,\r
+    /* [out] */ NC_INFO_LIST **info_list);\r
+\r
+CC_INT32 rcc_get_name( \r
+    /* [in] */ HCACHE cache,\r
+    /* [string][out] */ CC_CHAR **name);\r
+\r
+CC_INT32 rcc_set_principal( \r
+    /* [in] */ HCACHE cache,\r
+    /* [in] */ CC_INT32 vers,\r
+    /* [string][in] */ const CC_CHAR *principal);\r
+\r
+CC_INT32 rcc_get_principal( \r
+    /* [in] */ HCACHE cache,\r
+    /* [string][out] */ CC_CHAR **principal);\r
+\r
+CC_INT32 rcc_get_cred_version( \r
+    /* [in] */ HCACHE cache,\r
+    /* [out] */ CC_INT32 *vers);\r
+\r
+CC_INT32 rcc_lock_request( \r
+    /* [in] */ HCACHE cache,\r
+    /* [in] */ CC_INT32 lock_type);\r
+\r
+CC_INT32 rcc_store( \r
+    /* [in] */ HCACHE cache,\r
+    /* [in] */ CRED_UNION cred);\r
+\r
+CC_INT32 rcc_remove_cred( \r
+    /* [in] */ HCACHE cache,\r
+    /* [in] */ CRED_UNION cred);\r
+\r
+CC_INT32 rcc_seq_fetch_creds( \r
+    /* [in] */ HCACHE cache,\r
+    /* [out][in] */ HCRED_ITER *piter,\r
+    /* [out] */ CRED_UNION **cred);\r
+\r
+CC_INT32 rcc_seq_fetch_creds_begin( \r
+    /* [in] */ HCACHE cache,\r
+    /* [out] */ HCRED_ITER *piter);\r
+\r
+CC_INT32 rcc_seq_fetch_creds_end( \r
+    /* [out][in] */ HCRED_ITER *piter);\r
+\r
+CC_INT32 rcc_seq_fetch_creds_next( \r
+    /* [in] */ HCRED_ITER iter,\r
+    /* [out] */ CRED_UNION **cred);\r
+\r
+CC_UINT32 Connect( \r
+    /* [string][in] */ CC_CHAR *name);\r
+\r
+void Shutdown( void);\r
+\r
+\r
+extern handle_t ccapi_IfHandle;\r
+\r
+\r
+extern RPC_IF_HANDLE ccapi_ClientIfHandle;\r
+extern RPC_IF_HANDLE ccapi_ServerIfHandle;\r
+#endif /* __ccapi_INTERFACE_DEFINED__ */\r
+\r
+/* Additional Prototypes for ALL interfaces */\r
+\r
+void __RPC_USER HCTX_rundown( HCTX );\r
+void __RPC_USER HCACHE_rundown( HCACHE );\r
+void __RPC_USER HCACHE_ITER_rundown( HCACHE_ITER );\r
+void __RPC_USER HCRED_ITER_rundown( HCRED_ITER );\r
+\r
+/* end of Additional Prototypes */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+\r
diff --git a/src/ccapi/lib/win/OldCC/client.cxx b/src/ccapi/lib/win/OldCC/client.cxx
new file mode 100644 (file)
index 0000000..1f90510
--- /dev/null
@@ -0,0 +1,389 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include "stdio.h"    // KPKDBG\r
+\r
+#include "ccs_request.h"\r
+\r
+#include "ccapi.h"\r
+#include "util.h"\r
+\r
+extern "C" {\r
+#include "cci_debugging.h"\r
+#include "tls.h"    // KPKDBG\r
+    }\r
+\r
+#include "client.h"\r
+#include "init.hxx"\r
+#include "name.h"\r
+#include "secure.hxx"\r
+\r
+#define SECONDS_TO_WAIT 10\r
+\r
+#define STARTUP "CLIENT STARTUP: "\r
+#define DISCONNECT "CLIENT DISCONNECT: "\r
+\r
+bool Client::s_init = false;\r
+CcOsLock Client::sLock;\r
+\r
+static DWORD bind_client(char* ep OPTIONAL, Init::InitInfo& info, LPSTR* endpoint) {\r
+    DWORD status = 0;\r
+    unsigned char * pszStringBinding = NULL;\r
+\r
+    if (!ep) {\r
+        status = alloc_name(endpoint, "ep", isNT());\r
+        } \r
+    else {\r
+        *endpoint = ep;\r
+        }\r
+\r
+    if (!status) {\r
+        /* Use a convenience function to concatenate the elements of */\r
+        /* the string binding into the proper sequence.              */\r
+        status = RpcStringBindingCompose(0,            // uuid\r
+                                         (unsigned char*)"ncalrpc",    // protseq\r
+                                         0,            // address\r
+                                         (unsigned char*)(*endpoint),  // endpoint\r
+                                         0,            // options\r
+                                         &pszStringBinding);\r
+        cci_check_error(status);\r
+        }\r
+            \r
+    if (!status) {\r
+        /* Set the binding handle that will be used to bind to the server. */\r
+        status = RpcBindingFromStringBinding(pszStringBinding, &ccs_request_IfHandle);\r
+        cci_check_error(status);\r
+        }\r
+\r
+    if (!status) {\r
+        // Win9x might call RpcBindingSetAuthInfo (not Ex), but it does not\r
+        // quite work on Win9x...\r
+        if (isNT()) {\r
+            RPC_SECURITY_QOS qos;\r
+            qos.Version = RPC_C_SECURITY_QOS_VERSION;\r
+            qos.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;\r
+            qos.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;\r
+            qos.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY;\r
+\r
+            status = info.fRpcBindingSetAuthInfoEx(ccs_request_IfHandle,\r
+                                                   0, // principal\r
+                                                   RPC_C_AUTHN_LEVEL_CONNECT,\r
+                                                   RPC_C_AUTHN_WINNT,\r
+                                                   0, // current address space\r
+                                                   RPC_C_AUTHZ_NAME,\r
+                                                   &qos);\r
+            cci_check_error(status);\r
+            }\r
+        }\r
+\r
+    if (pszStringBinding) {\r
+        DWORD status = RpcStringFree(&pszStringBinding); \r
+        cci_check_error(status);\r
+        }\r
+    return cci_check_error(status);\r
+    }\r
+\r
+DWORD find_server(Init::InitInfo& info, LPSTR endpoint) {\r
+    DWORD               status      = 0;\r
+    LPSTR               event_name  = 0;\r
+    HANDLE              hEvent      = 0;\r
+    SECURITY_ATTRIBUTES sa          = { 0 };\r
+    PSECURITY_ATTRIBUTES psa        = 0;\r
+    STARTUPINFO         si          = { 0 };\r
+    PROCESS_INFORMATION pi          = { 0 };\r
+    char*               szExe       = 0;\r
+    char*               szDir       = 0;\r
+    BOOL                bRes        = FALSE;\r
+    char*               cmdline     = NULL;\r
+#if 0\r
+    HANDLE hToken = 0;\r
+#endif\r
+\r
+    psa = isNT() ? &sa : 0;\r
+\r
+//    cci_debug_printf("%s Looking for server; ccs_request_IfHandle:0x%X", __FUNCTION__, ccs_request_IfHandle);\r
+    status = cci_check_error(RpcMgmtIsServerListening(ccs_request_IfHandle));\r
+    if (status == RPC_S_NOT_LISTENING) {\r
+//        cci_debug_printf("  Server *NOT* found!");\r
+        si.cb = sizeof(si);\r
+\r
+        status = alloc_module_dir_name(CCAPI_DLL, &szDir);\r
+\r
+        if (!status) {\r
+            status = alloc_module_dir_name_with_file(CCAPI_DLL, CCAPI_EXE, &szExe);\r
+            }\r
+\r
+        if (!status) {\r
+            status = alloc_name(&event_name, "startup", isNT());\r
+            cci_check_error(status);\r
+            }\r
+\r
+        if (!status) {\r
+            if (isNT()) {\r
+                sa.nLength = sizeof(sa);\r
+                status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor);\r
+                cci_check_error(status);\r
+                }\r
+            }\r
+\r
+        if (!status) {\r
+            hEvent = CreateEvent(psa, FALSE, FALSE, event_name);\r
+            cci_debug_printf("  CreateEvent(... %s) returned hEvent 0x%X", event_name, hEvent);\r
+            if (!hEvent) status = GetLastError();\r
+            }\r
+\r
+        if (!status) {\r
+\r
+#if 0\r
+            if (SecureClient::IsImp()) {\r
+                cci_debug_printf(STARTUP "Token is impersonation token"));\r
+                SecureClient::DuplicateImpAsPrimary(hToken);\r
+                } \r
+            else {\r
+                cci_debug_printf(STARTUP "Token is NOT impersonation token"));\r
+                }\r
+#endif\r
+\r
+#if 0\r
+            if (hToken)\r
+                bRes = CreateProcessAsUser(hToken,\r
+                                       szExe, // app name\r
+                                       NULL, // cmd line\r
+                                       psa, // SA\r
+                                       psa, // SA\r
+                                       FALSE, \r
+                                       CREATE_NEW_PROCESS_GROUP | \r
+                                       //CREATE_NEW_CONSOLE |\r
+                                       NORMAL_PRIORITY_CLASS |\r
+                                       // CREATE_NO_WINDOW |\r
+                                       DETACHED_PROCESS |\r
+                                       0\r
+                                       ,\r
+                                       NULL, // environment\r
+                                       szDir, // current dir\r
+                                       &si,\r
+                                       &pi);\r
+            else\r
+#endif\r
+                alloc_cmdline_2_args(szExe, endpoint, "-D", &cmdline);\r
+                bRes = CreateProcess(  szExe,       // app name\r
+                                       NULL, //cmdline,     // cmd line is <server endpoint -[DC]>\r
+                                       psa,         // SA\r
+                                       psa,         // SA\r
+                                       FALSE, \r
+                                       CREATE_NEW_PROCESS_GROUP | \r
+                                       CREATE_NEW_CONSOLE |\r
+                                       NORMAL_PRIORITY_CLASS |\r
+                                       // CREATE_NO_WINDOW |\r
+                                       // DETACHED_PROCESS |    /* KPK TODO: was set - restore */\r
+                                       0\r
+                                       ,\r
+                                       NULL,        // environment\r
+                                       szDir,       // current dir\r
+                                       &si,\r
+                                       &pi);\r
+            if (!bRes) {\r
+                status = GetLastError();\r
+                cci_debug_printf("  CreateProcess returned %d; LastError: %d", bRes, status);\r
+                }\r
+            cci_debug_printf("  Waiting...");\r
+            }\r
+        cci_check_error(status);\r
+\r
+        if (!status) {\r
+            status = WaitForSingleObject(hEvent, (SECONDS_TO_WAIT)*1000);\r
+            status = RpcMgmtIsServerListening(ccs_request_IfHandle);\r
+            }\r
+        } \r
+    else if (status) {\r
+            cci_debug_printf("  unexpected error while looking for server: 0D%d / 0U%u / 0X%X", status, status, status);\r
+            } \r
+\r
+#if 0\r
+    if (hToken)\r
+        CloseHandle(hToken);\r
+#endif\r
+    if (szDir)                      free_alloc_p(&szDir);\r
+    if (szExe)                      free_alloc_p(&szExe);\r
+    if (hEvent)                     CloseHandle(hEvent);\r
+    if (pi.hThread)                 CloseHandle(pi.hThread);\r
+    if (pi.hProcess)                CloseHandle(pi.hProcess);\r
+    if (sa.lpSecurityDescriptor)    free_alloc_p(&sa.lpSecurityDescriptor);\r
+    return cci_check_error(status);\r
+\r
+}\r
+\r
+static\r
+DWORD\r
+authenticate_server(Init::InitInfo& info) {\r
+    DWORD               challenge       = 17; // XXX - maybe use random number\r
+    DWORD               desired_response= challenge + 1;\r
+    HANDLE              hMap            = 0;\r
+    LPSTR               mem_name        = 0;\r
+    PDWORD              pvalue          = 0;\r
+    CC_UINT32           response        = 0;\r
+    SECURITY_ATTRIBUTES sa              = { 0 };\r
+    DWORD               status          = 0;\r
+\r
+    cci_debug_printf("%s entry", __FUNCTION__);\r
+\r
+    status = alloc_name(&mem_name, "auth", isNT());\r
+    cci_check_error(status);\r
+\r
+    if (!status) {\r
+        if (isNT()) {\r
+            sa.nLength = sizeof(sa);\r
+            status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor);\r
+            }\r
+        }\r
+    cci_check_error(status);\r
+\r
+    if (!status) {\r
+        hMap = CreateFileMapping(INVALID_HANDLE_VALUE, isNT() ? &sa : 0, \r
+                                 PAGE_READWRITE, 0, sizeof(DWORD), mem_name);\r
+        if (!hMap)\r
+        status = GetLastError();\r
+        }\r
+    cci_check_error(status);\r
+\r
+    if (!status) {\r
+        pvalue = (PDWORD)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);\r
+        if (!pvalue) status = GetLastError();\r
+        }\r
+    cci_check_error(status);\r
+\r
+    if (!status) {\r
+        *pvalue = challenge;\r
+\r
+        RpcTryExcept {\r
+            response = ccs_authenticate( (CC_CHAR*)mem_name );\r
+            }\r
+        RpcExcept(1) {\r
+            status = RpcExceptionCode();\r
+            cci_check_error(status);\r
+            }\r
+        RpcEndExcept;\r
+        }\r
+    cci_check_error(status);\r
+\r
+    if (!status) {\r
+        // Check response\r
+        if ((response != desired_response) && (*pvalue != desired_response)) {\r
+            cci_debug_printf("  Could not authenticate server.");\r
+            status = ERROR_ACCESS_DENIED; // XXX - CO_E_NOMATCHINGSIDFOUND?\r
+            } \r
+        else {\r
+            cci_debug_printf("  Server authenticated!");\r
+            }\r
+        cci_check_error(status);\r
+        }\r
+\r
+    free_alloc_p(&mem_name);\r
+    free_alloc_p(&sa.lpSecurityDescriptor);\r
+    if (pvalue) {\r
+        BOOL ok = UnmapViewOfFile(pvalue);\r
+//        DEBUG_ASSERT(ok);\r
+        }\r
+    if (hMap) CloseHandle(hMap);\r
+    return status;\r
+}\r
+\r
+DWORD\r
+Client::Disconnect() {\r
+    DWORD status = 0;\r
+    if (ccs_request_IfHandle) {\r
+        /*  The calls to the remote procedures are complete. */\r
+        /*  Free the binding handle           */\r
+        status = RpcBindingFree(&ccs_request_IfHandle);\r
+        }\r
+    s_init  = false;\r
+    return status;\r
+    }\r
+\r
+DWORD\r
+Client::Connect(char* ep OPTIONAL) {\r
+    LPSTR   endpoint    = 0;\r
+    DWORD   status      = 0;\r
+\r
+    if (!ccs_request_IfHandle) {\r
+        Init::InitInfo info;\r
+\r
+        status = Init::Info(info);\r
+        cci_check_error(status);\r
+\r
+        if (!status) {\r
+            status = bind_client(ep, info, &endpoint);\r
+            cci_check_error(status);\r
+            }\r
+\r
+        if (!status) {\r
+            status = find_server(info, endpoint);\r
+            cci_check_error(status);\r
+            }\r
+\r
+        if (!status) {\r
+            status = authenticate_server(info);\r
+            cci_check_error(status);\r
+            }\r
+        }\r
+\r
+\r
+    if (endpoint && (endpoint != ep)) free_alloc_p(&endpoint);\r
+    \r
+    if (status) Client::Disconnect();\r
+    return status;\r
+    }\r
+\r
+DWORD Client::Initialize(char* ep OPTIONAL) {\r
+    CcAutoLock AL(Client::sLock);\r
+    SecureClient s;\r
+    ccs_request_IfHandle  = NULL;\r
+    if (s_init) return 0;\r
+    DWORD status = Client::Connect(ep);\r
+    if (!status) s_init = true;\r
+    return status;\r
+    }\r
+\r
+DWORD Client::Cleanup() {\r
+    CcAutoLock AL(Client::sLock);\r
+    SecureClient s;\r
+    return Client::Disconnect();\r
+    }\r
+\r
+DWORD Client::Reconnect(char* ep OPTIONAL) {\r
+    CcAutoLock AL(Client::sLock);\r
+    SecureClient s;\r
+    DWORD status = 0;\r
+\r
+    if (Initialized()) {\r
+        DWORD status = Client::Cleanup();\r
+        }\r
+    if ( (!status) ) {\r
+        status = Client::Initialize(ep);\r
+        }\r
+\r
+    return status;\r
+    }\r
diff --git a/src/ccapi/lib/win/OldCC/client.h b/src/ccapi/lib/win/OldCC/client.h
new file mode 100644 (file)
index 0000000..f263ce1
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef __DLL_CLIENT_H__\r
+#define __DLL_CLIENT_H__\r
+\r
+#include "autolock.hxx"\r
+#include "init.hxx"\r
+\r
+class Client {\r
+public:\r
+    static DWORD Initialize(char* ep OPTIONAL);\r
+    static DWORD Cleanup();\r
+    static DWORD Reconnect(char* ep OPTIONAL);\r
+\r
+    static bool Initialized() { return s_init; }\r
+\r
+    static CcOsLock sLock;\r
+\r
+private:\r
+    static bool s_init;\r
+\r
+    static DWORD Disconnect();\r
+    static DWORD Connect(char* ep OPTIONAL);\r
+    };\r
+\r
+#define CLIENT_INIT_EX(trap, error) \\r
+do \\r
+{ \\r
+    INIT_INIT_EX(trap, error); \\r
+    if (!Client::Initialized()) \\r
+    { \\r
+        DWORD status = Client::Initialize(0); \\r
+        if (status) return (trap) ? (error) : status; \\r
+    } \\r
+} while(0)\r
+\r
+#endif\r
diff --git a/src/ccapi/lib/win/OldCC/rpc.cxx b/src/ccapi/lib/win/OldCC/rpc.cxx
new file mode 100644 (file)
index 0000000..332f1c5
--- /dev/null
@@ -0,0 +1,79 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+\r
+extern "C" {\r
+#include "CredentialsCache.h"\r
+#include "secure.hxx"\r
+#include "client.h"\r
+#include "autolock.hxx"\r
+#include "cci_debugging.h"\r
+    }\r
+\r
+extern HANDLE hCCAPIv2Mutex;\r
+\r
+#define MAKE_RPC_CALL(rc, x) \\r
+do { \\r
+    WaitForSingleObject( hCCAPIv2Mutex, INFINITE ); \\r
+    SecureClient* s = 0; \\r
+    SecureClient::Start(s); \\r
+    CcAutoLock* a = 0; \\r
+    CcAutoLock::Start(a, Client::sLock); \\r
+    RpcTryExcept { \\r
+    cci_debug_printf("RpcTry: #x"); \\r
+        x; \\r
+    } \\r
+    RpcExcept(1) { \\r
+        rc = handle_exception(RpcExceptionCode()); \\r
+    } \\r
+    RpcEndExcept; \\r
+    CcAutoLock::Stop(a); \\r
+    SecureClient::Stop(s); \\r
+    ReleaseMutex( hCCAPIv2Mutex ); \\r
+} while (0)\r
+\r
+static\r
+DWORD\r
+handle_exception(DWORD code) {\r
+    cci_debug_printf("Runtime reported exception %u", code);\r
+    if (code == RPC_S_SERVER_UNAVAILABLE) {\r
+        Client::Reconnect(0);\r
+        }\r
+    return 4;\r
+    }\r
+\r
+//////////////////////////////////////////////////////////////////////////////\r
+\r
+cc_int32 cc_initialize() {\r
+\r
+    CLIENT_INIT_EX(true, 4);\r
+    cc_int32 rc = ccNoError;\r
+\r
+    MAKE_RPC_CALL(rc, rc = 5);\r
+    return rc;\r
+    }
\ No newline at end of file
diff --git a/src/ccapi/lib/win/WINCCAPI.sln b/src/ccapi/lib/win/WINCCAPI.sln
new file mode 100644 (file)
index 0000000..985f4c6
--- /dev/null
@@ -0,0 +1,20 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 9.00\r
+# Visual Studio 2005\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WINCCAPI", "WINCCAPI.vcproj", "{1137FC16-E53E-48C1-8293-085B4BE68C32}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Win32 = Debug|Win32\r
+               Release|Win32 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {1137FC16-E53E-48C1-8293-085B4BE68C32}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {1137FC16-E53E-48C1-8293-085B4BE68C32}.Debug|Win32.Build.0 = Debug|Win32\r
+               {1137FC16-E53E-48C1-8293-085B4BE68C32}.Release|Win32.ActiveCfg = Release|Win32\r
+               {1137FC16-E53E-48C1-8293-085B4BE68C32}.Release|Win32.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/src/ccapi/lib/win/WINCCAPI.vcproj b/src/ccapi/lib/win/WINCCAPI.vcproj
new file mode 100644 (file)
index 0000000..69b7722
--- /dev/null
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="8.00"\r
+       Name="WINCCAPI"\r
+       ProjectGUID="{1137FC16-E53E-48C1-8293-085B4BE68C32}"\r
+       RootNamespace="WINCCAPI"\r
+       Keyword="MakeFileProj"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="Debug"\r
+                       IntermediateDirectory="Debug"\r
+                       ConfigurationType="0"\r
+                       >\r
+                       <Tool\r
+                               Name="VCNMakeTool"\r
+                               BuildCommandLine="nmake"\r
+                               ReBuildCommandLine="nmake"\r
+                               CleanCommandLine="nmake clean"\r
+                               Output="output.log"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;"\r
+                               IncludeSearchPath=""\r
+                               ForcedIncludes=""\r
+                               AssemblySearchPath=""\r
+                               ForcedUsingAssemblies=""\r
+                               CompileAsManaged=""\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="Release"\r
+                       IntermediateDirectory="Release"\r
+                       ConfigurationType="0"\r
+                       >\r
+                       <Tool\r
+                               Name="VCNMakeTool"\r
+                               BuildCommandLine="nmake"\r
+                               ReBuildCommandLine="nmake"\r
+                               CleanCommandLine="nmake clean"\r
+                               Output="output.log"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;"\r
+                               IncludeSearchPath=""\r
+                               ForcedIncludes=""\r
+                               AssemblySearchPath=""\r
+                               ForcedUsingAssemblies=""\r
+                               CompileAsManaged=""\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\..\common\win\win-utils.h"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+                       >\r
+               </Filter>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\..\common\win\ccs_reply.Idl"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\ccs_request.idl"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\win-utils.c"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <File\r
+                       RelativePath="..\..\common\win\ccs_reply.Acf"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath="..\..\common\win\ccs_request.Acf"\r
+                       >\r
+               </File>\r
+               <File\r
+                       RelativePath=".\Makefile"\r
+                       >\r
+               </File>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/src/ccapi/lib/win/ccapi.def b/src/ccapi/lib/win/ccapi.def
new file mode 100644 (file)
index 0000000..0450331
--- /dev/null
@@ -0,0 +1,39 @@
+;LIBRARY               COMERR32\r
+HEAPSIZE       8192\r
+\r
+EXPORTS\r
+    cci_debug_printf\r
+    \r
+    cc_initialize\r
+\r
+       cci_string_new\r
+       cci_string_d_initializer\r
+       ccapi_string_release\r
+\r
+    cci_credentials_iterator_new \r
+    cci_credentials_iterator_write \r
+\r
+    cci_ccache_iterator_new \r
+    cci_ccache_iterator_write \r
+\r
+    ccapi_ccache_iterator_release \r
+    ccapi_ccache_iterator_next \r
+    ccapi_ccache_iterator_clone     \r
+\r
+    ccapi_credentials_iterator_release \r
+    ccapi_credentials_iterator_next \r
+    ccapi_credentials_iterator_clone\r
+    \r
+;debugging:\r
+    _cci_check_error\r
+    cci_os_ipc\r
+    cci_os_ipc_msg\r
+    cci_os_ipc_thread_init\r
+    cci_stream_data\r
+    cci_stream_write\r
+    cci_stream_new\r
+    \r
+    ccs_authenticate\r
+    \r
+           \r
+       
\ No newline at end of file
diff --git a/src/ccapi/lib/win/ccapi_os_ipc.cxx b/src/ccapi/lib/win/ccapi_os_ipc.cxx
new file mode 100644 (file)
index 0000000..7ee9176
--- /dev/null
@@ -0,0 +1,373 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+extern "C" {\r
+#include "k5-thread.h"\r
+#include "ccapi_os_ipc.h"\r
+#include "tls.h"\r
+#include "dllmain.h"\r
+#include "ccs_reply.h"\r
+#include "ccs_request.h"\r
+#include "win-utils.h"\r
+#include "ccutils.h"\r
+#include "util.h"\r
+    }\r
+\r
+#include "CredentialsCache.h"\r
+#include "secure.hxx"\r
+#include "opts.hxx"\r
+#include "client.h"\r
+#include "autolock.hxx"\r
+#include "cci_debugging.h"\r
+\r
+#define SECONDS_TO_WAIT 10\r
+#define CLIENT_REQUEST_RPC_HANDLE ccs_request_IfHandle\r
+\r
+extern HANDLE           hCCAPIv2Mutex;\r
+ParseOpts::Opts         opts                = { 0 };\r
+PSECURITY_ATTRIBUTES    psa                 = 0;\r
+SECURITY_ATTRIBUTES     sa                  = { 0 };\r
+\r
+/* The layout of the rest of this module:  \r
+\r
+   The entrypoints defined in ccs_os_ipc.h:\r
+    cci_os_ipc_thread_init\r
+    cci_os_ipc\r
+\r
+   Other routines needed by those four.\r
+    cci_os_connect\r
+    handle_exception\r
+ */\r
+\r
+cc_int32        ccapi_connect(const struct tspdata* tsp);\r
+static DWORD    handle_exception(DWORD code);\r
+\r
+extern "C" {\r
+cc_int32        cci_os_ipc_msg( cc_int32        in_launch_server,\r
+                                cci_stream_t    in_request_stream,\r
+                                cc_int32        in_msg,\r
+                                cci_stream_t*   out_reply_stream);\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+extern "C" cc_int32 cci_os_ipc_thread_init (void) {\r
+    cc_int32                    err         = ccNoError;\r
+    struct tspdata*             ptspdata;\r
+    HANDLE                      replyEvent;\r
+    UUID __RPC_FAR              uuid;\r
+    unsigned char __RPC_FAR*    uuidString  = NULL;\r
+\r
+    if (!GetTspData(&ptspdata)) return ccErrNoMem;\r
+\r
+    opts.cMinCalls  = 1;\r
+    opts.cMaxCalls  = 20;\r
+    opts.fDontWait  = TRUE;\r
+\r
+    err   = cci_check_error(UuidCreate(&uuid)); // Get a UUID\r
+    if (err == RPC_S_OK) {                      // Convert to string\r
+        err = UuidToString(&uuid, &uuidString);\r
+        }\r
+    if (!err) {                                 // Save in thread local storage\r
+        tspdata_setUUID(ptspdata, uuidString);\r
+        }\r
+    cci_debug_printf("%s UUID:<%s>", __FUNCTION__, tspdata_getUUID(ptspdata));\r
+\r
+    // Initialize old CCAPI if necessary:\r
+    if (!err) if (!Init::  Initialized()) err = Init::  Initialize( );\r
+    if (!err) if (!Client::Initialized()) err = Client::Initialize(0);\r
+\r
+    if (!err) {\r
+        /* Whenever a reply to an RPC request is received, the RPC caller needs to\r
+           know when the reply has been received.  It does that by waiting for a \r
+           client-specific event to be set.  Define the event name to be <UUID>_reply:  */\r
+        replyEvent = createThreadEvent((char*)uuidString, REPLY_SUFFIX);\r
+        }\r
+\r
+    if (replyEvent) tspdata_setReplyEvent(ptspdata, replyEvent);\r
+    else            err = cci_check_error(GetLastError());\r
+\r
+    if (uuidString) RpcStringFree(&uuidString);\r
+\r
+    return cci_check_error(err);\r
+    }\r
+\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 cci_os_ipc (cc_int32      in_launch_server,\r
+                     cci_stream_t  in_request_stream,\r
+                     cci_stream_t* out_reply_stream) {\r
+    return cci_os_ipc_msg(  in_launch_server, \r
+                            in_request_stream, \r
+                            CCMSG_REQUEST, \r
+                            out_reply_stream);\r
+    }\r
+\r
+extern "C" cc_int32 cci_os_ipc_msg( cc_int32        in_launch_server,\r
+                                    cci_stream_t    in_request_stream,\r
+                                    cc_int32        in_msg,\r
+                                    cci_stream_t*   out_reply_stream) {\r
+\r
+    cc_int32        err             = ccNoError;\r
+    cc_int32        done            = FALSE;\r
+    cc_int32        try_count       = 0;\r
+    cc_int32        server_died     = FALSE;\r
+    TCHAR*          pszStringBinding= NULL;\r
+    struct tspdata* ptspdata        = NULL;\r
+    char*           uuid            = NULL;\r
+    int             lenUUID         = 0;\r
+    unsigned int    trycount        = 0;\r
+    time_t          sst             = 0;\r
+    STARTUPINFO             si      = { 0 };\r
+    PROCESS_INFORMATION     pi      = { 0 };\r
+    HANDLE          replyEvent      = 0;\r
+    BOOL            bCCAPI_Connected= FALSE;\r
+\r
+    if (!in_request_stream) { err = cci_check_error (ccErrBadParam); }\r
+    if (!out_reply_stream ) { err = cci_check_error (ccErrBadParam); }\r
+    \r
+    if (!GetTspData(&ptspdata)) {return ccErrBadParam;}\r
+    bCCAPI_Connected = tspdata_getConnected  (ptspdata);\r
+    replyEvent       = tspdata_getReplyEvent (ptspdata);\r
+    sst              = tspdata_getSST (ptspdata);\r
+    uuid             = tspdata_getUUID(ptspdata);\r
+\r
+    // The lazy connection to the server has been put off as long as possible!\r
+    // ccapi_connect starts listening for replies as an RPC server and then\r
+    //   calls ccs_rpc_connect.\r
+    if (!bCCAPI_Connected) {\r
+        err                 = cci_check_error(ccapi_connect(ptspdata));\r
+        bCCAPI_Connected    = !err;\r
+        tspdata_setConnected(ptspdata, bCCAPI_Connected);\r
+        }\r
+\r
+    // Clear replyEvent so we can detect when a reply to our request has been received:\r
+    ResetEvent(replyEvent);\r
+    \r
+    //++ Use the old CCAPI implementation to try to talk to the server:\r
+    // It has all the code to use the RPC in a thread-safe way, make the endpoint, \r
+    //   (re)connect and (re)start the server.\r
+    // Note:  the old implementation wrapped the thread-safety stuff in a macro.\r
+    //   Here it is expanded and thus duplicated for each RPC call.  The new code has\r
+    //   a very limited number of RPC calls, unlike the older code.\r
+    WaitForSingleObject( hCCAPIv2Mutex, INFINITE );\r
+    SecureClient*   s = 0;\r
+    SecureClient::Start(s);\r
+    CcAutoLock*     a = 0;\r
+    CcAutoLock::Start(a, Client::sLock);\r
+\r
+    // Initialize old CCAPI if necessary:\r
+    if (!err) if (!Init::  Initialized()) err = cci_check_error(Init::  Initialize( ));\r
+    if (!err) if (!Client::Initialized()) err = cci_check_error(Client::Initialize(0));\r
+\r
+    // New code using new RPC procedures for sending the data and receiving a reply:\r
+    if (!err) {\r
+        RpcTryExcept {\r
+            if (!GetTspData(&ptspdata)) {return ccErrBadParam;}\r
+            uuid    = tspdata_getUUID(ptspdata);\r
+            lenUUID = 1 + strlen(uuid);     /* 1+ includes terminating \0. */\r
+            cci_debug_printf("%s calling remote ccs_rpc_request tsp*:0x%X", __FUNCTION__, ptspdata);\r
+            cci_debug_printf("  rpcmsg:%d; UUID[%d]:<%s> SST:%ld", in_msg, lenUUID, uuid, sst);\r
+\r
+            ccs_rpc_request(                    /* make call with user message: */\r
+                in_msg,                         /* Message type */\r
+                (unsigned char*)&ptspdata,      /* Our tspdata* will be sent back to the reply proc. */\r
+                (unsigned char*)uuid,\r
+                cci_stream_size(in_request_stream),\r
+                (unsigned char*)cci_stream_data(in_request_stream), /* Data buffer */\r
+                sst,                            /* session start time */\r
+                (long*)(&err) );                /* Return code */\r
+            }\r
+        RpcExcept(1) {\r
+            handle_exception(RpcExceptionCode());\r
+            }\r
+        RpcEndExcept;\r
+        }\r
+\r
+    cci_check_error(err);\r
+    CcAutoLock::Stop(a);\r
+    SecureClient::Stop(s);\r
+    ReleaseMutex(hCCAPIv2Mutex);       \r
+    //-- Use the old CCAPI implementation to try to talk to the server.\r
+\r
+    // Wait for reply handler to set event:\r
+    if (!err) {\r
+        cci_debug_printf("  Waiting for request reply.");\r
+        err = cci_check_error(WaitForSingleObject(replyEvent, INFINITE));//(SECONDS_TO_WAIT)*1000));\r
+        cci_debug_printf("  Request reply received!");\r
+        }\r
+\r
+    if (!err) {\r
+        err = cci_check_error(RpcMgmtIsServerListening(CLIENT_REQUEST_RPC_HANDLE));\r
+        }\r
+\r
+    if (!err && server_died) {\r
+        err = cci_check_error (ccErrServerUnavailable);\r
+        }\r
+#if 0    \r
+    if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) {\r
+        err = ccNoError;  /* If the server is not running just return an empty stream. */\r
+        }\r
+#endif\r
+\r
+    if (!err) {\r
+        *out_reply_stream = tspdata_getStream(ptspdata);\r
+        }\r
+    \r
+    cci_debug_printf("  payload:<%s>", cci_stream_data(*out_reply_stream));\r
+\r
+    return cci_check_error (err);    \r
+    }\r
+\r
+\r
+\r
+static DWORD handle_exception(DWORD code) {\r
+    cci_debug_printf("%s code %u; ccs_request_IfHandle:0x%X", __FUNCTION__, code, ccs_request_IfHandle);\r
+    if ( (code == RPC_S_SERVER_UNAVAILABLE) || (code == RPC_S_INVALID_BINDING) ) {\r
+        Client::Reconnect(0);\r
+        }\r
+    return 4;\r
+    }\r
+\r
+\r
+/* Establish a CCAPI connection with the server.\r
+ * The connect logic here is identical to the logic in the send request code.\r
+ * TODO:  merge this connect code with that request code.\r
+ */\r
+cc_int32 ccapi_connect(const struct tspdata* tsp) {\r
+    BOOL                    bListen     = TRUE;\r
+    char*                   endpoint    = NULL;\r
+    HANDLE                  replyEvent  = 0;\r
+    RPC_STATUS              status      = FALSE;\r
+    char*                   uuid        = NULL;\r
+\r
+    /* Start listening to our uuid before establishing the connection,\r
+     *  so that when the server tries to call ccapi_listen, we will be ready.\r
+     */\r
+\r
+    /* Build complete RPC uuid using previous CCAPI implementation: */\r
+    replyEvent      = tspdata_getReplyEvent(tsp);\r
+    uuid            = tspdata_getUUID(tsp);\r
+    endpoint        = clientEndpoint(uuid);\r
+    cci_debug_printf("%s Registering endpoint %s", __FUNCTION__, endpoint);\r
+\r
+    opts.cMinCalls  = 1;\r
+    opts.cMaxCalls  = 20;\r
+    opts.fDontWait  = TRUE;\r
+\r
+    if (!status) {\r
+        status = RpcServerUseProtseqEp((RPC_CSTR)"ncalrpc",\r
+                                       opts.cMaxCalls,\r
+                                       (RPC_CSTR)endpoint,\r
+                                       sa.lpSecurityDescriptor);  // SD\r
+        cci_check_error(status);\r
+        }\r
+\r
+    if (!status) {\r
+        status = RpcServerRegisterAuthInfo(0, // server principal\r
+                                           RPC_C_AUTHN_WINNT,\r
+                                           0,\r
+                                           0 );\r
+        cci_check_error(status);\r
+        }\r
+\r
+    cci_debug_printf("%s is listening ...", __FUNCTION__);\r
+\r
+    if (!status) {\r
+        if (!isNT()) {\r
+            status = RpcServerRegisterIf(ccs_reply_ServerIfHandle,  // interface \r
+                                         NULL,                      // MgrTypeUuid\r
+                                         NULL);                     // MgrEpv; null means use default\r
+            } \r
+        else {\r
+            status = RpcServerRegisterIfEx(ccs_reply_ServerIfHandle,// interface\r
+                                         NULL,                      // MgrTypeUuid\r
+                                         NULL,                      // MgrEpv; 0 means default\r
+                                         RPC_IF_ALLOW_SECURE_ONLY,\r
+                                         opts.cMaxCalls,\r
+                                         NULL);                     // No security callback.\r
+            }\r
+\r
+        cci_check_error(status);\r
+\r
+        if (!status) {\r
+            status = RpcServerListen(opts.cMinCalls,\r
+                                     opts.cMaxCalls,\r
+                                     TRUE);\r
+            cci_check_error(status);\r
+            }\r
+        }\r
+\r
+    // Clear replyEvent so we can detect when a reply to our connect request has been received:\r
+    ResetEvent(replyEvent);\r
+\r
+    // We use the old CCAPI implementation to try to talk to the server.  \r
+    // It has all the code to make the uuid, (re)connect and (re)start the server.\r
+    WaitForSingleObject( hCCAPIv2Mutex, INFINITE );\r
+    SecureClient*   s = 0;\r
+    SecureClient::Start(s);\r
+    CcAutoLock*     a = 0;\r
+    CcAutoLock::Start(a, Client::sLock);\r
+\r
+    // Initialize old CCAPI if necessary:\r
+    if (!status) if (!Init::  Initialized()) status = Init::  Initialize( );\r
+    if (!status) if (!Client::Initialized()) status = Client::Initialize(0);\r
+\r
+    // New code using new RPC procedures for sending the data and receiving a reply:\r
+    if (!status) {\r
+        RpcTryExcept {\r
+            ccs_rpc_connect(                /* make call with user message: */\r
+                CCMSG_CONNECT,              /* Message type */\r
+                (unsigned char*)&tsp,       /* Our tspdata* will be sent back to the reply proc. */\r
+                (unsigned char*)uuid,\r
+                (long*)(&status) );         /* Return code */\r
+            }\r
+        RpcExcept(1) {\r
+            cci_check_error(RpcExceptionCode());\r
+            status  = ccErrBadInternalMessage;\r
+            }\r
+        RpcEndExcept;\r
+        }\r
+\r
+    CcAutoLock::Stop(a);\r
+    SecureClient::Stop(s);\r
+    ReleaseMutex(hCCAPIv2Mutex);       \r
+\r
+    if (!status) {\r
+        cci_debug_printf("%s Waiting for replyEvent.", __FUNCTION__);\r
+        status = WaitForSingleObject(replyEvent, INFINITE);//(SECONDS_TO_WAIT)*1000);\r
+        status = cci_check_error(RpcMgmtIsServerListening(CLIENT_REQUEST_RPC_HANDLE));\r
+        cci_debug_printf("  Server %sFOUND!", (status) ? "NOT " : "");\r
+        }\r
+    if (status) {\r
+        cci_debug_printf("  unexpected error while looking for server... (%u)", status);\r
+        } \r
+    \r
+    cci_debug_printf("%s TODO:  check connect reply result.", __FUNCTION__);\r
+    cci_debug_printf("%s TODO:  merge this connect code with that request code.", __FUNCTION__);\r
+    return status;\r
+    }
\ No newline at end of file
diff --git a/src/ccapi/lib/win/ccs_reply_proc.c b/src/ccapi/lib/win/ccs_reply_proc.c
new file mode 100644 (file)
index 0000000..ebac6e3
--- /dev/null
@@ -0,0 +1,98 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <windows.h>\r
+\r
+#include "cci_debugging.h"\r
+#include "ccs_reply.h"          /* generated by MIDL compiler */\r
+#include "ccutils.h"\r
+#include "tls.h"\r
+#include "win-utils.h"\r
+\r
+\r
+void ccs_rpc_request_reply(\r
+    const long  rpcmsg,         /* Message type */\r
+    const char  tspHandle[],    /* Client's tspdata* */\r
+    const char* uuid,           /* uuid for making thread-specific event name */\r
+    const long  srvStartTime,   /* Server Start Time */\r
+    const long  cbIn,           /* Length of buffer */\r
+    const char* chIn,           /* Data buffer */\r
+    long*       ret_status ) {  /* Return code */\r
+\r
+    HANDLE          hEvent  = openThreadEvent(uuid, REPLY_SUFFIX);\r
+    DWORD*          p       = (DWORD*)(tspHandle);\r
+    struct tspdata* tsp     = (struct tspdata*)*p;\r
+    cci_stream_t    stream;\r
+    long            status  = 0;\r
+\r
+    cci_debug_printf("%s! msg#:%d SST:%ld uuid:%s", __FUNCTION__, rpcmsg, srvStartTime, uuid);\r
+    cci_debug_printf("  payload:<%s>", chIn);\r
+    cci_debug_printf("  uuid from handle:<%s>", tspdata_getUUID(tsp));\r
+\r
+    if (!status) {                         \r
+        status = cci_stream_new (&stream);  /* Create a stream for the request data */\r
+        }\r
+\r
+    if (!status) {                          /* Put the data into the stream */\r
+        status = cci_stream_write (stream, chIn, cbIn);\r
+        }\r
+\r
+    if (!status) {                          /* Put the data into the stream */\r
+        tspdata_setStream(tsp, stream);\r
+        }\r
+\r
+    SetEvent(hEvent);\r
+    CloseHandle(hEvent);\r
+    *ret_status  = status;\r
+    }\r
+\r
+void ccs_rpc_connect_reply(\r
+    const long  rpcmsg,         /* Message type */\r
+    const char  tspHandle[],    /* Client's tspdata* */\r
+    const char* uuid,           /* uuid for making thread-specific event name */\r
+    const long  srvStartTime,   /* Server Start Time */\r
+    long*       status ) {      /* Return code */\r
+\r
+    HANDLE  hEvent  = openThreadEvent(uuid, REPLY_SUFFIX);\r
+    DWORD*  p       = (DWORD*)(tspHandle);\r
+\r
+    cci_debug_printf("%s! msg#:%d SST:%ld uuid:%s", __FUNCTION__, rpcmsg, srvStartTime, uuid);\r
+\r
+    SetEvent(hEvent);\r
+    CloseHandle(hEvent);\r
+    }\r
+\r
+void ccapi_listen(\r
+    RPC_ASYNC_STATE*    rpcState,\r
+    handle_t            hBinding,\r
+    const long          rpcmsg,         /* Message type */\r
+    long*               status ) {      /* Return code */\r
+\r
+    cci_debug_printf("%s %s!", __FUNCTION__, rpcState->UserInfo);\r
+    *status = 0;\r
+    }\r
diff --git a/src/ccapi/lib/win/dllmain.cxx b/src/ccapi/lib/win/dllmain.cxx
new file mode 100644 (file)
index 0000000..7000e14
--- /dev/null
@@ -0,0 +1,279 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <windows.h>\r
+#include <LMCons.h>\r
+\r
+extern "C" {\r
+#include "dllmain.h"\r
+#include "tls.h"\r
+#include "cci_debugging.h"\r
+#include "ccapi_context.h"\r
+#include "client.h"\r
+\r
+//void cci_thread_init__auxinit();\r
+    }\r
+\r
+#define CCAPI_V2_MUTEX_NAME     TEXT("MIT_CCAPI_V4_MUTEX")\r
+\r
+// Process-specific data:\r
+static DWORD    dwTlsIndex;\r
+static char     _user[UNLEN+1];     // Username is used as part of the server and client endpoints.\r
+static  HANDLE  sessionToken;\r
+static char*    ep_prefices[]   = {"CCS", "CCAPI"};\r
+HANDLE          hCCAPIv2Mutex   = NULL;\r
+DWORD           firstThreadID   = 0;\r
+\r
+// These data structures are used by the old CCAPI implementation \r
+//  to keep track of the state of the RPC connection.  All data is static.\r
+static Init     init;\r
+static Client   client;\r
+\r
+// DllMain() is the entry-point function for this DLL. \r
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,     // DLL module handle\r
+                    DWORD fdwReason,        // reason called\r
+                    LPVOID lpvReserved) {   // reserved \r
+\r
+    struct tspdata* ptspdata;\r
+    BOOL            fIgnore;\r
+    BOOL            bStatus;\r
+    DWORD           status      = 0;        // 0 is success.\r
+    DWORD           maxUN       = sizeof(_user);\r
+    unsigned int    i           = 0;\r
+    unsigned int    j           = 0;\r
\r
+    switch (fdwReason) { \r
+        // The DLL is loading due to process initialization or a call to LoadLibrary:\r
+        case DLL_PROCESS_ATTACH: \r
+            cci_debug_printf("%s DLL_PROCESS_ATTACH", __FUNCTION__);\r
+            // Process-wide mutex used to allow only one thread at a time into the RPC code:\r
+            hCCAPIv2Mutex = CreateMutex(NULL, FALSE, CCAPI_V2_MUTEX_NAME);\r
+\r
+            // Figure out our username; it's process-wide:\r
+            bStatus = GetUserName(_user, &maxUN);\r
+            if (!bStatus) return bStatus;\r
+\r
+            // Remove any characters that aren't valid endpoint characters:\r
+            while (_user[j] != 0) {\r
+                if (isalnum(_user[j])) _user[i++] = _user[j];\r
+                j++;\r
+                }\r
+            _user[i]    = '\0';\r
+\r
+            // Our logon session is determined in client.cxx, old CCAPI code carried\r
+            //  over to this implementation.\r
+\r
+            // Allocate a TLS index:\r
+            if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE; \r
\r
+            // Initialize CCAPI once per DLL load:\r
+            firstThreadID = GetCurrentThreadId();\r
+\r
+            // Don't break; fallthrough: Initialize the TLS index for first thread.\r
\r
+        // The attached process creates a new thread:\r
+        case DLL_THREAD_ATTACH:\r
+            // Initialize the TLS index for this thread:\r
+            ptspdata    = (struct tspdata*) LocalAlloc(LPTR, sizeof(struct tspdata)); \r
+            cci_debug_printf("%s DLL_THREAD_ATTACH; tsp*:0x%X", __FUNCTION__, ptspdata);\r
+            if (ptspdata == NULL) return FALSE;\r
+            fIgnore     = TlsSetValue(dwTlsIndex, ptspdata); \r
+\r
+            memset(ptspdata, 0, sizeof(struct tspdata));\r
+\r
+            // Initialize CCAPI once per DLL load:\r
+            if (GetCurrentThreadId() == firstThreadID) cci_thread_init__auxinit();\r
+\r
+            break; \r
\r
+        // The thread of the attached process terminates:\r
+        case DLL_THREAD_DETACH: \r
+            cci_debug_printf("%s DLL_THREAD_DETACH", __FUNCTION__);\r
+            // Release the allocated memory for this thread:\r
+            ptspdata = (struct tspdata*)TlsGetValue(dwTlsIndex); \r
+            if (ptspdata != NULL) {\r
+                LocalFree((HLOCAL) ptspdata); \r
+                TlsSetValue(dwTlsIndex, NULL); \r
+                }\r
+            break; \r
\r
+        // DLL unload due to process termination or FreeLibrary:\r
+        case DLL_PROCESS_DETACH: \r
+            cci_debug_printf("%s DLL_PROCESS_DETACH", __FUNCTION__);\r
+            //++ Copied from previous implementation:\r
+            // Process Teardown "Problem"\r
+            //\r
+            // There are two problems that occur during process teardown:\r
+            //\r
+            // 1) Windows (NT/9x/2000) does not keep track of load/unload\r
+            //    ordering dependencies for use in process teardown.\r
+            //\r
+            // 2) The RPC exception handling in the RPC calls do not work\r
+            //    during process shutdown in Win9x.\r
+            //\r
+            // When a process is being torn down in Windows, the krbcc DLL\r
+            // may get a DLL_PROCESS_DETACH before other DLLs are done\r
+            // with it.  Thus, it may disconnect from the RPC server\r
+            // before the last shutdown RPC call.\r
+            //\r
+            // On NT/2000, this is ok because the RPC call will fail and just\r
+            // return an error.\r
+            //\r
+            // On Win9x/Me, the RPC exception will not be caught.\r
+            // However, Win9x ignores exceptions during process shutdown,\r
+            // so the exception will never be seen unless a debugger is\r
+            // attached to the proccess.\r
+            //\r
+            // A good potential woraround would be to have a global\r
+            // variable that denotes whether the DLL is attached to the\r
+            // process.  If it is not, all entrypoints into the DLL should\r
+            // return failure.\r
+            //\r
+            // A not as good workaround is below but ifdefed out.\r
+            //\r
+            // However, we can safely ignore this problem since it can\r
+            // only affects people running debuggers under 9x/Me who are\r
+            // using multiple DLLs that use this DLL.\r
+            //\r
+            WaitForSingleObject( hCCAPIv2Mutex, INFINITE );\r
+#if 0\r
+            bool process_teardown_workaround = false;\r
+            if (lpvReserved) {\r
+                Init::InitInfo info;\r
+                status = Init::Info(info);\r
+                if (status) break;\r
+                if (!info.isNT) process_teardown_workaround = true;\r
+            }\r
+            if (process_teardown_workaround)\r
+                break;\r
+#endif\r
+            // return value is ignored, so we set status for debugging purposes\r
+            status = Client::Cleanup();\r
+            status = Init::Cleanup();\r
+            ReleaseMutex( hCCAPIv2Mutex );\r
+            CloseHandle( hCCAPIv2Mutex );\r
+            //-- Copied from previous implementation.\r
+\r
+            // Release the allocated memory for this thread:\r
+            ptspdata = (struct tspdata*)TlsGetValue(dwTlsIndex); \r
+            if (ptspdata != NULL) LocalFree((HLOCAL) ptspdata);\r
+            TlsFree(dwTlsIndex);    // Release the TLS index.\r
+            break; \r
\r
+        default: break; \r
+        } \r
\r
+    UNREFERENCED_PARAMETER(hinstDLL);       // no whining!\r
+    UNREFERENCED_PARAMETER(lpvReserved); \r
+    return status ? FALSE : TRUE;\r
+}\r
+\r
+\r
+#ifdef __cplusplus    // If used by C++ code, \r
+extern "C" {          // we need to export the C interface\r
+#endif\r
+\r
+__declspec(dllexport)\r
+BOOL WINAPI PutTspData(struct tspdata* dw) {\r
+    LPVOID              lpvData; \r
+    struct tspdata**    pData;  // The stored memory pointer \r
+\r
+    // Retrieve a data pointer for the current thread:\r
+    lpvData = TlsGetValue(dwTlsIndex); \r
+\r
+    // If NULL, allocate memory for the TLS slot for this thread:\r
+    if (lpvData == NULL) {\r
+        lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct tspdata)); \r
+        if (lpvData == NULL)                      return FALSE;\r
+        if (!TlsSetValue(dwTlsIndex, lpvData))    return FALSE;\r
+        }\r
+\r
+    pData = (struct tspdata**) lpvData; // Cast to my data type.\r
+    // In this example, it is only a pointer to a DWORD\r
+    // but it can be a structure pointer to contain more complicated data.\r
+\r
+    (*pData) = dw;\r
+    return TRUE;\r
+    }\r
+\r
+__declspec(dllexport)\r
+BOOL WINAPI GetTspData(struct tspdata**  pdw) {\r
+   struct tspdata*  pData;      // The stored memory pointer \r
+\r
+   pData = (struct tspdata*)TlsGetValue(dwTlsIndex); \r
+   if (pData == NULL) return FALSE;\r
+   (*pdw) = pData;\r
+   return TRUE;\r
+    }\r
+\r
+#if 0   // replaced by clientEndpoint / serverEndpoint.\r
+__declspec(dllexport)\r
+char* WINAPI getEndpoint(enum EndpointType ep) {\r
+    // The server endpoint is of the form CCS_<LSID>\r
+    // The client endpoint is of the form CCAPI_<uuid>\r
+    //   Each client thread can have its own connection.\r
+    //\r
+    // NB:  Caller must free the data the returned char* points to.\r
+    struct tspdata* pData;\r
+    char*           s;\r
+    char*           uuid;\r
+    unsigned int    len;\r
+\r
+    switch (ep) {\r
+        case EPT_SERVER:\r
+            s       = (char*)malloc(32);    // Length of CCS_<DWORD>\r
+            sprintf(s, "%s_%ld", ep_prefices[EPT_SERVER], sessionToken);\r
+            break;\r
+        case EPT_CLIENT:\r
+            GetTspData(&pData);\r
+            uuid    = tspdata_getUUID(pData);\r
+            len     = 4 + strlen(ep_prefices[ep]) + strlen(_user) + strlen(uuid);\r
+            s       = (char*)malloc(len);\r
+            sprintf(s, "%s_%s_%s", ep_prefices[EPT_CLIENT], _user, uuid);\r
+            break;\r
+        default:;\r
+        }\r
+    cci_debug_printf("%s(%d) returning %s", __FUNCTION__, ep, s);\r
+\r
+    return s;\r
+    }\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+/*********************************************************************/\r
+/*                 MIDL allocate and free                            */\r
+/*********************************************************************/\r
+\r
+void  __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) {\r
+    return(malloc(len));\r
+    }\r
+\r
+void __RPC_USER midl_user_free(void __RPC_FAR * ptr) {\r
+    free(ptr);\r
+    }\r
diff --git a/src/ccapi/lib/win/dllmain.h b/src/ccapi/lib/win/dllmain.h
new file mode 100644 (file)
index 0000000..3ce2ac2
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef _dll_h\r
+#define _dll_h\r
+\r
+#include "windows.h"\r
+\r
+enum EndpointType {EPT_SERVER=0, EPT_CLIENT};\r
+\r
+#ifdef __cplusplus    // If used by C++ code, \r
+extern "C" {          // we need to export the C interface\r
+#endif\r
+__declspec(dllexport) BOOL  WINAPI PutTspData(struct tspdata*  p);\r
+__declspec(dllexport) BOOL  WINAPI GetTspData(struct tspdata** p);\r
+\r
+//__declspec(dllexport) char* WINAPI getEndpoint(enum EndpointType);\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif _dll_h
\ No newline at end of file
diff --git a/src/ccapi/server/win/Makefile b/src/ccapi/server/win/Makefile
new file mode 100644 (file)
index 0000000..deaebb2
--- /dev/null
@@ -0,0 +1,105 @@
+!include <Win32.Mak>\r
+\r
+# . is ...\pismere\athena\auth\krb5\src\ccapi\server\win\r
+CCAPI   = ..\..\r
+CO      = $(CCAPI)\common\r
+COWIN   = $(CCAPI)\common\win\r
+CCUTIL  = $(CCAPI)\common\win\OldCC\r
+LIBDIR  = $(CCAPI)\lib\r
+LIBWIN  = $(CCAPI)\lib\win\r
+K5SRC   = $(CCAPI)\..\r
+POSIX   = $(K5SRC)\lib\krb5\posix\r
+\r
+INC     = -I. -I.. -I$(CO) -I$(COWIN) -I$(K5SRC)\include -I..\..\..\util\et -I$(CCUTIL)\r
+\r
+!if "$(CPU)" == "i386"\r
+cflags = $(cflags) /EHsc -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 \\r
+$(INC) -MTd\r
+!else\r
+cflags = $(cflags) /W3 -D_CRTAPI1= -D_CRTAPI2= $(INC)\r
+!endif\r
+\r
+all : server\r
+\r
+server : server.exe\r
+\r
+common = cci_array_internal.obj cci_cred_union.obj cci_debugging.obj cci_identifier.obj \\r
+    cci_message.obj cci_stream.obj \r
+    \r
+commonwin = cci_os_debugging.obj \\r
+            cci_os_identifier.obj \\r
+            tls.obj \\r
+            win-utils.obj\r
+\r
+ccutils = ccutils.obj \r
+\r
+ccutilscxx = opts.obj util.obj secure.obj init.obj\r
+\r
+dll = ccapi_string.obj\r
+\r
+srv = ccs_array.obj ccs_cache_collection.obj ccs_callback.obj ccs_ccache.obj \\r
+    ccs_ccache_iterator.obj ccs_client.obj \\r
+    ccs_credentials.obj ccs_credentials_iterator.obj ccs_list.obj ccs_list_internal.obj \\r
+    ccs_lock.obj ccs_lock_state.obj ccs_pipe.obj ccs_server.obj \r
+\r
+srvwin = ccs_os_pipe.obj ccs_reply_c.obj \\r
+    ccs_request_proc.obj ccs_win_pipe.obj\r
+\r
+srvwincpp = ccs_os_server.obj ccs_request_s.obj WorkItem.obj WorkQueue.obj\r
+        \r
+linkobjs = $(common) $(commonwin) $(ccutils) $(ccutilscxx) \\r
+    $(srv) $(srvwin) $(srvwincpp)\r
+\r
+includes = ccs_reply.h ccs_request.h\r
+\r
+# Main program:\r
+server.exe : $(linkobjs) \r
+#    $(link) $(linkdebug) $(conflags) -MTd -out:ccapiserver.exe $(linkobjs) \\r
+    $(link) $(linkdebug) $(conflags) -out:ccapiserver.exe $(linkobjs) \\r
+        rpcrt4.lib advapi32.lib ws2_32.lib user32.lib\r
+\r
+\r
+ccs_request.h ccs_request_s.cpp : $(COWIN)\ccs_request.idl $(COWIN)\ccs_request.acf\r
+    midl $(MIDL_OPTIMIZATION) -oldnames -cpp_cmd $(cc) -cpp_opt "-E" -I. -I$(COWIN) -sstub \\r
+        ccs_request_s.cpp $(COWIN)\ccs_request.idl\r
+\r
+ccs_reply.h ccs_reply_c.c : $(COWIN)\ccs_reply.idl $(COWIN)\ccs_reply.acf\r
+    midl $(MIDL_OPTIMIZATION) -oldnames -cpp_cmd $(cc) -cpp_opt "-E" -I. -I$(COWIN) \\r
+    $(COWIN)\ccs_reply.idl\r
+\r
+$(common) : $(CO)\$*.c\r
+   $(cc) $(cdebug) $(cflags) $(CO)\$*.c\r
+\r
+$(commonwin) : $(COWIN)\$*.c\r
+   $(cc) $(cdebug) $(cflags) $(COWIN)\$*.c\r
+\r
+$(ccutils) : $(CCUTIL)\$*.c\r
+   $(cc) $(cdebug) $(cflags) $(CCUTIL)\$*.c\r
+\r
+$(ccutilscxx) : $(CCUTIL)\$*.cxx\r
+   $(cc) $(cdebug) $(cflags) $(CCUTIL)\$*.cxx\r
+\r
+$(srv) : ..\$*.c\r
+   $(cc) $(cdebug) $(cflags) ..\$*.c\r
+\r
+$(srvwin) : $*.c $(includes) \r
+   $(cc) $(cdebug) $(cflags) $*.c\r
+\r
+$(srvwincpp) : $*.cpp\r
+   $(cc) $(cdebug) $(cflags) $*.cpp\r
+\r
+\r
+# Clean up everything\r
+cleanall : clean\r
+    -del *.exe\r
+\r
+# Clean up everything but the .EXEs\r
+clean :\r
+    -del *.obj\r
+    -del *.map\r
+    -del ccs_request_s.c\r
+    -del ccs_request_c.c\r
+    -del ccs_request.h\r
+    -del ccs_reply_s.c\r
+    -del ccs_reply_c.c\r
+    -del ccs_reply.h\r
diff --git a/src/ccapi/server/win/Server.sln b/src/ccapi/server/win/Server.sln
new file mode 100644 (file)
index 0000000..64cc7f0
--- /dev/null
@@ -0,0 +1,20 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 9.00\r
+# Visual Studio 2005\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server", "Server.vcproj", "{114DCD80-6D13-4AAA-9510-B51CE6D94C1C}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Win32 = Debug|Win32\r
+               Release|Win32 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Debug|Win32.Build.0 = Debug|Win32\r
+               {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Release|Win32.ActiveCfg = Release|Win32\r
+               {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Release|Win32.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/src/ccapi/server/win/Server.vcproj b/src/ccapi/server/win/Server.vcproj
new file mode 100644 (file)
index 0000000..39db361
--- /dev/null
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="8.00"\r
+       Name="Server"\r
+       ProjectGUID="{114DCD80-6D13-4AAA-9510-B51CE6D94C1C}"\r
+       RootNamespace="Server"\r
+       Keyword="MakeFileProj"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="Debug"\r
+                       IntermediateDirectory="Debug"\r
+                       ConfigurationType="0"\r
+                       >\r
+                       <Tool\r
+                               Name="VCNMakeTool"\r
+                               BuildCommandLine="nmake"\r
+                               ReBuildCommandLine="nmake"\r
+                               CleanCommandLine="nmake clean"\r
+                               Output=""\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;"\r
+                               IncludeSearchPath=""\r
+                               ForcedIncludes=""\r
+                               AssemblySearchPath=""\r
+                               ForcedUsingAssemblies=""\r
+                               CompileAsManaged=""\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="Release"\r
+                       IntermediateDirectory="Release"\r
+                       ConfigurationType="0"\r
+                       >\r
+                       <Tool\r
+                               Name="VCNMakeTool"\r
+                               BuildCommandLine="nmake"\r
+                               ReBuildCommandLine="nmake"\r
+                               CleanCommandLine="nmake clean"\r
+                               Output=""\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;"\r
+                               IncludeSearchPath=""\r
+                               ForcedIncludes=""\r
+                               AssemblySearchPath=""\r
+                               ForcedUsingAssemblies=""\r
+                               CompileAsManaged=""\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\..\common\cci_debugging.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\cci_os_debugging.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\cci_stream.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ccs_reply.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ccs_request.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\ccs_server.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\ccutil\ccutils.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\ccutil\init.hxx"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\include\k5-platform.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\ccutil\secure.hxx"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\ccutil\util.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\win-utils.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\workitem.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\WorkQueue.h"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+                       >\r
+               </Filter>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\..\common\cci_debugging.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\cci_os_debugging.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\cci_stream.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\ccs_lock.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ccs_os_pipe.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ccs_os_server.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\ccs_reply.Idl"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ccs_reply_c.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ccs_reply_s.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\ccs_request.idl"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ccs_request_c.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ccs_request_proc.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\ccs_request_s.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\ccs_server.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\ccutil\ccutils.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\ccutil\init.cxx"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\ccutil\secure.cxx"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\ccutil\util.cxx"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\common\win\win-utils.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\WorkItem.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\WorkQueue.cpp"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <File\r
+                       RelativePath="..\..\common\win\ccs_reply.Acf"\r
+                       >\r
+               </File>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/src/ccapi/server/win/WorkItem.cpp b/src/ccapi/server/win/WorkItem.cpp
new file mode 100644 (file)
index 0000000..7e6aeb1
--- /dev/null
@@ -0,0 +1,126 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <string.h>\r
+#include "assert.h"\r
+\r
+#pragma warning (disable : 4996)\r
+\r
+#include "win-utils.h"\r
+#include "WorkItem.h"\r
+\r
+extern "C" {\r
+#include "cci_debugging.h"\r
+    }\r
+\r
+// CountedBuffer makes a copy of the data.  Each CountedBuffer must be deleted.\r
+\r
+void deleteBuffer(char** buf) {\r
+    if (*buf) {\r
+        delete [](*buf);\r
+        *buf = NULL;\r
+        }\r
+    }\r
+\r
+// WorkItem contains a CountedBuffer which must be deleted, \r
+//  so each WorkItem must be deleted.\r
+WorkItem::WorkItem(cci_stream_t buf, WIN_PIPE* pipe, const long type, const long sst) \r
+: _buf(buf), _rpcmsg(type), _pipe(pipe), _sst(sst) { }\r
+\r
+WorkItem::WorkItem(const WorkItem& item) : _buf(NULL), _rpcmsg(0), _pipe(NULL), _sst(0) {\r
+\r
+    cci_stream_t    _buf = NULL;\r
+    cci_stream_new(&_buf);\r
+    cci_stream_write(_buf, \r
+                     cci_stream_data(item.payload()),\r
+                     cci_stream_size(item.payload()) );\r
+    WorkItem(_buf, item._pipe, item._rpcmsg, item._sst);\r
+    }\r
+\r
+WorkItem::WorkItem() : _buf(NULL), _rpcmsg(CCMSG_INVALID), _pipe(NULL), _sst(0) { }\r
+\r
+WorkItem::~WorkItem() {\r
+    if (_buf)   cci_stream_release(_buf);\r
+    if (_pipe)  ccs_win_pipe_release(_pipe);\r
+    }\r
+\r
+const cci_stream_t WorkItem::take_payload() {\r
+    cci_stream_t  temp  = payload();\r
+    _buf                = NULL;\r
+    return temp;\r
+    }\r
+\r
+WIN_PIPE* WorkItem::take_pipe() {\r
+    WIN_PIPE* temp  = pipe();\r
+    _pipe           = NULL;\r
+    return temp;\r
+    }\r
+\r
+WorkList::WorkList() {\r
+    assert(InitializeCriticalSectionAndSpinCount(&cs, 0x80000400));\r
+    }\r
+\r
+WorkList::~WorkList() {\r
+    // Delete any WorkItems in the queue:\r
+    WorkItem*   item;\r
+    cci_debug_printf("%s", __FUNCTION__);\r
+    char        buf[2048];\r
+    char*       pbuf        = (char*)buf;\r
+    while (remove(&item)) {\r
+        cci_debug_printf("WorkList::~WorkList() deleting %s", item->print(pbuf));\r
+        delete item;\r
+        }\r
+\r
+    DeleteCriticalSection(&cs);\r
+    }\r
+\r
+char* WorkItem::print(char* buf) {\r
+    sprintf(buf, "WorkItem msg#:%d sst:%ld pipe:<%s>/0x%X", _rpcmsg, _sst, \r
+        ccs_win_pipe_getUuid(_pipe), ccs_win_pipe_getHandle(_pipe));\r
+    return buf;\r
+    }\r
+\r
+int WorkList::add(WorkItem* item) {\r
+    EnterCriticalSection(&cs);\r
+        wl.push_front(item);\r
+    LeaveCriticalSection(&cs);\r
+    return 1;\r
+    }\r
+\r
+int WorkList::remove(WorkItem** item) {\r
+    bool    bEmpty;\r
+\r
+    bEmpty = wl.empty() & 1;\r
+\r
+    if (!bEmpty) {\r
+        EnterCriticalSection(&cs);\r
+            *item    = wl.back();\r
+            wl.pop_back();\r
+        LeaveCriticalSection(&cs);\r
+        }\r
+\r
+    return !bEmpty;\r
+    }
\ No newline at end of file
diff --git a/src/ccapi/server/win/WorkQueue.cpp b/src/ccapi/server/win/WorkQueue.cpp
new file mode 100644 (file)
index 0000000..711ecc1
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+extern "C" {\r
+    #include "cci_debugging.h"\r
+    }\r
+\r
+#include "WorkItem.h"\r
+\r
+WorkList    worklist;\r
+\r
+/* C interfaces: */\r
+EXTERN_C    bool worklist_isEmpty() {\r
+        return worklist.isEmpty();\r
+        }\r
+\r
+EXTERN_C    int worklist_add(   const long          rpcmsg, \r
+                                const ccs_pipe_t    pipe, \r
+                                const cci_stream_t  stream, \r
+                                const time_t        serverStartTime) {\r
+        return worklist.add(new WorkItem(stream, pipe, rpcmsg, serverStartTime) );\r
+        }\r
+\r
+EXTERN_C    int  worklist_remove(long*              rpcmsg,\r
+                                 ccs_pipe_t*        pipe,\r
+                                 cci_stream_t*      stream,\r
+                                 time_t*            sst) {\r
+        WorkItem*   item    = NULL;\r
+        cc_int32    err     = worklist.remove(&item);\r
+\r
+        *rpcmsg         = item->type();\r
+        *pipe           = item->take_pipe();\r
+        *stream         = item->take_payload();\r
+        *sst            = item->sst();\r
+        delete item;\r
+        return err;\r
+        }\r
+\r
diff --git a/src/ccapi/server/win/WorkQueue.h b/src/ccapi/server/win/WorkQueue.h
new file mode 100644 (file)
index 0000000..106f9ac
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2007 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef _work_queue_h\r
+#define _work_queue_h\r
+\r
+#include "windows.h"\r
+#include "cci_stream.h"\r
+#include "ccs_pipe.h"\r
+\r
+EXTERN_C    BOOL worklist_isEmpty();\r
+\r
+EXTERN_C    void worklist_add(  const long          rpcmsg,\r
+                                const ccs_pipe_t    pipe,\r
+                                const cci_stream_t  stream,\r
+                                const time_t        serverStartTime);\r
+\r
+EXTERN_C    int  worklist_remove(long*              rpcmsg,\r
+                                 ccs_pipe_t*        pipe,\r
+                                 cci_stream_t*      stream,\r
+                                 time_t*            serverStartTime);\r
+\r
+#endif // _work_queue_h
\ No newline at end of file
diff --git a/src/ccapi/server/win/ccs_os_pipe.c b/src/ccapi/server/win/ccs_os_pipe.c
new file mode 100644 (file)
index 0000000..69dcec4
--- /dev/null
@@ -0,0 +1,64 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include "ccs_common.h"\r
+#include "ccs_os_pipe.h"\r
+#include "ccs_win_pipe.h"\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+/* On Windows, a pipe is a struct.  See ccs_win_pipe.h for details.         */\r
+   \r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_pipe_valid (ccs_pipe_t in_pipe) {\r
+    return ccs_win_pipe_valid(in_pipe);\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_pipe_copy (ccs_pipe_t* out_pipe, ccs_pipe_t  in_pipe) {\r
+    return ccs_win_pipe_copy(\r
+        out_pipe, \r
+        in_pipe);\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_pipe_release (ccs_pipe_t io_pipe) {\r
+    return ccs_win_pipe_release(io_pipe);\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_pipe_compare (ccs_pipe_t  pipe_1,\r
+                              ccs_pipe_t  pipe_2,\r
+                              cc_uint32  *out_equal) {\r
+\r
+    return ccs_win_pipe_compare(pipe_1, pipe_2, out_equal);\r
+    }\r
+\r
diff --git a/src/ccapi/server/win/ccs_os_server.cpp b/src/ccapi/server/win/ccs_os_server.cpp
new file mode 100644 (file)
index 0000000..0c3f766
--- /dev/null
@@ -0,0 +1,950 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include "process.h"\r
+#include "windows.h" \r
+\r
+extern "C" {\r
+#include "ccs_common.h"\r
+#include "ccs_os_server.h"\r
+#include <syslog.h>\r
+#include "ccs_reply.h"\r
+#include "ccs_request.h"\r
+#include "win-utils.h"\r
+#include "ccutils.h"\r
+#include "cci_stream.h"\r
+    }\r
+\r
+#include "WorkQueue.h"\r
+#include "util.h"\r
+#include "opts.hxx"\r
+#include "init.hxx"\r
+\r
+#pragma warning (disable : 4996)\r
+\r
+BOOL                bListen             = TRUE; /* Why aren't bool and true defined? */\r
+const char*         sessID              = NULL; /* The logon session we are running on behalf of. */\r
+time_t              _sst                = 0;\r
+unsigned char*      pszNetworkAddress   = NULL;\r
+unsigned char*      pszStringBinding    = NULL;\r
+BOOL                bRpcHandleInited    = FALSE; \r
+_RPC_ASYNC_STATE*    rpcState            = NULL;\r
+\r
+/* Thread procedures can take only one void* argument.  We put all the args we want \r
+   to pass into this struct and then pass a pointer to the struct: */\r
+struct RpcRcvArgs {\r
+    char*               networkAddress;\r
+    unsigned char*      protocolSequence;\r
+    unsigned char*      sessID;                     /* Used for this server's endpoint */\r
+    unsigned char*      uuid;                       /* Used for client's UUID */\r
+    ParseOpts::Opts*    opts;\r
+    RPC_STATUS          status;\r
+    } rpcargs = {   NULL,                       /* pszNetworkAddress    */\r
+                    (unsigned char*)"ncalrpc",  /* pszProtocolSequence  */\r
+                    NULL,                       /* sessID placeholder   */\r
+                    NULL,                       /* uuid   placeholder   */\r
+                    NULL };                     /* Opts placeholder     */\r
+\r
+/* Command line format:\r
+   argv[0] Program name\r
+   argv[1] session ID to use\r
+   argv[2] "D" Debug: go into infinite loop in ccs_os_server_initialize so process \r
+           can be attached in debugger.\r
+           Any other value: continue \r
+ */\r
+#define N_FIXED_ARGS 3\r
+#define SERVER_REPLY_RPC_HANDLE ccs_reply_IfHandle\r
+\r
+/* Forward declarations: */\r
+void            receiveLoop(void* rpcargs);\r
+void            connectionListener(void* rpcargs);\r
+void            Usage(const char* argv0);\r
+void            printError(TCHAR* msg);\r
+void            setMySST()      {_sst = time(&_sst);}\r
+time_t          getMySST()      {return _sst;}\r
+RPC_STATUS      send_connection_reply(ccs_pipe_t in_pipe);\r
+void RPC_ENTRY  clientListener( _RPC_ASYNC_STATE*,    \r
+                                void* Context,\r
+                                RPC_ASYNC_EVENT Event);\r
+RPC_STATUS RPC_ENTRY sec_callback(  IN RPC_IF_ID *Interface,\r
+                                    IN void *Context);\r
+RPC_STATUS      send_init(char* clientUUID);\r
+//DWORD alloc_name(LPSTR* pname, LPSTR postfix);\r
+\r
+\r
+/* The layout of the rest of this module:  \r
+\r
+   The four entrypoints defined in ccs_os_server.h:\r
+      ccs_os_server_initialize\r
+      cc_int32 ccs_os_server_cleanup \r
+      cc_int32 ccs_os_server_listen_loop \r
+      cc_int32 ccs_os_server_send_reply \r
+\r
+   Other routines needed by those four.\r
+ */\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_server_initialize (int argc, const char *argv[]) {\r
+    cc_int32        err                 = 0;\r
+    ParseOpts::Opts opts                = { 0 };\r
+    ParseOpts       PO;\r
+    BOOL            bAdjustedShutdown   = FALSE;\r
+    HMODULE         hKernel32           = GetModuleHandle("kernel32");\r
+\r
+    if (!err) {\r
+        sessID = argv[1];\r
+        setMySST();\r
+\r
+        opts.cMinCalls  = 1;\r
+        opts.cMaxCalls  = 20;\r
+        opts.fDontWait  = TRUE;\r
+\r
+#ifdef CCAPI_TEST_OPTIONS\r
+        PO.SetValidOpts("kemnfubc");\r
+#else\r
+        PO.SetValidOpts("kc");\r
+#endif\r
+\r
+        PO.Parse(opts, argc, (char**)argv);\r
+    \r
+//        while(*argv[2] == 'D') {}       /* Hang here to attach process with debugger. */\r
+\r
+        if (hKernel32) {\r
+            typedef BOOL (WINAPI *FP_SetProcessShutdownParameters)(DWORD, DWORD);\r
+            FP_SetProcessShutdownParameters pSetProcessShutdownParameters =\r
+                (FP_SetProcessShutdownParameters)\r
+                GetProcAddress(hKernel32, "SetProcessShutdownParameters");\r
+            if (pSetProcessShutdownParameters) {\r
+                bAdjustedShutdown = pSetProcessShutdownParameters(100, 0);\r
+                }\r
+            }\r
+        cci_debug_printf("%s Shutdown Parameters", \r
+            bAdjustedShutdown ? "Adjusted" : "Did not adjust");\r
+\r
+        err = Init::Initialize();\r
+        }\r
+\r
+//    if (!err) {\r
+//        if (opts.bShutdown) {\r
+//            status = shutdown_server(opts.pszEndpoint);\r
+//            }\r
+//        } \r
+//    else {\r
+//        status = startup_server(opts);\r
+//        }\r
+\r
+    if (err) {\r
+        Init::Cleanup();\r
+        fprintf(    stderr, "An error occured while %s the server (%u)\n", \r
+                    opts.bShutdown ? "shutting down" : "starting/running",\r
+                    err);\r
+        exit(cci_check_error (err));\r
+        }\r
+\r
+    return cci_check_error (err);\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]) {\r
+    cc_int32 err = 0;\r
+    \r
+    cci_debug_printf("%s for user <%s> shutting down.", argv[0], argv[1]);\r
+    \r
+    return cci_check_error (err);\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+/* This function takes work items off the work queue and executes them.\r
+ * This is the one and only place where the multi-threaded Windows code\r
+ * calls into the single-threaded common code.\r
+ *\r
+ * The actual 'listening' for requests from clients happens after receiveloop\r
+ * establishes the RPC endpoint the clients will connect to and the RPC procedures\r
+ * put the work items into the work queue.\r
+ */\r
+cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) {\r
+    cc_int32        err = 0;\r
+    uintptr_t       threadStatus;\r
+    unsigned int    loopCounter  = 0;\r
+\r
+    ParseOpts::Opts opts         = { 0 };\r
+    ParseOpts       PO;\r
+    \r
+    opts.cMinCalls  = 1;\r
+    opts.cMaxCalls  = 20;\r
+    opts.fDontWait  = TRUE;\r
+\r
+#ifdef CCAPI_TEST_OPTIONS\r
+    PO.SetValidOpts("kemnfubc");\r
+#else\r
+    PO.SetValidOpts("kc");\r
+#endif\r
+    PO.Parse(opts, argc, (char**)argv);\r
+\r
+        \r
+    //++ debug stuff\r
+    #define INFO_BUFFER_SIZE 32767\r
+    TCHAR  infoBuf[INFO_BUFFER_SIZE];\r
+    DWORD  bufCharCount = INFO_BUFFER_SIZE;\r
+    // Get and display the user name. \r
+    bufCharCount = INFO_BUFFER_SIZE;\r
+    if( !GetUserName( infoBuf, &bufCharCount ) )  printError( TEXT("GetUserName") ); \r
+    //--\r
+\r
+    /* Sending the reply from within the request RPC handler doesn't seem to work.\r
+       So we listen for requests in a separate thread and put the requests in a\r
+       queue.  */\r
+    rpcargs.sessID  = (unsigned char*)sessID;\r
+    rpcargs.opts    = &opts;\r
+    threadStatus    = _beginthread(receiveLoop, 0, (void*)&rpcargs);\r
+\r
+    /* We handle the queue entries here.  Work loop: */\r
+    while (TRUE) {\r
+        loopCounter++;\r
+        if (worklist_isEmpty() & 1) {\r
+            SleepEx(1000, TRUE);\r
+            }\r
+        else if (TRUE) {      // Take next WorkItem from the queue:\r
+            cci_stream_t    buf             = NULL;\r
+            long            rpcmsg          = CCMSG_INVALID;\r
+            time_t          serverStartTime = 0xDEADDEAD;\r
+            RPC_STATUS      status          = 0;\r
+            char*           uuid            = NULL;\r
+            cci_stream_t    stream          = NULL;\r
+            ccs_pipe_t     pipe             = NULL;\r
+            ccs_pipe_t     pipe2            = NULL;\r
+\r
+            if (worklist_remove(&rpcmsg, &pipe, &buf, &serverStartTime)) {\r
+                uuid = ccs_win_pipe_getUuid(pipe);\r
+                cci_debug_printf("%s: processing WorkItem msg:%ld pipeUUID:<%s> pipeHandle:0x%X SST:%ld", \r
+                    __FUNCTION__, rpcmsg, uuid, ccs_win_pipe_getHandle(pipe), serverStartTime);\r
+\r
+                if (serverStartTime <= getMySST()) {\r
+                    switch (rpcmsg) {\r
+                        case CCMSG_CONNECT: {\r
+                            cci_debug_printf("  Processing CONNECT");\r
+                            rpcargs.uuid    = (unsigned char*)uuid;\r
+\r
+                            // Even if a disconnect message is received before this code finishes,\r
+                            //  it won't be dequeued and processed until after this code finishes.\r
+                            //  So we can add the client after starting the connection listener.\r
+                            connectionListener((void*)&rpcargs);\r
+                            status  = rpcargs.status;\r
+\r
+                            if (!status) {\r
+                                status = ccs_server_add_client(pipe);\r
+                                }\r
+                            if (!status) {status = send_connection_reply(pipe);}\r
+                            break;\r
+                            }\r
+                        case CCMSG_DISCONNECT: {\r
+                            cci_debug_printf("  Processing DISCONNECT");\r
+                            if (!status) {\r
+                                status = ccs_server_remove_client(pipe);\r
+                                }\r
+                            break;\r
+                            }\r
+                        case CCMSG_REQUEST:\r
+                            cci_debug_printf("  Processing REQUEST");\r
+                            ccs_pipe_copy(&pipe2, pipe);\r
+                            // Dispatch message here, setting both pipes to the client UUID:\r
+                            err = ccs_server_handle_request (pipe, pipe2, buf);\r
+                            break;\r
+                        case CCMSG_PING:\r
+                            cci_debug_printf("  Processing PING");\r
+                            err = cci_stream_new  (&stream);\r
+                            err = cci_stream_write(stream, "This is a test of the emergency broadcasting system", 52);\r
+                            err = ccs_os_server_send_reply(pipe, stream);\r
+                            break;\r
+                        default:\r
+                            cci_debug_printf("Huh?  Received invalid message type %ld from UUID:<%s>", \r
+                                rpcmsg, uuid);\r
+                            break;\r
+                        }\r
+                    if (buf)        cci_stream_release(buf);\r
+                    /* Don't free uuid, which was allocated here.  A pointer to it is in the \r
+                       rpcargs struct which was passed to connectionListener which will be\r
+                       received by ccapi_listen when the client exits.  ccapi_listen needs \r
+                       the uuid to know which client to disconnect.\r
+                     */\r
+                    }\r
+                // Server's start time is different from what the client thinks.  \r
+                // That means the server has rebooted since the client connected.\r
+                else {      \r
+                    cci_debug_printf("Whoops!  Server has rebooted since client established connection.");\r
+                    }\r
+                }\r
+            else {cci_debug_printf("Huh?  Queue not empty but no item to remove.");}\r
+            }\r
+        }\r
+\r
+    return cci_check_error (err);\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_os_server_send_reply (ccs_pipe_t   in_pipe,\r
+                                   cci_stream_t in_reply_stream) {\r
+\r
+    /* ccs_pipe_t in_reply_pipe     is a char* reply endpoint.\r
+       cci_stream_t in_reply_stream is the data to be sent.\r
+     */\r
+\r
+    cc_int32    err     = 0;\r
+    char*       uuid    = ccs_win_pipe_getUuid(in_pipe);\r
+    HANDLE      h       = ccs_win_pipe_getHandle(in_pipe);\r
+\r
+    if (!err) {\r
+        err = send_init(uuid);      // Sets RPC handle to be used.\r
+        }\r
+\r
+    if (!err) {\r
+        RpcTryExcept {\r
+            long    status;\r
+            ccs_rpc_request_reply(                  // make call with user message\r
+                CCMSG_REQUEST_REPLY,                /* Message type */\r
+                (unsigned char*)&h,                 /* client's tspdata* */\r
+                (unsigned char*)uuid,\r
+                getMySST(),\r
+                cci_stream_size(in_reply_stream),   /* Length of buffer */\r
+                (const unsigned char*)cci_stream_data(in_reply_stream),   /* Data buffer */\r
+                &status );                          /* Return code */\r
+            }\r
+        RpcExcept(1) {\r
+            cci_check_error(RpcExceptionCode());\r
+            }\r
+        RpcEndExcept\r
+        }\r
+\r
+    /*  The calls to the remote procedures are complete. */\r
+    /*  Free whatever we allocated:                      */\r
+    err = RpcBindingFree(&SERVER_REPLY_RPC_HANDLE);\r
+\r
+    return cci_check_error (err);\r
+    }\r
+\r
+\r
+/* Windows-specific routines: */\r
+\r
+void Usage(const char* argv0) {\r
+    printf("Usage:\n");\r
+    printf("%s [m maxcalls] [n mincalls] [f dontwait] [h|?]]\n", argv0);\r
+    printf("    CCAPI server process.\n");\r
+    printf("    h|? whow usage message. <\n");\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+/* The receive thread repeatedly issues RpcServerListen.\r
+   When a message arrives, it is handled in the RPC procedure.  \r
+ */\r
+void    receiveLoop(void* rpcargs) {\r
+\r
+    struct RpcRcvArgs*      rcvargs     = (struct RpcRcvArgs*)rpcargs;\r
+    RPC_STATUS              status      = FALSE;\r
+    unsigned char*          pszSecurity = NULL;\r
+    LPSTR                   endpoint    = NULL;\r
+    LPSTR                   event_name  = NULL;\r
+    PSECURITY_DESCRIPTOR    psd         = NULL;\r
+    HANDLE                  hEvent      = 0;\r
+    Init::InitInfo          info;\r
+\r
+    cci_debug_printf("THREAD BEGIN: %s", __FUNCTION__);\r
+\r
+    status = Init::Info(info);\r
+\r
+    /* Build complete RPC endpoint using previous CCAPI implementation: */\r
+    if (!status) {\r
+        if (!rcvargs->opts->pszEndpoint) {\r
+            if (!status) {\r
+                status  = alloc_name(&endpoint,     "ep", isNT());\r
+                }\r
+\r
+            if (!status) {\r
+                status  = alloc_name(&event_name,   "startup", isNT());\r
+                }\r
+\r
+            if (!status) {\r
+                 hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name);\r
+                // We ignore any error opening the event because we do not know who started us.\r
+                //  [Comment paraphrased from previous implementation, whence it was copied.]\r
+                }\r
+            }\r
+        else {\r
+            endpoint = rcvargs->opts->pszEndpoint;\r
+            }\r
+        }\r
+\r
+    cci_debug_printf("%s Registering endpoint %s", __FUNCTION__, endpoint);\r
+\r
+    if (!status && isNT()) {\r
+        status = alloc_own_security_descriptor_NT(&psd);\r
+        }\r
+\r
+    if (!status) {\r
+        status = RpcServerUseProtseqEp(rcvargs->protocolSequence,\r
+                                       rcvargs->opts->cMaxCalls,\r
+                                       (RPC_CSTR)endpoint,\r
+                                       rcvargs->opts->bDontProtect ? 0 : psd);  // SD\r
+        }\r
+\r
+    if (!status) {\r
+        status = RpcServerRegisterAuthInfo(0, // server principal\r
+                                           RPC_C_AUTHN_WINNT,\r
+                                           0,\r
+                                           0);\r
+        }\r
+\r
+    while (bListen && !status) {\r
+        cci_debug_printf("%s is listening ...", __FUNCTION__);\r
+\r
+        if (!info.isNT) {\r
+            status = RpcServerRegisterIf(ccs_request_ServerIfHandle,    // interface \r
+                                         NULL,                          // MgrTypeUuid\r
+                                         NULL);                         // MgrEpv; null means use default\r
+            } \r
+        else {\r
+            status = info.fRpcServerRegisterIfEx(ccs_request_ServerIfHandle,  // interface\r
+                                         NULL,                          // MgrTypeUuid\r
+                                         NULL,                          // MgrEpv; 0 means default\r
+                                         RPC_IF_ALLOW_SECURE_ONLY,\r
+                                         rcvargs->opts->cMaxCalls,\r
+                                         rcvargs->opts->bSecCallback ? \r
+                                         (RPC_IF_CALLBACK_FN*)sec_callback : 0 );\r
+            }\r
+\r
+        if (!status) {\r
+            status = RpcServerListen(rcvargs->opts->cMinCalls,\r
+                                     rcvargs->opts->cMaxCalls,\r
+                                     rcvargs->opts->fDontWait);\r
+            }\r
+\r
+        if (!status) {\r
+            if (rcvargs->opts->fDontWait) {\r
+                if (hEvent) SetEvent(hEvent);   // Ignore any error -- SetEvent is an optimization.\r
+                status = RpcMgmtWaitServerListen();  \r
+                }\r
+            }\r
+        }\r
+\r
+    if (status) {           // Cleanup in case of errors:\r
+        if (hEvent) CloseHandle(hEvent);\r
+        free_alloc_p(&event_name);\r
+        free_alloc_p(&psd);\r
+        if (endpoint && (endpoint != rcvargs->opts->pszEndpoint)) \r
+            free_alloc_p(&endpoint);\r
+        }\r
+\r
+    _endthread();\r
+    }   // End receiveLoop\r
+\r
+\r
+#if 0\r
+\r
+    return status;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/* ------------------------------------------------------------------------ */\r
+/* The connection listener thread waits forever for a call to the CCAPI_CLIENT_<UUID>\r
+   endpoint, ccapi_listen function to complete.  If the call completes or gets an \r
+   RPC exception, it means the client has disappeared.\r
+\r
+   A separate connectionListener is started for each client that has connected to the server.\r
+ */\r
+\r
+void    connectionListener(void* rpcargs) {\r
+\r
+    struct RpcRcvArgs*  rcvargs     = (struct RpcRcvArgs*)rpcargs;\r
+    RPC_STATUS          status      = FALSE;\r
+    char*               endpoint;\r
+    unsigned char*      pszOptions  = NULL;\r
+    unsigned char *     pszUuid     = NULL;\r
+\r
+    endpoint    = clientEndpoint((char*)rcvargs->uuid);\r
+    rpcState    = (RPC_ASYNC_STATE*)malloc(sizeof(RPC_ASYNC_STATE));\r
+    status      = RpcAsyncInitializeHandle(rpcState, sizeof(RPC_ASYNC_STATE));\r
+    cci_debug_printf("");\r
+    cci_debug_printf("%s About to LISTEN to <%s>", __FUNCTION__, endpoint);\r
+\r
+    rpcState->UserInfo                  = rcvargs->uuid;\r
+    rpcState->NotificationType          = RpcNotificationTypeApc;\r
+    rpcState->u.APC.NotificationRoutine = clientListener;\r
+    rpcState->u.APC.hThread             = 0;\r
+\r
+    /* [If in use] Free previous binding: */\r
+    if (bRpcHandleInited) {     \r
+        // Free previous binding (could have been used to call ccapi_listen \r
+        //  in a different client thread).\r
+        // Don't check result or update status.\r
+        RpcStringFree(&pszStringBinding);\r
+        RpcBindingFree(&SERVER_REPLY_RPC_HANDLE);\r
+        bRpcHandleInited  = FALSE;\r
+        }\r
+\r
+    /* Set up binding to the client's endpoint: */\r
+    if (!status) {\r
+        status = RpcStringBindingCompose(\r
+                    pszUuid,\r
+                    pszProtocolSequence,\r
+                    pszNetworkAddress,\r
+                    (RPC_CSTR)endpoint,\r
+                    pszOptions,\r
+                    &pszStringBinding);\r
+        }\r
+\r
+    /* Set the binding handle that will be used to bind to the server. */\r
+    if (!status) {\r
+        status = RpcBindingFromStringBinding(pszStringBinding, &SERVER_REPLY_RPC_HANDLE); \r
+        }\r
+    if (!status) {bRpcHandleInited  = TRUE;}\r
+\r
+    RpcTryExcept {\r
+        cci_debug_printf("  Calling remote procedure ccapi_listen");\r
+        ccapi_listen(rpcState, SERVER_REPLY_RPC_HANDLE, CCMSG_LISTEN, &status);\r
+        /* Asynchronous call will return immediately. */\r
+        }\r
+    RpcExcept(1) {\r
+        status = cci_check_error(RpcExceptionCode());\r
+        }\r
+    RpcEndExcept\r
+    \r
+    rcvargs->status = status;\r
+    }   // End connectionListener\r
+\r
+\r
+void RPC_ENTRY clientListener(\r
+    _RPC_ASYNC_STATE* pAsync,\r
+    void* Context,\r
+    RPC_ASYNC_EVENT Event\r
+    ) {\r
+\r
+    ccs_pipe_t pipe = ccs_win_pipe_new((char*)pAsync->UserInfo, NULL);\r
+\r
+    cci_debug_printf("%s(0x%X, ...) async routine for <0x%X:%s>!", \r
+        __FUNCTION__, pAsync, pAsync->UserInfo, pAsync->UserInfo);\r
+\r
+    worklist_add(   CCMSG_DISCONNECT, \r
+                    pipe,\r
+                    NULL,               /* No payload with connect request */\r
+                    (const time_t)0 );  /* No server session number with connect request */\r
+    }\r
+\r
+\r
+void printError( TCHAR* msg ) {\r
+    DWORD eNum;\r
+    TCHAR sysMsg[256];\r
+    TCHAR* p;\r
+\r
+    eNum = GetLastError( );\r
+    FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | \r
+         FORMAT_MESSAGE_IGNORE_INSERTS,\r
+         NULL, eNum,\r
+         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\r
+         sysMsg, 256, NULL );\r
+\r
+    // Trim the end of the line and terminate it with a null\r
+    p = sysMsg;\r
+    while( ( *p > 31 ) || ( *p == 9 ) )\r
+        ++p;\r
+    do { *p-- = 0; } while( ( p >= sysMsg ) &&\r
+                          ( ( *p == '.' ) || ( *p < 33 ) ) );\r
+\r
+    // Display the message\r
+    cci_debug_printf("%s failed with error %d (%s)", msg, eNum, sysMsg);\r
+    }\r
+\r
+\r
+RPC_STATUS send_init(char* clientUUID) {\r
+    RPC_STATUS      status;\r
+    unsigned char * pszUuid             = NULL;\r
+    unsigned char * pszOptions          = NULL;\r
\r
+    /* Use a convenience function to concatenate the elements of */\r
+    /* the string binding into the proper sequence.              */\r
+    status = RpcStringBindingCompose(pszUuid,\r
+                                     pszProtocolSequence,\r
+                                     pszNetworkAddress,\r
+                                     (unsigned char*)clientEndpoint(clientUUID),\r
+                                     pszOptions,\r
+                                     &pszStringBinding);\r
+    if (status) {return (status);}\r
+\r
+    /* Set the binding handle that will be used to bind to the RPC server [the 'client']. */\r
+    status = RpcBindingFromStringBinding(pszStringBinding, &SERVER_REPLY_RPC_HANDLE);\r
+    return (status);\r
+    }\r
+\r
+RPC_STATUS send_finish() {\r
+    RPC_STATUS  status;\r
+    /* Can't shut down client -- it runs listen function which  */\r
+    /* server uses to detect the client going away.             */              \r
+\r
+    /*  The calls to the remote procedures are complete. */\r
+    /*  Free the string and the binding handle           */\r
+    status = RpcStringFree(&pszStringBinding);  // remote calls done; unbind\r
+    if (status) {return (status);}\r
+\r
+    status = RpcBindingFree(&SERVER_REPLY_RPC_HANDLE);  // remote calls done; unbind\r
+    \r
+    return (status);\r
+    }\r
+\r
+RPC_STATUS send_connection_reply(ccs_pipe_t in_pipe) {\r
+    char*       uuid    = ccs_win_pipe_getUuid  (in_pipe);\r
+    HANDLE      h       = ccs_win_pipe_getHandle(in_pipe);\r
+    RPC_STATUS  status  = send_init(uuid);\r
+\r
+    RpcTryExcept {\r
+        ccs_rpc_connect_reply(      // make call with user message\r
+            CCMSG_CONNECT_REPLY,    /* Message type */\r
+            (unsigned char*)&h,      /* client's tspdata* */\r
+            (unsigned char*)uuid,\r
+            getMySST(),             /* Server's session number = it's start time */\r
+            &status );              /* Return code */\r
+        }\r
+    RpcExcept(1) {\r
+        cci_check_error(RpcExceptionCode());\r
+        }\r
+    RpcEndExcept\r
+\r
+    status  = send_finish();\r
+    return (status);\r
+    }\r
+\r
+#if 0\r
+DWORD alloc_name(LPSTR* pname, LPSTR postfix) {\r
+    DWORD len = strlen(sessID) + 1 + strlen(postfix) + 1;\r
+\r
+    *pname = (LPSTR)malloc(len);\r
+    if (!*pname) return GetLastError();\r
+    _snprintf(*pname, len, "%s.%s", sessID, postfix);\r
+    return 0;\r
+    }\r
+#endif\r
+\r
+RPC_STATUS GetPeerName( RPC_BINDING_HANDLE hClient,\r
+                        LPTSTR pszClientName,\r
+                        int iMaxLen) {\r
+    RPC_STATUS Status          = RPC_S_OK;\r
+    RPC_BINDING_HANDLE hServer = NULL;\r
+    PTBYTE pszStringBinding    = NULL;\r
+    PTBYTE pszClientNetAddr    = NULL;\r
+    PTBYTE pszProtSequence     = NULL;\r
+\r
+    memset(pszClientName, 0, iMaxLen * sizeof(TCHAR));\r
+\r
+    __try {\r
+        // Create a partially bound server handle from the client handle.\r
+        Status = RpcBindingServerFromClient (hClient, &hServer);\r
+        if (Status != RPC_S_OK) __leave;\r
+\r
+        // Get the partially bound server string binding and parse it.\r
+        Status = RpcBindingToStringBinding (hServer,\r
+                                            &pszStringBinding);\r
+        if (Status != RPC_S_OK) __leave;\r
+\r
+        // String binding only contains protocol sequence and client\r
+        // address, and is not currently implemented for named pipes.\r
+        Status = RpcStringBindingParse (pszStringBinding, NULL,\r
+                                        &pszProtSequence, &pszClientNetAddr, \r
+                                        NULL, NULL);\r
+        if (Status != RPC_S_OK)\r
+            __leave;\r
+        int iLen = lstrlen(pszClientName) + 1;\r
+        if (iMaxLen < iLen)\r
+            Status = RPC_S_BUFFER_TOO_SMALL;\r
+        lstrcpyn(pszClientName, (LPCTSTR)pszClientNetAddr, iMaxLen);\r
+    }\r
+    __finally {\r
+        if (pszProtSequence)\r
+            RpcStringFree (&pszProtSequence);\r
+        \r
+        if (pszClientNetAddr)\r
+            RpcStringFree (&pszClientNetAddr);\r
+        \r
+        if (pszStringBinding)\r
+            RpcStringFree (&pszStringBinding);\r
+        \r
+        if (hServer)\r
+            RpcBindingFree (&hServer);\r
+    }\r
+    return Status;\r
+}\r
+\r
+struct client_auth_info {\r
+    RPC_AUTHZ_HANDLE authz_handle;\r
+    unsigned char* server_principal; // need to RpcFreeString this\r
+    ULONG authn_level;\r
+    ULONG authn_svc;\r
+    ULONG authz_svc;\r
+};\r
+\r
+RPC_STATUS\r
+GetClientId(\r
+    RPC_BINDING_HANDLE hClient,\r
+    char* client_id,\r
+    int max_len,\r
+    client_auth_info* info\r
+    )\r
+{\r
+    RPC_AUTHZ_HANDLE authz_handle = 0;\r
+    unsigned char* server_principal = 0;\r
+    ULONG authn_level = 0;\r
+    ULONG authn_svc = 0;\r
+    ULONG authz_svc = 0;\r
+    RPC_STATUS status = 0;\r
+\r
+    memset(client_id, 0, max_len);\r
+\r
+    if (info) {\r
+        memset(info, 0, sizeof(client_auth_info));\r
+    }\r
+\r
+    status = RpcBindingInqAuthClient(hClient, &authz_handle, \r
+                                     info ? &server_principal : 0, \r
+                                     &authn_level, &authn_svc, &authz_svc);\r
+    if (status == RPC_S_OK)\r
+    {\r
+        if (info) {\r
+            info->server_principal = server_principal;\r
+            info->authz_handle = authz_handle;\r
+            info->authn_level = authn_level;\r
+            info->authn_svc = authn_svc;\r
+            info->authz_svc = authz_svc;\r
+        }\r
+\r
+        if (authn_svc == RPC_C_AUTHN_WINNT) {\r
+            WCHAR* username = (WCHAR*)authz_handle;\r
+            int len = lstrlenW(username) + 1;\r
+            if (max_len < len)\r
+                status = RPC_S_BUFFER_TOO_SMALL;\r
+            _snprintf(client_id, max_len, "%S", username);\r
+        } else {\r
+            status = RPC_S_UNKNOWN_AUTHN_SERVICE;\r
+        }\r
+    }\r
+    return status;\r
+}\r
+\r
+char*\r
+rpc_error_to_string(\r
+    RPC_STATUS status\r
+    )\r
+{\r
+    switch(status) {\r
+    case RPC_S_OK:\r
+        return "OK";\r
+    case RPC_S_INVALID_BINDING:\r
+        return "Invalid binding";\r
+    case RPC_S_WRONG_KIND_OF_BINDING:\r
+        return "Wrong binding";\r
+    case RPC_S_BINDING_HAS_NO_AUTH:\r
+        RpcRaiseException(RPC_S_BINDING_HAS_NO_AUTH);\r
+        return "Binding has no auth";\r
+    default:\r
+        return "BUG: I am confused";\r
+    }\r
+}\r
+\r
+void\r
+print_client_info(\r
+    RPC_STATUS peer_status,\r
+    const char* peer_name,\r
+    RPC_STATUS client_status,\r
+    const char* client_id,\r
+    client_auth_info* info\r
+    )\r
+{\r
+    if (peer_status == RPC_S_OK || peer_status == RPC_S_BUFFER_TOO_SMALL) {\r
+        cci_debug_printf("%s Peer Name is \"%s\"", __FUNCTION__, peer_name);\r
+    } else {\r
+        cci_debug_printf("%s Error %u getting Peer Name (%s)",\r
+                     __FUNCTION__, peer_status, rpc_error_to_string(peer_status));\r
+    }\r
+\r
+    if (client_status == RPC_S_OK || client_status == RPC_S_BUFFER_TOO_SMALL) {\r
+        if (info) {\r
+            cci_debug_printf("%s Client Auth Info"\r
+                         "\tServer Principal:       %s\n"\r
+                         "\tAuthentication Level:   %d\n"\r
+                         "\tAuthentication Service: %d\n"\r
+                         "\tAuthorization Service:  %d\n",\r
+                         __FUNCTION__, \r
+                         info->server_principal,\r
+                         info->authn_level,\r
+                         info->authn_svc,\r
+                         info->authz_svc);\r
+        }\r
+        cci_debug_printf("%s Client ID is \"%s\"", __FUNCTION__, client_id);\r
+    } else {\r
+        cci_debug_printf("%s Error getting Client Info (%u = %s)", \r
+                     __FUNCTION__, client_status, rpc_error_to_string(client_status));\r
+    }\r
+}\r
+\r
+DWORD sid_check() {\r
+    DWORD status = 0;\r
+    HANDLE hToken_c = 0;\r
+    HANDLE hToken_s = 0;\r
+    PTOKEN_USER ptu_c = 0;\r
+    PTOKEN_USER ptu_s = 0;\r
+    DWORD len = 0;\r
+    BOOL bImpersonate = FALSE;\r
+\r
+    // Note GetUserName will fail while impersonating at identify\r
+    // level.  The workaround is to impersonate, OpenThreadToken,\r
+    // revert, call GetTokenInformation, and finally, call\r
+    // LookupAccountSid.\r
+\r
+    // XXX - Note: This workaround does not appear to work.\r
+    // OpenThreadToken fails with error 1346: "Either a requid\r
+    // impersonation level was not provided or the provided\r
+    // impersonation level is invalid".\r
+\r
+    status = RpcImpersonateClient(0);\r
+\r
+    if (!status) {\r
+        bImpersonate = TRUE;\r
+        if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken_c))\r
+            status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        status = RpcRevertToSelf();\r
+        }\r
+\r
+    if (!status) {\r
+        bImpersonate = FALSE;\r
+\r
+        len = 0;\r
+        GetTokenInformation(hToken_c, TokenUser, ptu_c, 0, &len);\r
+        if (len == 0) status = 1;\r
+        }\r
+\r
+    if (!status) {\r
+        if (!(ptu_c = (PTOKEN_USER)LocalAlloc(0, len)))\r
+            status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!GetTokenInformation(hToken_c, TokenUser, ptu_c, len, &len))\r
+            status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken_s))\r
+            status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        len = 0;\r
+        GetTokenInformation(hToken_s, TokenUser, ptu_s, 0, &len);\r
+        if (len == 0) status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!(ptu_s = (PTOKEN_USER)LocalAlloc(0, len)))\r
+            status = GetLastError();\r
+        }\r
+\r
+    if (!status) {\r
+        if (!GetTokenInformation(hToken_s, TokenUser, ptu_s, len, &len))\r
+            status = GetLastError();\r
+        }\r
+\r
+    if (!EqualSid(ptu_s->User.Sid, ptu_c->User.Sid))\r
+        status = RPC_S_ACCESS_DENIED;\r
+\r
+/* Cleanup: */\r
+    if (!hToken_c && !bImpersonate)\r
+        cci_debug_printf("%s Cannot impersonate (%u)", __FUNCTION__, status);\r
+    else if (!hToken_c)\r
+        cci_debug_printf("%s Failed to open client token (%u)", __FUNCTION__, status);\r
+    else if (bImpersonate)\r
+        cci_debug_printf("%s Failed to revert (%u)", __FUNCTION__, status);\r
+    else if (!ptu_c)\r
+        cci_debug_printf("%s Failed to get client token user info (%u)",\r
+                     __FUNCTION__, status);\r
+    else if (!hToken_s)\r
+        cci_debug_printf("%s Failed to open server token (%u)", __FUNCTION__, status);\r
+    else if (!ptu_s)\r
+        cci_debug_printf("%s Failed to get server token user info (%u)",\r
+                     __FUNCTION__, status);\r
+    else if (status == RPC_S_ACCESS_DENIED)\r
+        cci_debug_printf("%s SID **does not** match!", __FUNCTION__);\r
+    else if (status == RPC_S_OK)\r
+        cci_debug_printf("%s SID matches!", __FUNCTION__);\r
+    else \r
+        if (status) {\r
+            cci_debug_printf("%s unrecognized error %u", __FUNCTION__, status);\r
+            abort();\r
+            }\r
+\r
+    if (bImpersonate)   RpcRevertToSelf();\r
+    if (hToken_c && hToken_c != INVALID_HANDLE_VALUE)\r
+        CloseHandle(hToken_c);\r
+    if (ptu_c)          LocalFree(ptu_c);\r
+    if (hToken_s && hToken_s != INVALID_HANDLE_VALUE)\r
+        CloseHandle(hToken_s);\r
+    if (ptu_s)          LocalFree(ptu_s);\r
+    if (status) cci_debug_printf("%s returning %u", __FUNCTION__, status);\r
+    return status;\r
+    }\r
+\r
+RPC_STATUS RPC_ENTRY sec_callback(  IN RPC_IF_ID *Interface,\r
+                                    IN void *Context) {\r
+    char peer_name[1024];\r
+    char client_name[1024];\r
+    RPC_STATUS peer_status;\r
+    RPC_STATUS client_status;\r
+\r
+    cci_debug_printf("%s", __FUNCTION__);\r
+    peer_status = GetPeerName(Context, peer_name, sizeof(peer_name));\r
+    client_status = GetClientId(Context, client_name, sizeof(client_name), 0);\r
+    print_client_info(peer_status, peer_name, client_status, client_name, 0);\r
+    DWORD sid_status = sid_check();\r
+    cci_debug_printf("%s returning (%u)", __FUNCTION__, sid_status);\r
+    return sid_status;\r
+    }\r
+\r
+\r
+\r
+/*********************************************************************/\r
+/*                 MIDL allocate and free                            */\r
+/*********************************************************************/\r
+\r
+void  __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) {\r
+    return(malloc(len));\r
+    }\r
+\r
+void __RPC_USER midl_user_free(void __RPC_FAR * ptr) {\r
+    free(ptr);\r
+    }\r
diff --git a/src/ccapi/server/win/ccs_request_proc.c b/src/ccapi/server/win/ccs_request_proc.c
new file mode 100644 (file)
index 0000000..40713fb
--- /dev/null
@@ -0,0 +1,116 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+\r
+#include "ccs_request.h"    // header file generated by MIDL compiler\r
+#include "cci_debugging.h"\r
+#include "WorkQueue.h"\r
+#include "win-utils.h"\r
+#include "ccs_win_pipe.h"\r
+\r
+void ccs_rpc_request(\r
+    const long  rpcmsg,             /* Message type */\r
+    const char  tspHandle[],        /* Client's tspdata* */\r
+    const char* pszUUID,            /* Where client will listen for the reply */\r
+    const long  lenRequest,         /* Length of buffer */\r
+    const char  pbRequest[],        /* Data buffer */\r
+    const long  serverStartTime,    /* Which server session we're talking to */\r
+    long*       return_status ) {   /* Return code */\r
+\r
+    cc_int32        status  = 0;\r
+    cci_stream_t    stream;\r
+    DWORD*          p       = (DWORD*)(tspHandle);\r
+    WIN_PIPE*       pipe    = NULL;\r
+\r
+    cci_debug_printf("%s rpcmsg:%d; UUID:<%s> SST:<%s>", \r
+        __FUNCTION__, rpcmsg, pszUUID, serverStartTime);\r
+\r
+    status = (rpcmsg != CCMSG_REQUEST) && (rpcmsg != CCMSG_PING);\r
+    \r
+    if (!status) {                         \r
+        status = cci_stream_new (&stream);  /* Create a stream for the request data */\r
+        }\r
+\r
+    if (!status) {                          /* Put the data into the stream */\r
+        status = cci_stream_write (stream, pbRequest, lenRequest);\r
+        }\r
+\r
+    pipe = ccs_win_pipe_new(pszUUID, *p);    \r
+    worklist_add(rpcmsg, pipe, stream, serverStartTime);\r
+    *return_status = status;\r
+    }\r
+\r
+\r
+void ccs_rpc_connect(\r
+    const long  rpcmsg,             /* Message type */\r
+    const char  tspHandle[],        /* Client's tspdata* */\r
+    const char* pszUUID,            /* Data buffer */\r
+    long*       return_status ) {   /* Return code */\r
+\r
+    DWORD*      p       = (DWORD*)(tspHandle);\r
+    WIN_PIPE*   pipe    = ccs_win_pipe_new(pszUUID, *p);\r
+\r
+    cci_debug_printf("%s; rpcmsg:%d; UUID: <%s>", __FUNCTION__, rpcmsg, pszUUID);\r
+\r
+    worklist_add(   rpcmsg, \r
+                    pipe,\r
+                    NULL,               /* No payload with connect request */\r
+                    (const time_t)0 );  /* No server session number with connect request */\r
+    }\r
+\r
+\r
+// 'Authentication' is client setting a value in a file and the server\r
+//   returning that value plus one.\r
+CC_UINT32 ccs_authenticate(const CC_CHAR* name) {\r
+    HANDLE      hMap    = 0;\r
+    PDWORD      pvalue  = 0;\r
+    CC_UINT32   result  = 0;\r
+    DWORD       status  = 0;\r
+\r
+    cci_debug_printf("%s ( %s )", __FUNCTION__, name);\r
+\r
+    hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, (LPSTR)name);\r
+    status  = !hMap;\r
+\r
+    if (!status) {\r
+        pvalue = (PDWORD)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0);\r
+        status = !pvalue;\r
+        }\r
+\r
+    if (!status) {\r
+        *pvalue += 1;\r
+        result = *pvalue;\r
+        }\r
+\r
+    if (pvalue) {\r
+        UnmapViewOfFile(pvalue);\r
+        }\r
+\r
+    if (hMap) CloseHandle(hMap);\r
+    return result;\r
+    }
\ No newline at end of file
diff --git a/src/ccapi/server/win/ccs_win_pipe.c b/src/ccapi/server/win/ccs_win_pipe.c
new file mode 100644 (file)
index 0000000..4d121aa
--- /dev/null
@@ -0,0 +1,163 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#include "assert.h"\r
+\r
+#include "ccs_win_pipe.h"\r
+#include "cci_debugging.h"\r
+\r
+/* Ref:\r
+struct ccs_win_pipe_t {\r
+    char*   uuid;\r
+    HANDLE  clientHandle;\r
+    }\r
+ */\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+struct ccs_win_pipe_t* ccs_win_pipe_new (const char* uuid, const HANDLE h) {\r
+\r
+    cc_int32                err         = ccNoError;\r
+    struct ccs_win_pipe_t*  out_pipe    = NULL;\r
+    char*                   uuidCopy    = NULL;\r
+\r
+    if (!err) {\r
+        if (!uuid)      {err = cci_check_error(ccErrBadParam);}\r
+        }\r
+\r
+    if (!err) {\r
+        uuidCopy = (char*)malloc(1+strlen(uuid));\r
+        if (!uuidCopy)  {err = cci_check_error(ccErrBadParam);}\r
+        strcpy(uuidCopy, uuid);\r
+        }\r
+    \r
+    if (!err) {\r
+        out_pipe = (struct ccs_win_pipe_t*)malloc(sizeof(struct ccs_win_pipe_t));\r
+        if (!out_pipe)  {err = cci_check_error(ccErrBadParam);}\r
+        out_pipe->uuid          = uuidCopy;\r
+        out_pipe->clientHandle  = h;\r
+        }\r
+\r
+    cci_debug_printf("0x%X = %s(%s, 0x%X)", out_pipe, __FUNCTION__, uuid, h);\r
+\r
+    return out_pipe;\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_win_pipe_copy (WIN_PIPE** out_pipe, \r
+                            const WIN_PIPE* in_pipe) {\r
+\r
+    *out_pipe = \r
+        ccs_win_pipe_new(\r
+            ccs_win_pipe_getUuid  (in_pipe),\r
+            ccs_win_pipe_getHandle(in_pipe) );\r
+\r
+    return (*out_pipe) ? ccNoError : ccErrBadParam;\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_win_pipe_release(const WIN_PIPE* in_pipe) {\r
+\r
+    cc_int32 err = ccNoError;\r
+\r
+    if (!ccs_win_pipe_valid(in_pipe))   {err = cci_check_error(ccErrBadParam);}\r
+\r
+    if (!err) {\r
+        if (!in_pipe->uuid) free(in_pipe->uuid);\r
+        if (!in_pipe)       free(in_pipe);\r
+        }\r
+\r
+    return err;\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_win_pipe_valid (const WIN_PIPE* in_pipe) {\r
+\r
+    if (!in_pipe) {\r
+        cci_check_error(ccErrBadParam);\r
+        return FALSE;\r
+        }\r
+\r
+    if (!in_pipe->uuid) {\r
+        cci_check_error(ccErrBadParam);\r
+        return FALSE;\r
+        }\r
+\r
+    return TRUE;\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+cc_int32 ccs_win_pipe_compare    (const WIN_PIPE*   in_pipe_1,\r
+                                  const WIN_PIPE*   in_pipe_2,\r
+                                  cc_uint32         *out_equal) {\r
+\r
+    cc_int32 err    = ccNoError;\r
+    int      seq    = 0;\r
+    *out_equal      = FALSE;\r
+\r
+    if (!ccs_win_pipe_valid(in_pipe_1)) {err = cci_check_error(ccErrBadParam);}\r
+    if (!ccs_win_pipe_valid(in_pipe_2)) {err = cci_check_error(ccErrBadParam);}\r
+    if (!out_equal)                     {err = cci_check_error(ccErrBadParam);}\r
+\r
+    /* A disconnect doesn't have a tls* with it -- only the uuid.  SO only\r
+       compare the uuids.\r
+     */\r
+    if (!err) {\r
+        seq = strcmp(   ccs_win_pipe_getUuid(in_pipe_1),\r
+                        ccs_win_pipe_getUuid(in_pipe_2) );\r
+        *out_equal = (seq == 0);\r
+        }\r
+\r
+    return err;\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+char* ccs_win_pipe_getUuid    (const WIN_PIPE* in_pipe) {\r
+\r
+    char*   result = NULL;\r
+\r
+    if (!ccs_win_pipe_valid(in_pipe)) {cci_check_error(ccErrBadParam);}\r
+    else                              {result = in_pipe->uuid;}\r
+\r
+    return result;\r
+    }\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+HANDLE ccs_win_pipe_getHandle  (const WIN_PIPE* in_pipe) {\r
+\r
+    HANDLE result = NULL;\r
+\r
+    if (!ccs_win_pipe_valid(in_pipe)) {cci_check_error(ccErrBadParam);}\r
+    else                              {result = in_pipe->clientHandle;}\r
+\r
+    return result;\r
+    }\r
diff --git a/src/ccapi/server/win/ccs_win_pipe.h b/src/ccapi/server/win/ccs_win_pipe.h
new file mode 100644 (file)
index 0000000..afabe12
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+ * $Header$\r
+ *\r
+ * Copyright 2008 Massachusetts Institute of Technology.\r
+ * All Rights Reserved.\r
+ *\r
+ * Export of this software from the United States of America may\r
+ * require a specific license from the United States Government.\r
+ * It is the responsibility of any person or organization contemplating\r
+ * export to obtain such a license before exporting.\r
+ *\r
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r
+ * distribute this software and its documentation for any purpose and\r
+ * without fee is hereby granted, provided that the above copyright\r
+ * notice appear in all copies and that both that copyright notice and\r
+ * this permission notice appear in supporting documentation, and that\r
+ * the name of M.I.T. not be used in advertising or publicity pertaining\r
+ * to distribution of the software without specific, written prior\r
+ * permission.  Furthermore if you modify this software you must label\r
+ * your software as modified software and not distribute it in such a\r
+ * fashion that it might be confused with the original M.I.T. software.\r
+ * M.I.T. makes no representations about the suitability of\r
+ * this software for any purpose.  It is provided "as is" without express\r
+ * or implied warranty.\r
+ */\r
+\r
+#ifndef _ccs_win_pipe_h_\r
+#define _ccs_win_pipe_h_\r
+\r
+#include "windows.h"\r
+\r
+#include "CredentialsCache.h"\r
+\r
+/* ------------------------------------------------------------------------ */\r
+\r
+/* On Windows, a pipe is a struct containing a UUID and a handle.  Both the \r
+   UUID and handle are supplied by the client.  \r
+   \r
+   The UUID is used to build the client's reply endpoint.  \r
+   \r
+   The handle is to the requesting client thread's thread local storage struct,\r
+   so that the client's one and only reply handler can put reply data where\r
+   the requesting thread will be able to see it.\r
+ */\r
+   \r
+struct ccs_win_pipe_t {\r
+    char*   uuid;\r
+    HANDLE  clientHandle;\r
+    };\r
+\r
+typedef struct ccs_win_pipe_t WIN_PIPE;\r
+\r
+struct ccs_win_pipe_t*  ccs_win_pipe_new(const char* uuid, const HANDLE h);\r
+\r
+cc_int32    ccs_win_pipe_release    (const WIN_PIPE* io_pipe);\r
+\r
+cc_int32    ccs_win_pipe_compare    (const WIN_PIPE* win_pipe_1,\r
+                                     const WIN_PIPE* win_pipe_2,\r
+                                     cc_uint32  *out_equal);\r
+\r
+cc_int32    ccs_win_pipe_copy       (WIN_PIPE** out_pipe, \r
+                                     const WIN_PIPE* in_pipe);\r
+\r
+cc_int32    ccs_win_pipe_valid      (const WIN_PIPE* in_pipe);\r
+\r
+char*       ccs_win_pipe_getUuid    (const WIN_PIPE* in_pipe);\r
+HANDLE      ccs_win_pipe_getHandle  (const WIN_PIPE* in_pipe);\r
+\r
+#endif // _ccs_win_pipe_h_
\ No newline at end of file
diff --git a/src/ccapi/server/win/workitem.h b/src/ccapi/server/win/workitem.h
new file mode 100644 (file)
index 0000000..a9d1c0e
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef __WorkItem\r
+#define __WorkItem\r
+\r
+#include <list>\r
+#include "windows.h"\r
+\r
+extern "C" {\r
+    #include "cci_stream.h"\r
+    #include "ccs_pipe.h"\r
+    }\r
+\r
+class WorkItem {\r
+private:\r
+          cci_stream_t    _buf;\r
+          WIN_PIPE*       _pipe;\r
+    const long            _rpcmsg;\r
+    const long            _sst;\r
+public:\r
+    WorkItem(   cci_stream_t  buf, \r
+                WIN_PIPE*     pipe, \r
+                const long    type, \r
+                const long    serverStartTime);\r
+    WorkItem(   const         WorkItem&);\r
+    WorkItem();\r
+    ~WorkItem();\r
+\r
+    const cci_stream_t  payload()       const   {return _buf;}\r
+    const cci_stream_t  take_payload();\r
+          WIN_PIPE*     take_pipe();\r
+          WIN_PIPE*     pipe()          const   {return _pipe;}\r
+    const long          type()          const   {return _rpcmsg;}\r
+    const long          sst()           const   {return _sst;}\r
+    char*               print(char* buf);\r
+    };\r
+\r
+class WorkList {\r
+private:\r
+    std::list <WorkItem*>   wl;\r
+    CRITICAL_SECTION        cs;\r
+public:\r
+    WorkList();\r
+    ~WorkList();\r
+    int add(WorkItem*);\r
+    int remove(WorkItem**);\r
+    bool isEmpty() {return wl.empty();}\r
+    };\r
+\r
+#endif  // __WorkItem
\ No newline at end of file
diff --git a/src/ccapi/test/Makefile.w32 b/src/ccapi/test/Makefile.w32
new file mode 100644 (file)
index 0000000..077c20b
--- /dev/null
@@ -0,0 +1,64 @@
+# . is ccapi/test.\r
+CO      = ..\common\r
+COWIN   = $(CO)\win\r
+LIBDIR  = ..\lib\r
+LIBWIN  = $(LIBDIR)\win\r
+\r
+!include <Win32.Mak>\r
+\r
+INC = -I..\..\include -I..\..\util\et -I$(CO) -I$(COWIN) -I$(LIBDIR) -I$(LIBWIN)\r
+\r
+!if "$(CPU)" == "i386"\r
+cflags = $(cflags) /EHsc /MTd -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 \\r
+$(INC)\r
+!else\r
+cflags = $(cflags) /W3 -D_CRTAPI1= -D_CRTAPI2= $(INC)\r
+!endif\r
+LIBS = $(LIBWIN)\ccapi.lib\r
+\r
+DSTROOT = .\r
+SRC = $(DSTROOT)\r
+#OBJDIR = $(DSTROOT)\obj\r
+OBJDIR = .\r
+OBJEXT = obj\r
+TESTDIR = $(DSTROOT)\tests\r
+TESTEXT = exe\r
+DSTDIR = $(DSTROOT)\ccapi_tests\r
+PINGOBJS = pingtest.obj ccs_request_c.obj \r
+SIMPLEOBJS = simple_lock_test.obj\r
+\r
+OBJS =  cci_debugging.$(OBJEXT) \\r
+        ccs_request_c.obj \\r
+        cci_os_debugging.$(OBJEXT) \\r
+        win-utils.obj \\r
+        ccapi_os_ipc.obj \\r
+        cci_stream.obj\r
+        \r
+#all: build-base simple_lock_test pingtest \r
+all: build-base pingtest \r
+\r
+# compile base files used by all tests\r
+build-base: $(OBJS)\r
+    @echo "Base objects built."\r
+\r
+# rule to compile src files\r
+.c.obj:\r
+    $(cc) $(cdebug) $(cflags) /Fo$(OBJDIR)\$(*B).$(OBJEXT) $(SRC)\$(*B).c\r
+\r
+simple_lock_test: simple_lock_test.obj $(OBJS)\r
+       @echo R3+ Build $(*B) in $(TESTDIR)\r
+    $(cc) $(cdebug) $(cflags) $(*B).c\r
+    $(link) $(linkdebug) $(conflags) -out:$(TESTDIR)\$(*B).exe $(*B).obj \\r
+        $(LIBS) rpcrt4.lib\r
+       @echo R3- Built $(*B) in $(TESTDIR)\r
+\r
+pingtest: pingtest.obj\r
+       @echo R4+ Build $(*B) in $(TESTDIR)\r
+    $(cc) $(cdebug) $(cflags) $(*B).c\r
+#    $(link) $(linkdebug) $(conflags) -out:$(*B).exe $(*B).obj \\r
+    $(link) $(linkdebug) $(conflags) -out:$(*B).exe $(PINGOBJS) \\r
+        $(LIBS) rpcrt4.lib\r
+       @echo R4- Built $(*B) in $(TESTDIR)\r
+\r
+clean:\r
+       DEL *.$(OBJEXT)
\ No newline at end of file
diff --git a/src/ccapi/test/pingtest.c b/src/ccapi/test/pingtest.c
new file mode 100644 (file)
index 0000000..9927725
--- /dev/null
@@ -0,0 +1,108 @@
+// pingtest.c\r
+//\r
+// Test RPC to server, with PING message, which exists for no other purpose than this test.\r
+\r
+#include <stdio.h>\r
+#include <stdarg.h>\r
+\r
+#include "cci_debugging.h"\r
+#include "CredentialsCache.h"\r
+#include "cci_stream.h"\r
+#include "win-utils.h"\r
+\r
+#include "ccs_request.h"\r
+#define CLIENT_REQUEST_RPC_HANDLE ccs_request_IfHandle\r
+\r
+\r
+extern cc_int32 cci_os_ipc_thread_init (void);\r
+extern cc_int32 cci_os_ipc_msg( cc_int32        in_launch_server,\r
+                                cci_stream_t    in_request_stream,\r
+                                cc_int32        in_msg,\r
+                                cci_stream_t*   out_reply_stream);\r
+\r
+RPC_STATUS send_test(char* endpoint) {\r
+    unsigned char*  pszNetworkAddress   = NULL;\r
+    unsigned char*  pszOptions          = NULL;\r
+    unsigned char*  pszStringBinding    = NULL;\r
+    unsigned char*  pszUuid             = NULL;\r
+    RPC_STATUS      status;\r
\r
+    status = RpcStringBindingCompose(pszUuid,\r
+                                     (RPC_CSTR)"ncalrpc",\r
+                                     pszNetworkAddress,\r
+                                     (unsigned char*)endpoint,\r
+                                     pszOptions,\r
+                                     &pszStringBinding);\r
+    cci_debug_printf("%s pszStringBinding = %s", __FUNCTION__, pszStringBinding);\r
+    if (status) {return cci_check_error(status);}\r
+\r
+    /* Set the binding handle that will be used to bind to the RPC server [the 'client']. */\r
+    status = RpcBindingFromStringBinding(pszStringBinding, &CLIENT_REQUEST_RPC_HANDLE);\r
+    if (status) {return cci_check_error(status);}\r
+\r
+    status = RpcStringFree(&pszStringBinding);  // Temp var no longer needed.\r
+\r
+    if (!status) {\r
+        RpcTryExcept {\r
+            cci_debug_printf("%s calling remote procedure 'ccs_authenticate'", __FUNCTION__);\r
+            status = ccs_authenticate((CC_CHAR*)"DLLMAIN TEST!");\r
+            cci_debug_printf("  ccs_authenticate returned %d", status);\r
+            }\r
+        RpcExcept(1) {\r
+            status = cci_check_error(RpcExceptionCode());\r
+            }\r
+        RpcEndExcept\r
+        }\r
+\r
+    cci_check_error(RpcBindingFree(&CLIENT_REQUEST_RPC_HANDLE));\r
+\r
+    return (status);\r
+    }\r
+\r
+int main(   int argc, char *argv[]) {\r
+    cc_int32        err             = 0;\r
+    cc_context_t    context         = NULL;\r
+    cci_stream_t    send_stream     = NULL;\r
+    cci_stream_t    reply_stream    = NULL;\r
+    char*           message         = "Hello, RPC!";\r
+\r
+\r
+//    send_test("krbcc.229026.0.ep");\r
+\r
+#if 0\r
+    err = cc_initialize(&context, ccapi_version_7, NULL, NULL);\r
+#endif\r
+\r
+    if (!err) {\r
+        err = cci_os_ipc_thread_init();\r
+        }\r
+    if (!err) {\r
+        err = cci_stream_new  (&send_stream);\r
+        err = cci_stream_write(send_stream, message, 1+strlen(message));\r
+        }\r
+\r
+    if (!err) {\r
+        err = cci_os_ipc_msg(TRUE, send_stream, CCMSG_PING, &reply_stream); \r
+        }\r
+    Sleep(10*1000);\r
+    cci_debug_printf("Try finishing async call.");\r
+\r
+    Sleep(INFINITE);\r
+    cci_debug_printf("main: return. err == %d", err);\r
+    \r
+    return 0;\r
+    }\r
+\r
+\r
+\r
+/*********************************************************************/\r
+/*                 MIDL allocate and free                            */\r
+/*********************************************************************/\r
+\r
+void  __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) {\r
+    return(malloc(len));\r
+    }\r
+\r
+void __RPC_USER midl_user_free(void __RPC_FAR * ptr) {\r
+    free(ptr);\r
+    }\r
index 6674a1ef6cf6259d52453fb9e7867d0f34133aaf..254663c3a7637102abdb5afac1d381ea0ca20f99 100644 (file)
@@ -1,69 +1,84 @@
-/*
-    simple_lock_test.c
-    
-    Initializes two contexts in two different threads and tries to get read locks on both at the same time.
-    Hangs at line 24.
-*/
-#include <pthread.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <Kerberos/CredentialsCache.h>
-
-void * other_thread ()
-{
-    cc_int32 err;
-    cc_context_t context = NULL;
-    
-    err = cc_initialize(&context, ccapi_version_7, NULL, NULL);
-
-    fprintf(stderr, "thread: attempting lock. may hang. err == %d\n", err);
-
-    if (!err) {
-        // hangs with cc_lock_read which should succeed immediately, but does not hang with write, upgrade, and downgrade, which fail immediately
-        err = cc_context_lock(context, cc_lock_read, cc_lock_noblock);
-    }
-
-    if (context) {
-        cc_context_unlock(context);
-        cc_context_release(context);
-        context = NULL;
-    }
-    fprintf(stderr, "thread: return. err == %d\n", err);
-}
-
-
-int main (int argc, char *argv[])
-{
-    cc_int32 err;
-    int status;
-    pthread_t thread_id;
-    cc_context_t context = NULL;
-    
-    err = cc_initialize(&context, ccapi_version_7, NULL, NULL);
-    if (!err) {
-        err = cc_context_lock(context, cc_lock_read, cc_lock_noblock);
-    }
-    
-    fprintf(stderr, "main: initialized and read locked context. err == %d\n", err);
-
-    status = pthread_create (&thread_id, NULL, (void *) other_thread, NULL);
-    if (status != 0) {
-        fprintf(stderr,"Create error!\n");
-        exit(-1);
-    }
-
-    pthread_join(thread_id, NULL);
-    
-    fprintf(stderr, "main: unlocking and releasing context. err == %d\n", err);
-    
-    if (context) {
-        cc_context_unlock(context);
-        cc_context_release(context);
-        context = NULL;
-    }
-
-    fprintf(stderr, "main: return. err == %d\n", err);
-    
-    return 0;
-}
\ No newline at end of file
+/*\r
+    simple_lock_test.c\r
+    \r
+    Initializes two contexts in two different threads and tries to get read locks on both at the same time.\r
+    Hangs at line 24.\r
+*/\r
+#include <stdio.h>\r
+#include <stdarg.h>\r
+\r
+#include "cci_debugging.h"\r
+\r
+#ifdef TARGET_OS_MAC\r
+#include <stdlib.h>\r
+#include <Kerberos/CredentialsCache.h>\r
+#else\r
+#include "CredentialsCache.h"\r
+#endif\r
+\r
+\r
+void * other_thread () {\r
+    cc_int32 err;\r
+    cc_context_t context = NULL;\r
+    \r
+    err = cc_initialize(&context, ccapi_version_7, NULL, NULL);\r
+\r
+    cci_debug_printf("thread: attempting lock. may hang. err == %d", err);\r
+\r
+    if (!err) {\r
+        // hangs with cc_lock_read which should succeed immediately, but does not hang with write, upgrade, and downgrade, which fail immediately\r
+        err = cc_context_lock(context, cc_lock_read, cc_lock_noblock);\r
+        }\r
+\r
+    if (context) {\r
+        cc_context_unlock(context);\r
+        cc_context_release(context);\r
+        context = NULL;\r
+        }\r
+    cci_debug_printf("thread: return. err == %d", err);\r
+    }\r
+\r
+\r
+int main (int argc, char *argv[]) {\r
+    cc_int32        err;\r
+    int             status;\r
+    cc_context_t    context = NULL;\r
+\r
+#ifdef TARGET_OS_MAC\r
+    pthread_t       thread_id;\r
+#endif\r
+\r
+    err = cc_initialize(&context, ccapi_version_7, NULL, NULL);\r
+    if (!err) {\r
+        err = cc_context_lock(context, cc_lock_read, cc_lock_noblock);\r
+        }\r
+    \r
+    cci_debug_printf("main: initialized and read locked context. err == %d", err);\r
+\r
+#ifdef TARGET_OS_MAC\r
+   status = pthread_create (&thread_id, NULL, (void *) other_thread, NULL);\r
+    if (status != 0) {\r
+        cci_debug_printf("Create error!");\r
+        exit(-1);\r
+    }\r
+\r
+    pthread_join(thread_id, NULL);\r
+#else\r
+\r
+#endif\r
+    \r
+    cci_debug_printf("main: unlocking and releasing context. err == %d", err);\r
+    \r
+    if (context) {\r
+        cci_debug_printf("main: calling cc_context_unlock");\r
+        cc_context_unlock(context);\r
+        cci_debug_printf("main: calling cc_context_release");\r
+        cc_context_release(context);\r
+        context = NULL;\r
+       }\r
+\r
+    cci_debug_printf("main: return. err == %d", err);\r
+    \r
+     UNREFERENCED_PARAMETER(status);       // no whining!\r
+    return 0;\r
+    }
\ No newline at end of file