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.

874 lines
17 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. //
  3. //This file contains wrapper C functions for CGlobal Object
  4. //
  5. #include "precomp.h"
  6. #include "utils.h"
  7. #ifndef TLSPERF
  8. #include "global.h"
  9. extern CGlobal *g_CGlobal;
  10. #else
  11. #include "globalPerf.h"
  12. extern CGlobalPerf *g_CGlobal;
  13. #endif
  14. #include "assert.h"
  15. // The following table translates an ascii subset to 6 bit values as follows
  16. // (see rfc 1521):
  17. //
  18. // input hex (decimal)
  19. // 'A' --> 0x00 (0)
  20. // 'B' --> 0x01 (1)
  21. // ...
  22. // 'Z' --> 0x19 (25)
  23. // 'a' --> 0x1a (26)
  24. // 'b' --> 0x1b (27)
  25. // ...
  26. // 'z' --> 0x33 (51)
  27. // '0' --> 0x34 (52)
  28. // ...
  29. // '9' --> 0x3d (61)
  30. // '+' --> 0x3e (62)
  31. // '/' --> 0x3f (63)
  32. //
  33. // Encoded lines must be no longer than 76 characters.
  34. // The final "quantum" is handled as follows: The translation output shall
  35. // always consist of 4 characters. 'x', below, means a translated character,
  36. // and '=' means an equal sign. 0, 1 or 2 equal signs padding out a four byte
  37. // translation quantum means decoding the four bytes would result in 3, 2 or 1
  38. // unencoded bytes, respectively.
  39. //
  40. // unencoded size encoded data
  41. // -------------- ------------
  42. // 1 byte "xx=="
  43. // 2 bytes "xxx="
  44. // 3 bytes "xxxx"
  45. #define CB_BASE64LINEMAX 64 // others use 64 -- could be up to 76
  46. // Any other (invalid) input character value translates to 0x40 (64)
  47. const BYTE abDecode[256] =
  48. {
  49. /* 00: */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  50. /* 10: */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  51. /* 20: */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
  52. /* 30: */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
  53. /* 40: */ 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  54. /* 50: */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
  55. /* 60: */ 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  56. /* 70: */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
  57. /* 80: */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  58. /* 90: */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  59. /* a0: */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  60. /* b0: */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  61. /* c0: */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  62. /* d0: */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  63. /* e0: */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  64. /* f0: */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  65. };
  66. const UCHAR abEncode[] =
  67. /* 0 thru 25: */ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  68. /* 26 thru 51: */ "abcdefghijklmnopqrstuvwxyz"
  69. /* 52 thru 61: */ "0123456789"
  70. /* 62 and 63: */ "+/";
  71. DWORD LSBase64EncodeA(
  72. IN BYTE const *pbIn,
  73. IN DWORD cbIn,
  74. OUT CHAR *pchOut,
  75. OUT DWORD *pcchOut)
  76. {
  77. CHAR *pchOutT;
  78. DWORD cchOutEncode;
  79. // Allocate enough memory for full final translation quantum.
  80. cchOutEncode = ((cbIn + 2) / 3) * 4;
  81. // and enough for CR-LF pairs for every CB_BASE64LINEMAX character line.
  82. cchOutEncode +=
  83. 2 * ((cchOutEncode + CB_BASE64LINEMAX - 1) / CB_BASE64LINEMAX);
  84. pchOutT = pchOut;
  85. if (NULL == pchOut)
  86. {
  87. pchOutT += cchOutEncode;
  88. }
  89. else
  90. {
  91. DWORD cCol;
  92. assert(cchOutEncode <= *pcchOut);
  93. cCol = 0;
  94. while ((long) cbIn > 0) // signed comparison -- cbIn can wrap
  95. {
  96. BYTE ab3[3];
  97. if (cCol == CB_BASE64LINEMAX/4)
  98. {
  99. cCol = 0;
  100. *pchOutT++ = '\r';
  101. *pchOutT++ = '\n';
  102. }
  103. cCol++;
  104. memset(ab3, 0, sizeof(ab3));
  105. ab3[0] = *pbIn++;
  106. if (cbIn > 1)
  107. {
  108. ab3[1] = *pbIn++;
  109. if (cbIn > 2)
  110. {
  111. ab3[2] = *pbIn++;
  112. }
  113. }
  114. *pchOutT++ = abEncode[ab3[0] >> 2];
  115. *pchOutT++ = abEncode[((ab3[0] << 4) | (ab3[1] >> 4)) & 0x3f];
  116. *pchOutT++ = (cbIn > 1)?
  117. abEncode[((ab3[1] << 2) | (ab3[2] >> 6)) & 0x3f] : '=';
  118. *pchOutT++ = (cbIn > 2)? abEncode[ab3[2] & 0x3f] : '=';
  119. cbIn -= 3;
  120. }
  121. *pchOutT++ = '\r';
  122. *pchOutT++ = '\n';
  123. assert((DWORD) (pchOutT - pchOut) <= cchOutEncode);
  124. }
  125. *pcchOut = (DWORD)(pchOutT - pchOut);
  126. return(ERROR_SUCCESS);
  127. }
  128. DWORD LSBase64DecodeA(
  129. IN CHAR const *pchIn,
  130. IN DWORD cchIn,
  131. OUT BYTE *pbOut,
  132. OUT DWORD *pcbOut)
  133. {
  134. DWORD err = ERROR_SUCCESS;
  135. DWORD cchInDecode, cbOutDecode;
  136. CHAR const *pchInEnd;
  137. CHAR const *pchInT;
  138. BYTE *pbOutT;
  139. // Count the translatable characters, skipping whitespace & CR-LF chars.
  140. cchInDecode = 0;
  141. pchInEnd = &pchIn[cchIn];
  142. for (pchInT = pchIn; pchInT < pchInEnd; pchInT++)
  143. {
  144. if (sizeof(abDecode) < (unsigned) *pchInT || abDecode[*pchInT] > 63)
  145. {
  146. // skip all whitespace
  147. if (*pchInT == ' ' ||
  148. *pchInT == '\t' ||
  149. *pchInT == '\r' ||
  150. *pchInT == '\n')
  151. {
  152. continue;
  153. }
  154. if (0 != cchInDecode)
  155. {
  156. if ((cchInDecode % 4) == 0)
  157. {
  158. break; // ends on quantum boundary
  159. }
  160. // The length calculation may stop in the middle of the last
  161. // translation quantum, because the equal sign padding
  162. // characters are treated as invalid input. If the last
  163. // translation quantum is not 4 bytes long, it must be 2 or 3
  164. // bytes long.
  165. if (*pchInT == '=' && (cchInDecode % 4) != 1)
  166. {
  167. break; // normal termination
  168. }
  169. }
  170. err = ERROR_INVALID_DATA;
  171. goto error;
  172. }
  173. cchInDecode++;
  174. }
  175. assert(pchInT <= pchInEnd);
  176. pchInEnd = pchInT; // don't process any trailing stuff again
  177. // We know how many translatable characters are in the input buffer, so now
  178. // set the output buffer size to three bytes for every four (or fraction of
  179. // four) input bytes.
  180. cbOutDecode = ((cchInDecode + 3) / 4) * 3;
  181. pbOutT = pbOut;
  182. if (NULL == pbOut)
  183. {
  184. pbOutT += cbOutDecode;
  185. }
  186. else
  187. {
  188. // Decode one quantum at a time: 4 bytes ==> 3 bytes
  189. assert(cbOutDecode <= *pcbOut);
  190. pchInT = pchIn;
  191. while (cchInDecode > 0)
  192. {
  193. DWORD i;
  194. BYTE ab4[4];
  195. memset(ab4, 0, sizeof(ab4));
  196. for (i = 0; i < min(sizeof(ab4)/sizeof(ab4[0]), cchInDecode); i++)
  197. {
  198. while (
  199. sizeof(abDecode) > (unsigned) *pchInT &&
  200. 63 < abDecode[*pchInT])
  201. {
  202. pchInT++;
  203. }
  204. assert(pchInT < pchInEnd);
  205. ab4[i] = (BYTE) *pchInT++;
  206. }
  207. // Translate 4 input characters into 6 bits each, and deposit the
  208. // resulting 24 bits into 3 output bytes by shifting as appropriate.
  209. // out[0] = in[0]:in[1] 6:2
  210. // out[1] = in[1]:in[2] 4:4
  211. // out[2] = in[2]:in[3] 2:6
  212. *pbOutT++ =
  213. (BYTE) ((abDecode[ab4[0]] << 2) | (abDecode[ab4[1]] >> 4));
  214. if (i > 2)
  215. {
  216. *pbOutT++ =
  217. (BYTE) ((abDecode[ab4[1]] << 4) | (abDecode[ab4[2]] >> 2));
  218. }
  219. if (i > 3)
  220. {
  221. *pbOutT++ = (BYTE) ((abDecode[ab4[2]] << 6) | abDecode[ab4[3]]);
  222. }
  223. cchInDecode -= i;
  224. }
  225. assert((DWORD) (pbOutT - pbOut) <= cbOutDecode);
  226. }
  227. *pcbOut = (DWORD)(pbOutT - pbOut);
  228. error:
  229. return(err);
  230. }
  231. #ifndef TLSPERF
  232. CGlobal * GetGlobalContext(void)
  233. #else
  234. CGlobalPerf * GetGlobalContext(void)
  235. #endif
  236. {
  237. return g_CGlobal;
  238. }
  239. DWORD WINAPI ProcessThread(void *pData)
  240. {
  241. DWORD dwRetCode = ERROR_SUCCESS;
  242. dwRetCode = ProcessRequest();
  243. /*
  244. DWORD dwTime = 1;
  245. HWND *phProgress = (HWND *)pData;
  246. SendMessage(g_hProgressWnd, PBM_SETRANGE, 0, MAKELPARAM(0,PROGRESS_MAX_VAL));
  247. //
  248. // Increment the progress bar every second till you get Progress Event
  249. //
  250. SendMessage(g_hProgressWnd, PBM_SETPOS ,(WPARAM)1, 0);
  251. do
  252. {
  253. SendMessage(g_hProgressWnd, PBM_DELTAPOS ,(WPARAM)PROGRESS_STEP_VAL, 0);
  254. }
  255. while(WAIT_TIMEOUT == WaitForSingleObject(g_hProgressEvent,PROGRESS_SLEEP_TIME));
  256. SendMessage(g_hProgressWnd, PBM_SETPOS ,(WPARAM)PROGRESS_MAX_VAL, 0);
  257. */
  258. ExitThread(0);
  259. return 0;
  260. }
  261. static DWORD (*g_pfnThread)(void *);
  262. static void * g_vpData;
  263. LRW_DLG_INT CALLBACK
  264. ProgressProc(
  265. IN HWND hwnd,
  266. IN UINT uMsg,
  267. IN WPARAM wParam,
  268. IN LPARAM lParam
  269. );
  270. DWORD ShowProgressBox(HWND hwnd,
  271. DWORD (*pfnThread)(void *vpData),
  272. DWORD dwTitle,
  273. DWORD dwProgressText,
  274. void * vpData)
  275. {
  276. DWORD dwReturn = ERROR_SUCCESS;
  277. g_pfnThread = pfnThread;
  278. g_vpData = vpData;
  279. DialogBox( GetGlobalContext()->GetInstanceHandle(),
  280. MAKEINTRESOURCE(IDD_AUTHENTICATE),
  281. hwnd,
  282. ProgressProc);
  283. return dwReturn;
  284. }
  285. LRW_DLG_INT CALLBACK
  286. ProgressProc(
  287. IN HWND hwnd,
  288. IN UINT uMsg,
  289. IN WPARAM wParam,
  290. IN LPARAM lParam
  291. )
  292. {
  293. BOOL bStatus = FALSE;
  294. static int nCounter;
  295. static HWND hProgress;
  296. static HANDLE hThread;
  297. if (uMsg == WM_INITDIALOG)
  298. {
  299. DWORD dwTID = 0;
  300. ShowWindow(hwnd, SW_SHOWNORMAL);
  301. SetTimer(hwnd, 1, 500, NULL);
  302. hProgress = GetDlgItem(hwnd, IDC_PROGRESSBAR);
  303. hThread = CreateThread(NULL, 0, g_pfnThread, g_vpData, 0, &dwTID);
  304. //Set the range & the initial position
  305. SendMessage(hProgress, PBM_SETRANGE, 0, MAKELPARAM(0,PROGRESS_MAX_VAL));
  306. SendMessage(hProgress, PBM_SETPOS ,(WPARAM)0, 0);
  307. // Set Title & the Introductory text
  308. // Create thread to process the request
  309. }
  310. else if (uMsg == WM_CLOSE)
  311. {
  312. KillTimer(hwnd, 1);
  313. }
  314. else if (uMsg == WM_TIMER)
  315. {
  316. if (WAIT_OBJECT_0 != WaitForSingleObject(hThread, 0))
  317. {
  318. nCounter++;
  319. if (nCounter < PROGRESS_MAX_VAL-5)
  320. {
  321. SendMessage(hProgress, PBM_DELTAPOS ,(WPARAM)PROGRESS_STEP_VAL, 0);
  322. }
  323. }
  324. else
  325. {
  326. SendMessage(hProgress, PBM_SETPOS ,(WPARAM)PROGRESS_MAX_VAL, 0);
  327. CloseHandle(hThread);
  328. EndDialog(hwnd, 0);
  329. }
  330. }
  331. return bStatus;
  332. }
  333. void SetInstanceHandle(HINSTANCE hInst)
  334. {
  335. g_CGlobal->SetInstanceHandle(hInst);
  336. }
  337. void SetLSName(LPTSTR lpstrLSName)
  338. {
  339. g_CGlobal->SetLSName(lpstrLSName);
  340. }
  341. HINSTANCE GetInstanceHandle()
  342. {
  343. return g_CGlobal->GetInstanceHandle();
  344. }
  345. DWORD InitGlobal()
  346. {
  347. return g_CGlobal->InitGlobal();
  348. }
  349. DWORD CheckRequieredFields()
  350. {
  351. return g_CGlobal->CheckRequieredFields();
  352. }
  353. //
  354. // This function loads the Message Text from the String Table and displays
  355. // the given message
  356. //
  357. int LRMessageBox(HWND hWndParent,DWORD dwMsgId,DWORD dwErrorCode /*=0*/)
  358. {
  359. return g_CGlobal->LRMessageBox(hWndParent,dwMsgId,dwErrorCode);
  360. }
  361. //
  362. // This function tries to connect to the LS using LSAPI and returns TRUE if
  363. // successful to connect else returns FALSE
  364. //
  365. BOOL IsLSRunning()
  366. {
  367. return g_CGlobal->IsLSRunning();
  368. }
  369. //
  370. // This function gets LS Certs and stores Certs & Cert Extensions in the
  371. // CGlobal object. If no certs , it returns IDS_ERR_NO_CERT
  372. //
  373. //
  374. // This function is used only in ONLINE mode to authenticate LS.
  375. // Assumption - GetLSCertificates should have been called before calling
  376. // this function.
  377. //
  378. DWORD AuthenticateLS()
  379. {
  380. return g_CGlobal->AuthenticateLS();
  381. }
  382. DWORD LRGetLastError()
  383. {
  384. return g_CGlobal->LRGetLastError();
  385. }
  386. TCHAR * GetRegistrationID(void)
  387. {
  388. return g_CGlobal->GetRegistrationID();
  389. }
  390. TCHAR * GetLicenseServerID(void)
  391. {
  392. return g_CGlobal->GetLicenseServerID();
  393. }
  394. void SetRequestType(DWORD dwMode)
  395. {
  396. g_CGlobal->SetRequestType(dwMode);
  397. }
  398. int GetRequestType(void)
  399. {
  400. return g_CGlobal->GetRequestType();
  401. }
  402. BOOL IsOnlineCertRequestCreated()
  403. {
  404. return g_CGlobal->IsOnlineCertRequestCreated();
  405. }
  406. DWORD SetLRState(DWORD dwState)
  407. {
  408. return g_CGlobal->SetLRState(dwState);
  409. }
  410. DWORD SetCertificatePIN(LPTSTR lpszPIN)
  411. {
  412. return g_CGlobal->SetCertificatePIN(lpszPIN);
  413. }
  414. DWORD PopulateCountryComboBox(HWND hWndCmb)
  415. {
  416. return g_CGlobal->PopulateCountryComboBox(hWndCmb);
  417. }
  418. DWORD GetCountryCode(CString sDesc,LPTSTR szCode)
  419. {
  420. return g_CGlobal->GetCountryCode(sDesc,szCode);
  421. }
  422. DWORD PopulateProductComboBox(HWND hWndCmb)
  423. {
  424. return g_CGlobal->PopulateProductComboBox(hWndCmb);
  425. }
  426. DWORD GetProductCode(CString sDesc,LPTSTR szCode)
  427. {
  428. return g_CGlobal->GetProductCode(sDesc,szCode);
  429. }
  430. DWORD PopulateReasonComboBox(HWND hWndCmb, DWORD dwType)
  431. {
  432. return g_CGlobal->PopulateReasonComboBox(hWndCmb, dwType);
  433. }
  434. DWORD GetReasonCode(CString sDesc,LPTSTR szCode, DWORD dwType)
  435. {
  436. return g_CGlobal->GetReasonCode(sDesc,szCode, dwType);
  437. }
  438. DWORD ProcessRequest()
  439. {
  440. return g_CGlobal->ProcessRequest();
  441. }
  442. void LRSetLastRetCode(DWORD dwCode)
  443. {
  444. g_CGlobal->LRSetLastRetCode(dwCode);
  445. }
  446. DWORD LRGetLastRetCode()
  447. {
  448. return g_CGlobal->LRGetLastRetCode();
  449. }
  450. void LRPush(DWORD dwPageId)
  451. {
  452. g_CGlobal->LRPush(dwPageId);
  453. }
  454. DWORD LRPop()
  455. {
  456. return g_CGlobal->LRPop();
  457. }
  458. BOOL ValidateEmailId(CString sEmailId)
  459. {
  460. return g_CGlobal->ValidateEmailId(sEmailId);
  461. }
  462. BOOL CheckProgramValidity(CString sProgramName)
  463. {
  464. return g_CGlobal->CheckProgramValidity(sProgramName);
  465. }
  466. BOOL ValidateLRString(CString sStr)
  467. {
  468. return g_CGlobal->ValidateLRString(sStr);
  469. }
  470. DWORD PopulateCountryRegionComboBox(HWND hWndCmb)
  471. {
  472. return g_CGlobal->PopulateCountryRegionComboBox(hWndCmb);
  473. }
  474. DWORD SetLSLKP(TCHAR * tcLKP)
  475. {
  476. return g_CGlobal->SetLSLKP(tcLKP);
  477. }
  478. DWORD PingCH(void)
  479. {
  480. return g_CGlobal->PingCH();
  481. }
  482. DWORD AddRetailSPKToList(HWND hListView, TCHAR * lpszRetailSPK)
  483. {
  484. return g_CGlobal->AddRetailSPKToList(hListView, lpszRetailSPK);
  485. }
  486. void DeleteRetailSPKFromList(TCHAR * lpszRetailSPK)
  487. {
  488. g_CGlobal->DeleteRetailSPKFromList(lpszRetailSPK);
  489. return;
  490. }
  491. void LoadFromList(HWND hListView)
  492. {
  493. g_CGlobal->LoadFromList(hListView);
  494. return;
  495. }
  496. void UpdateSPKStatus(TCHAR * lpszRetailSPK, TCHAR tcStatus)
  497. {
  498. g_CGlobal->UpdateSPKStatus(lpszRetailSPK, tcStatus);
  499. return;
  500. }
  501. DWORD SetConfirmationNumber(TCHAR * tcConf)
  502. {
  503. return g_CGlobal->SetConfirmationNumber(tcConf);
  504. }
  505. DWORD SetLSSPK(TCHAR * tcp)
  506. {
  507. return g_CGlobal->SetLSSPK(tcp);
  508. }
  509. void SetCSRNumber(TCHAR * tcp)
  510. {
  511. g_CGlobal->SetCSRNumber(tcp);
  512. return;
  513. }
  514. TCHAR * GetCSRNumber(void)
  515. {
  516. return g_CGlobal->GetCSRNumber();
  517. }
  518. void SetWWWSite(TCHAR * tcp)
  519. {
  520. g_CGlobal->SetWWWSite(tcp);
  521. return;
  522. }
  523. TCHAR * GetWWWSite(void)
  524. {
  525. return g_CGlobal->GetWWWSite();
  526. }
  527. DWORD ResetLSSPK(void)
  528. {
  529. return g_CGlobal->ResetLSSPK();
  530. }
  531. void SetReFresh(DWORD dw)
  532. {
  533. g_CGlobal->SetReFresh(dw);
  534. }
  535. DWORD GetReFresh(void)
  536. {
  537. return g_CGlobal->GetReFresh();
  538. }
  539. void SetModifiedRetailSPK(CString sRetailSPK)
  540. {
  541. g_CGlobal->SetModifiedRetailSPK(sRetailSPK);
  542. }
  543. void GetModifiedRetailSPK(CString &sRetailSPK)
  544. {
  545. g_CGlobal->GetModifiedRetailSPK(sRetailSPK);
  546. }
  547. void ModifyRetailSPKFromList(TCHAR * lpszOldSPK,TCHAR * lpszNewSPK)
  548. {
  549. g_CGlobal->ModifyRetailSPKFromList(lpszOldSPK,lpszNewSPK);
  550. }
  551. DWORD ValidateRetailSPK(TCHAR * lpszRetailSPK)
  552. {
  553. return g_CGlobal->ValidateRetailSPK(lpszRetailSPK);
  554. }
  555. DWORD GetCountryDesc(CString sCode,LPTSTR szDesc)
  556. {
  557. return g_CGlobal->GetCountryDesc(sCode, szDesc);
  558. }
  559. DWORD CGlobal::SetEncodedInRegistry(LPCSTR lpszOID, LPCTSTR lpszValue)
  560. {
  561. HKEY hKey = NULL;
  562. DWORD dwDisposition = 0;
  563. DWORD dwRetCode = ERROR_SUCCESS;
  564. DWORD dwLen = 0;
  565. char * cpOut;
  566. HCRYPTPROV hProv = NULL;
  567. HCRYPTKEY hCKey = NULL;
  568. HCRYPTHASH hHash = NULL;
  569. PBYTE pbKey = NULL;
  570. DWORD cbKey = 0;
  571. if(!CryptAcquireContext(&hProv,
  572. NULL,
  573. NULL,
  574. PROV_RSA_FULL,
  575. CRYPT_VERIFYCONTEXT))
  576. {
  577. dwRetCode = GetLastError();
  578. goto done;
  579. }
  580. if(!CryptCreateHash(hProv,
  581. CALG_MD5,
  582. 0,
  583. 0,
  584. &hHash))
  585. {
  586. dwRetCode = GetLastError();
  587. goto done;
  588. }
  589. if(!CryptHashData(hHash,
  590. (BYTE *) lpszValue,
  591. lstrlen(lpszValue)*sizeof(TCHAR),
  592. 0))
  593. {
  594. dwRetCode = GetLastError();
  595. goto done;
  596. }
  597. if(!CryptDeriveKey(hProv,
  598. CALG_RC4,
  599. hHash,
  600. CRYPT_EXPORTABLE,
  601. &hCKey))
  602. {
  603. dwRetCode = GetLastError();
  604. goto done;
  605. }
  606. if(!CryptExportKey(
  607. hCKey,
  608. NULL,
  609. PUBLICKEYBLOB,
  610. 0,
  611. NULL,
  612. &cbKey))
  613. {
  614. dwRetCode = GetLastError();
  615. if(dwRetCode != ERROR_SUCCESS && dwRetCode != ERROR_MORE_DATA)
  616. goto done;
  617. pbKey = (PBYTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,cbKey);
  618. if(!CryptExportKey(
  619. hCKey,
  620. NULL,
  621. PUBLICKEYBLOB,
  622. 0,
  623. pbKey,
  624. &cbKey))
  625. {
  626. dwRetCode = GetLastError();
  627. goto done;
  628. }
  629. }
  630. dwRetCode = ConnectToLSRegistry();
  631. if(dwRetCode != ERROR_SUCCESS)
  632. {
  633. goto done;
  634. }
  635. dwRetCode = RegCreateKeyEx ( m_hLSRegKey,
  636. REG_LRWIZ_PARAMS,
  637. 0,
  638. NULL,
  639. REG_OPTION_NON_VOLATILE,
  640. KEY_ALL_ACCESS,
  641. NULL,
  642. &hKey,
  643. &dwDisposition);
  644. if(dwRetCode != ERROR_SUCCESS)
  645. {
  646. LRSetLastError(dwRetCode);
  647. dwRetCode = IDS_ERR_REGCREATE_FAILED;
  648. goto done;
  649. }
  650. if (_tcslen(lpszValue) != 0)
  651. {
  652. LSBase64EncodeA ((PBYTE) lpszValue, _tcslen(lpszValue)*sizeof(TCHAR), NULL, &dwLen);
  653. cpOut = new char[dwLen+1];
  654. if (cpOut == NULL)
  655. {
  656. dwRetCode = IDS_ERR_OUTOFMEM;
  657. goto done;
  658. }
  659. memset(cpOut, 0, dwLen+1);
  660. LSBase64EncodeA ((PBYTE) lpszValue, _tcslen(lpszValue)*sizeof(TCHAR), cpOut, &dwLen);
  661. }
  662. else
  663. {
  664. cpOut = new char[2];
  665. memset(cpOut, 0, 2);
  666. }
  667. RegSetValueExA ( hKey,
  668. lpszOID,
  669. 0,
  670. REG_SZ,
  671. (PBYTE) cpOut,
  672. dwLen
  673. );
  674. delete cpOut;
  675. done:
  676. if (hKey != NULL)
  677. {
  678. RegCloseKey(hKey);
  679. }
  680. DisconnectLSRegistry();
  681. return dwRetCode;
  682. }