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.

1453 lines
40 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: misc.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include <stdafx.h>
  11. #include <float.h>
  12. #include "certsrv.h"
  13. #include "misc.h"
  14. #include "clibres.h"
  15. #include "setupids.h"
  16. #include "csresstr.h"
  17. #include <activeds.h>
  18. #include <dsgetdc.h>
  19. #include <lm.h>
  20. #include <common.ver>
  21. #include "urls.h"
  22. #include "csdisp.h"
  23. #define __dwFILE__ __dwFILE_CERTMMC_MISC_CPP__
  24. bool operator==(
  25. const struct _QUERY_RESTRICTION& lhs,
  26. const struct _QUERY_RESTRICTION& rhs)
  27. {
  28. return
  29. 0==_wcsicmp(lhs.szField, rhs.szField) &&
  30. lhs.iOperation==rhs.iOperation &&
  31. variant_t(&lhs.varValue)==variant_t(&rhs.varValue);
  32. }
  33. PQUERY_RESTRICTION QueryRestrictionFound(
  34. PQUERY_RESTRICTION pQR,
  35. PQUERY_RESTRICTION pQRListHead)
  36. {
  37. while(pQRListHead)
  38. {
  39. if(*pQR==*pQRListHead)
  40. return pQRListHead;
  41. pQRListHead = pQRListHead->pNext;
  42. }
  43. return NULL;
  44. }
  45. // returns (if cstr.IsEmpty()) ? NULL : cstr)
  46. LPCWSTR GetNullMachineName(CString* pcstr)
  47. {
  48. LPCWSTR szMachine = (pcstr->IsEmpty()) ? NULL : (LPCWSTR)*pcstr;
  49. return szMachine;
  50. }
  51. BOOL FIsCurrentMachine(LPCWSTR str)
  52. {
  53. BOOL fIsCurrentMachine = FALSE;
  54. LPWSTR szName1 = NULL, szName2 = NULL;
  55. DWORD dwErr;
  56. dwErr = myGetComputerNames(&szName1, &szName2);
  57. _JumpIfError(dwErr, error, "myGetComputerNames");
  58. if ((str != NULL) &&
  59. (wcslen(str) > 2) &&
  60. (str[0] == '\\') &&
  61. (str[1] == '\\') )
  62. str = &str[2]; // skip whackwhack
  63. // if machine specified as not current machine
  64. if ( (NULL == str) ||
  65. (str[0] == '\0') ||
  66. (0 == mylstrcmpiL(str, szName1)) ||
  67. (0 == mylstrcmpiL(str, szName2)) )
  68. fIsCurrentMachine = TRUE;
  69. error:
  70. if (szName1)
  71. LocalFree(szName1);
  72. if (szName2)
  73. LocalFree(szName2);
  74. return fIsCurrentMachine;
  75. }
  76. /////////////////////////////////////////
  77. // fxns to load/save cstrings to a streams
  78. STDMETHODIMP CStringLoad(CString& cstr, IStream *pStm)
  79. {
  80. ASSERT(pStm);
  81. HRESULT hr;
  82. DWORD cbSize=0;
  83. // get cbSize (bytes)
  84. hr = ReadOfSize(pStm, &cbSize, sizeof(cbSize));
  85. _JumpIfError(hr, Ret, "ReadOfSize cbSize");
  86. // get string
  87. hr = ReadOfSize(
  88. pStm,
  89. cstr.GetBuffer(cbSize/sizeof(WCHAR)-1), // less terminator, GetBuffer adds 1 for it
  90. cbSize);
  91. cstr.ReleaseBuffer(); // not clear why we do this...
  92. _JumpIfError(hr, Ret, "Read cstr.GetBuffer");
  93. if(!cstr.IsZeroTerminated())
  94. {
  95. hr = ERROR_FILE_CORRUPT;
  96. _JumpError(hr, Ret, "zero terminated string expected");
  97. }
  98. Ret:
  99. return hr;
  100. }
  101. STDMETHODIMP
  102. CStringSave(
  103. CString& cstr,
  104. IStream *pStm,
  105. BOOL /* fClearDirty */ )
  106. {
  107. ASSERT(pStm);
  108. HRESULT hr;
  109. // Write the string (null cstr will return 0 chars, output nullstr "")
  110. DWORD cbSize = (cstr.GetLength()+1)*sizeof(WCHAR);
  111. // write size in bytes
  112. hr = WriteOfSize(pStm, &cbSize, sizeof(cbSize));
  113. _JumpIfError(hr, error, "WriteOfSize cbSize");
  114. // write string (null cstr will return 0 chars, output nullstr "")
  115. hr = WriteOfSize(pStm, (LPWSTR)(LPCWSTR)cstr, cbSize);
  116. _JumpIfError(hr, error, "Write cstr");
  117. error:
  118. return hr;
  119. }
  120. STDMETHODIMP CStringGetSizeMax(CString& cstr, int* piSize)
  121. {
  122. *piSize = sizeof(DWORD);
  123. *piSize += (cstr.GetLength()+1)* sizeof(WCHAR);
  124. return S_OK;
  125. }
  126. STDMETHODIMP VariantLoad(VARIANT& var, IStream *pStm)
  127. {
  128. HRESULT hr;
  129. VARIANT varTmp;
  130. DWORD dwSize;
  131. VariantInit(&varTmp);
  132. VariantInit(&var);
  133. // get target variant type
  134. hr = ReadOfSize(pStm, &var.vt, sizeof(var.vt));
  135. _JumpIfError(hr, error, "Read type");
  136. // get cb
  137. hr = ReadOfSize(pStm, &dwSize, sizeof(DWORD));
  138. _JumpIfError(hr, error, "Read cb");
  139. varTmp.vt = VT_BSTR;
  140. varTmp.bstrVal = SysAllocStringByteLen(NULL, dwSize);
  141. _JumpIfOutOfMemory(hr, error, varTmp.bstrVal);
  142. // get pb
  143. hr = ReadOfSize(pStm, varTmp.bstrVal, dwSize);
  144. _JumpIfError(hr, error, "Read pb");
  145. // change type to target type var.vt
  146. hr = VariantChangeType(&var, &varTmp, 0, var.vt);
  147. _JumpIfError(hr, error, "VariantChangeType");
  148. error:
  149. VariantClear(&varTmp);
  150. return hr;
  151. }
  152. STDMETHODIMP
  153. VariantSave(
  154. VARIANT& var,
  155. IStream *pStm,
  156. BOOL /* fClearDirty */ )
  157. {
  158. HRESULT hr;
  159. DWORD dwSize;
  160. VARIANT varTmp;
  161. VariantInit(&varTmp);
  162. // write variant type
  163. hr = WriteOfSize(pStm, &var.vt, sizeof(var.vt));
  164. _JumpIfError(hr, error, "Write type");
  165. // convert to bstr
  166. hr = VariantChangeType(&varTmp, &var, 0, VT_BSTR);
  167. _JumpIfError(hr, error, "VariantChangeType");
  168. // write cb
  169. dwSize = SysStringByteLen(varTmp.bstrVal);
  170. hr = WriteOfSize(pStm, &dwSize, sizeof(DWORD));
  171. _JumpIfError(hr, error, "Write cb");
  172. // write pb
  173. hr = WriteOfSize(pStm, varTmp.bstrVal, dwSize);
  174. _JumpIfError(hr, error, "Write pb");
  175. error:
  176. VariantClear(&varTmp);
  177. return hr;
  178. }
  179. STDMETHODIMP VariantGetSizeMax(VARIANT& var, int* piSize)
  180. {
  181. HRESULT hr;
  182. VARIANT varTmp;
  183. VariantInit(&varTmp);
  184. // write var type, cb
  185. *piSize = sizeof(var.vt) + sizeof(DWORD);
  186. // write pb len: convert to bstr
  187. hr = VariantChangeType(&varTmp, &var, 0, VT_BSTR);
  188. _JumpIfError(hr, error, "VariantChangeType");
  189. *piSize += SysStringByteLen(varTmp.bstrVal);
  190. error:
  191. VariantClear(&varTmp);
  192. return hr;
  193. }
  194. DWORD AllocAndReturnConfigValue(HKEY hKey, LPCWSTR szConfigEntry, PBYTE* ppbOut, DWORD* pcbOut, DWORD* pdwType)
  195. {
  196. DWORD dwRet;
  197. dwRet = RegQueryValueExW(
  198. hKey,
  199. szConfigEntry,
  200. NULL,
  201. pdwType,
  202. NULL,
  203. pcbOut);
  204. _JumpIfError(dwRet, Ret, "RegQueryValueExW");
  205. ASSERT(ppbOut != NULL);
  206. *ppbOut = new BYTE[*pcbOut];
  207. if (NULL == *ppbOut)
  208. {
  209. dwRet = (DWORD) E_OUTOFMEMORY;
  210. _JumpError(dwRet, Ret, "new");
  211. }
  212. dwRet = RegQueryValueExW(
  213. hKey,
  214. szConfigEntry,
  215. NULL,
  216. pdwType,
  217. *ppbOut,
  218. pcbOut);
  219. if (dwRet != ERROR_SUCCESS)
  220. {
  221. delete [] *ppbOut;
  222. *ppbOut = NULL;
  223. _JumpError(dwRet, Ret, "RegQueryValueExW");
  224. }
  225. Ret:
  226. return dwRet;
  227. }
  228. //////////////////////////////////////////////////////////////////
  229. // given an error code and a console pointer, will pop error dlg
  230. void DisplayCertSrvErrorWithContext(HWND hwnd, DWORD dwErr, UINT iRscContext)
  231. {
  232. CString cstrContext;
  233. cstrContext.LoadString(iRscContext);
  234. DisplayCertSrvErrorWithContext(hwnd, dwErr, (LPCWSTR)cstrContext);
  235. }
  236. void DisplayCertSrvErrorWithContext(HWND hwnd, DWORD dwErr, LPCWSTR szContext)
  237. {
  238. CString cstrTitle, cstrFullText;
  239. cstrTitle.LoadString(IDS_MSG_TITLE);
  240. cstrFullText = szContext;
  241. if (dwErr != ERROR_SUCCESS)
  242. {
  243. if (!cstrFullText.IsEmpty())
  244. cstrFullText += L"\n\n";
  245. WCHAR const *pwszError = myGetErrorMessageText(dwErr, TRUE);
  246. cstrFullText += pwszError;
  247. // Free the buffer
  248. if (NULL != pwszError)
  249. {
  250. LocalFree(const_cast<WCHAR *>(pwszError));
  251. }
  252. }
  253. ::MessageBoxW(hwnd, cstrFullText, cstrTitle,
  254. MB_OK|
  255. (S_OK!=dwErr?MB_ICONERROR:MB_ICONINFORMATION));
  256. }
  257. void DisplayGenericCertSrvError(HWND hwnd, DWORD dwErr)
  258. {
  259. DisplayCertSrvErrorWithContext(hwnd, dwErr, (UINT)0);
  260. }
  261. void DisplayGenericCertSrvError(LPCONSOLE pConsole, DWORD dwErr)
  262. {
  263. ASSERT(pConsole);
  264. WCHAR const *pwszError = myGetErrorMessageText(dwErr, TRUE);
  265. // ...
  266. // Display the string.
  267. CString cstrTitle;
  268. cstrTitle.LoadString(IDS_MSG_TITLE);
  269. pConsole->MessageBoxW(pwszError, cstrTitle, MB_OK, NULL);
  270. // Free the buffer.
  271. if (NULL != pwszError)
  272. {
  273. LocalFree(const_cast<WCHAR *>(pwszError));
  274. }
  275. }
  276. enum ENUM_PERIOD DurationEnumFromNonLocalizedString(LPCWSTR szPeriod)
  277. {
  278. if (0 == LSTRCMPIS(szPeriod, wszPERIODYEARS))
  279. return ENUM_PERIOD_YEARS;
  280. if (0 == LSTRCMPIS(szPeriod, wszPERIODMONTHS))
  281. return ENUM_PERIOD_MONTHS;
  282. if (0 == LSTRCMPIS(szPeriod, wszPERIODWEEKS))
  283. return ENUM_PERIOD_WEEKS;
  284. if (0 == LSTRCMPIS(szPeriod, wszPERIODDAYS))
  285. return ENUM_PERIOD_DAYS;
  286. if (0 == LSTRCMPIS(szPeriod, wszPERIODHOURS))
  287. return ENUM_PERIOD_HOURS;
  288. if (0 == LSTRCMPIS(szPeriod, wszPERIODMINUTES))
  289. return ENUM_PERIOD_MINUTES;
  290. if (0 == LSTRCMPIS(szPeriod, wszPERIODSECONDS))
  291. return ENUM_PERIOD_SECONDS;
  292. return ENUM_PERIOD_INVALID;
  293. }
  294. BOOL StringFromDurationEnum(int iEnum, CString* pcstr, BOOL fLocalized)
  295. {
  296. if (NULL == pcstr)
  297. return FALSE;
  298. switch (iEnum)
  299. {
  300. case(ENUM_PERIOD_YEARS):
  301. if (fLocalized)
  302. *pcstr = g_pResources->m_szPeriod_Years;
  303. else
  304. *pcstr = wszPERIODYEARS;
  305. break;
  306. case(ENUM_PERIOD_MONTHS):
  307. if (fLocalized)
  308. *pcstr = g_pResources->m_szPeriod_Months;
  309. else
  310. *pcstr = wszPERIODMONTHS;
  311. break;
  312. case(ENUM_PERIOD_WEEKS):
  313. if (fLocalized)
  314. *pcstr = g_pResources->m_szPeriod_Weeks;
  315. else
  316. *pcstr = wszPERIODWEEKS;
  317. break;
  318. case(ENUM_PERIOD_DAYS):
  319. if (fLocalized)
  320. *pcstr = g_pResources->m_szPeriod_Days;
  321. else
  322. *pcstr = wszPERIODDAYS;
  323. break;
  324. case(ENUM_PERIOD_HOURS):
  325. if (fLocalized)
  326. *pcstr = g_pResources->m_szPeriod_Hours;
  327. else
  328. *pcstr = wszPERIODHOURS;
  329. break;
  330. case(ENUM_PERIOD_MINUTES):
  331. if (fLocalized)
  332. *pcstr = g_pResources->m_szPeriod_Minutes;
  333. else
  334. *pcstr = wszPERIODMINUTES;
  335. break;
  336. case(ENUM_PERIOD_SECONDS):
  337. if (fLocalized)
  338. *pcstr = g_pResources->m_szPeriod_Seconds;
  339. else
  340. *pcstr = wszPERIODSECONDS;
  341. break;
  342. }
  343. if (! (pcstr->IsEmpty()) )
  344. return TRUE;
  345. return FALSE;
  346. }
  347. LPCWSTR OperationToStr(int iOperation)
  348. {
  349. switch(iOperation)
  350. {
  351. case CVR_SEEK_EQ:
  352. return L"=";
  353. case CVR_SEEK_LT:
  354. return L"<";
  355. case CVR_SEEK_LE:
  356. return L"<=";
  357. case CVR_SEEK_GE:
  358. return L">=";
  359. case CVR_SEEK_GT:
  360. return L">";
  361. }
  362. return NULL;
  363. }
  364. int StrToOperation(LPCWSTR szOperation)
  365. {
  366. if (0 == wcscmp(szOperation, L"="))
  367. return CVR_SEEK_EQ;
  368. else if (0 == wcscmp(szOperation, L"<"))
  369. return CVR_SEEK_LT;
  370. else if (0 == wcscmp(szOperation, L"<="))
  371. return CVR_SEEK_LE;
  372. else if (0 == wcscmp(szOperation, L">="))
  373. return CVR_SEEK_GE;
  374. else if (0 == wcscmp(szOperation, L">"))
  375. return CVR_SEEK_GT;
  376. return 0;
  377. }
  378. // returns localized string time (even for date!)
  379. BOOL MakeDisplayStrFromDBVariant(VARIANT* pvt, VARIANT* pvOut)
  380. {
  381. HRESULT hr;
  382. VariantInit(pvOut);
  383. LPWSTR szLocalTime = NULL;
  384. ASSERT(pvt);
  385. ASSERT(pvOut);
  386. if ((NULL == pvt) || (NULL == pvOut))
  387. return FALSE;
  388. if (pvt->vt == VT_DATE)
  389. {
  390. hr = myGMTDateToWszLocalTime(
  391. &pvt->date,
  392. FALSE,
  393. &szLocalTime);
  394. _JumpIfError(hr, error, "myGMTDateToWszLocalTime");
  395. pvOut->bstrVal = ::SysAllocString(szLocalTime);
  396. _JumpIfOutOfMemory(hr, error, pvOut->bstrVal);
  397. pvOut->vt = VT_BSTR;
  398. }
  399. else
  400. {
  401. hr = VariantChangeType(pvOut, pvt, 0, VT_BSTR);
  402. _JumpIfError(hr, error, "VariantChangeType");
  403. }
  404. error:
  405. if (szLocalTime)
  406. LocalFree(szLocalTime);
  407. return (pvOut->vt == VT_BSTR);
  408. }
  409. DWORD CryptAlgToStr(CString* pcstrAlgName, LPCWSTR szProv, DWORD dwProvType, DWORD dwAlg)
  410. {
  411. DWORD dwRet;
  412. HCRYPTPROV hCrypt = NULL;
  413. DWORD Flags = CRYPT_FIRST;
  414. DWORD cb;
  415. PROV_ENUMALGS Alg;
  416. pcstrAlgName->Empty();
  417. if (!CryptAcquireContext(
  418. &hCrypt,
  419. NULL,
  420. szProv,
  421. dwProvType,
  422. CRYPT_VERIFYCONTEXT))
  423. {
  424. dwRet = GetLastError();
  425. _JumpError(dwRet, Ret, "CryptAcquireContext");
  426. }
  427. while (TRUE)
  428. {
  429. cb = sizeof(Alg);
  430. if (!CryptGetProvParam(hCrypt, PP_ENUMALGS, (BYTE *) &Alg, &cb, Flags))
  431. break;
  432. if (Alg.aiAlgid == dwAlg)
  433. {
  434. *pcstrAlgName = Alg.szName;
  435. break;
  436. }
  437. Flags = 0;
  438. }
  439. dwRet = ERROR_SUCCESS;
  440. Ret:
  441. if (hCrypt)
  442. CryptReleaseContext(hCrypt, 0);
  443. return dwRet;
  444. }
  445. LPCWSTR FindUnlocalizedColName(LPCWSTR strColumn)
  446. {
  447. HRESULT hr = S_OK;
  448. LPCWSTR szTrial = NULL;
  449. for(DWORD dwIndex=0; (S_OK == hr); dwIndex++)
  450. {
  451. hr = myGetColumnName(
  452. dwIndex,
  453. FALSE, // unlocalized
  454. &szTrial);
  455. _PrintIfError(hr, "myGetColumnName");
  456. if ((S_OK == hr) && (NULL != szTrial))
  457. {
  458. if (0 == wcscmp(strColumn, szTrial))
  459. return szTrial;
  460. }
  461. }
  462. return NULL;
  463. }
  464. // given field, op, variant, copies into data struct
  465. PQUERY_RESTRICTION NewQueryRestriction(LPCWSTR szField, UINT iOp, VARIANT* pvarValue)
  466. {
  467. DWORD dwLen = sizeof(QUERY_RESTRICTION);
  468. dwLen += WSZ_BYTECOUNT(szField);
  469. PQUERY_RESTRICTION pNew = (QUERY_RESTRICTION*)LocalAlloc(LPTR, dwLen);
  470. if (NULL == pNew)
  471. return NULL;
  472. PBYTE pCurWrite = ((PBYTE)pNew) + sizeof(QUERY_RESTRICTION) ;
  473. pNew->szField = (LPWSTR)pCurWrite;
  474. wcscpy(pNew->szField, szField);
  475. pNew->iOperation = iOp;
  476. // copy data pointed to by pvarValue
  477. CopyMemory(&pNew->varValue, pvarValue, sizeof(VARIANT));
  478. // good enough except for string -- alloc for it
  479. if (VT_BSTR == pvarValue->vt)
  480. {
  481. pNew->varValue.bstrVal = SysAllocString(pvarValue->bstrVal);
  482. if (NULL == pNew->varValue.bstrVal)
  483. {
  484. // failed!
  485. FreeQueryRestriction(pNew);
  486. pNew = NULL;
  487. }
  488. }
  489. return pNew;
  490. }
  491. void FreeQueryRestriction(PQUERY_RESTRICTION pQR)
  492. {
  493. VariantClear(&pQR->varValue);
  494. LocalFree(pQR);
  495. }
  496. void FreeQueryRestrictionList(PQUERY_RESTRICTION pQR)
  497. {
  498. PQUERY_RESTRICTION pTmp;
  499. while(pQR)
  500. {
  501. pTmp = pQR->pNext;
  502. FreeQueryRestriction(pQR);
  503. pQR = pTmp;
  504. }
  505. }
  506. void ListInsertAtEnd(void** ppList, void* pElt)
  507. {
  508. if (pElt != NULL)
  509. {
  510. // he's always at the end of the list
  511. ((PELT_PTR)pElt)->pNext = NULL;
  512. void* pCurPtr = *ppList;
  513. if (*ppList == NULL)
  514. {
  515. *ppList = pElt;
  516. }
  517. else
  518. {
  519. while( ((PELT_PTR)pCurPtr)->pNext != NULL )
  520. {
  521. pCurPtr = ((PELT_PTR)pCurPtr)->pNext;
  522. }
  523. ((PELT_PTR)pCurPtr)->pNext = (PELT_PTR) pElt;
  524. }
  525. }
  526. return;
  527. }
  528. // dwIndex should be zero at first, then passed in for each consecutive call
  529. LPWSTR RegEnumKeyContaining(
  530. HKEY hBaseKey,
  531. LPCWSTR szContainsString,
  532. DWORD* pdwIndex)
  533. {
  534. HRESULT hr = S_OK;
  535. LPWSTR szBuf = NULL;
  536. DWORD cbBuf = 0, cbBufUsed;
  537. FILETIME ft;
  538. ASSERT(pdwIndex);
  539. hr = RegQueryInfoKey(
  540. hBaseKey,
  541. NULL,
  542. NULL, // classes
  543. NULL, // reserved
  544. NULL, // cSubkeys
  545. &cbBuf, // maxsubkeylen in chars (not counting null term)
  546. NULL, // max class len
  547. NULL, // num values
  548. NULL, // max value name len
  549. NULL, // max value len
  550. NULL, // sec descr
  551. NULL // last filetime
  552. );
  553. _JumpIfError(hr, Ret, "RegQueryInfoKey");
  554. cbBuf += 1;
  555. cbBuf *= sizeof(WCHAR);
  556. szBuf = (LPWSTR)LocalAlloc(LMEM_FIXED, cbBuf);
  557. _JumpIfOutOfMemory(hr, Ret, szBuf);
  558. for (; ; (*pdwIndex)++)
  559. {
  560. // tell api how much memory we have (incl NULL char)
  561. cbBufUsed = cbBuf;
  562. hr = RegEnumKeyEx(
  563. hBaseKey,
  564. *pdwIndex,
  565. szBuf,
  566. &cbBufUsed, // doesn't get updated in small buffer case?!
  567. NULL,
  568. NULL,
  569. NULL,
  570. &ft);
  571. _JumpIfError2(hr, Ret, "RegEnumKeyEx", ERROR_NO_MORE_ITEMS);
  572. // we have data, check if it is one we're interested in
  573. if (NULL != wcsstr(szBuf, szContainsString))
  574. break;
  575. }
  576. // don't point at this one again
  577. (*pdwIndex)++;
  578. hr = S_OK;
  579. Ret:
  580. if (S_OK != hr)
  581. {
  582. LocalFree(szBuf);
  583. szBuf = NULL;
  584. }
  585. return ( szBuf );
  586. }
  587. DISPLAYSTRING_EXPANSION g_displayStrings[11] =
  588. {
  589. { wszFCSAPARM_SERVERDNSNAME, IDS_TOKEN_SERVERDNSNAME, IDS_TOKENDESC_SERVERDNSNAME }, //%1
  590. { wszFCSAPARM_SERVERSHORTNAME, IDS_TOKEN_SERVERSHORTNAME, IDS_TOKENDESC_SERVERSHORTNAME }, //%2
  591. { wszFCSAPARM_SANITIZEDCANAME, IDS_TOKEN_SANITIZEDCANAME, IDS_TOKENDESC_SANITIZEDCANAME }, //%3
  592. { wszFCSAPARM_CERTFILENAMESUFFIX, IDS_TOKEN_CERTFILENAMESUFFIX, IDS_TOKENDESC_CERTFILENAMESUFFIX }, //%4
  593. { L"", IDS_DESCR_UNKNOWN, IDS_DESCR_UNKNOWN }, // %5 not available
  594. { wszFCSAPARM_CONFIGDN, IDS_TOKEN_CONFIGDN, IDS_TOKENDESC_CONFIGDN }, //%6
  595. { wszFCSAPARM_SANITIZEDCANAMEHASH, IDS_TOKEN_SANITIZEDCANAMEHASH, IDS_TOKENDESC_SANITIZEDCANAMEHASH }, //%7
  596. { wszFCSAPARM_CRLFILENAMESUFFIX, IDS_TOKEN_CRLFILENAMESUFFIX, IDS_TOKENDESC_CRLFILENAMESUFFIX }, //%8
  597. { wszFCSAPARM_CRLDELTAFILENAMESUFFIX, IDS_TOKEN_CRLDELTAFILENAMESUFFIX,IDS_TOKENDESC_CRLDELTAFILENAMESUFFIX}, //%9
  598. { wszFCSAPARM_DSCRLATTRIBUTE, IDS_TOKEN_DSCRLATTRIBUTE, IDS_TOKENDESC_DSCRLATTRIBUTE }, //%10
  599. { wszFCSAPARM_DSCACERTATTRIBUTE, IDS_TOKEN_DSCACERTATTRIBUTE, IDS_TOKENDESC_DSCACERTATTRIBUTE }, //%11
  600. };
  601. /////////////////////////////////////////
  602. // fxns to load resources automatically
  603. CLocalizedResources *g_pResources = NULL;
  604. CLocalizedResources::CLocalizedResources()
  605. {
  606. m_fLoaded = FALSE;
  607. }
  608. BOOL CLocalizedResources::Load()
  609. {
  610. if (!m_fLoaded)
  611. {
  612. HINSTANCE hRsrc = AfxGetResourceHandle();
  613. myVerifyResourceStrings(g_hInstance);
  614. // Load strings from resources
  615. m_ColumnHead_Name.LoadString(IDS_COLUMN_NAME);
  616. m_ColumnHead_Size.LoadString(IDS_COLUMN_SIZE);
  617. m_ColumnHead_Type.LoadString(IDS_COLUMN_TYPE);
  618. m_ColumnHead_Description.LoadString(IDS_COLUMN_DESCRIPTION);
  619. m_DescrStr_CA.LoadString(IDS_DESCR_CA);
  620. m_DescrStr_Unknown.LoadString(IDS_DESCR_UNKNOWN);
  621. m_szFilterApplied.LoadString(IDS_STATUSBAR_FILTER_APPLIED);
  622. m_szSortedAscendingTemplate.LoadString(IDS_STATUSBAR_SORTEDBY_ASCEND);
  623. m_szSortedDescendingTemplate.LoadString(IDS_STATUSBAR_SORTEDBY_DESCEND);
  624. m_szStoppedServerMsg.LoadString(IDS_STOPPED_SERVER_MSG);
  625. m_szStatusBarErrorFormat.LoadString(IDS_STATUSBAR_ERRORTEMPLATE);
  626. m_szRevokeReason_Unspecified.LoadString(IDS_CRL_REASON_UNSPECIFIED);
  627. m_szRevokeReason_KeyCompromise.LoadString(IDS_CRL_REASON_KEY_COMPROMISE);
  628. m_szRevokeReason_CaCompromise.LoadString(IDS_CRL_REASON_CA_COMPROMISE);
  629. m_szRevokeReason_Affiliation.LoadString(IDS_CRL_REASON_AFFILIATION_CHANGED);
  630. m_szRevokeReason_Superseded.LoadString(IDS_CRL_REASON_SUPERSEDED);
  631. m_szRevokeReason_Cessatation.LoadString(IDS_CRL_REASON_CESSATION_OF_OPERATION);
  632. m_szRevokeReason_CertHold.LoadString(IDS_CRL_REASON_CERTIFICATE_HOLD);
  633. m_szRevokeReason_RemoveFromCRL.LoadString(IDS_CRL_REASON_REMOVE_FROM_CRL);
  634. m_szPeriod_Seconds.LoadString(IDS_PERIOD_SECONDS);
  635. m_szPeriod_Minutes.LoadString(IDS_PERIOD_MINUTES);
  636. m_szPeriod_Hours.LoadString(IDS_PERIOD_HOURS);
  637. m_szPeriod_Days.LoadString(IDS_PERIOD_DAYS);
  638. m_szPeriod_Weeks.LoadString(IDS_PERIOD_WEEKS);
  639. m_szPeriod_Months.LoadString(IDS_PERIOD_MONTHS);
  640. m_szPeriod_Years.LoadString(IDS_PERIOD_YEARS);
  641. m_szYes.LoadString(IDS_YES);
  642. // Load the bitmaps from the dll
  643. m_bmpSvrMgrToolbar1.LoadBitmap(IDB_TOOLBAR_SVRMGR1);
  644. // load view strings to struct members, point to struct members
  645. int i;
  646. // viewResult items
  647. for(i=0; ((viewResultItems[i].item.strName != NULL) && (viewResultItems[i].item.strStatusBarText != NULL)); i++)
  648. {
  649. LoadString(hRsrc, viewResultItems[i].uiString1, viewResultItems[i].szString1, ARRAYSIZE(viewResultItems[i].szString1));
  650. viewResultItems[i].item.strName = viewResultItems[i].szString1;
  651. LoadString(hRsrc, viewResultItems[i].uiString2, viewResultItems[i].szString2, ARRAYSIZE(viewResultItems[i].szString2));
  652. viewResultItems[i].item.strStatusBarText = viewResultItems[i].szString2;
  653. }
  654. // taskResultItemsSingleSel
  655. for(i=0; ((taskResultItemsSingleSel[i].myitem.item.strName != NULL) && (taskResultItemsSingleSel[i].myitem.item.strStatusBarText != NULL)); i++)
  656. {
  657. LoadString(hRsrc, taskResultItemsSingleSel[i].myitem.uiString1, taskResultItemsSingleSel[i].myitem.szString1, ARRAYSIZE(taskResultItemsSingleSel[i].myitem.szString1));
  658. taskResultItemsSingleSel[i].myitem.item.strName = taskResultItemsSingleSel[i].myitem.szString1;
  659. LoadString(hRsrc, taskResultItemsSingleSel[i].myitem.uiString2, taskResultItemsSingleSel[i].myitem.szString2, ARRAYSIZE(taskResultItemsSingleSel[i].myitem.szString2));
  660. taskResultItemsSingleSel[i].myitem.item.strStatusBarText = taskResultItemsSingleSel[i].myitem.szString2;
  661. }
  662. // task start/stop
  663. for(i=0; ((taskStartStop[i].item.strName != NULL) && (taskStartStop[i].item.strStatusBarText != NULL)); i++)
  664. {
  665. LoadString(hRsrc, taskStartStop[i].uiString1, taskStartStop[i].szString1, ARRAYSIZE(taskStartStop[i].szString1));
  666. taskStartStop[i].item.strName = taskStartStop[i].szString1;
  667. LoadString(hRsrc, taskStartStop[i].uiString2, taskStartStop[i].szString2, ARRAYSIZE(taskStartStop[i].szString2));
  668. taskStartStop[i].item.strStatusBarText = taskStartStop[i].szString2;
  669. }
  670. // taskitems
  671. for(i=0; ((taskItems[i].myitem.item.strName != NULL) && (taskItems[i].myitem.item.strStatusBarText != NULL)); i++)
  672. {
  673. LoadString(hRsrc, taskItems[i].myitem.uiString1, taskItems[i].myitem.szString1, ARRAYSIZE(taskItems[i].myitem.szString1));
  674. taskItems[i].myitem.item.strName = taskItems[i].myitem.szString1;
  675. LoadString(hRsrc, taskItems[i].myitem.uiString2, taskItems[i].myitem.szString2, ARRAYSIZE(taskItems[i].myitem.szString2));
  676. taskItems[i].myitem.item.strStatusBarText = taskItems[i].myitem.szString2;
  677. }
  678. // topitems
  679. for(i=0; ((topItems[i].myitem.item.strName != NULL) && (topItems[i].myitem.item.strStatusBarText != NULL)); i++)
  680. {
  681. LoadString(hRsrc, topItems[i].myitem.uiString1, topItems[i].myitem.szString1, ARRAYSIZE(topItems[i].myitem.szString1));
  682. topItems[i].myitem.item.strName = topItems[i].myitem.szString1;
  683. LoadString(hRsrc, topItems[i].myitem.uiString2, topItems[i].myitem.szString2, ARRAYSIZE(topItems[i].myitem.szString2));
  684. topItems[i].myitem.item.strStatusBarText = topItems[i].myitem.szString2;
  685. }
  686. for (i=0; ((SvrMgrToolbar1Buttons[i].item.lpButtonText != NULL) && (SvrMgrToolbar1Buttons[i].item.lpTooltipText != NULL)); i++)
  687. {
  688. LoadString(hRsrc, SvrMgrToolbar1Buttons[i].uiString1, SvrMgrToolbar1Buttons[i].szString1, ARRAYSIZE(SvrMgrToolbar1Buttons[i].szString1));
  689. SvrMgrToolbar1Buttons[i].item.lpButtonText = SvrMgrToolbar1Buttons[i].szString1;
  690. LoadString(hRsrc, SvrMgrToolbar1Buttons[i].uiString2, SvrMgrToolbar1Buttons[i].szString2, ARRAYSIZE(SvrMgrToolbar1Buttons[i].szString2));
  691. SvrMgrToolbar1Buttons[i].item.lpTooltipText = SvrMgrToolbar1Buttons[i].szString2;
  692. }
  693. // load replacement tokens
  694. for (i=0; i<DISPLAYSTRINGS_TOKEN_COUNT; i++)
  695. {
  696. g_displayStrings[i].pcstrExpansionString = new CString;
  697. if (g_displayStrings[i].pcstrExpansionString != NULL)
  698. g_displayStrings[i].pcstrExpansionString->LoadString(g_displayStrings[i].uTokenID);
  699. g_displayStrings[i].pcstrExpansionStringDescr = new CString;
  700. if (g_displayStrings[i].pcstrExpansionStringDescr != NULL)
  701. g_displayStrings[i].pcstrExpansionStringDescr->LoadString(g_displayStrings[i].uTokenDescrID);
  702. }
  703. m_fLoaded = TRUE;
  704. }
  705. return m_fLoaded;
  706. }
  707. CLocalizedResources::~CLocalizedResources()
  708. {
  709. m_fLoaded = FALSE;
  710. for (int i=0; i<DISPLAYSTRINGS_TOKEN_COUNT; i++)
  711. {
  712. if (g_displayStrings[i].pcstrExpansionString)
  713. delete g_displayStrings[i].pcstrExpansionString;
  714. if (g_displayStrings[i].pcstrExpansionStringDescr)
  715. delete g_displayStrings[i].pcstrExpansionStringDescr;
  716. }
  717. }
  718. HRESULT ReadOfSize(IStream* pStm, void* pbData, ULONG cbData)
  719. {
  720. HRESULT hr;
  721. ULONG nBytesRead;
  722. hr = pStm->Read(pbData, cbData, &nBytesRead);
  723. if ((hr == S_OK) && (nBytesRead != cbData))
  724. hr = HRESULT_FROM_WIN32(ERROR_HANDLE_EOF);
  725. return hr;
  726. }
  727. HRESULT WriteOfSize(IStream* pStm, void* pbData, ULONG cbData)
  728. {
  729. HRESULT hr;
  730. ULONG nBytesWritten;
  731. hr = pStm->Write(pbData, cbData, &nBytesWritten);
  732. if ((hr == S_OK) && (nBytesWritten != cbData))
  733. hr = HRESULT_FROM_WIN32(ERROR_HANDLE_DISK_FULL);
  734. return hr;
  735. }
  736. HRESULT
  737. myOIDToName(
  738. IN WCHAR const *pwszObjId,
  739. OUT LPWSTR* pszName)
  740. {
  741. HRESULT hr = S_OK;
  742. WCHAR const *pwszName1 = L"";
  743. WCHAR const *pwszName2;
  744. WCHAR *pwszT = NULL;
  745. WCHAR rgwchName[64];
  746. if (pszName == NULL)
  747. {
  748. hr = E_POINTER;
  749. _JumpError(hr, error, "pszName NULL");
  750. }
  751. pwszT = (LPWSTR) LocalAlloc(LMEM_FIXED, (1 + 1 + wcslen(pwszObjId)) * sizeof(WCHAR));
  752. if (NULL == pwszT)
  753. {
  754. hr = E_OUTOFMEMORY;
  755. _JumpError(hr, error, "no memory for skip counts array");
  756. }
  757. wcscpy(&pwszT[1], pwszObjId);
  758. *pwszT = L'+';
  759. pwszName1 = myGetOIDName(pwszT); // Group OID lookup
  760. *pwszT = L'-';
  761. pwszName2 = myGetOIDName(pwszT); // Generic OID lookup
  762. if (0 == mylstrcmpiL(pwszName1, pwszName2))
  763. {
  764. pwszName2 = L""; // display only one if they're the same
  765. }
  766. if (L'\0' == *pwszName1)
  767. {
  768. pwszName1 = pwszName2;
  769. pwszName2 = L"";
  770. }
  771. if (L'\0' != *pwszName2 &&
  772. ARRAYSIZE(rgwchName) > wcslen(pwszName1) + wcslen(pwszName2) + 3)
  773. {
  774. wcscpy(rgwchName, pwszName1);
  775. wcscat(rgwchName, L" " wszLPAREN);
  776. wcscat(rgwchName, pwszName2);
  777. wcscat(rgwchName, wszRPAREN);
  778. pwszName1 = rgwchName;
  779. }
  780. *pszName = (LPWSTR)LocalAlloc(LMEM_FIXED, (wcslen(pwszName1)+1)*sizeof(WCHAR));
  781. if (NULL == *pszName)
  782. {
  783. hr = E_OUTOFMEMORY;
  784. _JumpError(hr, error, "pszName");
  785. }
  786. wcscpy(*pszName, pwszName1);
  787. error:
  788. if (NULL != pwszT)
  789. {
  790. LocalFree(pwszT);
  791. }
  792. return hr;
  793. }
  794. #include "csdisp.h"
  795. HRESULT
  796. myDumpFormattedObject(
  797. IN WCHAR const *pwszObjId,
  798. IN BYTE const *pbObject,
  799. IN DWORD cbObject,
  800. OUT LPWSTR* ppwszFormatted)
  801. {
  802. HRESULT hr = S_OK;
  803. char * pszObjId = NULL;
  804. DWORD cbFormatted;
  805. if (ppwszFormatted == NULL)
  806. {
  807. hr = E_POINTER;
  808. _JumpError(hr, error, "NULL param");
  809. }
  810. if (!ConvertWszToSz(&pszObjId, pwszObjId, -1))
  811. {
  812. hr = E_OUTOFMEMORY;
  813. _JumpError(hr, error, "ConvertWszToSz");
  814. }
  815. // format the object using the installed formatting function
  816. if (!CryptFormatObject(
  817. X509_ASN_ENCODING,
  818. 0,
  819. CRYPT_FORMAT_STR_MULTI_LINE | CRYPT_FORMAT_STR_NO_HEX,
  820. NULL,
  821. pszObjId,
  822. pbObject,
  823. cbObject,
  824. NULL,
  825. &cbFormatted))
  826. {
  827. hr = myHLastError();
  828. _JumpIfError(hr, error, "CryptFormatObject");
  829. }
  830. *ppwszFormatted = (WCHAR *) LocalAlloc(LMEM_FIXED, cbFormatted);
  831. if (NULL == *ppwszFormatted)
  832. {
  833. hr = E_OUTOFMEMORY;
  834. _JumpError(hr, error, "LocalAlloc");
  835. }
  836. if (!CryptFormatObject(
  837. X509_ASN_ENCODING,
  838. 0,
  839. CRYPT_FORMAT_STR_MULTI_LINE | CRYPT_FORMAT_STR_NO_HEX,
  840. NULL,
  841. pszObjId,
  842. pbObject,
  843. cbObject,
  844. *ppwszFormatted,
  845. &cbFormatted))
  846. {
  847. hr = myHLastError();
  848. _JumpError(hr, error, "CryptFormatObject");
  849. }
  850. /*
  851. if (g_fVerbose)
  852. {
  853. if (0 == strcmp(szOID_SUBJECT_ALT_NAME, pszObjId) ||
  854. 0 == strcmp(szOID_SUBJECT_ALT_NAME2, pszObjId) ||
  855. 0 == strcmp(szOID_ISSUER_ALT_NAME, pszObjId) ||
  856. 0 == strcmp(szOID_ISSUER_ALT_NAME2, pszObjId))
  857. {
  858. DumpAltName(pbObject, cbObject);
  859. }
  860. }
  861. */
  862. error:
  863. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr || CRYPT_E_ASN1_BADTAG == hr)
  864. {
  865. // fix up nonfatal errors
  866. CString cstrUnknown;
  867. cstrUnknown.LoadString(IDS_UNKNOWN_EXTENSION);
  868. hr = myDupString((LPCWSTR)cstrUnknown, ppwszFormatted);
  869. _PrintIfError(hr, "myDupString failure");
  870. }
  871. if (pszObjId)
  872. LocalFree(pszObjId);
  873. return hr;
  874. }
  875. void
  876. InplaceStripControlChars(WCHAR* szString)
  877. {
  878. // remove \r and \n AND \t formatting through end-of-string
  879. if (NULL != szString)
  880. {
  881. while (*szString != L'\0')
  882. {
  883. switch(*szString)
  884. {
  885. case L'\r':
  886. case L'\n':
  887. case L'\t':
  888. *szString = L' ';
  889. break;
  890. }
  891. szString++;
  892. }
  893. }
  894. }
  895. HANDLE EnablePrivileges(LPCWSTR ppcwszPrivileges[], ULONG cPrivileges)
  896. {
  897. BOOL fResult = FALSE;
  898. HANDLE hToken = INVALID_HANDLE_VALUE;
  899. HANDLE hOriginalThreadToken = INVALID_HANDLE_VALUE;
  900. PTOKEN_PRIVILEGES ptp;
  901. ULONG nBufferSize;
  902. // Note that TOKEN_PRIVILEGES includes a single LUID_AND_ATTRIBUTES
  903. nBufferSize = sizeof(TOKEN_PRIVILEGES) + (cPrivileges - 1)*sizeof(LUID_AND_ATTRIBUTES);
  904. ptp = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, nBufferSize);
  905. if (!ptp)
  906. return INVALID_HANDLE_VALUE;
  907. //
  908. // Initialize the Privileges Structure
  909. //
  910. ptp->PrivilegeCount = cPrivileges;
  911. for (ULONG i = 0; i < cPrivileges; i++)
  912. {
  913. fResult = LookupPrivilegeValue(NULL, ppcwszPrivileges[i], &ptp->Privileges[i].Luid);
  914. if (!fResult)
  915. break;
  916. ptp->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED;
  917. }
  918. if(fResult)
  919. {
  920. //
  921. // Open the Token
  922. //
  923. hToken = hOriginalThreadToken = INVALID_HANDLE_VALUE;
  924. fResult = OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE, FALSE, &hToken);
  925. if (fResult)
  926. hOriginalThreadToken = hToken; // Remember the thread token
  927. else
  928. fResult = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hToken);
  929. }
  930. if (fResult)
  931. {
  932. HANDLE hNewToken;
  933. //
  934. // Duplicate that Token
  935. //
  936. fResult = DuplicateTokenEx(hToken,
  937. TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  938. NULL, // PSECURITY_ATTRIBUTES
  939. SecurityImpersonation, // SECURITY_IMPERSONATION_LEVEL
  940. TokenImpersonation, // TokenType
  941. &hNewToken); // Duplicate token
  942. if (fResult)
  943. {
  944. //
  945. // Add new privileges
  946. //
  947. fResult = AdjustTokenPrivileges(hNewToken, // TokenHandle
  948. FALSE, // DisableAllPrivileges
  949. ptp, // NewState
  950. 0, // BufferLength
  951. NULL, // PreviousState
  952. NULL); // ReturnLength
  953. if (fResult)
  954. {
  955. //
  956. // Begin impersonating with the new token
  957. //
  958. fResult = SetThreadToken(NULL, hNewToken);
  959. }
  960. CloseHandle(hNewToken);
  961. }
  962. }
  963. // If something failed, don't return a token
  964. if (!fResult)
  965. hOriginalThreadToken = INVALID_HANDLE_VALUE;
  966. // Close the original token if we aren't returning it
  967. if (hOriginalThreadToken == INVALID_HANDLE_VALUE && hToken != INVALID_HANDLE_VALUE)
  968. CloseHandle(hToken);
  969. // If we succeeded, but there was no original thread token,
  970. // return NULL to indicate we need to do SetThreadToken(NULL, NULL)
  971. // to release privs.
  972. if (fResult && hOriginalThreadToken == INVALID_HANDLE_VALUE)
  973. hOriginalThreadToken = NULL;
  974. LocalFree(ptp);
  975. return hOriginalThreadToken;
  976. }
  977. void ReleasePrivileges(HANDLE hToken)
  978. {
  979. BOOL fResult;
  980. if (INVALID_HANDLE_VALUE != hToken)
  981. {
  982. fResult = SetThreadToken(NULL, hToken);
  983. if (hToken)
  984. CloseHandle(hToken);
  985. }
  986. }
  987. HRESULT
  988. myGetActiveModule(
  989. CertSvrCA *pCA,
  990. IN BOOL fPolicyModule,
  991. IN DWORD Index,
  992. OPTIONAL OUT LPOLESTR *ppwszProgIdModule, // CoTaskMem*
  993. OPTIONAL OUT CLSID *pclsidModule)
  994. {
  995. HRESULT hr;
  996. WCHAR *pwsz;
  997. variant_t var;
  998. hr = pCA->GetConfigEntry(
  999. fPolicyModule?wszREGKEYPOLICYMODULES:wszREGKEYEXITMODULES,
  1000. wszREGACTIVE,
  1001. &var);
  1002. _JumpIfError(hr, error, "GetConfigEntry");
  1003. hr = HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND);
  1004. if(V_VT(&var)==VT_BSTR)
  1005. {
  1006. pwsz = V_BSTR(&var);
  1007. }
  1008. else if(V_VT(&var)==(VT_ARRAY|VT_BSTR))
  1009. {
  1010. SafeArrayEnum<BSTR> saenum(V_ARRAY(&var));
  1011. hr = saenum.GetAt(Index, pwsz);
  1012. _JumpIfError(hr, error, "GetConfigEntry");
  1013. }
  1014. else
  1015. {
  1016. _JumpError(hr, error, "Bad active entry type");
  1017. }
  1018. if(!pwsz)
  1019. {
  1020. _JumpError(hr, error, "empty entry");
  1021. }
  1022. if (NULL != pclsidModule)
  1023. {
  1024. hr = CLSIDFromProgID(pwsz, pclsidModule);
  1025. _JumpIfError(hr, error, "CLSIDFromProgID");
  1026. }
  1027. if (NULL != ppwszProgIdModule)
  1028. {
  1029. *ppwszProgIdModule = (LPOLESTR) CoTaskMemAlloc(
  1030. (wcslen(pwsz) + 1) * sizeof(WCHAR));
  1031. if (NULL == *ppwszProgIdModule)
  1032. {
  1033. hr = E_OUTOFMEMORY;
  1034. _JumpError(hr, error, "CoTaskMemAlloc");
  1035. }
  1036. wcscpy(*ppwszProgIdModule, pwsz);
  1037. }
  1038. hr = S_OK; // not reset after ERROR_MOD_NOT_FOUND in all cases
  1039. error:
  1040. return(hr);
  1041. }
  1042. HRESULT FindComputerObjectSid(
  1043. LPCWSTR pcwszCAComputerDNSName,
  1044. PSID &pSid)
  1045. {
  1046. HRESULT hr = S_OK;
  1047. ADS_SEARCHPREF_INFO asi[1];
  1048. IDirectorySearch *pSearch = NULL;
  1049. LPWSTR pwszAttr = L"objectSid";
  1050. ADS_SEARCH_HANDLE hADS = NULL;
  1051. static LPCWSTR pwszgc = L"GC://";
  1052. static LPCWSTR pwszformat = L"(&(objectClass=computer)(servicePrincipalName=host/%ws))";
  1053. LPWSTR pwszSearchFilter = NULL;
  1054. LPWSTR pwszGC = NULL;
  1055. DWORD dwres;
  1056. PDOMAIN_CONTROLLER_INFO pdci = NULL;
  1057. ADS_SEARCH_COLUMN col;
  1058. dwres = DsGetDcName(
  1059. NULL,
  1060. NULL,
  1061. NULL,
  1062. NULL,
  1063. DS_RETURN_DNS_NAME|DS_DIRECTORY_SERVICE_REQUIRED,
  1064. &pdci);
  1065. if(NO_ERROR != dwres)
  1066. {
  1067. hr = myHError(dwres);
  1068. _JumpIfError(hr, error, "DsGetDcName");
  1069. }
  1070. pwszGC = (LPWSTR)LocalAlloc(LMEM_FIXED,
  1071. sizeof(WCHAR)*(wcslen(pwszgc)+wcslen(pdci->DnsForestName)+1));
  1072. _JumpIfAllocFailed(pwszGC, error);
  1073. wcscpy(pwszGC, pwszgc);
  1074. wcscat(pwszGC, pdci->DnsForestName);
  1075. hr = ADsGetObject(pwszGC, IID_IDirectorySearch, (void**)&pSearch);
  1076. _JumpIfError(hr, error, "ADsGetObject(GC:)");
  1077. asi[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  1078. asi[0].vValue.dwType = ADSTYPE_INTEGER;
  1079. asi[0].vValue.Integer = ADS_SCOPE_SUBTREE;
  1080. hr = pSearch->SetSearchPreference(asi, 1);
  1081. _JumpIfError(hr, error, "SetSearchPreference");
  1082. pwszSearchFilter = (LPWSTR)LocalAlloc(LMEM_FIXED,
  1083. sizeof(WCHAR)*(wcslen(pwszformat)+wcslen(pcwszCAComputerDNSName)+1));
  1084. wsprintf(pwszSearchFilter, pwszformat, pcwszCAComputerDNSName);
  1085. hr = pSearch->ExecuteSearch(
  1086. pwszSearchFilter,
  1087. &pwszAttr,
  1088. 1,
  1089. &hADS);
  1090. _JumpIfErrorStr(hr, error, "ExecuteSearch", pwszSearchFilter);
  1091. hr = pSearch->GetFirstRow(hADS);
  1092. _JumpIfError(hr, error, "GetFirstRow");
  1093. hr = pSearch->GetColumn(hADS, pwszAttr, &col);
  1094. _JumpIfErrorStr(hr, error, "GetColumn", pwszAttr);
  1095. CSASSERT(IsValidSid(col.pADsValues[0].OctetString.lpValue));
  1096. CSASSERT(GetLengthSid(col.pADsValues[0].OctetString.lpValue)==
  1097. col.pADsValues[0].OctetString.dwLength);
  1098. pSid = LocalAlloc(LMEM_FIXED, col.pADsValues[0].OctetString.dwLength);
  1099. _JumpIfAllocFailed(pSid, error);
  1100. CopySid(col.pADsValues[0].OctetString.dwLength,
  1101. pSid,
  1102. col.pADsValues[0].OctetString.lpValue);
  1103. error:
  1104. if(pdci)
  1105. NetApiBufferFree(pdci);
  1106. if(pSearch)
  1107. {
  1108. pSearch->FreeColumn(&col);
  1109. if(hADS)
  1110. pSearch->CloseSearchHandle(hADS);
  1111. pSearch->Release();
  1112. }
  1113. LOCAL_FREE(pwszSearchFilter);
  1114. LOCAL_FREE(pwszGC);
  1115. return hr;
  1116. }
  1117. HRESULT IsUserDomainAdministrator(BOOL* pfIsAdministrator)
  1118. {
  1119. HRESULT hr = S_OK;
  1120. *pfIsAdministrator = FALSE;
  1121. PSID psidAdministrators;
  1122. SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  1123. BOOL bResult = AllocateAndInitializeSid (&siaNtAuthority, 2,
  1124. SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
  1125. 0, 0, 0, 0, 0, 0, &psidAdministrators);
  1126. if ( bResult )
  1127. {
  1128. bResult = CheckTokenMembership (0, psidAdministrators,
  1129. pfIsAdministrator);
  1130. ASSERT (bResult);
  1131. if ( !bResult )
  1132. {
  1133. hr = myHLastError ();
  1134. _PrintError(hr, "CheckTokenMembership");
  1135. }
  1136. FreeSid (psidAdministrators);
  1137. }
  1138. else
  1139. {
  1140. hr = myHLastError ();
  1141. _PrintError(hr, "AllocateAndInitializeSid");
  1142. }
  1143. return hr;
  1144. }
  1145. BOOL RestartService(HWND hWnd, CertSvrMachine* pMachine)
  1146. {
  1147. // notify user we can't apply immediately
  1148. CString cstrText;
  1149. cstrText.LoadString(IDS_CONFIRM_SERVICE_RESTART);
  1150. if (IDYES == ::MessageBox(hWnd, (LPCWSTR)cstrText, (LPCWSTR)g_pResources->m_DescrStr_CA, MB_YESNO | MB_ICONWARNING ))
  1151. {
  1152. DWORD dwErr;
  1153. // stop the service
  1154. if (pMachine->IsCertSvrServiceRunning())
  1155. pMachine->CertSvrStartStopService(hWnd, FALSE);
  1156. // start the serviec
  1157. dwErr = pMachine->CertSvrStartStopService(hWnd, TRUE);
  1158. if (S_OK != dwErr)
  1159. DisplayGenericCertSrvError(hWnd, dwErr);
  1160. return TRUE;
  1161. }
  1162. return FALSE; // didn't restart
  1163. }
  1164. static BOOL s_fLogOpened = FALSE;
  1165. VOID
  1166. LogOpen(
  1167. IN BOOL fForceOpen)
  1168. {
  1169. BOOL fOpenLog;
  1170. DbgPrintfInit("+"); // reinitialize debug print mask first
  1171. fOpenLog = DbgIsSSActive(DBG_SS_OPENLOG);
  1172. if (fOpenLog || fForceOpen)
  1173. {
  1174. if (!s_fLogOpened)
  1175. {
  1176. csiLogOpen("+certmmc.log");
  1177. s_fLogOpened = TRUE;
  1178. CSILOGFILEVERSION(0, L"certmmc.dll", szCSVER_STR);
  1179. }
  1180. }
  1181. }
  1182. VOID
  1183. LogClose()
  1184. {
  1185. if (s_fLogOpened)
  1186. {
  1187. csiLogClose();
  1188. s_fLogOpened = FALSE;
  1189. }
  1190. }