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.

1804 lines
51 KiB

  1. // USERLIST.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "EFSADU.h"
  5. #include "USERLIST.h"
  6. #include "cryptui.h"
  7. #include "objsel.h"
  8. #include <winefs.h>
  9. #include "efsui.h"
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15. #define OTHERPEOPLE L"AddressBook"
  16. #define TRUSTEDPEOPLE L"TrustedPeople"
  17. LPSTR EfsOidlpstr = szOID_KP_EFS;
  18. /////////////////////////////////////////////////////////////////////////////
  19. // USERLIST dialog
  20. USERLIST::USERLIST(CWnd* pParent /*=NULL*/)
  21. : CDialog(USERLIST::IDD, pParent)
  22. {
  23. //{{AFX_DATA_INIT(USERLIST)
  24. //}}AFX_DATA_INIT
  25. }
  26. USERLIST::USERLIST(LPCTSTR FileName, CWnd* pParent /*=NULL*/)
  27. : CDialog(USERLIST::IDD, pParent)
  28. {
  29. m_FileName = FileName;
  30. }
  31. void USERLIST::DoDataExchange(CDataExchange* pDX)
  32. {
  33. CDialog::DoDataExchange(pDX);
  34. //{{AFX_DATA_MAP(USERLIST)
  35. DDX_Control(pDX, IDC_LISTRA, m_RecoveryListCtrl);
  36. DDX_Control(pDX, IDC_LISTUSER, m_UserListCtrl);
  37. DDX_Control(pDX, IDC_ADD, m_AddButton);
  38. DDX_Control(pDX, IDC_REMOVE, m_RemoveButton);
  39. //}}AFX_DATA_MAP
  40. }
  41. BEGIN_MESSAGE_MAP(USERLIST, CDialog)
  42. //{{AFX_MSG_MAP(USERLIST)
  43. ON_BN_CLICKED(IDC_REMOVE, OnRemove)
  44. ON_BN_CLICKED(IDC_ADD, OnAdd)
  45. ON_NOTIFY(NM_SETFOCUS, IDC_LISTUSER, OnSetfocusListuser)
  46. ON_NOTIFY(NM_KILLFOCUS, IDC_LISTUSER, OnKillfocusListuser)
  47. ON_NOTIFY(LVN_ITEMCHANGED, IDC_LISTUSER, OnItemchangedListuser)
  48. //}}AFX_MSG_MAP
  49. END_MESSAGE_MAP()
  50. /////////////////////////////////////////////////////////////////////////////
  51. // USERLIST message handlers
  52. void USERLIST::OnRemove()
  53. {
  54. int ItemPos;
  55. BOOL NoAction = FALSE;
  56. CString NoCertName;
  57. try{
  58. NoCertName.LoadString(IDS_NOCERTNAME);
  59. }
  60. catch(...){
  61. NoAction = TRUE;
  62. }
  63. if (NoAction){
  64. return;
  65. }
  66. ItemPos = m_UserListCtrl.GetNextItem( -1, LVNI_SELECTED );
  67. while ( ItemPos != -1 ){
  68. CString CertName;
  69. LPTSTR pCertName;
  70. CertName = m_UserListCtrl.GetItemText( ItemPos, 0 );
  71. if ( !CertName.Compare(NoCertName) ){
  72. pCertName = NULL;
  73. } else {
  74. pCertName = CertName.GetBuffer(CertName.GetLength() + 1);
  75. }
  76. m_Users.Remove( pCertName);
  77. m_UserListCtrl.DeleteItem( ItemPos );
  78. if (pCertName){
  79. CertName.ReleaseBuffer();
  80. }
  81. //
  82. // Because we have deleted the item. We have to start from -1 again.
  83. //
  84. ItemPos = m_UserListCtrl.GetNextItem( -1, LVNI_SELECTED );
  85. }
  86. m_AddButton.SetFocus();
  87. }
  88. void USERLIST::OnCancel()
  89. {
  90. // TODO: Add extra cleanup here
  91. CDialog::OnCancel();
  92. }
  93. void USERLIST::OnOK()
  94. {
  95. // TODO: Add extra validation here
  96. LONG NoUsersToAdd = m_Users.GetUserAddedCnt();
  97. LONG NoUsersToRemove = m_Users.GetUserRemovedCnt();
  98. if ( (NoUsersToRemove - NoUsersToAdd) >= m_CurrentUsers) {
  99. //
  100. // All the users are going to be removed from the file. Do not allow.
  101. //
  102. CString ErrMsg;
  103. if (ErrMsg.LoadString(IDS_NOREMOVEALL)){
  104. MessageBox(ErrMsg);
  105. }
  106. return;
  107. }
  108. CDialog::OnOK();
  109. }
  110. STDAPI_(void) EfsDetail(HWND hwndParent, LPCWSTR FileName)
  111. {
  112. INT_PTR RetCode;
  113. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  114. DWORD FileAttributes = GetFileAttributes(FileName);
  115. if ( (-1 != FileAttributes) && ( FileAttributes & FILE_ATTRIBUTE_DIRECTORY)){
  116. CString ErrMsg;
  117. if (ErrMsg.LoadString(IDS_NOADDUSERDIR)){
  118. MessageBox(hwndParent, ErrMsg, NULL, MB_OK);
  119. }
  120. return;
  121. }
  122. CWnd cwnd;
  123. cwnd.FromHandle(hwndParent);
  124. USERLIST DetailDialog(FileName, &cwnd);
  125. RetCode = DetailDialog.DoModal();
  126. if ( IDOK == RetCode ){
  127. //
  128. // Commit the change
  129. //
  130. DetailDialog.ApplyChanges( FileName );
  131. } else if (IDCANCEL == RetCode) {
  132. //
  133. // Nothing needs to be done
  134. //
  135. }
  136. }
  137. BOOL WINAPI EfsFilter(
  138. PCCERT_CONTEXT pCertContext,
  139. BOOL *pfInitialSelectedCert,
  140. void *pvCallbackData
  141. )
  142. {
  143. BOOL disp = FALSE;
  144. PCERT_ENHKEY_USAGE pUsage = NULL;
  145. DWORD cbUsage = 0;
  146. if (CertGetEnhancedKeyUsage(
  147. pCertContext,
  148. 0,
  149. NULL,
  150. &cbUsage) && 0 != cbUsage){
  151. pUsage = (PCERT_ENHKEY_USAGE) new BYTE[cbUsage];
  152. if (pUsage){
  153. if (CertGetEnhancedKeyUsage(
  154. pCertContext,
  155. 0,
  156. pUsage,
  157. &cbUsage)){
  158. //
  159. // Search for EFS usage
  160. //
  161. DWORD cUsages = pUsage->cUsageIdentifier;
  162. while (cUsages){
  163. if (!strcmp(szOID_KP_EFS, pUsage->rgpszUsageIdentifier[cUsages-1])){
  164. disp = TRUE;
  165. break;
  166. }
  167. cUsages--;
  168. }
  169. }
  170. delete [] pUsage;
  171. }
  172. }
  173. return disp;
  174. }
  175. BOOL USERLIST::OnInitDialog()
  176. {
  177. CDialog::OnInitDialog();
  178. CString WinTitle;
  179. RECT ListRect;
  180. DWORD ColWidth;
  181. CString ColName;
  182. CString ColCert;
  183. CString RecName;
  184. LPTSTR UserCertName = NULL;
  185. BOOL EnableAddButton = FALSE;
  186. PENCRYPTION_CERTIFICATE_HASH_LIST pUsers = NULL;
  187. PENCRYPTION_CERTIFICATE_HASH_LIST pRecs = NULL;
  188. try {
  189. DWORD RetCode;
  190. AfxFormatString1( WinTitle, IDS_DETAILWINTITLE, m_FileName );
  191. SetWindowText( WinTitle );
  192. m_CertChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
  193. m_CertChainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
  194. //
  195. // Check EFS EKU
  196. //
  197. m_CertChainPara.RequestedUsage.Usage.cUsageIdentifier = 1;
  198. m_CertChainPara.RequestedUsage.Usage.rgpszUsageIdentifier=&EfsOidlpstr;
  199. m_UserListCtrl.GetClientRect(&ListRect);
  200. ColName.LoadString(IDS_USERCOLTITLE);
  201. ColCert.LoadString(IDS_CERTCOLTITLE);
  202. RecName.LoadString(IDS_RECCOLTITLE);
  203. ColWidth = ( ListRect.right - ListRect.left ) / 4;
  204. m_UserListCtrl.InsertColumn(0, ColName, LVCFMT_LEFT, ColWidth*3 );
  205. m_UserListCtrl.InsertColumn(1, ColCert, LVCFMT_LEFT, ColWidth );
  206. m_RecoveryListCtrl.GetClientRect(&ListRect);
  207. ColWidth = ( ListRect.right - ListRect.left ) / 4;
  208. m_RecoveryListCtrl.InsertColumn(0, RecName, LVCFMT_LEFT, ColWidth*3 );
  209. m_RecoveryListCtrl.InsertColumn(1, ColCert, LVCFMT_LEFT, ColWidth );
  210. RetCode = QueryUsersOnEncryptedFile( (LPWSTR)(LPCWSTR) m_FileName, &pUsers);
  211. if ( !RetCode ){
  212. RetCode = QueryRecoveryAgentsOnEncryptedFile( (LPWSTR)(LPCWSTR) m_FileName, &pRecs);
  213. if ( !RetCode ){
  214. //
  215. // Got the info about the encrypted file
  216. //
  217. DWORD NUsers = pUsers->nCert_Hash;
  218. BOOL RecDone = FALSE;
  219. PENCRYPTION_CERTIFICATE_HASH_LIST pCertHashList = pUsers;
  220. m_CurrentUsers = (LONG) NUsers;
  221. //
  222. // Get all the users
  223. //
  224. while ( NUsers > 0 ){
  225. UserCertName = new TCHAR[_tcslen(pCertHashList->pUsers[NUsers - 1]->lpDisplayInformation) + 1];
  226. if (UserCertName){
  227. _tcscpy(UserCertName, pCertHashList->pUsers[NUsers - 1]->lpDisplayInformation);
  228. } else {
  229. AfxThrowMemoryException( );
  230. }
  231. //
  232. // We got the user name
  233. //
  234. if (RecDone){
  235. RetCode = m_Recs.Add(
  236. UserCertName,
  237. pCertHashList->pUsers[NUsers - 1]->pHash,
  238. NULL
  239. );
  240. } else {
  241. //
  242. // Try to get a better name from the cert
  243. //
  244. LPTSTR UserName;
  245. RetCode = TryGetBetterNameInCert(pCertHashList->pUsers[NUsers - 1]->pHash, &UserName);
  246. if (ERROR_SUCCESS == RetCode){
  247. //
  248. // We get a better name from the certs
  249. //
  250. delete [] UserCertName;
  251. UserCertName = UserName;
  252. }
  253. RetCode = m_Users.Add(
  254. UserCertName,
  255. pCertHashList->pUsers[NUsers - 1]->pHash,
  256. NULL
  257. );
  258. }
  259. if ( NO_ERROR != RetCode ) {
  260. delete [] UserCertName;
  261. UserCertName = NULL;
  262. }
  263. NUsers--;
  264. if (NUsers == 0 && !RecDone){
  265. //
  266. // Let's deal with the recovery agents.
  267. //
  268. RecDone = TRUE;
  269. pCertHashList = pRecs;
  270. NUsers = pRecs->nCert_Hash;
  271. }
  272. }
  273. if ( pRecs ){
  274. FreeEncryptionCertificateHashList( pRecs );
  275. pRecs = NULL;
  276. }
  277. //
  278. // In memory intial list established
  279. //
  280. SetUpListBox(&EnableAddButton);
  281. } else {
  282. //
  283. // Cannot get recovery info
  284. //
  285. CString ErrMsg;
  286. if (ErrMsg.LoadString(IDS_NORECINFO)){
  287. MessageBox(ErrMsg);
  288. }
  289. }
  290. if ( pUsers ){
  291. FreeEncryptionCertificateHashList( pUsers );
  292. pUsers = NULL;
  293. }
  294. } else {
  295. //
  296. // Cannot get user info
  297. //
  298. CString ErrMsg;
  299. if (ErrMsg.LoadString(IDS_NOINFO)){
  300. MessageBox(ErrMsg);
  301. }
  302. }
  303. }
  304. catch (...) {
  305. //
  306. // The exception mostly is caused by out of memory.
  307. // We can not prevent the page to be displayed from this routine,
  308. // So we just go ahead with empty list
  309. //
  310. m_UserListCtrl.DeleteAllItems( );
  311. m_RecoveryListCtrl.DeleteAllItems( );
  312. //
  313. // Delete works even if UserCertName == NULL
  314. //
  315. delete [] UserCertName;
  316. if ( pUsers ){
  317. FreeEncryptionCertificateHashList( pUsers );
  318. }
  319. if ( pRecs ){
  320. FreeEncryptionCertificateHashList( pRecs );
  321. }
  322. }
  323. m_RemoveButton.EnableWindow( FALSE );
  324. if ( !EnableAddButton ){
  325. m_AddButton.EnableWindow( FALSE );
  326. }
  327. return TRUE; // return TRUE unless you set the focus to a control
  328. // EXCEPTION: OCX Property Pages should return FALSE
  329. }
  330. void USERLIST::ShowRemove()
  331. {
  332. if (m_UserListCtrl.GetSelectedCount() > 0){
  333. //
  334. // Enable the Remove Button
  335. //
  336. m_RemoveButton.EnableWindow( TRUE );
  337. } else {
  338. //
  339. // Disable the Remove Button
  340. //
  341. m_RemoveButton.EnableWindow( FALSE );
  342. }
  343. }
  344. DWORD
  345. USERLIST::ApplyChanges(
  346. LPCTSTR FileName
  347. )
  348. {
  349. DWORD RetCode = NO_ERROR;
  350. DWORD NoUsersToRemove;
  351. DWORD NoUsersToAdd;
  352. DWORD RemoveUserIndex;
  353. DWORD AddUserIndex;
  354. PENCRYPTION_CERTIFICATE_HASH_LIST RemoveUserList = NULL;
  355. PENCRYPTION_CERTIFICATE_LIST AddUserList = NULL;
  356. PVOID EnumHandle;
  357. //
  358. // Get all the users to be added or removed first
  359. //
  360. NoUsersToAdd = m_Users.GetUserAddedCnt();
  361. NoUsersToRemove = m_Users.GetUserRemovedCnt();
  362. if ( (NoUsersToAdd == 0) && (NoUsersToRemove == 0)){
  363. return NO_ERROR;
  364. }
  365. if ( NoUsersToAdd ) {
  366. //
  367. // At least one user is to be added
  368. //
  369. DWORD BytesToAllocate;
  370. BytesToAllocate = sizeof ( ENCRYPTION_CERTIFICATE_LIST ) +
  371. NoUsersToAdd * sizeof ( PENCRYPTION_CERTIFICATE ) +
  372. NoUsersToAdd * sizeof (ENCRYPTION_CERTIFICATE);
  373. AddUserList = (PENCRYPTION_CERTIFICATE_LIST) new BYTE[BytesToAllocate];
  374. if ( NULL == AddUserList ){
  375. //
  376. // Out of memory. Try our best to display the error message.
  377. //
  378. try {
  379. CString ErrMsg;
  380. if (ErrMsg.LoadString(IDS_ERRORMEM)){
  381. ::MessageBox(NULL, ErrMsg, NULL, MB_OK);
  382. }
  383. }
  384. catch (...) {
  385. }
  386. return ERROR_NOT_ENOUGH_MEMORY;
  387. }
  388. AddUserList->nUsers = NoUsersToAdd;
  389. AddUserList->pUsers = (PENCRYPTION_CERTIFICATE *)(((PBYTE) AddUserList) +
  390. sizeof ( ENCRYPTION_CERTIFICATE_LIST ));
  391. }
  392. if ( NoUsersToRemove ){
  393. //
  394. // At least one user is to be removed
  395. //
  396. DWORD BytesToAllocate;
  397. BytesToAllocate = sizeof ( ENCRYPTION_CERTIFICATE_HASH_LIST ) +
  398. NoUsersToRemove * sizeof ( PENCRYPTION_CERTIFICATE_HASH) +
  399. NoUsersToRemove * sizeof (ENCRYPTION_CERTIFICATE_HASH);
  400. RemoveUserList = (PENCRYPTION_CERTIFICATE_HASH_LIST) new BYTE[BytesToAllocate];
  401. if ( NULL == RemoveUserList ){
  402. //
  403. // Out of memory. Try our best to display the error message.
  404. //
  405. if (AddUserList){
  406. delete [] AddUserList;
  407. AddUserList = NULL;
  408. }
  409. try {
  410. CString ErrMsg;
  411. if (ErrMsg.LoadString(IDS_ERRORMEM)){
  412. ::MessageBox(NULL, ErrMsg, NULL, MB_OK);
  413. }
  414. }
  415. catch (...) {
  416. }
  417. return ERROR_NOT_ENOUGH_MEMORY;
  418. }
  419. RemoveUserList->nCert_Hash = NoUsersToRemove;
  420. RemoveUserList->pUsers = (PENCRYPTION_CERTIFICATE_HASH *)(((PBYTE) RemoveUserList) +
  421. sizeof ( ENCRYPTION_CERTIFICATE_HASH_LIST ));
  422. }
  423. EnumHandle = m_Users.StartEnum();
  424. RemoveUserIndex = 0;
  425. AddUserIndex = 0;
  426. while ( EnumHandle ){
  427. DWORD Flag;
  428. PSID UserSid;
  429. PVOID CertData;
  430. LPTSTR UserName;
  431. EnumHandle = m_Users.GetNextChangedUser(
  432. EnumHandle,
  433. &UserName,
  434. &UserSid,
  435. &CertData,
  436. &Flag
  437. );
  438. if ( Flag ){
  439. //
  440. // We get our changed user
  441. //
  442. if ( Flag & USERADDED ){
  443. ASSERT( AddUserList );
  444. //
  445. // Add the user to the adding list
  446. //
  447. PENCRYPTION_CERTIFICATE EfsCert;
  448. ASSERT (AddUserIndex < NoUsersToAdd);
  449. EfsCert= (PENCRYPTION_CERTIFICATE)(((PBYTE) AddUserList) +
  450. sizeof ( ENCRYPTION_CERTIFICATE_LIST ) +
  451. NoUsersToAdd * sizeof ( PENCRYPTION_CERTIFICATE) +
  452. AddUserIndex * sizeof (ENCRYPTION_CERTIFICATE));
  453. AddUserList->pUsers[AddUserIndex] = EfsCert;
  454. EfsCert->pUserSid = (SID *) UserSid;
  455. EfsCert->cbTotalLength = sizeof (ENCRYPTION_CERTIFICATE);
  456. EfsCert->pCertBlob = (PEFS_CERTIFICATE_BLOB) CertData;
  457. AddUserIndex++;
  458. } else if ( Flag & USERREMOVED ) {
  459. ASSERT (RemoveUserList);
  460. //
  461. // Add the user to the removing list
  462. //
  463. PENCRYPTION_CERTIFICATE_HASH EfsCertHash;
  464. ASSERT (RemoveUserIndex < NoUsersToRemove);
  465. EfsCertHash= (PENCRYPTION_CERTIFICATE_HASH)(((PBYTE) RemoveUserList) +
  466. sizeof ( ENCRYPTION_CERTIFICATE_HASH_LIST ) +
  467. NoUsersToRemove * sizeof ( PENCRYPTION_CERTIFICATE_HASH) +
  468. RemoveUserIndex * sizeof (ENCRYPTION_CERTIFICATE_HASH));
  469. RemoveUserList->pUsers[RemoveUserIndex] = EfsCertHash;
  470. EfsCertHash->cbTotalLength = sizeof (ENCRYPTION_CERTIFICATE_HASH);
  471. EfsCertHash->pUserSid = (SID *)UserSid;
  472. EfsCertHash->pHash = (PEFS_HASH_BLOB) CertData;
  473. EfsCertHash->lpDisplayInformation = NULL;
  474. RemoveUserIndex++;
  475. } else {
  476. ASSERT(FALSE);
  477. }
  478. }
  479. }
  480. ASSERT(RemoveUserIndex == NoUsersToRemove);
  481. ASSERT(AddUserIndex == NoUsersToAdd);
  482. if ( AddUserIndex && AddUserList ){
  483. //
  484. // Add the user to the file list
  485. //
  486. RetCode = AddUsersToEncryptedFile(FileName, AddUserList);
  487. if ( NO_ERROR != RetCode ){
  488. CString ErrMsg;
  489. TCHAR ErrCode[16];
  490. _ltot(RetCode, ErrCode, 10 );
  491. AfxFormatString1( ErrMsg, IDS_ADDUSERERR, ErrCode );
  492. MessageBox(ErrMsg);
  493. }
  494. }
  495. if ( RemoveUserIndex && RemoveUserList){
  496. //
  497. // Remove the user from the list
  498. //
  499. DWORD RetCodeBak = RetCode;
  500. RetCode = RemoveUsersFromEncryptedFile(FileName, RemoveUserList);
  501. if ( NO_ERROR != RetCode ){
  502. CString ErrMsg;
  503. TCHAR ErrCode[16];
  504. _ltot(RetCode, ErrCode, 10 );
  505. AfxFormatString1( ErrMsg, IDS_REMOVEUSERERR, ErrCode );
  506. MessageBox(ErrMsg);
  507. } else {
  508. //
  509. // Reflect the error happened
  510. //
  511. RetCode = RetCodeBak;
  512. }
  513. }
  514. if (AddUserList){
  515. delete [] AddUserList;
  516. }
  517. if (RemoveUserList){
  518. delete [] RemoveUserList;
  519. }
  520. return RetCode;
  521. }
  522. DWORD
  523. USERLIST::AddNewUsers(CUsers &NewUser)
  524. {
  525. DWORD RetCode = ERROR_SUCCESS;
  526. m_UserListCtrl.DeleteAllItems( );
  527. RetCode = m_Users.Add(NewUser);
  528. SetUpListBox(NULL);
  529. return RetCode;
  530. }
  531. void USERLIST::SetUpListBox(BOOL *EnableAdd)
  532. {
  533. PVOID EnumHandle;
  534. try{
  535. CString NoCertName;
  536. NoCertName.LoadString(IDS_NOCERTNAME);
  537. if (EnumHandle = m_Users.StartEnum()){
  538. LV_ITEM fillItem;
  539. fillItem.mask = LVIF_TEXT;
  540. //
  541. // At least one user is available
  542. //
  543. while ( EnumHandle ){
  544. CString CertName;
  545. CString CertHash;
  546. fillItem.iItem = 0;
  547. fillItem.iSubItem = 0;
  548. EnumHandle = m_Users.GetNextUser(EnumHandle, CertName, CertHash);
  549. if (!EnumHandle && CertName.IsEmpty() && CertHash.IsEmpty()) {
  550. //
  551. // No more items.
  552. //
  553. break;
  554. }
  555. if (CertName.IsEmpty()){
  556. fillItem.pszText = NoCertName.GetBuffer(NoCertName.GetLength() + 1);
  557. } else {
  558. fillItem.pszText = CertName.GetBuffer(CertName.GetLength() + 1);
  559. }
  560. //
  561. // Add the user to the list
  562. //
  563. fillItem.iItem = m_UserListCtrl.InsertItem(&fillItem);
  564. if (CertName.IsEmpty()){
  565. NoCertName.ReleaseBuffer();
  566. } else {
  567. CertName.ReleaseBuffer();
  568. }
  569. if ( fillItem.iItem != -1 ){
  570. if ( EnableAdd ){
  571. *EnableAdd = TRUE;
  572. }
  573. if (CertHash.IsEmpty()){
  574. fillItem.pszText = NULL;
  575. } else {
  576. fillItem.pszText = CertHash.GetBuffer(CertHash.GetLength() + 1);
  577. }
  578. fillItem.iSubItem = 1;
  579. m_UserListCtrl.SetItem(&fillItem);
  580. if (!CertHash.IsEmpty()){
  581. CertHash.ReleaseBuffer();
  582. }
  583. }
  584. }
  585. }
  586. if (EnableAdd){
  587. //
  588. // From the dialog init. Do the Rec list as well
  589. //
  590. if (EnumHandle = m_Recs.StartEnum()){
  591. LV_ITEM fillItem;
  592. fillItem.mask = LVIF_TEXT;
  593. //
  594. // At least one user is available
  595. //
  596. while ( EnumHandle ){
  597. CString CertName;
  598. CString CertHash;
  599. fillItem.iItem = 0;
  600. fillItem.iSubItem = 0;
  601. EnumHandle = m_Recs.GetNextUser(EnumHandle, CertName, CertHash);
  602. if (!EnumHandle && CertName.IsEmpty() && CertHash.IsEmpty()) {
  603. //
  604. // No more items.
  605. //
  606. break;
  607. }
  608. //
  609. // Add the agent to the list
  610. //
  611. if (CertName.IsEmpty()){
  612. fillItem.pszText = NoCertName.GetBuffer(NoCertName.GetLength() + 1);
  613. } else {
  614. fillItem.pszText = CertName.GetBuffer(CertName.GetLength() + 1);
  615. }
  616. fillItem.iItem = m_RecoveryListCtrl.InsertItem(&fillItem);
  617. if (CertName.IsEmpty()){
  618. NoCertName.ReleaseBuffer();
  619. } else {
  620. CertName.ReleaseBuffer();
  621. }
  622. if ( fillItem.iItem != -1 ){
  623. if (CertHash.IsEmpty()){
  624. fillItem.pszText = NULL;
  625. } else {
  626. fillItem.pszText = CertHash.GetBuffer(CertHash.GetLength() + 1);
  627. }
  628. fillItem.iSubItem = 1;
  629. m_RecoveryListCtrl.SetItem(&fillItem);
  630. if (!CertHash.IsEmpty()){
  631. CertHash.ReleaseBuffer();
  632. }
  633. }
  634. }
  635. }
  636. }
  637. }
  638. catch(...){
  639. m_UserListCtrl.DeleteAllItems( );
  640. m_RecoveryListCtrl.DeleteAllItems( );
  641. if ( EnableAdd ){
  642. *EnableAdd = FALSE;
  643. }
  644. }
  645. }
  646. DWORD
  647. USERLIST::GetCertNameFromCertContext(
  648. PCCERT_CONTEXT CertContext,
  649. LPTSTR * UserDispName
  650. )
  651. //////////////////////////////////////////////////////////////////////
  652. // Routine Description:
  653. // Get the user name from the certificate
  654. // Arguments:
  655. // CertContext -- Cert Context
  656. // UserCertName -- User Common Name
  657. // ( Caller is responsible to delete this memory using delete [] )
  658. // Return Value:
  659. // ERROR_SUCCESS if succeed.
  660. // If No Name found. "USER_UNKNOWN is returned".
  661. //
  662. //////////////////////////////////////////////////////////////////////
  663. {
  664. DWORD NameLength;
  665. DWORD UserNameBufLen = 0;
  666. DWORD BlobLen = 0;
  667. PCERT_EXTENSION AlterNameExt = NULL;
  668. BOOL b;
  669. LPTSTR DNSName = NULL;
  670. LPTSTR UPNName = NULL;
  671. LPTSTR CommonName = NULL;
  672. if ( NULL == UserDispName ){
  673. return ERROR_SUCCESS;
  674. }
  675. *UserDispName = NULL;
  676. AlterNameExt = CertFindExtension(
  677. szOID_SUBJECT_ALT_NAME2,
  678. CertContext->pCertInfo->cExtension,
  679. CertContext->pCertInfo->rgExtension
  680. );
  681. if (AlterNameExt){
  682. //
  683. // Find the alternative name
  684. //
  685. b = CryptDecodeObject(
  686. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  687. szOID_SUBJECT_ALT_NAME ,
  688. AlterNameExt->Value.pbData,
  689. AlterNameExt->Value.cbData,
  690. 0,
  691. NULL,
  692. &BlobLen
  693. );
  694. if (b){
  695. //
  696. // Let's decode it
  697. //
  698. CERT_ALT_NAME_INFO *AltNameInfo = NULL;
  699. AltNameInfo = (CERT_ALT_NAME_INFO *) new BYTE[BlobLen];
  700. if (AltNameInfo){
  701. b = CryptDecodeObject(
  702. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  703. szOID_SUBJECT_ALT_NAME,
  704. AlterNameExt->Value.pbData,
  705. AlterNameExt->Value.cbData,
  706. 0,
  707. AltNameInfo,
  708. &BlobLen
  709. );
  710. if (b){
  711. //
  712. // Now search for the UPN, SPN, DNS, EFS name
  713. //
  714. DWORD cAltEntry = AltNameInfo->cAltEntry;
  715. DWORD ii = 0;
  716. while (ii < cAltEntry){
  717. if ((AltNameInfo->rgAltEntry[ii].dwAltNameChoice == CERT_ALT_NAME_OTHER_NAME ) &&
  718. !strcmp(szOID_NT_PRINCIPAL_NAME, AltNameInfo->rgAltEntry[ii].pOtherName->pszObjId)
  719. ){
  720. //
  721. // We found the UPN name
  722. //
  723. CERT_NAME_VALUE* CertUPNName = NULL;
  724. b = CryptDecodeObject(
  725. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  726. X509_UNICODE_ANY_STRING,
  727. AltNameInfo->rgAltEntry[ii].pOtherName->Value.pbData,
  728. AltNameInfo->rgAltEntry[ii].pOtherName->Value.cbData,
  729. 0,
  730. NULL,
  731. &BlobLen
  732. );
  733. if (b){
  734. CertUPNName = (CERT_NAME_VALUE *) new BYTE[BlobLen];
  735. if (CertUPNName){
  736. b = CryptDecodeObject(
  737. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  738. X509_UNICODE_ANY_STRING,
  739. AltNameInfo->rgAltEntry[ii].pOtherName->Value.pbData,
  740. AltNameInfo->rgAltEntry[ii].pOtherName->Value.cbData,
  741. 0,
  742. CertUPNName,
  743. &BlobLen
  744. );
  745. if (b){
  746. UPNName = (LPTSTR)new BYTE[CertUPNName->Value.cbData + sizeof(WCHAR)];
  747. if (UPNName){
  748. wcscpy(UPNName, (LPCTSTR) CertUPNName->Value.pbData);
  749. }
  750. }
  751. delete [] CertUPNName;
  752. if (UPNName){
  753. //
  754. // Got the UPN name. Stop searching.
  755. //
  756. break;
  757. }
  758. }
  759. }
  760. } else {
  761. //
  762. // Check for other alternative name
  763. //
  764. if (AltNameInfo->rgAltEntry[ii].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME){
  765. DNSName = AltNameInfo->rgAltEntry[ii].pwszDNSName;
  766. }
  767. }
  768. ii++;
  769. }
  770. if ( NULL == UPNName ){
  771. //
  772. // No UPN name, let's get the other option
  773. //
  774. if (DNSName){
  775. UPNName = (LPTSTR)new TCHAR[wcslen( DNSName ) + 1];
  776. if (UPNName){
  777. wcscpy(UPNName, DNSName);
  778. }
  779. }
  780. }
  781. }
  782. delete [] AltNameInfo;
  783. }
  784. }
  785. }
  786. NameLength = CertGetNameString(
  787. CertContext,
  788. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  789. 0,
  790. NULL,
  791. NULL,
  792. 0
  793. );
  794. if ( NameLength > 1){
  795. //
  796. // The display name exist. Go get the display name.
  797. //
  798. CommonName = new TCHAR[NameLength];
  799. if ( NULL == CommonName ){
  800. if (UPNName){
  801. delete [] UPNName;
  802. }
  803. return ERROR_NOT_ENOUGH_MEMORY;
  804. }
  805. UserNameBufLen = NameLength;
  806. NameLength = CertGetNameString(
  807. CertContext,
  808. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  809. 0,
  810. NULL,
  811. CommonName,
  812. UserNameBufLen
  813. );
  814. ASSERT (NameLength == UserNameBufLen);
  815. }
  816. if (CommonName || UPNName){
  817. NameLength = 3;
  818. if (CommonName){
  819. NameLength += wcslen(CommonName);
  820. }
  821. if (UPNName){
  822. NameLength += wcslen(UPNName);
  823. }
  824. *UserDispName = new TCHAR[NameLength];
  825. if (CommonName){
  826. wcscpy(*UserDispName, CommonName);
  827. if (UPNName){
  828. wcscat(*UserDispName, L"(");
  829. wcscat(*UserDispName, UPNName);
  830. wcscat(*UserDispName, L")");
  831. }
  832. } else {
  833. wcscpy(*UserDispName, UPNName);
  834. }
  835. if (CommonName){
  836. delete [] CommonName;
  837. }
  838. if (UPNName){
  839. delete [] UPNName;
  840. }
  841. return ERROR_SUCCESS;
  842. }
  843. try {
  844. CString UnknownCertName;
  845. UnknownCertName.LoadString(IDS_NOCERTNAME);
  846. UserNameBufLen = UnknownCertName.GetLength();
  847. *UserDispName = new TCHAR[UserNameBufLen + 1];
  848. _tcscpy( *UserDispName, UnknownCertName);
  849. }
  850. catch (...){
  851. return ERROR_NOT_ENOUGH_MEMORY;
  852. }
  853. return ERROR_SUCCESS;
  854. }
  855. void USERLIST::OnAdd()
  856. {
  857. CRYPTUI_SELECTCERTIFICATE_STRUCTW cryptUI;
  858. HCERTSTORE otherStore;
  859. HCERTSTORE trustedStore;
  860. HCERTSTORE memStore;
  861. HCERTSTORE localStore[2];
  862. PCCERT_CONTEXT selectedCert;
  863. CString DlgTitle;
  864. CString DispText;
  865. LPTSTR UserDispName;
  866. HRESULT hr;
  867. DWORD rc;
  868. DWORD StoreNum = 0;
  869. DWORD StoreIndex = 0xffffffff;
  870. BOOL EfsEkuExist = FALSE;
  871. DWORD ii;
  872. BOOL ContinueProcess = TRUE;
  873. otherStore = CertOpenStore(
  874. CERT_STORE_PROV_SYSTEM_W,
  875. 0, // dwEncodingType
  876. 0, // hCryptProv,
  877. CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_MAXIMUM_ALLOWED_FLAG,
  878. OTHERPEOPLE
  879. );
  880. trustedStore = CertOpenStore(
  881. CERT_STORE_PROV_SYSTEM_W,
  882. 0, // dwEncodingType
  883. 0, // hCryptProv,
  884. CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_MAXIMUM_ALLOWED_FLAG,
  885. TRUSTEDPEOPLE
  886. );
  887. if (otherStore) {
  888. localStore[0] = otherStore;
  889. StoreNum++;
  890. }
  891. if (trustedStore) {
  892. localStore[StoreNum] = trustedStore;
  893. StoreNum++;
  894. }
  895. memStore = CertOpenStore(
  896. CERT_STORE_PROV_MEMORY,
  897. 0,
  898. 0,
  899. CERT_STORE_MAXIMUM_ALLOWED_FLAG,
  900. NULL
  901. );
  902. if (!memStore) {
  903. CString ErrMsg;
  904. TCHAR ErrCode[16];
  905. _ltot(GetLastError(), ErrCode, 10 );
  906. AfxFormatString1( ErrMsg, IDS_INTERNALERROR, ErrCode );
  907. MessageBox(ErrMsg);
  908. if (otherStore) {
  909. CertCloseStore( otherStore, 0 );
  910. }
  911. if (trustedStore) {
  912. CertCloseStore( trustedStore, 0 );
  913. }
  914. return;
  915. }
  916. //
  917. // Let's put it into a memory store to eliminate the redundancy
  918. //
  919. ii = 0;
  920. while ( (ii < StoreNum) && ContinueProcess ) {
  921. PCCERT_CONTEXT pCertContext = NULL;
  922. while (pCertContext = CertEnumCertificatesInStore(
  923. localStore[ii],
  924. pCertContext
  925. )) {
  926. if (!CertAddCertificateLinkToStore(
  927. memStore,
  928. pCertContext,
  929. CERT_STORE_ADD_USE_EXISTING,
  930. NULL
  931. )){
  932. CString ErrMsg;
  933. TCHAR ErrCode[16];
  934. _ltot(GetLastError(), ErrCode, 10 );
  935. AfxFormatString1( ErrMsg, IDS_INTERNALERROR, ErrCode );
  936. MessageBox(ErrMsg);
  937. ContinueProcess = FALSE;
  938. break;
  939. }
  940. }
  941. ii++;
  942. }
  943. if (!ContinueProcess) {
  944. if (otherStore) {
  945. CertCloseStore( otherStore, 0 );
  946. }
  947. if (trustedStore) {
  948. CertCloseStore( trustedStore, 0 );
  949. }
  950. CertCloseStore( memStore, 0 );
  951. return;
  952. }
  953. if (StoreNum != 0) {
  954. RtlZeroMemory(&cryptUI, sizeof (CRYPTUI_SELECTCERTIFICATE_STRUCTW));
  955. cryptUI.dwSize = sizeof (CRYPTUI_SELECTCERTIFICATE_STRUCTW);
  956. cryptUI.dwFlags = CRYPTUI_SELECTCERT_ADDFROMDS;
  957. cryptUI.cDisplayStores = 1;
  958. cryptUI.rghDisplayStores = &memStore;
  959. cryptUI.pFilterCallback = EfsFilter;
  960. cryptUI.dwDontUseColumn = CRYPTUI_SELECT_LOCATION_COLUMN | CRYPTUI_SELECT_ISSUEDBY_COLUMN | CRYPTUI_SELECT_INTENDEDUSE_COLUMN;
  961. if (DlgTitle.LoadString(IDS_DLGTITLE)){
  962. cryptUI.szTitle = (LPCWSTR) DlgTitle.GetBuffer(DlgTitle.GetLength() + 1);
  963. }
  964. if (DispText.LoadString(IDS_DISPTEXT)){
  965. cryptUI.szDisplayString = (LPCWSTR) DispText.GetBuffer(DispText.GetLength() + 1);
  966. }
  967. selectedCert = CryptUIDlgSelectCertificateW(&cryptUI);
  968. if ( selectedCert ){
  969. PCCERT_CHAIN_CONTEXT pChainContext;
  970. //
  971. // Let's first see if the cert is from DS, if Yes, add the EFS EKU first if no EKU.
  972. //
  973. StoreIndex = CertInStore(localStore, StoreNum, selectedCert);
  974. if (StoreIndex >= StoreNum){
  975. //
  976. // The cert is not in the local stores. Let's see if we need add the EKU or not.
  977. //
  978. EfsEkuExist = EfsFilter(selectedCert, NULL, NULL);
  979. if (!EfsEkuExist) {
  980. //
  981. // Let's add the EFS EKU
  982. //
  983. CTL_USAGE EfsEkuUsage;
  984. DWORD cbEncoded;
  985. void *pbEncoded;
  986. CRYPT_DATA_BLOB EfsEkuBlob;
  987. EfsEkuUsage.cUsageIdentifier = 1; // Only adding EFS EKU
  988. EfsEkuUsage.rgpszUsageIdentifier = &EfsOidlpstr;
  989. if(!CryptEncodeObjectEx(
  990. X509_ASN_ENCODING,
  991. szOID_ENHANCED_KEY_USAGE,
  992. &EfsEkuUsage,
  993. CRYPT_ENCODE_ALLOC_FLAG,
  994. NULL, // Use LocalFree
  995. &pbEncoded,
  996. &cbEncoded
  997. )){
  998. //
  999. // Failed to encode the EFS EKU
  1000. //
  1001. CString ErrMsg;
  1002. TCHAR ErrCode[16];
  1003. ContinueProcess = FALSE;
  1004. _ltot(GetLastError(), ErrCode, 10 );
  1005. AfxFormatString1( ErrMsg, IDS_ADDEFSEKUFAIL, ErrCode );
  1006. MessageBox(ErrMsg);
  1007. } else {
  1008. //
  1009. // Now let's add the EKU to the cert
  1010. //
  1011. EfsEkuBlob.cbData=cbEncoded;
  1012. EfsEkuBlob.pbData=(BYTE *)pbEncoded;
  1013. if(!CertSetCertificateContextProperty(
  1014. selectedCert,
  1015. CERT_ENHKEY_USAGE_PROP_ID,
  1016. 0,
  1017. &EfsEkuBlob)){
  1018. //
  1019. // Failed to add the EFS EKU
  1020. //
  1021. CString ErrMsg;
  1022. TCHAR ErrCode[16];
  1023. ContinueProcess = FALSE;
  1024. _ltot(GetLastError(), ErrCode, 10 );
  1025. AfxFormatString1( ErrMsg, IDS_ADDEFSEKUFAIL, ErrCode );
  1026. MessageBox(ErrMsg);
  1027. }
  1028. }
  1029. }
  1030. }
  1031. //
  1032. // Let's validate the cert first
  1033. //
  1034. if (ContinueProcess && CertGetCertificateChain (
  1035. HCCE_CURRENT_USER,
  1036. selectedCert,
  1037. NULL,
  1038. NULL,
  1039. &m_CertChainPara,
  1040. CERT_CHAIN_REVOCATION_CHECK_CHAIN,
  1041. NULL,
  1042. &pChainContext
  1043. )) {
  1044. PCERT_SIMPLE_CHAIN pChain = pChainContext->rgpChain[ pChainContext->cChain - 1 ];
  1045. PCERT_CHAIN_ELEMENT pElement = pChain->rgpElement[ pChain->cElement - 1 ];
  1046. BOOL bSelfSigned = pElement->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED;
  1047. BOOL ContinueAdd = TRUE;
  1048. DWORD dwErrorStatus = pChainContext->TrustStatus.dwErrorStatus;
  1049. if (0 == (dwErrorStatus & ~CERT_TRUST_REVOCATION_STATUS_UNKNOWN)) {
  1050. //
  1051. // The validation succeed. If the cert is from the DS (not in the store we opened), we will put it
  1052. // in the my Other People's store
  1053. //
  1054. if (StoreIndex >= StoreNum) {
  1055. //
  1056. // The cert is not in our local stores. Add it to the other people
  1057. //
  1058. if (otherStore) {
  1059. if(!CertAddCertificateContextToStore(
  1060. otherStore,
  1061. selectedCert,
  1062. CERT_STORE_ADD_NEW,
  1063. NULL) ) {
  1064. //
  1065. // The error code is only for debug.
  1066. // If we failed to add the cert to other People store,
  1067. // it is fine to continue
  1068. //
  1069. rc = GetLastError();
  1070. }
  1071. }
  1072. }
  1073. } else {
  1074. //
  1075. // The cert validation failed, as the user if we will accept the cert. If yes, the cert
  1076. // will be added to my TrustedPeople.
  1077. //
  1078. if (((dwErrorStatus & ~CERT_TRUST_REVOCATION_STATUS_UNKNOWN) == CERT_TRUST_IS_UNTRUSTED_ROOT) && bSelfSigned) {
  1079. //
  1080. // A self signed cert. Ask the user if he would like to accept.
  1081. // If it is already in the trusted store, we can skip the pop up.
  1082. //
  1083. DWORD StoreIndex;
  1084. if (trustedStore) {
  1085. StoreIndex = CertInStore(&trustedStore, 1, selectedCert);
  1086. }
  1087. if (StoreIndex >= 1) {
  1088. CString ErrMsg;
  1089. TCHAR ErrCode[16];
  1090. int buttonID;
  1091. _ltot(GetLastError(), ErrCode, 10 );
  1092. AfxFormatString1( ErrMsg, IDS_ACCEPTSELFCERT, ErrCode );
  1093. buttonID = MessageBox(ErrMsg, NULL, MB_ICONQUESTION | MB_YESNO);
  1094. if (IDYES == buttonID) {
  1095. //
  1096. // User Accepted the cert.
  1097. //
  1098. if (trustedStore) {
  1099. if(!CertAddCertificateContextToStore(
  1100. trustedStore,
  1101. selectedCert,
  1102. CERT_STORE_ADD_NEW,
  1103. NULL) ) {
  1104. //
  1105. // The error code is only for debug.
  1106. // If we failed to add the cert to other People store,
  1107. // it is fine to continue
  1108. //
  1109. rc = GetLastError();
  1110. }
  1111. }
  1112. } else {
  1113. //
  1114. // User declined the cert.
  1115. //
  1116. ContinueAdd = FALSE;
  1117. }
  1118. }
  1119. } else {
  1120. //
  1121. // Let's get the error code of the chain building.
  1122. //
  1123. CERT_CHAIN_POLICY_PARA PolicyPara;
  1124. CERT_CHAIN_POLICY_STATUS PolicyStatus;
  1125. ContinueAdd = FALSE;
  1126. RtlZeroMemory(&PolicyPara, sizeof(CERT_CHAIN_POLICY_PARA));
  1127. RtlZeroMemory(&PolicyStatus, sizeof(CERT_CHAIN_POLICY_STATUS));
  1128. PolicyPara.cbSize = sizeof(CERT_CHAIN_POLICY_PARA);
  1129. PolicyStatus.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS);
  1130. if (CertVerifyCertificateChainPolicy(
  1131. CERT_CHAIN_POLICY_BASE,
  1132. pChainContext,
  1133. &PolicyPara,
  1134. &PolicyStatus
  1135. ) && PolicyStatus.dwError ) {
  1136. //
  1137. // Display the error to the user.
  1138. //
  1139. DWORD len;
  1140. LPWSTR DisplayBuffer;
  1141. len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  1142. NULL, PolicyStatus.dwError, 0,
  1143. (LPWSTR)&DisplayBuffer, 0, NULL);
  1144. if (len && DisplayBuffer) {
  1145. MessageBox(DisplayBuffer);
  1146. LocalFree(DisplayBuffer);
  1147. }
  1148. }
  1149. }
  1150. }
  1151. CertFreeCertificateChain( pChainContext );
  1152. if (ContinueAdd) {
  1153. hr = GetCertNameFromCertContext(selectedCert, &UserDispName);
  1154. if ( ERROR_SUCCESS == hr ){
  1155. EFS_CERTIFICATE_BLOB CertBlob;
  1156. CertBlob.cbData = selectedCert->cbCertEncoded;
  1157. CertBlob.pbData = selectedCert->pbCertEncoded;
  1158. CertBlob.dwCertEncodingType = selectedCert->dwCertEncodingType;
  1159. hr = m_Users.Add(
  1160. UserDispName,
  1161. (PVOID)&CertBlob,
  1162. NULL,
  1163. USERADDED,
  1164. (PVOID)selectedCert
  1165. );
  1166. if ( (ERROR_SUCCESS != hr) && (CRYPT_E_EXISTS != hr) ){
  1167. //
  1168. // Error in adding the user
  1169. //
  1170. CertFreeCertificateContext(selectedCert);
  1171. selectedCert = NULL;
  1172. } else {
  1173. //
  1174. // We could just insert the items here to improve the performace.
  1175. // But we don't have the time right now. We could fix this later
  1176. // if performance is a problem here.
  1177. //
  1178. m_UserListCtrl.DeleteAllItems( );
  1179. SetUpListBox(NULL);
  1180. if ( hr == ERROR_SUCCESS ){
  1181. //
  1182. // UserDispName is used in m_Users.Add
  1183. //
  1184. UserDispName = NULL;
  1185. }
  1186. /* This is the old code when we have the single list.
  1187. //
  1188. // Add the user to the list box.
  1189. //
  1190. if ( hr == ERROR_SUCCESS ){
  1191. if (m_UsersList.AddString(UserDispName) < 0){
  1192. //
  1193. // Error to add to the list box
  1194. //
  1195. m_Users.Remove(UserDispName);
  1196. }
  1197. UserDispName = NULL;
  1198. } else {
  1199. //
  1200. // Let's check if we need to add this to the list box.
  1201. //
  1202. if (m_UsersList.FindStringExact( 0, UserDispName ) < 0){
  1203. //
  1204. // Not found
  1205. //
  1206. if (m_UsersList.AddString(UserDispName) < 0){
  1207. //
  1208. // Error to add to the list box
  1209. //
  1210. m_Users.Remove(UserDispName);
  1211. }
  1212. }
  1213. }
  1214. */
  1215. }
  1216. if (UserDispName){
  1217. delete [] UserDispName;
  1218. }
  1219. } else {
  1220. CertFreeCertificateContext(selectedCert);
  1221. }
  1222. }
  1223. } else {
  1224. CString ErrMsg;
  1225. TCHAR ErrCode[16];
  1226. CertFreeCertificateContext(selectedCert);
  1227. if (ContinueProcess) {
  1228. //
  1229. // The error has not been processed.
  1230. //
  1231. _ltot(GetLastError(), ErrCode, 10 );
  1232. AfxFormatString1( ErrMsg, IDS_COULDNOTVERIFYCERT, ErrCode );
  1233. MessageBox(ErrMsg);
  1234. }
  1235. }
  1236. }
  1237. if (!DlgTitle.IsEmpty()){
  1238. DlgTitle.ReleaseBuffer();
  1239. }
  1240. if (!DispText.IsEmpty()){
  1241. DispText.ReleaseBuffer();
  1242. }
  1243. if (otherStore) {
  1244. CertCloseStore( otherStore, 0 );
  1245. }
  1246. if (trustedStore) {
  1247. CertCloseStore( trustedStore, 0 );
  1248. }
  1249. }
  1250. CertCloseStore( memStore, 0 );
  1251. return;
  1252. }
  1253. DWORD USERLIST::TryGetBetterNameInCert(PEFS_HASH_BLOB HashData, LPTSTR *UserName)
  1254. {
  1255. HCERTSTORE localStore;
  1256. PCCERT_CONTEXT pCertContext;
  1257. DWORD retCode;
  1258. //
  1259. // We will add the remote case later
  1260. //
  1261. localStore = CertOpenStore(
  1262. CERT_STORE_PROV_SYSTEM_W,
  1263. 0, // dwEncodingType
  1264. 0, // hCryptProv,
  1265. CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_MAXIMUM_ALLOWED_FLAG,
  1266. TRUSTEDPEOPLE
  1267. );
  1268. if (localStore != NULL) {
  1269. //
  1270. // Let's try to the cert in the store
  1271. //
  1272. pCertContext = CertFindCertificateInStore( localStore,
  1273. CRYPT_ASN_ENCODING,
  1274. 0,
  1275. CERT_FIND_HASH,
  1276. (CRYPT_HASH_BLOB *)HashData,
  1277. NULL
  1278. );
  1279. if ( pCertContext ){
  1280. retCode = GetCertNameFromCertContext(
  1281. pCertContext,
  1282. UserName
  1283. );
  1284. CertFreeCertificateContext(pCertContext);
  1285. }
  1286. else {
  1287. retCode = GetLastError();
  1288. }
  1289. CertCloseStore( localStore, 0 );
  1290. } else {
  1291. retCode = GetLastError();
  1292. }
  1293. return retCode;
  1294. }
  1295. DWORD USERLIST::CertInStore(HCERTSTORE *pStores, DWORD StoreNum, PCCERT_CONTEXT selectedCert)
  1296. {
  1297. DWORD ii = 0;
  1298. PCCERT_CONTEXT pCert = NULL;
  1299. while (ii < StoreNum) {
  1300. pCert = CertFindCertificateInStore(
  1301. pStores[ii],
  1302. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1303. 0,
  1304. CERT_FIND_EXISTING,
  1305. selectedCert,
  1306. pCert
  1307. );
  1308. if (pCert) {
  1309. //
  1310. // We found it.
  1311. //
  1312. CertFreeCertificateContext(pCert);
  1313. break;
  1314. }
  1315. ii++;
  1316. }
  1317. return ii;
  1318. }
  1319. void USERLIST::OnSetfocusListuser(NMHDR* pNMHDR, LRESULT* pResult)
  1320. {
  1321. int ItemPos;
  1322. ShowRemove();
  1323. ItemPos = m_UserListCtrl.GetNextItem( -1, LVNI_SELECTED );
  1324. if ( ItemPos == -1 ){
  1325. m_UserListCtrl.SetItem(0, 0, LVIF_STATE, NULL, 0, LVIS_SELECTED, LVIS_SELECTED, 0);
  1326. }
  1327. *pResult = 0;
  1328. }
  1329. void USERLIST::OnKillfocusListuser(NMHDR* pNMHDR, LRESULT* pResult)
  1330. {
  1331. ShowRemove();
  1332. *pResult = 0;
  1333. }
  1334. void USERLIST::OnItemchangedListuser(NMHDR* pNMHDR, LRESULT* pResult)
  1335. {
  1336. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  1337. ShowRemove();
  1338. *pResult = 0;
  1339. }