Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

412 lines
9.4 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. // TlsHunt.cpp : implementation file
  3. //
  4. #include "stdafx.h"
  5. #include <lm.h>
  6. #include "LicMgr.h"
  7. #include "defines.h"
  8. #include "LSServer.h"
  9. #include "MainFrm.h"
  10. #include "RtList.h"
  11. #include "lSmgrdoc.h"
  12. #include "LtView.h"
  13. #include "cntdlg.h"
  14. #include "addkp.h"
  15. #include "treenode.h"
  16. #include "ntsecapi.h"
  17. #include "lrwizapi.h"
  18. #include "TlsHunt.h"
  19. #ifdef _DEBUG
  20. #define new DEBUG_NEW
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CTlsHunt dialog
  26. CTlsHunt::~CTlsHunt()
  27. {
  28. if(m_hThread != NULL)
  29. CloseHandle(m_hThread);
  30. }
  31. CTlsHunt::CTlsHunt(CWnd* pParent /*=NULL*/)
  32. : CDialog(CTlsHunt::IDD, pParent)
  33. {
  34. //{{AFX_DATA_INIT(CTlsHunt)
  35. // NOTE: the ClassWizard will add member initialization here
  36. //}}AFX_DATA_INIT
  37. m_hThread = NULL;
  38. memset(&m_EnumData, 0, sizeof(m_EnumData));
  39. }
  40. void CTlsHunt::DoDataExchange(CDataExchange* pDX)
  41. {
  42. CDialog::DoDataExchange(pDX);
  43. //{{AFX_DATA_MAP(CTlsHunt)
  44. // NOTE: the ClassWizard will add DDX and DDV calls here
  45. //}}AFX_DATA_MAP
  46. }
  47. BEGIN_MESSAGE_MAP(CTlsHunt, CDialog)
  48. //{{AFX_MSG_MAP(CTlsHunt)
  49. ON_WM_CREATE()
  50. //ON_MESSAGE(WM_DONEDISCOVERY, OnDoneDiscovery)
  51. ON_WM_CLOSE()
  52. ON_WM_CANCELMODE()
  53. //}}AFX_MSG_MAP
  54. END_MESSAGE_MAP()
  55. /////////////////////////////////////////////////////////////////////////////
  56. // CTlsHunt message handlers
  57. //------------------------------------------------------------------
  58. BOOL
  59. CTlsHunt::ServerEnumCallBack(
  60. TLS_HANDLE hHandle,
  61. LPCTSTR pszServerName,
  62. HANDLE dwUserData
  63. )
  64. /*++
  65. ++*/
  66. {
  67. ServerEnumData* pEnumData = (ServerEnumData *)dwUserData;
  68. BOOL bCancel;
  69. bCancel = (InterlockedExchange(&(pEnumData->dwDone), pEnumData->dwDone) == 1);
  70. if(bCancel == TRUE)
  71. {
  72. return TRUE;
  73. }
  74. if(pszServerName && pszServerName[0] != _TEXT('\0'))
  75. {
  76. #if DBG
  77. OutputDebugString(pszServerName);
  78. OutputDebugString(L"\n");
  79. #endif
  80. CString itemTxt;
  81. itemTxt.Format(IDS_TRYSERVER, pszServerName);
  82. pEnumData->pWaitDlg->SendDlgItemMessage(
  83. IDC_TLSERVER_NAME,
  84. WM_SETTEXT,
  85. 0,
  86. (LPARAM)(LPCTSTR)itemTxt
  87. );
  88. }
  89. if(hHandle)
  90. {
  91. DWORD dwStatus;
  92. DWORD dwErrCode;
  93. TCHAR szServer[MAX_COMPUTERNAME_LENGTH+1];
  94. DWORD dwBufSize = sizeof(szServer) / sizeof(szServer[0]);
  95. if(pEnumData == NULL || pEnumData->pMainFrm == NULL)
  96. {
  97. SetLastError(ERROR_INVALID_PARAMETER);
  98. return TRUE;
  99. }
  100. memset(szServer, 0, sizeof(szServer));
  101. dwStatus = TLSGetServerNameEx(
  102. hHandle,
  103. szServer,
  104. &dwBufSize,
  105. &dwErrCode
  106. );
  107. if(dwStatus == ERROR_SUCCESS && dwErrCode == ERROR_SUCCESS)
  108. {
  109. //
  110. // Make NT4 RPC call to ensure this server is compatible
  111. // with our version
  112. //
  113. pEnumData->pMainFrm->ConnectServer(szServer);
  114. pEnumData->dwNumServer++;
  115. }
  116. }
  117. //
  118. // Continue enumeration
  119. //
  120. return InterlockedExchange(&(pEnumData->dwDone), pEnumData->dwDone) == 1;
  121. }
  122. /////////////////////////////////////////////////////////////////////
  123. DWORD WINAPI
  124. CTlsHunt::DiscoveryThread(
  125. PVOID ptr
  126. )
  127. /*++
  128. ++*/
  129. {
  130. DWORD hResult;
  131. ServerEnumData* pEnumData = (ServerEnumData *)ptr;
  132. LPWSTR* pszEnterpriseServer = NULL;
  133. DWORD dwCount;
  134. DWORD index;
  135. static BOOL fInitialized = FALSE;
  136. if (!fInitialized)
  137. {
  138. TLSInit();
  139. fInitialized = TRUE;
  140. }
  141. //
  142. // Look for all license server in domain
  143. //
  144. hResult = EnumerateTlsServer(
  145. CTlsHunt::ServerEnumCallBack,
  146. ptr,
  147. 3 * 1000,
  148. FALSE
  149. );
  150. // Find enterprise server
  151. if(pEnumData->dwDone == 0)
  152. {
  153. hResult = GetAllEnterpriseServers(
  154. &pszEnterpriseServer,
  155. &dwCount
  156. );
  157. if(hResult == ERROR_SUCCESS && dwCount != 0 && pszEnterpriseServer != NULL)
  158. {
  159. TLS_HANDLE TlsHandle = NULL;
  160. //
  161. // Inform dialog
  162. //
  163. for(index = 0; index < dwCount && pEnumData->dwDone == 0; index++)
  164. {
  165. if(pszEnterpriseServer[index] == NULL)
  166. continue;
  167. if(ServerEnumCallBack(
  168. NULL,
  169. pszEnterpriseServer[index],
  170. pEnumData
  171. ) == TRUE)
  172. {
  173. continue;
  174. }
  175. TlsHandle = TLSConnectToLsServer(
  176. pszEnterpriseServer[index]
  177. );
  178. if(TlsHandle == NULL)
  179. {
  180. continue;
  181. }
  182. DWORD dwVersion;
  183. RPC_STATUS rpcStatus;
  184. rpcStatus = TLSGetVersion(
  185. TlsHandle,
  186. &dwVersion
  187. );
  188. if(rpcStatus != RPC_S_OK)
  189. {
  190. continue;
  191. }
  192. if( TLSIsBetaNTServer() == IS_LSSERVER_RTM(dwVersion) )
  193. {
  194. continue;
  195. }
  196. ServerEnumCallBack(
  197. TlsHandle,
  198. pszEnterpriseServer[index],
  199. pEnumData
  200. );
  201. TLSDisconnectFromServer(TlsHandle);
  202. }
  203. } else
  204. {
  205. // Failure in GetAllEnterpriseServers
  206. pszEnterpriseServer = NULL;
  207. dwCount = 0;
  208. }
  209. }
  210. if(pszEnterpriseServer != NULL)
  211. {
  212. for( index = 0; index < dwCount; index ++)
  213. {
  214. if(pszEnterpriseServer[index] != NULL)
  215. {
  216. LocalFree(pszEnterpriseServer[index]);
  217. }
  218. }
  219. LocalFree(pszEnterpriseServer);
  220. }
  221. pEnumData->pWaitDlg->PostMessage(WM_DONEDISCOVERY);
  222. ExitThread(hResult);
  223. return hResult;
  224. }
  225. BOOL CTlsHunt::OnInitDialog()
  226. {
  227. CDialog::OnInitDialog();
  228. ASSERT(m_hThread != NULL);
  229. if(m_hThread != NULL)
  230. {
  231. ResumeThread(m_hThread);
  232. }
  233. return TRUE; // return TRUE unless you set the focus to a control
  234. // EXCEPTION: OCX Property Pages should return FALSE
  235. }
  236. int CTlsHunt::OnCreate(LPCREATESTRUCT lpCreateStruct)
  237. {
  238. if (CDialog::OnCreate(lpCreateStruct) == -1)
  239. return -1;
  240. m_EnumData.pWaitDlg = this;
  241. m_EnumData.pMainFrm = (CMainFrame *)GetParentFrame();
  242. m_EnumData.dwNumServer = 0;
  243. m_EnumData.dwDone = 0;
  244. DWORD dwId;
  245. m_hThread = (HANDLE)CreateThread(
  246. NULL,
  247. 0,
  248. CTlsHunt::DiscoveryThread,
  249. &m_EnumData,
  250. CREATE_SUSPENDED, // suspended thread
  251. &dwId
  252. );
  253. if(m_hThread == NULL)
  254. {
  255. //
  256. // Can't create thread.
  257. //
  258. AfxMessageBox(IDS_CREATETHREAD);
  259. return -1;
  260. }
  261. return 0;
  262. }
  263. void CTlsHunt::OnCancel()
  264. {
  265. if( m_hThread != NULL &&
  266. WaitForSingleObject(m_hThread, 0) == WAIT_TIMEOUT )
  267. {
  268. InterlockedExchange(&(m_EnumData.dwDone), 1);
  269. CString txt;
  270. txt.LoadString(IDS_CANCELDISCOVERY);
  271. SendDlgItemMessage(
  272. IDC_TLSERVER_NAME,
  273. WM_SETTEXT,
  274. 0,
  275. (LPARAM)(LPCTSTR)txt
  276. );
  277. CWnd* btn = GetDlgItem(IDCANCEL);
  278. ASSERT(btn);
  279. if(btn != NULL)
  280. {
  281. btn->EnableWindow(FALSE);
  282. }
  283. }
  284. else
  285. {
  286. CDialog::OnCancel();
  287. }
  288. }
  289. void CTlsHunt::OnDoneDiscovery()
  290. {
  291. if(m_hThread != NULL)
  292. {
  293. WaitForSingleObject(m_hThread, INFINITE);
  294. CloseHandle(m_hThread);
  295. m_hThread = NULL;
  296. }
  297. CDialog::EndDialog(0);
  298. }
  299. void CTlsHunt::OnClose()
  300. {
  301. if(m_hThread != NULL)
  302. {
  303. InterlockedExchange(&(m_EnumData.dwDone), 1);
  304. CString txt;
  305. txt.LoadString(IDS_CANCELDISCOVERY);
  306. SendDlgItemMessage(
  307. IDC_TLSERVER_NAME,
  308. WM_SETTEXT,
  309. 0,
  310. (LPARAM)(LPCTSTR)txt
  311. );
  312. CWnd* btn = GetDlgItem(IDCANCEL);
  313. ASSERT(btn);
  314. if(btn != NULL)
  315. {
  316. btn->EnableWindow(FALSE);
  317. }
  318. }
  319. else
  320. {
  321. CDialog::OnClose();
  322. }
  323. }
  324. BOOL CTlsHunt::PreTranslateMessage(MSG* pMsg)
  325. {
  326. if(pMsg->message == WM_DONEDISCOVERY)
  327. {
  328. OnDoneDiscovery();
  329. return TRUE;
  330. }
  331. return CDialog::PreTranslateMessage(pMsg);
  332. }