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.

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