Leaked source code of windows server 2003
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.

736 lines
15 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. source.cpp
  5. Abstract:
  6. Select certificate source dialog implementation.
  7. Author:
  8. Jeff Parham (jeffparh) 13-Dec-1995
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "ccfapi.h"
  13. #include "source.h"
  14. #include "paper.h"
  15. #include "nlicdlg.h"
  16. #include "utils.h"
  17. #include <htmlhelp.h>
  18. #include <strsafe.h> //include last
  19. #ifdef _DEBUG
  20. #undef THIS_FILE
  21. static char BASED_CODE THIS_FILE[] = __FILE__;
  22. #endif
  23. // 3.51-style
  24. static CString l_strOldEntryName;
  25. static const DWORD l_dwOldEntryIndex = (DWORD) (-1L);
  26. CCertSourceSelectDlg::CCertSourceSelectDlg(CWnd* pParent /*=NULL*/)
  27. : CDialog(CCertSourceSelectDlg::IDD, pParent)
  28. /*++
  29. Routine Description:
  30. Constructor for dialog.
  31. Arguments:
  32. pParent - owner window.
  33. Return Values:
  34. None.
  35. --*/
  36. {
  37. //{{AFX_DATA_INIT(CCertSourceSelectDlg)
  38. m_strSource = _T("");
  39. //}}AFX_DATA_INIT
  40. m_dwEnterFlags = 0;
  41. m_pszProductName = NULL;
  42. m_pszServerName = NULL;
  43. m_pszVendor = NULL;
  44. l_strOldEntryName.LoadString( IDS_NO_CERTIFICATE_SOURCE_NAME );
  45. m_hLls = NULL;
  46. }
  47. CCertSourceSelectDlg::~CCertSourceSelectDlg()
  48. /*++
  49. Routine Description:
  50. Destructor for dialog.
  51. Arguments:
  52. None.
  53. Return Values:
  54. None.
  55. --*/
  56. {
  57. if ( NULL != m_hLls )
  58. {
  59. LlsClose( m_hLls );
  60. }
  61. }
  62. void CCertSourceSelectDlg::DoDataExchange(CDataExchange* pDX)
  63. /*++
  64. Routine Description:
  65. Called by framework to exchange dialog data.
  66. Arguments:
  67. pDX - data exchange object.
  68. Return Values:
  69. None.
  70. --*/
  71. {
  72. CDialog::DoDataExchange(pDX);
  73. //{{AFX_DATA_MAP(CCertSourceSelectDlg)
  74. DDX_Control(pDX, IDC_CERT_SOURCE, m_cboxSource);
  75. DDX_CBString(pDX, IDC_CERT_SOURCE, m_strSource);
  76. //}}AFX_DATA_MAP
  77. }
  78. BEGIN_MESSAGE_MAP(CCertSourceSelectDlg, CDialog)
  79. //{{AFX_MSG_MAP(CCertSourceSelectDlg)
  80. ON_BN_CLICKED(IDC_MY_HELP, OnHelp)
  81. ON_WM_DESTROY()
  82. //}}AFX_MSG_MAP
  83. END_MESSAGE_MAP()
  84. BOOL CCertSourceSelectDlg::OnInitDialog()
  85. /*++
  86. Routine Description:
  87. Handler for WM_INITDIALOG.
  88. Arguments:
  89. None.
  90. Return Values:
  91. Returns false if focus set manually.
  92. --*/
  93. {
  94. CDialog::OnInitDialog();
  95. GetSourceList();
  96. m_cboxSource.SetCurSel( 0 );
  97. return TRUE;
  98. }
  99. void CCertSourceSelectDlg::OnOK()
  100. /*++
  101. Routine Description:
  102. Handler for BN_CLICKED of OK.
  103. Arguments:
  104. None.
  105. Return Values:
  106. None.
  107. --*/
  108. {
  109. if ( NULL != GetParent() )
  110. GetParent()->EnableWindow();
  111. ShowWindow( FALSE );
  112. if ( ERROR_SUCCESS == CallCertificateSource( (int)m_cboxSource.GetItemData( m_cboxSource.GetCurSel() ) ) )
  113. CDialog::OnOK();
  114. else
  115. ShowWindow( TRUE );
  116. }
  117. void CCertSourceSelectDlg::OnHelp()
  118. /*++
  119. Routine Description:
  120. Handler for help button click.
  121. Arguments:
  122. None.
  123. Return Values:
  124. None.
  125. --*/
  126. {
  127. WinHelp( IDD, HELP_CONTEXT );
  128. }
  129. void CCertSourceSelectDlg::WinHelp(DWORD dwData, UINT nCmd)
  130. /*++
  131. Routine Description:
  132. Call WinHelp for this dialog.
  133. Arguments:
  134. dwData (DWORD)
  135. nCmd (UINT)
  136. Return Values:
  137. None.
  138. --*/
  139. {
  140. ::HtmlHelp(m_hWnd, L"liceconcepts.chm", HH_DISPLAY_TOPIC,0);
  141. UNREFERENCED_PARAMETER(dwData);
  142. UNREFERENCED_PARAMETER(nCmd);
  143. /*
  144. BOOL ok = ::WinHelp( m_hWnd, theApp.GetHelpFileName(), nCmd, dwData );
  145. */ ASSERT( ok );
  146. }
  147. void CCertSourceSelectDlg::OnDestroy()
  148. /*++
  149. Routine Description:
  150. Handler for WM_DESTROY.
  151. Arguments:
  152. None.
  153. Return Values:
  154. None.
  155. --*/
  156. {
  157. WinHelp( 0, HELP_QUIT );
  158. CDialog::OnDestroy();
  159. }
  160. void CCertSourceSelectDlg::GetSourceList()
  161. /*++
  162. Routine Description:
  163. Insert list of valid certificate sources into list box.
  164. Arguments:
  165. None.
  166. Return Values:
  167. None.
  168. --*/
  169. {
  170. BOOL ok = TRUE;
  171. int nCboxIndex;
  172. if ( NULL == m_pszProductName )
  173. {
  174. // otherwise we know that the product is secure, otherwise it would have
  175. // been handed to the unsecure product entry dialog already, and we
  176. // wouldn't offer to let the user use the unsecure entry dialog
  177. // add standard non-secure certificate source to possible choices
  178. nCboxIndex = m_cboxSource.AddString( l_strOldEntryName );
  179. ok = ( 0 <= nCboxIndex )
  180. && ( CB_ERR != m_cboxSource.SetItemData( nCboxIndex, l_dwOldEntryIndex ) );
  181. }
  182. if ( ok
  183. && ConnectServer()
  184. && LlsCapabilityIsSupported( m_hLls, LLS_CAPABILITY_SECURE_CERTIFICATES ) )
  185. {
  186. // secure certificates supported on the target server (post-3.51 license server)
  187. // add secure certificate sources to source list
  188. for ( int nSourceIndex=0; ok && ( nSourceIndex < m_cslSourceList.GetNumSources() ); nSourceIndex++ )
  189. {
  190. nCboxIndex = m_cboxSource.AddString( m_cslSourceList.GetSourceDisplayName( nSourceIndex ) );
  191. if ( nCboxIndex < 0 )
  192. {
  193. // couldn't add string to combo box
  194. ok = FALSE;
  195. }
  196. else
  197. {
  198. // string added; associate index of source with it
  199. ok = ( CB_ERR != m_cboxSource.SetItemData( nCboxIndex, nSourceIndex ) );
  200. }
  201. }
  202. }
  203. if ( !ok )
  204. {
  205. theApp.SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  206. theApp.DisplayLastError();
  207. EndDialog( IDABORT );
  208. }
  209. else if ( m_cboxSource.GetCount() == 0 )
  210. {
  211. AfxMessageBox( IDS_NO_PRODUCT_CERTIFICATE_SOURCES, MB_OK | MB_ICONSTOP, 0 );
  212. EndDialog( IDABORT );
  213. }
  214. }
  215. DWORD CCertSourceSelectDlg::CallCertificateSource( int nIndex )
  216. /*++
  217. Routine Description:
  218. Call the certificate source with the specified index into the source list.
  219. Arguments:
  220. nIndex (int)
  221. Return Values:
  222. ERROR_SUCCESS
  223. ERROR_SERVICE_NOT_FOUND
  224. Win error
  225. --*/
  226. {
  227. DWORD dwError = ERROR_SERVICE_NOT_FOUND;
  228. if ( l_dwOldEntryIndex == nIndex )
  229. {
  230. dwError = NoCertificateEnter( m_hWnd, m_pszServerName, m_pszProductName, m_pszVendor, m_dwEnterFlags );
  231. }
  232. else
  233. {
  234. HMODULE hDll;
  235. hDll = ::LoadLibrary( m_cslSourceList.GetSourceImagePath( nIndex ) );
  236. if ( NULL == hDll )
  237. {
  238. dwError = GetLastError();
  239. theApp.SetLastError( dwError );
  240. theApp.DisplayLastError();
  241. }
  242. else
  243. {
  244. CHAR *pszExportName = NULL;
  245. PCCF_ENTER_API pfn;
  246. dwError = CatUnicodeAndAnsiStrings(
  247. m_cslSourceList.GetSourceName( nIndex ),
  248. "CertificateEnter",
  249. &pszExportName);
  250. if (ERROR_SUCCESS == dwError)
  251. {
  252. ASSERT(NULL != pszExportName);
  253. pfn = (PCCF_ENTER_API) GetProcAddress( hDll, pszExportName );
  254. if ( NULL == pfn )
  255. {
  256. dwError = GetLastError();
  257. theApp.SetLastError( dwError );
  258. theApp.DisplayLastError();
  259. }
  260. else
  261. {
  262. dwError = (*pfn)( m_hWnd, m_pszServerName, m_pszProductName, m_pszVendor, m_dwEnterFlags );
  263. }
  264. // BUG# 692774
  265. LocalFree(pszExportName);
  266. }
  267. ::FreeLibrary( hDll );
  268. }
  269. }
  270. return dwError;
  271. }
  272. void CCertSourceSelectDlg::AbortDialogIfNecessary()
  273. /*++
  274. Routine Description:
  275. Display error message and abort dialog if connection lost.
  276. Arguments:
  277. None.
  278. Return Values:
  279. None.
  280. --*/
  281. {
  282. theApp.DisplayLastError();
  283. if ( theApp.IsConnectionDropped() )
  284. {
  285. EndDialog( IDABORT );
  286. }
  287. }
  288. BOOL CCertSourceSelectDlg::ConnectServer()
  289. /*++
  290. Routine Description:
  291. Establish a connection to the license service on the target server.
  292. Arguments:
  293. None.
  294. Return Values:
  295. BOOL.
  296. --*/
  297. {
  298. NTSTATUS nt;
  299. HRESULT hr;
  300. size_t cch;
  301. if ( NULL == m_hLls )
  302. {
  303. LPTSTR pszUniServerName = NULL;
  304. if ( NULL == m_pszServerName )
  305. {
  306. pszUniServerName = NULL;
  307. nt = STATUS_SUCCESS;
  308. }
  309. else
  310. {
  311. cch = 1 + strlen( m_pszServerName );
  312. pszUniServerName = (LPTSTR) LocalAlloc( LMEM_FIXED, sizeof(TCHAR) * cch );
  313. if ( NULL == pszUniServerName )
  314. {
  315. nt = ERROR_NOT_ENOUGH_MEMORY;
  316. theApp.SetLastError( (DWORD) nt );
  317. }
  318. else
  319. {
  320. hr = StringCchPrintf(pszUniServerName, cch, L"%hs", m_pszServerName);
  321. ASSERT(SUCCEEDED(hr));
  322. nt = STATUS_SUCCESS;
  323. }
  324. }
  325. if ( STATUS_SUCCESS == nt )
  326. {
  327. nt = ConnectTo( pszUniServerName, &m_hLls );
  328. }
  329. if ( NULL != pszUniServerName )
  330. {
  331. LocalFree( pszUniServerName );
  332. }
  333. }
  334. if ( NULL == m_hLls )
  335. {
  336. theApp.DisplayLastError();
  337. if ( ( NULL != m_hWnd ) && IsWindow( m_hWnd ) )
  338. {
  339. EndDialog( IDABORT );
  340. }
  341. }
  342. return ( NULL != m_hLls );
  343. }
  344. NTSTATUS CCertSourceSelectDlg::ConnectTo( LPTSTR pszServerName, PLLS_HANDLE phLls )
  345. /*++
  346. Routine Description:
  347. Establish a connection to the license service on the given server.
  348. Arguments:
  349. pszServerName (CString)
  350. The target server. An empty value indicates the local server.
  351. phLls (PLLS_HANDLE)
  352. On return, holds the handle to the standard LLS RPC.
  353. Return Values:
  354. STATUS_SUCCESS or NT status code.
  355. --*/
  356. {
  357. NTSTATUS nt;
  358. nt = ::LlsConnect( pszServerName, phLls );
  359. theApp.SetLastLlsError( nt );
  360. if ( STATUS_SUCCESS != nt )
  361. {
  362. *phLls = NULL;
  363. }
  364. return nt;
  365. }
  366. DWORD CCertSourceSelectDlg::CertificateEnter( HWND hWndParent, LPCSTR pszServerName, LPCSTR pszProductName, LPCSTR pszVendor, DWORD dwFlags, LPCSTR pszSourceToUse )
  367. /*++
  368. Routine Description:
  369. Display a dialog allowing the user to enter a license certificate
  370. into the system.
  371. Arguments:
  372. pszServerName (LPCSTR)
  373. Name of the server for which licenses are to be installed. Note that
  374. this may not be the same as the server on which licenses are actually
  375. installed, as, for example, per seat licenses are always installed on
  376. the enterprise server. A NULL value indicates the local server.
  377. pszProductName (LPCSTR)
  378. Product for which licenses are to be installed. A NULL value indicates
  379. that the user should be allowed to choose.
  380. pszVendor (LPCSTR)
  381. Name of the vendor of the product. This value should be NULL if
  382. pszProductName is NULL, and should be non-NULL if pszProductName is
  383. non-NULL.
  384. dwFlags (DWORD)
  385. A bitfield containing one or more of the following:
  386. CCF_ENTER_FLAG_PER_SEAT_ONLY
  387. Allow the user to enter only per seat licenses. Not valid in
  388. combination with CCF_ENTER_FLAG_PER_SERVER_ONLY.
  389. CCF_ENTER_FLAG_PER_SERVER_ONLY
  390. Allow the user to enter only per server licenses. Not valid in
  391. combination with CCF_ENTER_FLAG_PER_SEAT_ONLY.
  392. pszSourceToUse (LPCSTR)
  393. Name of the secure certificate source to use to install the certificate,
  394. e.g., "Paper". A NULL value indicates that the user should be allowed
  395. to choose.
  396. Return Value:
  397. ERROR_SUCCESS (A certificate was successfully entered into the system.)
  398. ERROR_CANCELLED (The user cancelled without installing a certificate.)
  399. other Win error
  400. --*/
  401. {
  402. DWORD dwError;
  403. HRESULT hr;
  404. m_pszServerName = pszServerName;
  405. m_pszProductName = pszProductName;
  406. m_pszVendor = pszVendor;
  407. m_dwEnterFlags = dwFlags;
  408. if ( pszSourceToUse != NULL )
  409. {
  410. CString strSourceToUse = pszSourceToUse;
  411. int nSrcIndex;
  412. for ( nSrcIndex = 0; nSrcIndex < m_cslSourceList.GetNumSources(); nSrcIndex++ )
  413. {
  414. if ( !strSourceToUse.CompareNoCase( m_cslSourceList.GetSourceDisplayName( nSrcIndex ) ) )
  415. {
  416. // use this certificate source
  417. break;
  418. }
  419. }
  420. if ( m_cslSourceList.GetNumSources() == nSrcIndex )
  421. {
  422. // requested certificate source is not available
  423. dwError = ERROR_SERVICE_NOT_FOUND;
  424. }
  425. else
  426. {
  427. // don't display dialog, just use the indicated source
  428. dwError = CallCertificateSource( nSrcIndex );
  429. }
  430. }
  431. else if ( pszProductName != NULL )
  432. {
  433. // find out if this is a secure product
  434. if ( !ConnectServer() )
  435. {
  436. dwError = theApp.GetLastError();
  437. }
  438. else
  439. {
  440. BOOL bProductIsSecure;
  441. if ( !LlsCapabilityIsSupported( m_hLls, LLS_CAPABILITY_SECURE_CERTIFICATES ) )
  442. {
  443. // no extended RPC, so all products on this server must be unsecure
  444. bProductIsSecure = FALSE;
  445. dwError = ERROR_SUCCESS;
  446. }
  447. else
  448. {
  449. LPTSTR pszUniProductName;
  450. size_t cch;
  451. cch = 1 + strlen( pszProductName );
  452. pszUniProductName = (LPTSTR) LocalAlloc( LMEM_FIXED, sizeof( TCHAR ) * cch );
  453. if ( NULL == pszUniProductName )
  454. {
  455. dwError = ERROR_NOT_ENOUGH_MEMORY;
  456. theApp.SetLastError( dwError );
  457. theApp.DisplayLastError();
  458. }
  459. else
  460. {
  461. dwError = ERROR_SUCCESS;
  462. hr = StringCchPrintf(pszUniProductName, cch, L"%hs", pszProductName);
  463. ASSERT(SUCCEEDED(hr));
  464. BOOL bIsSecure;
  465. bProductIsSecure = ( STATUS_SUCCESS == ::LlsProductSecurityGet( m_hLls, pszUniProductName, &bIsSecure ) )
  466. && bIsSecure;
  467. LocalFree( pszUniProductName );
  468. }
  469. }
  470. if ( ERROR_SUCCESS == dwError )
  471. {
  472. if ( !bProductIsSecure )
  473. {
  474. // unsecure product; no need to select source
  475. dwError = NoCertificateEnter( hWndParent, pszServerName, pszProductName, pszVendor, dwFlags );
  476. }
  477. else
  478. if ( 1 == m_cslSourceList.GetNumSources() )
  479. {
  480. // product is secure and there is only one source to choose from; use it!
  481. dwError = CallCertificateSource( 0 );
  482. }
  483. else if ( IDOK == DoModal() )
  484. {
  485. dwError = ERROR_SUCCESS;
  486. }
  487. else
  488. {
  489. dwError = ERROR_CANCELLED;
  490. }
  491. }
  492. }
  493. }
  494. else if ( !ConnectServer() )
  495. {
  496. dwError = theApp.GetLastError();
  497. }
  498. else if ( !LlsCapabilityIsSupported( m_hLls, LLS_CAPABILITY_SECURE_CERTIFICATES )
  499. || !m_cslSourceList.GetNumSources() )
  500. {
  501. // secure certificates not supported or no sources available; use unsecure source
  502. dwError = NoCertificateEnter( hWndParent, pszServerName, pszProductName, pszVendor, dwFlags );
  503. }
  504. else if ( IDOK == DoModal() )
  505. {
  506. dwError = ERROR_SUCCESS;
  507. }
  508. else
  509. {
  510. dwError = ERROR_CANCELLED;
  511. }
  512. return dwError;
  513. }