1 /* 2 * $Header$ 3 * 4 * Copyright 2008 Massachusetts Institute of Technology. 5 * All Rights Reserved. 6 * 7 * Export of this software from the United States of America may 8 * require a specific license from the United States Government. 9 * It is the responsibility of any person or organization contemplating 10 * export to obtain such a license before exporting. 11 * 12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 13 * distribute this software and its documentation for any purpose and 14 * without fee is hereby granted, provided that the above copyright 15 * notice appear in all copies and that both that copyright notice and 16 * this permission notice appear in supporting documentation, and that 17 * the name of M.I.T. not be used in advertising or publicity pertaining 18 * to distribution of the software without specific, written prior 19 * permission. Furthermore if you modify this software you must label 20 * your software as modified software and not distribute it in such a 21 * fashion that it might be confused with the original M.I.T. software. 22 * M.I.T. makes no representations about the suitability of 23 * this software for any purpose. It is provided "as is" without express 24 * or implied warranty. 25 */ 26 27 #include <windows.h> 28 #include "init.hxx" 29 #include "secure.hxx" 30 31 extern "C" { 32 #include "cci_debugging.h" 33 } 34 35 36 CcOsLock Init::s_lock; 37 DWORD Init::s_refcount = 0; 38 DWORD Init::s_error = ERROR_INVALID_HANDLE; 39 bool Init::s_init = false; 40 Init::InitInfo Init::s_info = { 0 }; 41 HINSTANCE Init::s_hRpcDll = 0; 42 43 #define INIT "INIT: " 44 45 static 46 void 47 ShowInfo( 48 Init::InitInfo& info 49 ); 50 51 DWORD 52 Init::Info( 53 InitInfo& info 54 ) 55 { 56 // This function will not do automatic initialization. 57 CcAutoLock AL(s_lock); 58 if (!s_init) { 59 memset(&info, 0, sizeof(info)); 60 return s_error ? s_error : ERROR_INVALID_HANDLE; 61 } else { 62 info = s_info; 63 return 0; 64 } 65 } 66 67 DWORD 68 Init::Initialize() { 69 CcAutoLock AL(s_lock); 70 // cci_debug_printf("%s s_init:%d", __FUNCTION__, s_init); 71 if (s_init) { 72 s_refcount++; 73 return 0; 74 } 75 SecureClient s; 76 DWORD status = 0; 77 OSVERSIONINFO osvi; 78 BOOL isSupportedVersion = FALSE; 79 memset(&s_info, 0, sizeof(s_info)); 80 memset(&osvi, 0, sizeof(osvi)); 81 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 82 83 status = !GetVersionEx(&osvi); // Returns a boolean. Invert to 0 is OK. 84 85 if (!status) { 86 switch(osvi.dwPlatformId) { 87 case VER_PLATFORM_WIN32_WINDOWS: 88 s_info.isNT = FALSE; 89 isSupportedVersion = TRUE; 90 break; 91 case VER_PLATFORM_WIN32_NT: 92 s_info.isNT = TRUE; 93 isSupportedVersion = TRUE; 94 break; 95 case VER_PLATFORM_WIN32s: 96 default: 97 s_info.isNT = FALSE; 98 break; 99 } 100 101 if (!isSupportedVersion) { 102 cci_debug_printf("%s Trying to run on an unsupported version of Windows", __FUNCTION__); 103 status = 1; 104 } 105 } 106 107 if (!status) {status = !s_info.isNT;} 108 109 if (!status) {status = !(s_hRpcDll = LoadLibrary(TEXT("rpcrt4.dll")));} 110 111 if (!status) { 112 s_info.fRpcBindingSetAuthInfoEx = (FP_RpcBindingSetAuthInfoEx) 113 GetProcAddress(s_hRpcDll, TEXT(FN_RpcBindingSetAuthInfoEx)); 114 if (!s_info.fRpcBindingSetAuthInfoEx) { 115 cci_debug_printf(" Running on NT but could not find RpcBindinSetAuthInfoEx"); 116 status = 1; 117 } 118 } 119 120 if (!status) { 121 s_info.fRpcServerRegisterIfEx = (FP_RpcServerRegisterIfEx) 122 GetProcAddress(s_hRpcDll, TEXT(FN_RpcServerRegisterIfEx)); 123 if (!s_info.fRpcServerRegisterIfEx) { 124 cci_debug_printf(" Running on NT but could not find RpcServerRegisterIfEx"); 125 status = 1; 126 } 127 } 128 129 if (!status) { 130 status = SecureClient::Attach(); 131 if (status) { 132 cci_debug_printf(" SecureClient::Attach() failed (%u)", status); 133 } 134 } 135 136 if (status) { 137 memset(&s_info, 0, sizeof(s_info)); 138 if (s_hRpcDll) { 139 FreeLibrary(s_hRpcDll); 140 s_hRpcDll = 0; 141 } 142 cci_debug_printf(" Init::Attach() failed (%u)", status); 143 } else { 144 s_refcount++; 145 s_init = true; 146 ShowInfo(s_info); 147 } 148 s_error = status; 149 return status; 150 } 151 152 DWORD 153 Init::Cleanup( 154 ) 155 { 156 CcAutoLock AL(s_lock); 157 s_refcount--; 158 if (s_refcount) return 0; 159 if (!s_init) return 0; 160 DWORD error = 0; 161 if (s_hRpcDll) { 162 FreeLibrary(s_hRpcDll); 163 s_hRpcDll = 0; 164 } 165 error = SecureClient::Detach(); 166 memset(&s_info, 0, sizeof(s_info)); 167 s_init = false; 168 s_error = 0; 169 if (error) { 170 cci_debug_printf(" Init::Detach() had an error (%u)", error); 171 } 172 return error; 173 } 174 175 static 176 void 177 ShowInfo( 178 Init::InitInfo& info 179 ) 180 { 181 if (info.isNT) { 182 cci_debug_printf(" Running on Windows NT using secure mode"); 183 } else { 184 cci_debug_printf(" Running insecurely on non-NT Windows"); 185 } 186 return; 187 } 188