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
Info(InitInfo & info)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
Initialize()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
Cleanup()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
ShowInfo(Init::InitInfo & info)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