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.

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