summaryrefslogtreecommitdiffstats
path: root/src/ccapi/lib
diff options
context:
space:
mode:
authorKevin Koch <kpkoch@mit.edu>2008-01-22 19:14:04 +0000
committerKevin Koch <kpkoch@mit.edu>2008-01-22 19:14:04 +0000
commit7bfff83859f4bfb254c659dc0caa529735fd2507 (patch)
tree0a9f78c9ae794e3f98616b7d7f9cc59825aef216 /src/ccapi/lib
parentfaf9366d3111f171e157b1e45ba7b49d5a529903 (diff)
downloadkrb5-7bfff83859f4bfb254c659dc0caa529735fd2507.tar.gz
krb5-7bfff83859f4bfb254c659dc0caa529735fd2507.tar.xz
krb5-7bfff83859f4bfb254c659dc0caa529735fd2507.zip
Windows CCAPI snapshot. Should build & pass ping test
TargetVersion: 1.7 Component: krb5-libs Ticket: 5594 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20203 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/ccapi/lib')
-rw-r--r--src/ccapi/lib/win/Makefile116
-rw-r--r--src/ccapi/lib/win/OldCC/ccapi.h284
-rw-r--r--src/ccapi/lib/win/OldCC/client.cxx389
-rw-r--r--src/ccapi/lib/win/OldCC/client.h61
-rw-r--r--src/ccapi/lib/win/OldCC/rpc.cxx79
-rw-r--r--src/ccapi/lib/win/WINCCAPI.sln20
-rw-r--r--src/ccapi/lib/win/WINCCAPI.vcproj111
-rw-r--r--src/ccapi/lib/win/ccapi.def39
-rw-r--r--src/ccapi/lib/win/ccapi_os_ipc.cxx373
-rw-r--r--src/ccapi/lib/win/ccs_reply_proc.c98
-rw-r--r--src/ccapi/lib/win/dllmain.cxx279
-rw-r--r--src/ccapi/lib/win/dllmain.h45
12 files changed, 1894 insertions, 0 deletions
diff --git a/src/ccapi/lib/win/Makefile b/src/ccapi/lib/win/Makefile
new file mode 100644
index 000000000..4bdd98df7
--- /dev/null
+++ b/src/ccapi/lib/win/Makefile
@@ -0,0 +1,116 @@
+!include <Win32.Mak>
+
+# . is ...\pismere\athena\auth\krb5\src\ccapi\lib\win
+CCAPI = ..\..
+CO = $(CCAPI)\common
+COWIN = $(CCAPI)\common\win
+CCUTIL = $(CCAPI)\common\win\OldCC
+LIBDIR = $(CCAPI)\lib
+LIBWIN = $(LIBDIR)\win
+K5SRC = $(CCAPI)\..
+POSIX = $(K5SRC)\lib\krb5\posix
+OLDCC = $(LIBWIN)\OldCC
+
+INC = -I.. -I$(CO) -I$(COWIN) -I$(K5SRC)\include -I..\..\..\util\et -I$(OLDCC) \
+ -I$(LIBWIN) -I$(CCUTIL)
+MIDLI = /I $(K5SRC)\include /I. /I$(COWIN) /I$(CO)
+
+!if "$(CPU)" == "i386"
+cflags = $(cflags) /EHsc /MDd -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 \
+$(INC) -D_CRT_SECURE_NO_WARNINGS
+!else
+cflags = $(cflags) /W3 -D_CRTAPI1= -D_CRTAPI2= $(INC)
+!endif
+
+!if "$(PREPROCESS)" == "P"
+cflags = $(cflags) -P
+!endif
+
+all : ccapi.dll
+
+common = cci_array_internal.obj cci_cred_union.obj cci_debugging.obj cci_identifier.obj \
+ cci_message.obj cci_stream.obj
+
+commonwin = cci_os_debugging.obj \
+ cci_os_identifier.obj \
+ tls.obj \
+ win-utils.obj
+
+dll = ccapi_ccache.obj \
+ ccapi_ccache_iterator.obj \
+ ccapi_context.obj \
+ ccapi_context_change_time.obj \
+ ccapi_credentials.obj \
+ ccapi_credentials_iterator.obj \
+ ccapi_ipc.obj \
+ ccapi_string.obj
+
+dllwin = ccs_reply_s.obj \
+ ccs_reply_proc.obj \
+ ccs_request_c.obj
+
+dllwincxx = ccapi_os_ipc.obj \
+ dllmain.obj
+
+oldcc = client.obj \
+ rpc.obj
+
+utils = ccutils.obj
+
+utilscxx = init.obj \
+ secure.obj \
+ util.obj
+
+
+linkobjs = $(common) $(commonwin) $(dll) $(dllwin) $(dllwincxx) $(oldcc) $(utils) $(utilscxx)
+
+#includes =
+
+# Main program:
+ccapi.dll : $(linkobjs) ccapi.def
+ $(link) $(linkdebug) $(conflags) -out:ccapi.dll /DEF:ccapi.def /implib:ccapi.lib $(dlllflags) \
+ $(linkobjs) rpcrt4.lib kernel32.lib user32.lib $(conlibsdll)
+
+
+ccs_request.h ccs_request_c.c ccs_request_s.c : $(COWIN)\ccs_request.idl $(COWIN)\ccs_request.acf
+ midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(cc) -cpp_opt "-E" \
+ $(COWIN)\ccs_request.idl
+
+ccs_reply.h ccs_reply_c.c ccs_reply_s.c : $(COWIN)\ccs_reply.idl $(COWIN)\ccs_reply.acf
+ midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(cc) -cpp_opt "-E" -I. -I$(COWIN) \
+ $(COWIN)\ccs_reply.idl
+
+$(common) : $(CO)\$*.c
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(CO)\$*.c
+
+$(commonwin) : $(COWIN)\$*.c
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(COWIN)\$*.c
+
+$(dll) : $(LIBDIR)\$*.c
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(LIBDIR)\$*.c
+
+$(dllwin) : $*.c ccs_reply.h ccs_request.h
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(LIBWIN)\$*.c
+
+$(dllwincxx) : $*.cxx ccs_reply.h ccs_request.h
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(LIBWIN)\$*.cxx
+
+$(oldcc) : $(OLDCC)\$*.cxx
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(OLDCC)\$*.cxx
+
+$(utils) : $(CCUTIL)\$*.c
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(CCUTIL)\$*.c
+
+$(utilscxx) : $(CCUTIL)\$*.cxx
+ $(cc) $(cdebug) $(cflags) $(cvarsdll) $(CCUTIL)\$*.cxx
+
+
+
+# Clean up everything
+cleanall : clean
+ -del *.dll
+
+# Clean up everything but the .EXEs
+clean :
+ -del *.obj
+ -del *.map
diff --git a/src/ccapi/lib/win/OldCC/ccapi.h b/src/ccapi/lib/win/OldCC/ccapi.h
new file mode 100644
index 000000000..65a72edb4
--- /dev/null
+++ b/src/ccapi/lib/win/OldCC/ccapi.h
@@ -0,0 +1,284 @@
+
+
+/* this ALWAYS GENERATED file contains the definitions for the interfaces */
+
+
+ /* File created by MIDL compiler version 6.00.0366 */
+/* at Fri Nov 30 10:06:16 2007
+ */
+/* Compiler settings for ccapi.idl:
+ Oic, W1, Zp8, env=Win32 (32b run)
+ protocol : dce , ms_ext, c_ext, oldnames
+ error checks: allocation ref bounds_check enum stub_data
+ VC __declspec() decoration level:
+ __declspec(uuid()), __declspec(selectany), __declspec(novtable)
+ DECLSPEC_UUID(), MIDL_INTERFACE()
+*/
+//@@MIDL_FILE_HEADING( )
+
+#pragma warning( disable: 4049 ) /* more than 64k source lines */
+
+
+/* verify that the <rpcndr.h> version is high enough to compile this file*/
+#ifndef __REQUIRED_RPCNDR_H_VERSION__
+#define __REQUIRED_RPCNDR_H_VERSION__ 440
+#endif
+
+#include "rpc.h"
+#include "rpcndr.h"
+
+#ifndef __ccapi_h__
+#define __ccapi_h__
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once
+#endif
+
+/* Forward Declarations */
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+void * __RPC_USER MIDL_user_allocate(size_t);
+void __RPC_USER MIDL_user_free( void * );
+
+#ifndef __ccapi_INTERFACE_DEFINED__
+#define __ccapi_INTERFACE_DEFINED__
+
+/* interface ccapi */
+/* [implicit_handle][unique][version][uuid] */
+
+typedef /* [context_handle] */ struct opaque_handle_CTX *HCTX;
+
+typedef /* [context_handle] */ struct opaque_handle_CACHE *HCACHE;
+
+typedef /* [context_handle] */ struct opaque_handle_CACHE_ITER *HCACHE_ITER;
+
+typedef /* [context_handle] */ struct opaque_handle_CRED_ITER *HCRED_ITER;
+
+typedef unsigned char CC_CHAR;
+
+typedef unsigned char CC_UCHAR;
+
+typedef int CC_INT32;
+
+typedef unsigned int CC_UINT32;
+
+typedef CC_INT32 CC_TIME_T;
+
+
+enum __MIDL_ccapi_0001
+ { STK_AFS = 0,
+ STK_DES = 1
+ } ;
+
+enum __MIDL_ccapi_0002
+ { CC_API_VER_1 = 1,
+ CC_API_VER_2 = 2
+ } ;
+
+enum __MIDL_ccapi_0003
+ { KRB_NAME_SZ = 40,
+ KRB_INSTANCE_SZ = 40,
+ KRB_REALM_SZ = 40,
+ MAX_V4_CRED_LEN = 1250
+ } ;
+typedef struct _NC_INFO
+ {
+ /* [string] */ CC_CHAR *name;
+ /* [string] */ CC_CHAR *principal;
+ CC_INT32 vers;
+ } NC_INFO;
+
+typedef struct _NC_INFO_LIST
+ {
+ CC_UINT32 length;
+ /* [size_is] */ NC_INFO *info;
+ } NC_INFO_LIST;
+
+typedef struct _V4_CRED
+ {
+ CC_UCHAR kversion;
+ CC_CHAR principal[ 41 ];
+ CC_CHAR principal_instance[ 41 ];
+ CC_CHAR service[ 41 ];
+ CC_CHAR service_instance[ 41 ];
+ CC_CHAR realm[ 41 ];
+ CC_UCHAR session_key[ 8 ];
+ CC_INT32 kvno;
+ CC_INT32 str_to_key;
+ CC_INT32 issue_date;
+ CC_INT32 lifetime;
+ CC_UINT32 address;
+ CC_INT32 ticket_sz;
+ CC_UCHAR ticket[ 1250 ];
+ } V4_CRED;
+
+typedef struct _CC_DATA
+ {
+ CC_UINT32 type;
+ CC_UINT32 length;
+ /* [size_is] */ CC_UCHAR *data;
+ } CC_DATA;
+
+typedef struct _CC_DATA_LIST
+ {
+ CC_UINT32 count;
+ /* [size_is] */ CC_DATA *data;
+ } CC_DATA_LIST;
+
+typedef struct _V5_CRED
+ {
+ /* [string] */ CC_CHAR *client;
+ /* [string] */ CC_CHAR *server;
+ CC_DATA keyblock;
+ CC_TIME_T authtime;
+ CC_TIME_T starttime;
+ CC_TIME_T endtime;
+ CC_TIME_T renew_till;
+ CC_UINT32 is_skey;
+ CC_UINT32 ticket_flags;
+ CC_DATA_LIST addresses;
+ CC_DATA ticket;
+ CC_DATA second_ticket;
+ CC_DATA_LIST authdata;
+ } V5_CRED;
+
+typedef /* [switch_type] */ union _CRED_PTR_UNION
+ {
+ /* [case()] */ V4_CRED *pV4Cred;
+ /* [case()] */ V5_CRED *pV5Cred;
+ } CRED_PTR_UNION;
+
+typedef struct _CRED_UNION
+ {
+ CC_INT32 cred_type;
+ /* [switch_is] */ CRED_PTR_UNION cred;
+ } CRED_UNION;
+
+CC_INT32 rcc_initialize(
+ /* [out] */ HCTX *pctx);
+
+CC_INT32 rcc_shutdown(
+ /* [out][in] */ HCTX *pctx);
+
+CC_INT32 rcc_get_change_time(
+ /* [in] */ HCTX ctx,
+ /* [out] */ CC_TIME_T *time);
+
+CC_INT32 rcc_create(
+ /* [in] */ HCTX ctx,
+ /* [string][in] */ const CC_CHAR *name,
+ /* [string][in] */ const CC_CHAR *principal,
+ /* [in] */ CC_INT32 vers,
+ /* [in] */ CC_UINT32 flags,
+ /* [out] */ HCACHE *pcache);
+
+CC_INT32 rcc_open(
+ /* [in] */ HCTX ctx,
+ /* [string][in] */ const CC_CHAR *name,
+ /* [in] */ CC_INT32 vers,
+ /* [in] */ CC_UINT32 flags,
+ /* [out] */ HCACHE *pcache);
+
+CC_INT32 rcc_close(
+ /* [out][in] */ HCACHE *pcache);
+
+CC_INT32 rcc_destroy(
+ /* [out][in] */ HCACHE *pcache);
+
+CC_INT32 rcc_seq_fetch_NCs_begin(
+ /* [in] */ HCTX ctx,
+ /* [out] */ HCACHE_ITER *piter);
+
+CC_INT32 rcc_seq_fetch_NCs_end(
+ /* [out][in] */ HCACHE_ITER *piter);
+
+CC_INT32 rcc_seq_fetch_NCs_next(
+ /* [in] */ HCACHE_ITER iter,
+ /* [out] */ HCACHE *pcache);
+
+CC_INT32 rcc_seq_fetch_NCs(
+ /* [in] */ HCTX ctx,
+ /* [out][in] */ HCACHE_ITER *piter,
+ /* [out] */ HCACHE *pcache);
+
+CC_INT32 rcc_get_NC_info(
+ /* [in] */ HCTX ctx,
+ /* [out] */ NC_INFO_LIST **info_list);
+
+CC_INT32 rcc_get_name(
+ /* [in] */ HCACHE cache,
+ /* [string][out] */ CC_CHAR **name);
+
+CC_INT32 rcc_set_principal(
+ /* [in] */ HCACHE cache,
+ /* [in] */ CC_INT32 vers,
+ /* [string][in] */ const CC_CHAR *principal);
+
+CC_INT32 rcc_get_principal(
+ /* [in] */ HCACHE cache,
+ /* [string][out] */ CC_CHAR **principal);
+
+CC_INT32 rcc_get_cred_version(
+ /* [in] */ HCACHE cache,
+ /* [out] */ CC_INT32 *vers);
+
+CC_INT32 rcc_lock_request(
+ /* [in] */ HCACHE cache,
+ /* [in] */ CC_INT32 lock_type);
+
+CC_INT32 rcc_store(
+ /* [in] */ HCACHE cache,
+ /* [in] */ CRED_UNION cred);
+
+CC_INT32 rcc_remove_cred(
+ /* [in] */ HCACHE cache,
+ /* [in] */ CRED_UNION cred);
+
+CC_INT32 rcc_seq_fetch_creds(
+ /* [in] */ HCACHE cache,
+ /* [out][in] */ HCRED_ITER *piter,
+ /* [out] */ CRED_UNION **cred);
+
+CC_INT32 rcc_seq_fetch_creds_begin(
+ /* [in] */ HCACHE cache,
+ /* [out] */ HCRED_ITER *piter);
+
+CC_INT32 rcc_seq_fetch_creds_end(
+ /* [out][in] */ HCRED_ITER *piter);
+
+CC_INT32 rcc_seq_fetch_creds_next(
+ /* [in] */ HCRED_ITER iter,
+ /* [out] */ CRED_UNION **cred);
+
+CC_UINT32 Connect(
+ /* [string][in] */ CC_CHAR *name);
+
+void Shutdown( void);
+
+
+extern handle_t ccapi_IfHandle;
+
+
+extern RPC_IF_HANDLE ccapi_ClientIfHandle;
+extern RPC_IF_HANDLE ccapi_ServerIfHandle;
+#endif /* __ccapi_INTERFACE_DEFINED__ */
+
+/* Additional Prototypes for ALL interfaces */
+
+void __RPC_USER HCTX_rundown( HCTX );
+void __RPC_USER HCACHE_rundown( HCACHE );
+void __RPC_USER HCACHE_ITER_rundown( HCACHE_ITER );
+void __RPC_USER HCRED_ITER_rundown( HCRED_ITER );
+
+/* end of Additional Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/src/ccapi/lib/win/OldCC/client.cxx b/src/ccapi/lib/win/OldCC/client.cxx
new file mode 100644
index 000000000..1f9051093
--- /dev/null
+++ b/src/ccapi/lib/win/OldCC/client.cxx
@@ -0,0 +1,389 @@
+/*
+ * $Header$
+ *
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "stdio.h" // KPKDBG
+
+#include "ccs_request.h"
+
+#include "ccapi.h"
+#include "util.h"
+
+extern "C" {
+#include "cci_debugging.h"
+#include "tls.h" // KPKDBG
+ }
+
+#include "client.h"
+#include "init.hxx"
+#include "name.h"
+#include "secure.hxx"
+
+#define SECONDS_TO_WAIT 10
+
+#define STARTUP "CLIENT STARTUP: "
+#define DISCONNECT "CLIENT DISCONNECT: "
+
+bool Client::s_init = false;
+CcOsLock Client::sLock;
+
+static DWORD bind_client(char* ep OPTIONAL, Init::InitInfo& info, LPSTR* endpoint) {
+ DWORD status = 0;
+ unsigned char * pszStringBinding = NULL;
+
+ if (!ep) {
+ status = alloc_name(endpoint, "ep", isNT());
+ }
+ else {
+ *endpoint = ep;
+ }
+
+ if (!status) {
+ /* Use a convenience function to concatenate the elements of */
+ /* the string binding into the proper sequence. */
+ status = RpcStringBindingCompose(0, // uuid
+ (unsigned char*)"ncalrpc", // protseq
+ 0, // address
+ (unsigned char*)(*endpoint), // endpoint
+ 0, // options
+ &pszStringBinding);
+ cci_check_error(status);
+ }
+
+ if (!status) {
+ /* Set the binding handle that will be used to bind to the server. */
+ status = RpcBindingFromStringBinding(pszStringBinding, &ccs_request_IfHandle);
+ cci_check_error(status);
+ }
+
+ if (!status) {
+ // Win9x might call RpcBindingSetAuthInfo (not Ex), but it does not
+ // quite work on Win9x...
+ if (isNT()) {
+ RPC_SECURITY_QOS qos;
+ qos.Version = RPC_C_SECURITY_QOS_VERSION;
+ qos.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
+ qos.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;
+ qos.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY;
+
+ status = info.fRpcBindingSetAuthInfoEx(ccs_request_IfHandle,
+ 0, // principal
+ RPC_C_AUTHN_LEVEL_CONNECT,
+ RPC_C_AUTHN_WINNT,
+ 0, // current address space
+ RPC_C_AUTHZ_NAME,
+ &qos);
+ cci_check_error(status);
+ }
+ }
+
+ if (pszStringBinding) {
+ DWORD status = RpcStringFree(&pszStringBinding);
+ cci_check_error(status);
+ }
+ return cci_check_error(status);
+ }
+
+DWORD find_server(Init::InitInfo& info, LPSTR endpoint) {
+ DWORD status = 0;
+ LPSTR event_name = 0;
+ HANDLE hEvent = 0;
+ SECURITY_ATTRIBUTES sa = { 0 };
+ PSECURITY_ATTRIBUTES psa = 0;
+ STARTUPINFO si = { 0 };
+ PROCESS_INFORMATION pi = { 0 };
+ char* szExe = 0;
+ char* szDir = 0;
+ BOOL bRes = FALSE;
+ char* cmdline = NULL;
+#if 0
+ HANDLE hToken = 0;
+#endif
+
+ psa = isNT() ? &sa : 0;
+
+// cci_debug_printf("%s Looking for server; ccs_request_IfHandle:0x%X", __FUNCTION__, ccs_request_IfHandle);
+ status = cci_check_error(RpcMgmtIsServerListening(ccs_request_IfHandle));
+ if (status == RPC_S_NOT_LISTENING) {
+// cci_debug_printf(" Server *NOT* found!");
+ si.cb = sizeof(si);
+
+ status = alloc_module_dir_name(CCAPI_DLL, &szDir);
+
+ if (!status) {
+ status = alloc_module_dir_name_with_file(CCAPI_DLL, CCAPI_EXE, &szExe);
+ }
+
+ if (!status) {
+ status = alloc_name(&event_name, "startup", isNT());
+ cci_check_error(status);
+ }
+
+ if (!status) {
+ if (isNT()) {
+ sa.nLength = sizeof(sa);
+ status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor);
+ cci_check_error(status);
+ }
+ }
+
+ if (!status) {
+ hEvent = CreateEvent(psa, FALSE, FALSE, event_name);
+ cci_debug_printf(" CreateEvent(... %s) returned hEvent 0x%X", event_name, hEvent);
+ if (!hEvent) status = GetLastError();
+ }
+
+ if (!status) {
+
+#if 0
+ if (SecureClient::IsImp()) {
+ cci_debug_printf(STARTUP "Token is impersonation token"));
+ SecureClient::DuplicateImpAsPrimary(hToken);
+ }
+ else {
+ cci_debug_printf(STARTUP "Token is NOT impersonation token"));
+ }
+#endif
+
+#if 0
+ if (hToken)
+ bRes = CreateProcessAsUser(hToken,
+ szExe, // app name
+ NULL, // cmd line
+ psa, // SA
+ psa, // SA
+ FALSE,
+ CREATE_NEW_PROCESS_GROUP |
+ //CREATE_NEW_CONSOLE |
+ NORMAL_PRIORITY_CLASS |
+ // CREATE_NO_WINDOW |
+ DETACHED_PROCESS |
+ 0
+ ,
+ NULL, // environment
+ szDir, // current dir
+ &si,
+ &pi);
+ else
+#endif
+ alloc_cmdline_2_args(szExe, endpoint, "-D", &cmdline);
+ bRes = CreateProcess( szExe, // app name
+ NULL, //cmdline, // cmd line is <server endpoint -[DC]>
+ psa, // SA
+ psa, // SA
+ FALSE,
+ CREATE_NEW_PROCESS_GROUP |
+ CREATE_NEW_CONSOLE |
+ NORMAL_PRIORITY_CLASS |
+ // CREATE_NO_WINDOW |
+ // DETACHED_PROCESS | /* KPK TODO: was set - restore */
+ 0
+ ,
+ NULL, // environment
+ szDir, // current dir
+ &si,
+ &pi);
+ if (!bRes) {
+ status = GetLastError();
+ cci_debug_printf(" CreateProcess returned %d; LastError: %d", bRes, status);
+ }
+ cci_debug_printf(" Waiting...");
+ }
+ cci_check_error(status);
+
+ if (!status) {
+ status = WaitForSingleObject(hEvent, (SECONDS_TO_WAIT)*1000);
+ status = RpcMgmtIsServerListening(ccs_request_IfHandle);
+ }
+ }
+ else if (status) {
+ cci_debug_printf(" unexpected error while looking for server: 0D%d / 0U%u / 0X%X", status, status, status);
+ }
+
+#if 0
+ if (hToken)
+ CloseHandle(hToken);
+#endif
+ if (szDir) free_alloc_p(&szDir);
+ if (szExe) free_alloc_p(&szExe);
+ if (hEvent) CloseHandle(hEvent);
+ if (pi.hThread) CloseHandle(pi.hThread);
+ if (pi.hProcess) CloseHandle(pi.hProcess);
+ if (sa.lpSecurityDescriptor) free_alloc_p(&sa.lpSecurityDescriptor);
+ return cci_check_error(status);
+
+}
+
+static
+DWORD
+authenticate_server(Init::InitInfo& info) {
+ DWORD challenge = 17; // XXX - maybe use random number
+ DWORD desired_response= challenge + 1;
+ HANDLE hMap = 0;
+ LPSTR mem_name = 0;
+ PDWORD pvalue = 0;
+ CC_UINT32 response = 0;
+ SECURITY_ATTRIBUTES sa = { 0 };
+ DWORD status = 0;
+
+ cci_debug_printf("%s entry", __FUNCTION__);
+
+ status = alloc_name(&mem_name, "auth", isNT());
+ cci_check_error(status);
+
+ if (!status) {
+ if (isNT()) {
+ sa.nLength = sizeof(sa);
+ status = alloc_own_security_descriptor_NT(&sa.lpSecurityDescriptor);
+ }
+ }
+ cci_check_error(status);
+
+ if (!status) {
+ hMap = CreateFileMapping(INVALID_HANDLE_VALUE, isNT() ? &sa : 0,
+ PAGE_READWRITE, 0, sizeof(DWORD), mem_name);
+ if (!hMap)
+ status = GetLastError();
+ }
+ cci_check_error(status);
+
+ if (!status) {
+ pvalue = (PDWORD)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
+ if (!pvalue) status = GetLastError();
+ }
+ cci_check_error(status);
+
+ if (!status) {
+ *pvalue = challenge;
+
+ RpcTryExcept {
+ response = ccs_authenticate( (CC_CHAR*)mem_name );
+ }
+ RpcExcept(1) {
+ status = RpcExceptionCode();
+ cci_check_error(status);
+ }
+ RpcEndExcept;
+ }
+ cci_check_error(status);
+
+ if (!status) {
+ // Check response
+ if ((response != desired_response) && (*pvalue != desired_response)) {
+ cci_debug_printf(" Could not authenticate server.");
+ status = ERROR_ACCESS_DENIED; // XXX - CO_E_NOMATCHINGSIDFOUND?
+ }
+ else {
+ cci_debug_printf(" Server authenticated!");
+ }
+ cci_check_error(status);
+ }
+
+ free_alloc_p(&mem_name);
+ free_alloc_p(&sa.lpSecurityDescriptor);
+ if (pvalue) {
+ BOOL ok = UnmapViewOfFile(pvalue);
+// DEBUG_ASSERT(ok);
+ }
+ if (hMap) CloseHandle(hMap);
+ return status;
+}
+
+DWORD
+Client::Disconnect() {
+ DWORD status = 0;
+ if (ccs_request_IfHandle) {
+ /* The calls to the remote procedures are complete. */
+ /* Free the binding handle */
+ status = RpcBindingFree(&ccs_request_IfHandle);
+ }
+ s_init = false;
+ return status;
+ }
+
+DWORD
+Client::Connect(char* ep OPTIONAL) {
+ LPSTR endpoint = 0;
+ DWORD status = 0;
+
+ if (!ccs_request_IfHandle) {
+ Init::InitInfo info;
+
+ status = Init::Info(info);
+ cci_check_error(status);
+
+ if (!status) {
+ status = bind_client(ep, info, &endpoint);
+ cci_check_error(status);
+ }
+
+ if (!status) {
+ status = find_server(info, endpoint);
+ cci_check_error(status);
+ }
+
+ if (!status) {
+ status = authenticate_server(info);
+ cci_check_error(status);
+ }
+ }
+
+
+ if (endpoint && (endpoint != ep)) free_alloc_p(&endpoint);
+
+ if (status) Client::Disconnect();
+ return status;
+ }
+
+DWORD Client::Initialize(char* ep OPTIONAL) {
+ CcAutoLock AL(Client::sLock);
+ SecureClient s;
+ ccs_request_IfHandle = NULL;
+ if (s_init) return 0;
+ DWORD status = Client::Connect(ep);
+ if (!status) s_init = true;
+ return status;
+ }
+
+DWORD Client::Cleanup() {
+ CcAutoLock AL(Client::sLock);
+ SecureClient s;
+ return Client::Disconnect();
+ }
+
+DWORD Client::Reconnect(char* ep OPTIONAL) {
+ CcAutoLock AL(Client::sLock);
+ SecureClient s;
+ DWORD status = 0;
+
+ if (Initialized()) {
+ DWORD status = Client::Cleanup();
+ }
+ if ( (!status) ) {
+ status = Client::Initialize(ep);
+ }
+
+ return status;
+ }
diff --git a/src/ccapi/lib/win/OldCC/client.h b/src/ccapi/lib/win/OldCC/client.h
new file mode 100644
index 000000000..f263ce1c0
--- /dev/null
+++ b/src/ccapi/lib/win/OldCC/client.h
@@ -0,0 +1,61 @@
+/*
+ * $Header$
+ *
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef __DLL_CLIENT_H__
+#define __DLL_CLIENT_H__
+
+#include "autolock.hxx"
+#include "init.hxx"
+
+class Client {
+public:
+ static DWORD Initialize(char* ep OPTIONAL);
+ static DWORD Cleanup();
+ static DWORD Reconnect(char* ep OPTIONAL);
+
+ static bool Initialized() { return s_init; }
+
+ static CcOsLock sLock;
+
+private:
+ static bool s_init;
+
+ static DWORD Disconnect();
+ static DWORD Connect(char* ep OPTIONAL);
+ };
+
+#define CLIENT_INIT_EX(trap, error) \
+do \
+{ \
+ INIT_INIT_EX(trap, error); \
+ if (!Client::Initialized()) \
+ { \
+ DWORD status = Client::Initialize(0); \
+ if (status) return (trap) ? (error) : status; \
+ } \
+} while(0)
+
+#endif
diff --git a/src/ccapi/lib/win/OldCC/rpc.cxx b/src/ccapi/lib/win/OldCC/rpc.cxx
new file mode 100644
index 000000000..332f1c503
--- /dev/null
+++ b/src/ccapi/lib/win/OldCC/rpc.cxx
@@ -0,0 +1,79 @@
+/*
+ * $Header$
+ *
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+extern "C" {
+#include "CredentialsCache.h"
+#include "secure.hxx"
+#include "client.h"
+#include "autolock.hxx"
+#include "cci_debugging.h"
+ }
+
+extern HANDLE hCCAPIv2Mutex;
+
+#define MAKE_RPC_CALL(rc, x) \
+do { \
+ WaitForSingleObject( hCCAPIv2Mutex, INFINITE ); \
+ SecureClient* s = 0; \
+ SecureClient::Start(s); \
+ CcAutoLock* a = 0; \
+ CcAutoLock::Start(a, Client::sLock); \
+ RpcTryExcept { \
+ cci_debug_printf("RpcTry: #x"); \
+ x; \
+ } \
+ RpcExcept(1) { \
+ rc = handle_exception(RpcExceptionCode()); \
+ } \
+ RpcEndExcept; \
+ CcAutoLock::Stop(a); \
+ SecureClient::Stop(s); \
+ ReleaseMutex( hCCAPIv2Mutex ); \
+} while (0)
+
+static
+DWORD
+handle_exception(DWORD code) {
+ cci_debug_printf("Runtime reported exception %u", code);
+ if (code == RPC_S_SERVER_UNAVAILABLE) {
+ Client::Reconnect(0);
+ }
+ return 4;
+ }
+
+//////////////////////////////////////////////////////////////////////////////
+
+cc_int32 cc_initialize() {
+
+ CLIENT_INIT_EX(true, 4);
+ cc_int32 rc = ccNoError;
+
+ MAKE_RPC_CALL(rc, rc = 5);
+ return rc;
+ } \ 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
index 000000000..985f4c610
--- /dev/null
+++ b/src/ccapi/lib/win/WINCCAPI.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WINCCAPI", "WINCCAPI.vcproj", "{1137FC16-E53E-48C1-8293-085B4BE68C32}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1137FC16-E53E-48C1-8293-085B4BE68C32}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1137FC16-E53E-48C1-8293-085B4BE68C32}.Debug|Win32.Build.0 = Debug|Win32
+ {1137FC16-E53E-48C1-8293-085B4BE68C32}.Release|Win32.ActiveCfg = Release|Win32
+ {1137FC16-E53E-48C1-8293-085B4BE68C32}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/ccapi/lib/win/WINCCAPI.vcproj b/src/ccapi/lib/win/WINCCAPI.vcproj
new file mode 100644
index 000000000..69b7722e8
--- /dev/null
+++ b/src/ccapi/lib/win/WINCCAPI.vcproj
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="WINCCAPI"
+ ProjectGUID="{1137FC16-E53E-48C1-8293-085B4BE68C32}"
+ RootNamespace="WINCCAPI"
+ Keyword="MakeFileProj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="nmake"
+ ReBuildCommandLine="nmake"
+ CleanCommandLine="nmake clean"
+ Output="output.log"
+ PreprocessorDefinitions="WIN32;_DEBUG;"
+ IncludeSearchPath=""
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="nmake"
+ ReBuildCommandLine="nmake"
+ CleanCommandLine="nmake clean"
+ Output="output.log"
+ PreprocessorDefinitions="WIN32;NDEBUG;"
+ IncludeSearchPath=""
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\common\win\win-utils.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\common\win\ccs_reply.Idl"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccs_request.idl"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\win-utils.c"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="..\..\common\win\ccs_reply.Acf"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccs_request.Acf"
+ >
+ </File>
+ <File
+ RelativePath=".\Makefile"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/ccapi/lib/win/ccapi.def b/src/ccapi/lib/win/ccapi.def
new file mode 100644
index 000000000..0450331ec
--- /dev/null
+++ b/src/ccapi/lib/win/ccapi.def
@@ -0,0 +1,39 @@
+;LIBRARY COMERR32
+HEAPSIZE 8192
+
+EXPORTS
+ cci_debug_printf
+
+ cc_initialize
+
+ cci_string_new
+ cci_string_d_initializer
+ ccapi_string_release
+
+ cci_credentials_iterator_new
+ cci_credentials_iterator_write
+
+ cci_ccache_iterator_new
+ cci_ccache_iterator_write
+
+ ccapi_ccache_iterator_release
+ ccapi_ccache_iterator_next
+ ccapi_ccache_iterator_clone
+
+ ccapi_credentials_iterator_release
+ ccapi_credentials_iterator_next
+ ccapi_credentials_iterator_clone
+
+;debugging:
+ _cci_check_error
+ cci_os_ipc
+ cci_os_ipc_msg
+ cci_os_ipc_thread_init
+ cci_stream_data
+ cci_stream_write
+ cci_stream_new
+
+ ccs_authenticate
+
+
+ \ 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
index 000000000..7ee917627
--- /dev/null
+++ b/src/ccapi/lib/win/ccapi_os_ipc.cxx
@@ -0,0 +1,373 @@
+/*
+ * $Header$
+ *
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+extern "C" {
+#include "k5-thread.h"
+#include "ccapi_os_ipc.h"
+#include "tls.h"
+#include "dllmain.h"
+#include "ccs_reply.h"
+#include "ccs_request.h"
+#include "win-utils.h"
+#include "ccutils.h"
+#include "util.h"
+ }
+
+#include "CredentialsCache.h"
+#include "secure.hxx"
+#include "opts.hxx"
+#include "client.h"
+#include "autolock.hxx"
+#include "cci_debugging.h"
+
+#define SECONDS_TO_WAIT 10
+#define CLIENT_REQUEST_RPC_HANDLE ccs_request_IfHandle
+
+extern HANDLE hCCAPIv2Mutex;
+ParseOpts::Opts opts = { 0 };
+PSECURITY_ATTRIBUTES psa = 0;
+SECURITY_ATTRIBUTES sa = { 0 };
+
+/* The layout of the rest of this module:
+
+ The entrypoints defined in ccs_os_ipc.h:
+ cci_os_ipc_thread_init
+ cci_os_ipc
+
+ Other routines needed by those four.
+ cci_os_connect
+ handle_exception
+ */
+
+cc_int32 ccapi_connect(const struct tspdata* tsp);
+static DWORD handle_exception(DWORD code);
+
+extern "C" {
+cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server,
+ cci_stream_t in_request_stream,
+ cc_int32 in_msg,
+ cci_stream_t* out_reply_stream);
+ }
+
+/* ------------------------------------------------------------------------ */
+
+extern "C" cc_int32 cci_os_ipc_thread_init (void) {
+ cc_int32 err = ccNoError;
+ struct tspdata* ptspdata;
+ HANDLE replyEvent;
+ UUID __RPC_FAR uuid;
+ unsigned char __RPC_FAR* uuidString = NULL;
+
+ if (!GetTspData(&ptspdata)) return ccErrNoMem;
+
+ opts.cMinCalls = 1;
+ opts.cMaxCalls = 20;
+ opts.fDontWait = TRUE;
+
+ err = cci_check_error(UuidCreate(&uuid)); // Get a UUID
+ if (err == RPC_S_OK) { // Convert to string
+ err = UuidToString(&uuid, &uuidString);
+ }
+ if (!err) { // Save in thread local storage
+ tspdata_setUUID(ptspdata, uuidString);
+ }
+ cci_debug_printf("%s UUID:<%s>", __FUNCTION__, tspdata_getUUID(ptspdata));
+
+ // Initialize old CCAPI if necessary:
+ if (!err) if (!Init:: Initialized()) err = Init:: Initialize( );
+ if (!err) if (!Client::Initialized()) err = Client::Initialize(0);
+
+ if (!err) {
+ /* Whenever a reply to an RPC request is received, the RPC caller needs to
+ know when the reply has been received. It does that by waiting for a
+ client-specific event to be set. Define the event name to be <UUID>_reply: */
+ replyEvent = createThreadEvent((char*)uuidString, REPLY_SUFFIX);
+ }
+
+ if (replyEvent) tspdata_setReplyEvent(ptspdata, replyEvent);
+ else err = cci_check_error(GetLastError());
+
+ if (uuidString) RpcStringFree(&uuidString);
+
+ return cci_check_error(err);
+ }
+
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_os_ipc (cc_int32 in_launch_server,
+ cci_stream_t in_request_stream,
+ cci_stream_t* out_reply_stream) {
+ return cci_os_ipc_msg( in_launch_server,
+ in_request_stream,
+ CCMSG_REQUEST,
+ out_reply_stream);
+ }
+
+extern "C" cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server,
+ cci_stream_t in_request_stream,
+ cc_int32 in_msg,
+ cci_stream_t* out_reply_stream) {
+
+ cc_int32 err = ccNoError;
+ cc_int32 done = FALSE;
+ cc_int32 try_count = 0;
+ cc_int32 server_died = FALSE;
+ TCHAR* pszStringBinding= NULL;
+ struct tspdata* ptspdata = NULL;
+ char* uuid = NULL;
+ int lenUUID = 0;
+ unsigned int trycount = 0;
+ time_t sst = 0;
+ STARTUPINFO si = { 0 };
+ PROCESS_INFORMATION pi = { 0 };
+ HANDLE replyEvent = 0;
+ BOOL bCCAPI_Connected= FALSE;
+
+ if (!in_request_stream) { err = cci_check_error (ccErrBadParam); }
+ if (!out_reply_stream ) { err = cci_check_error (ccErrBadParam); }
+
+ if (!GetTspData(&ptspdata)) {return ccErrBadParam;}
+ bCCAPI_Connected = tspdata_getConnected (ptspdata);
+ replyEvent = tspdata_getReplyEvent (ptspdata);
+ sst = tspdata_getSST (ptspdata);
+ uuid = tspdata_getUUID(ptspdata);
+
+ // The lazy connection to the server has been put off as long as possible!
+ // ccapi_connect starts listening for replies as an RPC server and then
+ // calls ccs_rpc_connect.
+ if (!bCCAPI_Connected) {
+ err = cci_check_error(ccapi_connect(ptspdata));
+ bCCAPI_Connected = !err;
+ tspdata_setConnected(ptspdata, bCCAPI_Connected);
+ }
+
+ // Clear replyEvent so we can detect when a reply to our request has been received:
+ ResetEvent(replyEvent);
+
+ //++ Use the old CCAPI implementation to try to talk to the server:
+ // It has all the code to use the RPC in a thread-safe way, make the endpoint,
+ // (re)connect and (re)start the server.
+ // Note: the old implementation wrapped the thread-safety stuff in a macro.
+ // Here it is expanded and thus duplicated for each RPC call. The new code has
+ // a very limited number of RPC calls, unlike the older code.
+ WaitForSingleObject( hCCAPIv2Mutex, INFINITE );
+ SecureClient* s = 0;
+ SecureClient::Start(s);
+ CcAutoLock* a = 0;
+ CcAutoLock::Start(a, Client::sLock);
+
+ // Initialize old CCAPI if necessary:
+ if (!err) if (!Init:: Initialized()) err = cci_check_error(Init:: Initialize( ));
+ if (!err) if (!Client::Initialized()) err = cci_check_error(Client::Initialize(0));
+
+ // New code using new RPC procedures for sending the data and receiving a reply:
+ if (!err) {
+ RpcTryExcept {
+ if (!GetTspData(&ptspdata)) {return ccErrBadParam;}
+ uuid = tspdata_getUUID(ptspdata);
+ lenUUID = 1 + strlen(uuid); /* 1+ includes terminating \0. */
+ cci_debug_printf("%s calling remote ccs_rpc_request tsp*:0x%X", __FUNCTION__, ptspdata);
+ cci_debug_printf(" rpcmsg:%d; UUID[%d]:<%s> SST:%ld", in_msg, lenUUID, uuid, sst);
+
+ ccs_rpc_request( /* make call with user message: */
+ in_msg, /* Message type */
+ (unsigned char*)&ptspdata, /* Our tspdata* will be sent back to the reply proc. */
+ (unsigned char*)uuid,
+ cci_stream_size(in_request_stream),
+ (unsigned char*)cci_stream_data(in_request_stream), /* Data buffer */
+ sst, /* session start time */
+ (long*)(&err) ); /* Return code */
+ }
+ RpcExcept(1) {
+ handle_exception(RpcExceptionCode());
+ }
+ RpcEndExcept;
+ }
+
+ cci_check_error(err);
+ CcAutoLock::Stop(a);
+ SecureClient::Stop(s);
+ ReleaseMutex(hCCAPIv2Mutex);
+ //-- Use the old CCAPI implementation to try to talk to the server.
+
+ // Wait for reply handler to set event:
+ if (!err) {
+ cci_debug_printf(" Waiting for request reply.");
+ err = cci_check_error(WaitForSingleObject(replyEvent, INFINITE));//(SECONDS_TO_WAIT)*1000));
+ cci_debug_printf(" Request reply received!");
+ }
+
+ if (!err) {
+ err = cci_check_error(RpcMgmtIsServerListening(CLIENT_REQUEST_RPC_HANDLE));
+ }
+
+ if (!err && server_died) {
+ err = cci_check_error (ccErrServerUnavailable);
+ }
+#if 0
+ if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) {
+ err = ccNoError; /* If the server is not running just return an empty stream. */
+ }
+#endif
+
+ if (!err) {
+ *out_reply_stream = tspdata_getStream(ptspdata);
+ }
+
+ cci_debug_printf(" payload:<%s>", cci_stream_data(*out_reply_stream));
+
+ return cci_check_error (err);
+ }
+
+
+
+static DWORD handle_exception(DWORD code) {
+ cci_debug_printf("%s code %u; ccs_request_IfHandle:0x%X", __FUNCTION__, code, ccs_request_IfHandle);
+ if ( (code == RPC_S_SERVER_UNAVAILABLE) || (code == RPC_S_INVALID_BINDING) ) {
+ Client::Reconnect(0);
+ }
+ return 4;
+ }
+
+
+/* Establish a CCAPI connection with the server.
+ * The connect logic here is identical to the logic in the send request code.
+ * TODO: merge this connect code with that request code.
+ */
+cc_int32 ccapi_connect(const struct tspdata* tsp) {
+ BOOL bListen = TRUE;
+ char* endpoint = NULL;
+ HANDLE replyEvent = 0;
+ RPC_STATUS status = FALSE;
+ char* uuid = NULL;
+
+ /* Start listening to our uuid before establishing the connection,
+ * so that when the server tries to call ccapi_listen, we will be ready.
+ */
+
+ /* Build complete RPC uuid using previous CCAPI implementation: */
+ replyEvent = tspdata_getReplyEvent(tsp);
+ uuid = tspdata_getUUID(tsp);
+ endpoint = clientEndpoint(uuid);
+ cci_debug_printf("%s Registering endpoint %s", __FUNCTION__, endpoint);
+
+ opts.cMinCalls = 1;
+ opts.cMaxCalls = 20;
+ opts.fDontWait = TRUE;
+
+ if (!status) {
+ status = RpcServerUseProtseqEp((RPC_CSTR)"ncalrpc",
+ opts.cMaxCalls,
+ (RPC_CSTR)endpoint,
+ sa.lpSecurityDescriptor); // SD
+ cci_check_error(status);
+ }
+
+ if (!status) {
+ status = RpcServerRegisterAuthInfo(0, // server principal
+ RPC_C_AUTHN_WINNT,
+ 0,
+ 0 );
+ cci_check_error(status);
+ }
+
+ cci_debug_printf("%s is listening ...", __FUNCTION__);
+
+ if (!status) {
+ if (!isNT()) {
+ status = RpcServerRegisterIf(ccs_reply_ServerIfHandle, // interface
+ NULL, // MgrTypeUuid
+ NULL); // MgrEpv; null means use default
+ }
+ else {
+ status = RpcServerRegisterIfEx(ccs_reply_ServerIfHandle,// interface
+ NULL, // MgrTypeUuid
+ NULL, // MgrEpv; 0 means default
+ RPC_IF_ALLOW_SECURE_ONLY,
+ opts.cMaxCalls,
+ NULL); // No security callback.
+ }
+
+ cci_check_error(status);
+
+ if (!status) {
+ status = RpcServerListen(opts.cMinCalls,
+ opts.cMaxCalls,
+ TRUE);
+ cci_check_error(status);
+ }
+ }
+
+ // Clear replyEvent so we can detect when a reply to our connect request has been received:
+ ResetEvent(replyEvent);
+
+ // We use the old CCAPI implementation to try to talk to the server.
+ // It has all the code to make the uuid, (re)connect and (re)start the server.
+ WaitForSingleObject( hCCAPIv2Mutex, INFINITE );
+ SecureClient* s = 0;
+ SecureClient::Start(s);
+ CcAutoLock* a = 0;
+ CcAutoLock::Start(a, Client::sLock);
+
+ // Initialize old CCAPI if necessary:
+ if (!status) if (!Init:: Initialized()) status = Init:: Initialize( );
+ if (!status) if (!Client::Initialized()) status = Client::Initialize(0);
+
+ // New code using new RPC procedures for sending the data and receiving a reply:
+ if (!status) {
+ RpcTryExcept {
+ ccs_rpc_connect( /* make call with user message: */
+ CCMSG_CONNECT, /* Message type */
+ (unsigned char*)&tsp, /* Our tspdata* will be sent back to the reply proc. */
+ (unsigned char*)uuid,
+ (long*)(&status) ); /* Return code */
+ }
+ RpcExcept(1) {
+ cci_check_error(RpcExceptionCode());
+ status = ccErrBadInternalMessage;
+ }
+ RpcEndExcept;
+ }
+
+ CcAutoLock::Stop(a);
+ SecureClient::Stop(s);
+ ReleaseMutex(hCCAPIv2Mutex);
+
+ if (!status) {
+ cci_debug_printf("%s Waiting for replyEvent.", __FUNCTION__);
+ status = WaitForSingleObject(replyEvent, INFINITE);//(SECONDS_TO_WAIT)*1000);
+ status = cci_check_error(RpcMgmtIsServerListening(CLIENT_REQUEST_RPC_HANDLE));
+ cci_debug_printf(" Server %sFOUND!", (status) ? "NOT " : "");
+ }
+ if (status) {
+ cci_debug_printf(" unexpected error while looking for server... (%u)", status);
+ }
+
+ cci_debug_printf("%s TODO: check connect reply result.", __FUNCTION__);
+ cci_debug_printf("%s TODO: merge this connect code with that request code.", __FUNCTION__);
+ return status;
+ } \ 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
index 000000000..ebac6e3cf
--- /dev/null
+++ b/src/ccapi/lib/win/ccs_reply_proc.c
@@ -0,0 +1,98 @@
+/*
+ * $Header$
+ *
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+
+#include "cci_debugging.h"
+#include "ccs_reply.h" /* generated by MIDL compiler */
+#include "ccutils.h"
+#include "tls.h"
+#include "win-utils.h"
+
+
+void ccs_rpc_request_reply(
+ const long rpcmsg, /* Message type */
+ const char tspHandle[], /* Client's tspdata* */
+ const char* uuid, /* uuid for making thread-specific event name */
+ const long srvStartTime, /* Server Start Time */
+ const long cbIn, /* Length of buffer */
+ const char* chIn, /* Data buffer */
+ long* ret_status ) { /* Return code */
+
+ HANDLE hEvent = openThreadEvent(uuid, REPLY_SUFFIX);
+ DWORD* p = (DWORD*)(tspHandle);
+ struct tspdata* tsp = (struct tspdata*)*p;
+ cci_stream_t stream;
+ long status = 0;
+
+ cci_debug_printf("%s! msg#:%d SST:%ld uuid:%s", __FUNCTION__, rpcmsg, srvStartTime, uuid);
+ cci_debug_printf(" payload:<%s>", chIn);
+ cci_debug_printf(" uuid from handle:<%s>", tspdata_getUUID(tsp));
+
+ if (!status) {
+ status = cci_stream_new (&stream); /* Create a stream for the request data */
+ }
+
+ if (!status) { /* Put the data into the stream */
+ status = cci_stream_write (stream, chIn, cbIn);
+ }
+
+ if (!status) { /* Put the data into the stream */
+ tspdata_setStream(tsp, stream);
+ }
+
+ SetEvent(hEvent);
+ CloseHandle(hEvent);
+ *ret_status = status;
+ }
+
+void ccs_rpc_connect_reply(
+ const long rpcmsg, /* Message type */
+ const char tspHandle[], /* Client's tspdata* */
+ const char* uuid, /* uuid for making thread-specific event name */
+ const long srvStartTime, /* Server Start Time */
+ long* status ) { /* Return code */
+
+ HANDLE hEvent = openThreadEvent(uuid, REPLY_SUFFIX);
+ DWORD* p = (DWORD*)(tspHandle);
+
+ cci_debug_printf("%s! msg#:%d SST:%ld uuid:%s", __FUNCTION__, rpcmsg, srvStartTime, uuid);
+
+ SetEvent(hEvent);
+ CloseHandle(hEvent);
+ }
+
+void ccapi_listen(
+ RPC_ASYNC_STATE* rpcState,
+ handle_t hBinding,
+ const long rpcmsg, /* Message type */
+ long* status ) { /* Return code */
+
+ cci_debug_printf("%s %s!", __FUNCTION__, rpcState->UserInfo);
+ *status = 0;
+ }
diff --git a/src/ccapi/lib/win/dllmain.cxx b/src/ccapi/lib/win/dllmain.cxx
new file mode 100644
index 000000000..7000e1418
--- /dev/null
+++ b/src/ccapi/lib/win/dllmain.cxx
@@ -0,0 +1,279 @@
+/*
+ * $Header$
+ *
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include <windows.h>
+#include <LMCons.h>
+
+extern "C" {
+#include "dllmain.h"
+#include "tls.h"
+#include "cci_debugging.h"
+#include "ccapi_context.h"
+#include "client.h"
+
+//void cci_thread_init__auxinit();
+ }
+
+#define CCAPI_V2_MUTEX_NAME TEXT("MIT_CCAPI_V4_MUTEX")
+
+// Process-specific data:
+static DWORD dwTlsIndex;
+static char _user[UNLEN+1]; // Username is used as part of the server and client endpoints.
+static HANDLE sessionToken;
+static char* ep_prefices[] = {"CCS", "CCAPI"};
+HANDLE hCCAPIv2Mutex = NULL;
+DWORD firstThreadID = 0;
+
+// These data structures are used by the old CCAPI implementation
+// to keep track of the state of the RPC connection. All data is static.
+static Init init;
+static Client client;
+
+// DllMain() is the entry-point function for this DLL.
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, // DLL module handle
+ DWORD fdwReason, // reason called
+ LPVOID lpvReserved) { // reserved
+
+ struct tspdata* ptspdata;
+ BOOL fIgnore;
+ BOOL bStatus;
+ DWORD status = 0; // 0 is success.
+ DWORD maxUN = sizeof(_user);
+ unsigned int i = 0;
+ unsigned int j = 0;
+
+ switch (fdwReason) {
+ // The DLL is loading due to process initialization or a call to LoadLibrary:
+ case DLL_PROCESS_ATTACH:
+ cci_debug_printf("%s DLL_PROCESS_ATTACH", __FUNCTION__);
+ // Process-wide mutex used to allow only one thread at a time into the RPC code:
+ hCCAPIv2Mutex = CreateMutex(NULL, FALSE, CCAPI_V2_MUTEX_NAME);
+
+ // Figure out our username; it's process-wide:
+ bStatus = GetUserName(_user, &maxUN);
+ if (!bStatus) return bStatus;
+
+ // Remove any characters that aren't valid endpoint characters:
+ while (_user[j] != 0) {
+ if (isalnum(_user[j])) _user[i++] = _user[j];
+ j++;
+ }
+ _user[i] = '\0';
+
+ // Our logon session is determined in client.cxx, old CCAPI code carried
+ // over to this implementation.
+
+ // Allocate a TLS index:
+ if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
+
+ // Initialize CCAPI once per DLL load:
+ firstThreadID = GetCurrentThreadId();
+
+ // Don't break; fallthrough: Initialize the TLS index for first thread.
+
+ // The attached process creates a new thread:
+ case DLL_THREAD_ATTACH:
+ // Initialize the TLS index for this thread:
+ ptspdata = (struct tspdata*) LocalAlloc(LPTR, sizeof(struct tspdata));
+ cci_debug_printf("%s DLL_THREAD_ATTACH; tsp*:0x%X", __FUNCTION__, ptspdata);
+ if (ptspdata == NULL) return FALSE;
+ fIgnore = TlsSetValue(dwTlsIndex, ptspdata);
+
+ memset(ptspdata, 0, sizeof(struct tspdata));
+
+ // Initialize CCAPI once per DLL load:
+ if (GetCurrentThreadId() == firstThreadID) cci_thread_init__auxinit();
+
+ break;
+
+ // The thread of the attached process terminates:
+ case DLL_THREAD_DETACH:
+ cci_debug_printf("%s DLL_THREAD_DETACH", __FUNCTION__);
+ // Release the allocated memory for this thread:
+ ptspdata = (struct tspdata*)TlsGetValue(dwTlsIndex);
+ if (ptspdata != NULL) {
+ LocalFree((HLOCAL) ptspdata);
+ TlsSetValue(dwTlsIndex, NULL);
+ }
+ break;
+
+ // DLL unload due to process termination or FreeLibrary:
+ case DLL_PROCESS_DETACH:
+ cci_debug_printf("%s DLL_PROCESS_DETACH", __FUNCTION__);
+ //++ Copied from previous implementation:
+ // Process Teardown "Problem"
+ //
+ // There are two problems that occur during process teardown:
+ //
+ // 1) Windows (NT/9x/2000) does not keep track of load/unload
+ // ordering dependencies for use in process teardown.
+ //
+ // 2) The RPC exception handling in the RPC calls do not work
+ // during process shutdown in Win9x.
+ //
+ // When a process is being torn down in Windows, the krbcc DLL
+ // may get a DLL_PROCESS_DETACH before other DLLs are done
+ // with it. Thus, it may disconnect from the RPC server
+ // before the last shutdown RPC call.
+ //
+ // On NT/2000, this is ok because the RPC call will fail and just
+ // return an error.
+ //
+ // On Win9x/Me, the RPC exception will not be caught.
+ // However, Win9x ignores exceptions during process shutdown,
+ // so the exception will never be seen unless a debugger is
+ // attached to the proccess.
+ //
+ // A good potential woraround would be to have a global
+ // variable that denotes whether the DLL is attached to the
+ // process. If it is not, all entrypoints into the DLL should
+ // return failure.
+ //
+ // A not as good workaround is below but ifdefed out.
+ //
+ // However, we can safely ignore this problem since it can
+ // only affects people running debuggers under 9x/Me who are
+ // using multiple DLLs that use this DLL.
+ //
+ WaitForSingleObject( hCCAPIv2Mutex, INFINITE );
+#if 0
+ bool process_teardown_workaround = false;
+ if (lpvReserved) {
+ Init::InitInfo info;
+ status = Init::Info(info);
+ if (status) break;
+ if (!info.isNT) process_teardown_workaround = true;
+ }
+ if (process_teardown_workaround)
+ break;
+#endif
+ // return value is ignored, so we set status for debugging purposes
+ status = Client::Cleanup();
+ status = Init::Cleanup();
+ ReleaseMutex( hCCAPIv2Mutex );
+ CloseHandle( hCCAPIv2Mutex );
+ //-- Copied from previous implementation.
+
+ // Release the allocated memory for this thread:
+ ptspdata = (struct tspdata*)TlsGetValue(dwTlsIndex);
+ if (ptspdata != NULL) LocalFree((HLOCAL) ptspdata);
+ TlsFree(dwTlsIndex); // Release the TLS index.
+ break;
+
+ default: break;
+ }
+
+ UNREFERENCED_PARAMETER(hinstDLL); // no whining!
+ UNREFERENCED_PARAMETER(lpvReserved);
+ return status ? FALSE : TRUE;
+}
+
+
+#ifdef __cplusplus // If used by C++ code,
+extern "C" { // we need to export the C interface
+#endif
+
+__declspec(dllexport)
+BOOL WINAPI PutTspData(struct tspdata* dw) {
+ LPVOID lpvData;
+ struct tspdata** pData; // The stored memory pointer
+
+ // Retrieve a data pointer for the current thread:
+ lpvData = TlsGetValue(dwTlsIndex);
+
+ // If NULL, allocate memory for the TLS slot for this thread:
+ if (lpvData == NULL) {
+ lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct tspdata));
+ if (lpvData == NULL) return FALSE;
+ if (!TlsSetValue(dwTlsIndex, lpvData)) return FALSE;
+ }
+
+ pData = (struct tspdata**) lpvData; // Cast to my data type.
+ // In this example, it is only a pointer to a DWORD
+ // but it can be a structure pointer to contain more complicated data.
+
+ (*pData) = dw;
+ return TRUE;
+ }
+
+__declspec(dllexport)
+BOOL WINAPI GetTspData(struct tspdata** pdw) {
+ struct tspdata* pData; // The stored memory pointer
+
+ pData = (struct tspdata*)TlsGetValue(dwTlsIndex);
+ if (pData == NULL) return FALSE;
+ (*pdw) = pData;
+ return TRUE;
+ }
+
+#if 0 // replaced by clientEndpoint / serverEndpoint.
+__declspec(dllexport)
+char* WINAPI getEndpoint(enum EndpointType ep) {
+ // The server endpoint is of the form CCS_<LSID>
+ // The client endpoint is of the form CCAPI_<uuid>
+ // Each client thread can have its own connection.
+ //
+ // NB: Caller must free the data the returned char* points to.
+ struct tspdata* pData;
+ char* s;
+ char* uuid;
+ unsigned int len;
+
+ switch (ep) {
+ case EPT_SERVER:
+ s = (char*)malloc(32); // Length of CCS_<DWORD>
+ sprintf(s, "%s_%ld", ep_prefices[EPT_SERVER], sessionToken);
+ break;
+ case EPT_CLIENT:
+ GetTspData(&pData);
+ uuid = tspdata_getUUID(pData);
+ len = 4 + strlen(ep_prefices[ep]) + strlen(_user) + strlen(uuid);
+ s = (char*)malloc(len);
+ sprintf(s, "%s_%s_%s", ep_prefices[EPT_CLIENT], _user, uuid);
+ break;
+ default:;
+ }
+ cci_debug_printf("%s(%d) returning %s", __FUNCTION__, ep, s);
+
+ return s;
+ }
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*********************************************************************/
+/* MIDL allocate and free */
+/*********************************************************************/
+
+void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) {
+ return(malloc(len));
+ }
+
+void __RPC_USER midl_user_free(void __RPC_FAR * ptr) {
+ free(ptr);
+ }
diff --git a/src/ccapi/lib/win/dllmain.h b/src/ccapi/lib/win/dllmain.h
new file mode 100644
index 000000000..3ce2ac230
--- /dev/null
+++ b/src/ccapi/lib/win/dllmain.h
@@ -0,0 +1,45 @@
+/*
+ * $Header$
+ *
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef _dll_h
+#define _dll_h
+
+#include "windows.h"
+
+enum EndpointType {EPT_SERVER=0, EPT_CLIENT};
+
+#ifdef __cplusplus // If used by C++ code,
+extern "C" { // we need to export the C interface
+#endif
+__declspec(dllexport) BOOL WINAPI PutTspData(struct tspdata* p);
+__declspec(dllexport) BOOL WINAPI GetTspData(struct tspdata** p);
+
+//__declspec(dllexport) char* WINAPI getEndpoint(enum EndpointType);
+#ifdef __cplusplus
+}
+#endif
+
+#endif _dll_h \ No newline at end of file