/* * $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 #include "init.hxx" #include "secure.hxx" extern "C" { #include "cci_debugging.h" } CcOsLock Init::s_lock; DWORD Init::s_refcount = 0; DWORD Init::s_error = ERROR_INVALID_HANDLE; bool Init::s_init = false; Init::InitInfo Init::s_info = { 0 }; HINSTANCE Init::s_hRpcDll = 0; #define INIT "INIT: " static void ShowInfo( Init::InitInfo& info ); DWORD Init::Info( InitInfo& info ) { // This function will not do automatic initialization. CcAutoLock AL(s_lock); if (!s_init) { memset(&info, 0, sizeof(info)); return s_error ? s_error : ERROR_INVALID_HANDLE; } else { info = s_info; return 0; } } DWORD Init::Initialize() { CcAutoLock AL(s_lock); // cci_debug_printf("%s s_init:%d", __FUNCTION__, s_init); if (s_init) { s_refcount++; return 0; } SecureClient s; DWORD status = 0; OSVERSIONINFO osvi; BOOL isSupportedVersion = FALSE; memset(&s_info, 0, sizeof(s_info)); memset(&osvi, 0, sizeof(osvi)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); status = !GetVersionEx(&osvi); // Returns a boolean. Invert to 0 is OK. if (!status) { switch(osvi.dwPlatformId) { case VER_PLATFORM_WIN32_WINDOWS: s_info.isNT = FALSE; isSupportedVersion = TRUE; break; case VER_PLATFORM_WIN32_NT: s_info.isNT = TRUE; isSupportedVersion = TRUE; break; case VER_PLATFORM_WIN32s: default: s_info.isNT = FALSE; break; } if (!isSupportedVersion) { cci_debug_printf("%s Trying to run on an unsupported version of Windows", __FUNCTION__); status = 1; } } if (!status) {status = !s_info.isNT;} if (!status) {status = !(s_hRpcDll = LoadLibrary(TEXT("rpcrt4.dll")));} if (!status) { s_info.fRpcBindingSetAuthInfoEx = (FP_RpcBindingSetAuthInfoEx) GetProcAddress(s_hRpcDll, TEXT(FN_RpcBindingSetAuthInfoEx)); if (!s_info.fRpcBindingSetAuthInfoEx) { cci_debug_printf(" Running on NT but could not find RpcBindinSetAuthInfoEx"); status = 1; } } if (!status) { s_info.fRpcServerRegisterIfEx = (FP_RpcServerRegisterIfEx) GetProcAddress(s_hRpcDll, TEXT(FN_RpcServerRegisterIfEx)); if (!s_info.fRpcServerRegisterIfEx) { cci_debug_printf(" Running on NT but could not find RpcServerRegisterIfEx"); status = 1; } } if (!status) { status = SecureClient::Attach(); if (status) { cci_debug_printf(" SecureClient::Attach() failed (%u)", status); } } if (status) { memset(&s_info, 0, sizeof(s_info)); if (s_hRpcDll) { FreeLibrary(s_hRpcDll); s_hRpcDll = 0; } cci_debug_printf(" Init::Attach() failed (%u)", status); } else { s_refcount++; s_init = true; ShowInfo(s_info); } s_error = status; return status; } DWORD Init::Cleanup( ) { CcAutoLock AL(s_lock); s_refcount--; if (s_refcount) return 0; if (!s_init) return 0; DWORD error = 0; if (s_hRpcDll) { FreeLibrary(s_hRpcDll); s_hRpcDll = 0; } error = SecureClient::Detach(); memset(&s_info, 0, sizeof(s_info)); s_init = false; s_error = 0; if (error) { cci_debug_printf(" Init::Detach() had an error (%u)", error); } return error; } static void ShowInfo( Init::InitInfo& info ) { if (info.isNT) { cci_debug_printf(" Running on Windows NT using secure mode"); } else { cci_debug_printf(" Running insecurely on non-NT Windows"); } return; }