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.

1850 lines
41 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: common.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "pch.h"
  11. #include <SnapBase.h>
  12. #include "common.h"
  13. #include "editor.h"
  14. #include "connection.h"
  15. #include "credui.h"
  16. #ifdef DEBUG_ALLOCATOR
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. #endif
  23. ////////////////////////////////////////////////////////////////////////////////////////
  24. extern LPCWSTR g_lpszRootDSE;
  25. ////////////////////////////////////////////////////////////////////////////////////////
  26. HRESULT OpenObjectWithCredentials(
  27. CConnectionData* pConnectData,
  28. const BOOL bUseCredentials,
  29. LPCWSTR lpszPath,
  30. const IID& iid,
  31. LPVOID* ppObject,
  32. HWND hWnd,
  33. HRESULT& hResult
  34. )
  35. {
  36. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  37. HRESULT hr = S_OK;
  38. hResult = S_OK;
  39. CWaitCursor cursor;
  40. CWnd* pCWnd = CWnd::FromHandle(hWnd);
  41. CCredentialObject* pCredObject = pConnectData->GetCredentialObject();
  42. if (bUseCredentials)
  43. {
  44. CString sUserName;
  45. UINT uiDialogResult = IDOK;
  46. WCHAR szPassword[MAX_PASSWORD_LENGTH + 1];
  47. while (uiDialogResult != IDCANCEL)
  48. {
  49. pCredObject->GetUsername(sUserName);
  50. pCredObject->GetPassword(szPassword);
  51. hr = ADsOpenObject((LPWSTR)lpszPath,
  52. (LPWSTR)(LPCWSTR)sUserName,
  53. szPassword,
  54. ADS_SECURE_AUTHENTICATION | ADS_FAST_BIND,
  55. iid,
  56. ppObject
  57. );
  58. ZeroMemory(szPassword, sizeof(WCHAR[MAX_PASSWORD_LENGTH + 1]));
  59. // If logon fails pop up the credentials dialog box
  60. //
  61. if (HRESULT_CODE(hr) == ERROR_LOGON_FAILURE ||
  62. HRESULT_CODE(hr) == ERROR_NOT_AUTHENTICATED ||
  63. HRESULT_CODE(hr) == ERROR_INVALID_PASSWORD ||
  64. HRESULT_CODE(hr) == ERROR_PASSWORD_EXPIRED ||
  65. HRESULT_CODE(hr) == ERROR_ACCOUNT_DISABLED ||
  66. HRESULT_CODE(hr) == ERROR_ACCOUNT_LOCKED_OUT ||
  67. hr == E_ADS_BAD_PATHNAME)
  68. {
  69. CString sConnectName;
  70. // GetConnectionNode() is NULL when the connection is first being
  71. // create, but since it is the connection node we can get the name
  72. // directly from the CConnectionData.
  73. //
  74. ASSERT(pConnectData != NULL);
  75. if (pConnectData->GetConnectionNode() == NULL)
  76. {
  77. pConnectData->GetName(sConnectName);
  78. }
  79. else
  80. {
  81. sConnectName = pConnectData->GetConnectionNode()->GetDisplayName();
  82. }
  83. CCredentialDialog credDialog(pCredObject, sConnectName, pCWnd);
  84. uiDialogResult = credDialog.DoModal();
  85. cursor.Restore();
  86. if (uiDialogResult == IDCANCEL)
  87. {
  88. hResult = E_FAIL;
  89. }
  90. else
  91. {
  92. hResult = S_OK;
  93. }
  94. }
  95. else
  96. {
  97. break;
  98. }
  99. }
  100. }
  101. else
  102. {
  103. hr = ADsOpenObject((LPWSTR)lpszPath, NULL, NULL,
  104. ADS_SECURE_AUTHENTICATION | ADS_FAST_BIND, iid, ppObject);
  105. }
  106. return hr;
  107. }
  108. HRESULT OpenObjectWithCredentials(
  109. CCredentialObject* pCredObject,
  110. LPCWSTR lpszPath,
  111. const IID& iid,
  112. LPVOID* ppObject
  113. )
  114. {
  115. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  116. HRESULT hr;
  117. if (pCredObject->UseCredentials())
  118. {
  119. CString sUserName;
  120. UINT uiDialogResult = IDOK;
  121. WCHAR szPassword[MAX_PASSWORD_LENGTH + 1];
  122. pCredObject->GetUsername(sUserName);
  123. pCredObject->GetPassword(szPassword);
  124. hr = ADsOpenObject((LPWSTR)lpszPath,
  125. (LPWSTR)(LPCWSTR)sUserName,
  126. szPassword,
  127. ADS_SECURE_AUTHENTICATION | ADS_FAST_BIND,
  128. iid,
  129. ppObject
  130. );
  131. ZeroMemory(szPassword, sizeof(WCHAR[MAX_PASSWORD_LENGTH + 1]));
  132. }
  133. else
  134. {
  135. hr = ADsOpenObject((LPWSTR)lpszPath, NULL, NULL,
  136. ADS_SECURE_AUTHENTICATION | ADS_FAST_BIND, iid, ppObject);
  137. }
  138. return hr;
  139. }
  140. HRESULT CALLBACK BindingCallbackFunction(LPCWSTR lpszPathName,
  141. DWORD dwReserved,
  142. REFIID riid,
  143. void FAR * FAR * ppObject,
  144. LPARAM lParam)
  145. {
  146. CCredentialObject* pCredObject = reinterpret_cast<CCredentialObject*>(lParam);
  147. if (pCredObject == NULL)
  148. {
  149. return E_FAIL;
  150. }
  151. HRESULT hr = OpenObjectWithCredentials(pCredObject,
  152. lpszPathName,
  153. riid,
  154. ppObject);
  155. return hr;
  156. }
  157. HRESULT GetRootDSEObject(CConnectionData* pConnectData,
  158. IADs** ppDirObject)
  159. {
  160. // Get data from connection node
  161. //
  162. CString sRootDSE, sServer, sPort, sLDAP;
  163. pConnectData->GetDomainServer(sServer);
  164. pConnectData->GetLDAP(sLDAP);
  165. pConnectData->GetPort(sPort);
  166. if (sServer != _T(""))
  167. {
  168. sRootDSE = sLDAP + sServer;
  169. if (sPort != _T(""))
  170. {
  171. sRootDSE = sRootDSE + _T(":") + sPort + _T("/");
  172. }
  173. else
  174. {
  175. sRootDSE = sRootDSE + _T("/");
  176. }
  177. sRootDSE = sRootDSE + g_lpszRootDSE;
  178. }
  179. else
  180. {
  181. sRootDSE = sLDAP + g_lpszRootDSE;
  182. }
  183. HRESULT hr, hCredResult;
  184. hr = OpenObjectWithCredentials(
  185. pConnectData,
  186. pConnectData->GetCredentialObject()->UseCredentials(),
  187. (LPWSTR)(LPCWSTR)sRootDSE,
  188. IID_IADs,
  189. (LPVOID*) ppDirObject,
  190. NULL,
  191. hCredResult
  192. );
  193. if ( FAILED(hr) )
  194. {
  195. if (SUCCEEDED(hCredResult))
  196. {
  197. ADSIEditErrorMessage(hr);
  198. }
  199. return hr;
  200. }
  201. return hr;
  202. }
  203. HRESULT GetItemFromRootDSE(LPCWSTR lpszRootDSEItem,
  204. CString& sItem,
  205. CConnectionData* pConnectData)
  206. {
  207. // Get data from connection node
  208. //
  209. CString sRootDSE, sServer, sPort, sLDAP;
  210. pConnectData->GetDomainServer(sServer);
  211. pConnectData->GetLDAP(sLDAP);
  212. pConnectData->GetPort(sPort);
  213. if (sServer != _T(""))
  214. {
  215. sRootDSE = sLDAP + sServer;
  216. if (sPort != _T(""))
  217. {
  218. sRootDSE = sRootDSE + _T(":") + sPort + _T("/");
  219. }
  220. else
  221. {
  222. sRootDSE = sRootDSE + _T("/");
  223. }
  224. sRootDSE = sRootDSE + g_lpszRootDSE;
  225. }
  226. else
  227. {
  228. sRootDSE = sLDAP + g_lpszRootDSE;
  229. }
  230. CComPtr<IADs> pADs;
  231. HRESULT hr, hCredResult;
  232. hr = OpenObjectWithCredentials(
  233. pConnectData,
  234. pConnectData->GetCredentialObject()->UseCredentials(),
  235. (LPWSTR)(LPCWSTR)sRootDSE,
  236. IID_IADs,
  237. (LPVOID*) &pADs,
  238. NULL,
  239. hCredResult
  240. );
  241. if ( FAILED(hr) )
  242. {
  243. if (SUCCEEDED(hCredResult))
  244. {
  245. ADSIEditErrorMessage(hr);
  246. }
  247. return hr;
  248. }
  249. VARIANT var;
  250. VariantInit(&var);
  251. hr = pADs->Get( (LPWSTR)lpszRootDSEItem, &var );
  252. if ( FAILED(hr) )
  253. {
  254. VariantClear(&var);
  255. return hr;
  256. }
  257. BSTR bstrItem = V_BSTR(&var);
  258. sItem = bstrItem;
  259. VariantClear(&var);
  260. return S_OK;
  261. }
  262. HRESULT VariantToStringList( VARIANT& refvar, CStringList& refstringlist)
  263. {
  264. HRESULT hr = S_OK;
  265. long start, end;
  266. if ( !(V_VT(&refvar) & VT_ARRAY) )
  267. {
  268. if ( V_VT(&refvar) != VT_BSTR )
  269. {
  270. hr = VariantChangeType( &refvar, &refvar,0, VT_BSTR );
  271. if( FAILED(hr) )
  272. {
  273. return hr;
  274. }
  275. }
  276. refstringlist.AddHead( V_BSTR(&refvar) );
  277. return hr;
  278. }
  279. SAFEARRAY *saAttributes = V_ARRAY( &refvar );
  280. //
  281. // Figure out the dimensions of the array.
  282. //
  283. hr = SafeArrayGetLBound( saAttributes, 1, &start );
  284. if( FAILED(hr) )
  285. return hr;
  286. hr = SafeArrayGetUBound( saAttributes, 1, &end );
  287. if( FAILED(hr) )
  288. return hr;
  289. VARIANT SingleResult;
  290. VariantInit( &SingleResult );
  291. //
  292. // Process the array elements.
  293. //
  294. for ( long idx = start; idx <= end; idx++ )
  295. {
  296. hr = SafeArrayGetElement( saAttributes, &idx, &SingleResult );
  297. if( FAILED(hr) )
  298. {
  299. return hr;
  300. }
  301. if ( V_VT(&SingleResult) != VT_BSTR )
  302. {
  303. if ( V_VT(&SingleResult) == VT_NULL )
  304. {
  305. V_VT(&SingleResult ) = VT_BSTR;
  306. V_BSTR(&SingleResult ) = SysAllocString(L"0");
  307. }
  308. else
  309. {
  310. hr = VariantChangeType( &SingleResult, &SingleResult,0, VT_BSTR );
  311. if( FAILED(hr) )
  312. {
  313. return hr;
  314. }
  315. }
  316. }
  317. //if ( V_VT(&SingleResult) != VT_BSTR )
  318. // return E_UNEXPECTED;
  319. refstringlist.AddHead( V_BSTR(&SingleResult) );
  320. VariantClear( &SingleResult );
  321. }
  322. return S_OK;
  323. } // VariantToStringList()
  324. /////////////////////////////////////////////////////////////////////
  325. HRESULT StringListToVariant( VARIANT& refvar, const CStringList& refstringlist)
  326. {
  327. HRESULT hr = S_OK;
  328. int cCount = refstringlist.GetCount();
  329. SAFEARRAYBOUND rgsabound[1];
  330. rgsabound[0].lLbound = 0;
  331. rgsabound[0].cElements = cCount;
  332. SAFEARRAY* psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
  333. if (NULL == psa)
  334. return E_OUTOFMEMORY;
  335. VariantClear( &refvar );
  336. V_VT(&refvar) = VT_VARIANT|VT_ARRAY;
  337. V_ARRAY(&refvar) = psa;
  338. VARIANT SingleResult;
  339. VariantInit( &SingleResult );
  340. V_VT(&SingleResult) = VT_BSTR;
  341. POSITION pos = refstringlist.GetHeadPosition();
  342. long i;
  343. for (i = 0; i < cCount, pos != NULL; i++)
  344. {
  345. V_BSTR(&SingleResult) = T2BSTR((LPCTSTR)refstringlist.GetNext(pos));
  346. hr = SafeArrayPutElement(psa, &i, &SingleResult);
  347. if( FAILED(hr) )
  348. return hr;
  349. }
  350. if (i != cCount || pos != NULL)
  351. return E_UNEXPECTED;
  352. return hr;
  353. } // StringListToVariant()
  354. ///////////////////////////////////////////////////////////////////////////////////////
  355. BOOL GetErrorMessage(HRESULT hr, CString& szErrorString, BOOL bTryADsIErrors)
  356. {
  357. HRESULT hrGetLast = S_OK;
  358. DWORD status;
  359. PTSTR ptzSysMsg = NULL;
  360. // first check if we have extended ADs errors
  361. if ((hr != S_OK) && bTryADsIErrors)
  362. {
  363. WCHAR Buf1[256], Buf2[256];
  364. hrGetLast = ::ADsGetLastError(&status, Buf1, 256, Buf2, 256);
  365. TRACE(_T("ADsGetLastError returned status of %lx, error: %s, name %s\n"),
  366. status, Buf1, Buf2);
  367. if ((status != ERROR_INVALID_DATA) && (status != 0))
  368. {
  369. hr = status;
  370. }
  371. }
  372. // try the system first
  373. int nChars = ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
  374. | FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr,
  375. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  376. (PTSTR)&ptzSysMsg, 0, NULL);
  377. if (nChars == 0)
  378. {
  379. //try ads errors
  380. static HMODULE g_adsMod = 0;
  381. if (0 == g_adsMod)
  382. g_adsMod = GetModuleHandle (L"activeds.dll");
  383. nChars = ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
  384. | FORMAT_MESSAGE_FROM_HMODULE, g_adsMod, hr,
  385. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  386. (PTSTR)&ptzSysMsg, 0, NULL);
  387. }
  388. if (nChars > 0)
  389. {
  390. szErrorString = ptzSysMsg;
  391. ::LocalFree(ptzSysMsg);
  392. }
  393. else
  394. {
  395. szErrorString.Format(L"Error code: X%x", hr);
  396. }
  397. return (nChars > 0);
  398. }
  399. ////////////////////////////////////////////////////////////////////////////////////
  400. typedef struct tagSYNTAXMAP
  401. {
  402. LPCWSTR lpszAttr;
  403. VARTYPE type;
  404. } SYNTAXMAP;
  405. SYNTAXMAP ldapSyntax[] =
  406. {
  407. _T("DN"), VT_BSTR,
  408. _T("DIRECTORYSTRING"), VT_BSTR,
  409. _T("IA5STRING"), VT_BSTR,
  410. _T("CASEIGNORESTRING"), VT_BSTR,
  411. _T("PRINTABLESTRING"), VT_BSTR,
  412. _T("NUMERICSTRING"), VT_BSTR,
  413. _T("UTCTIME"), VT_DATE,
  414. _T("ORNAME"), VT_BSTR,
  415. _T("OCTETSTRING"), VT_BSTR,
  416. _T("BOOLEAN"), VT_BOOL,
  417. _T("INTEGER"), VT_I4,
  418. _T("OID"), VT_BSTR,
  419. _T("INTEGER8"), VT_I8,
  420. _T("OBJECTSECURITYDESCRIPTOR"), VT_BSTR,
  421. NULL, 0,
  422. };
  423. #define MAX_ATTR_STRING_LENGTH 30
  424. VARTYPE VariantTypeFromSyntax(LPCWSTR lpszProp )
  425. {
  426. int idx=0;
  427. while( ldapSyntax[idx].lpszAttr )
  428. {
  429. if ( _wcsnicmp(lpszProp, ldapSyntax[idx].lpszAttr, MAX_ATTR_STRING_LENGTH) )
  430. {
  431. return ldapSyntax[idx].type;
  432. }
  433. idx++;
  434. }
  435. ASSERT(FALSE);
  436. return VT_BSTR;
  437. }
  438. //////////////////////////////////////////////////////////////////////////////////////////////////
  439. //
  440. // Function : GetStringFromADsValue
  441. //
  442. // Formats an ADSVALUE struct into a string
  443. //
  444. ///////////////////////////////////////////////////////////////////////////////////////////////////
  445. void GetStringFromADsValue(const PADSVALUE pADsValue, CString& szValue, DWORD dwMaxCharCount)
  446. {
  447. szValue.Empty();
  448. if (!pADsValue)
  449. {
  450. ASSERT(pADsValue);
  451. return;
  452. }
  453. CString sTemp;
  454. switch( pADsValue->dwType )
  455. {
  456. case ADSTYPE_DN_STRING :
  457. sTemp.Format(L"%s", pADsValue->DNString);
  458. break;
  459. case ADSTYPE_CASE_EXACT_STRING :
  460. sTemp.Format(L"%s", pADsValue->CaseExactString);
  461. break;
  462. case ADSTYPE_CASE_IGNORE_STRING:
  463. sTemp.Format(L"%s", pADsValue->CaseIgnoreString);
  464. break;
  465. case ADSTYPE_PRINTABLE_STRING :
  466. sTemp.Format(L"%s", pADsValue->PrintableString);
  467. break;
  468. case ADSTYPE_NUMERIC_STRING :
  469. sTemp.Format(L"%s", pADsValue->NumericString);
  470. break;
  471. case ADSTYPE_OBJECT_CLASS :
  472. sTemp.Format(L"%s", pADsValue->ClassName);
  473. break;
  474. case ADSTYPE_BOOLEAN :
  475. sTemp.Format(L"%s", ((DWORD)pADsValue->Boolean) ? L"TRUE" : L"FALSE");
  476. break;
  477. case ADSTYPE_INTEGER :
  478. sTemp.Format(L"%d", (DWORD) pADsValue->Integer);
  479. break;
  480. case ADSTYPE_OCTET_STRING :
  481. {
  482. CString sOctet;
  483. BYTE b;
  484. for ( DWORD idx=0; idx<pADsValue->OctetString.dwLength; idx++)
  485. {
  486. b = ((BYTE *)pADsValue->OctetString.lpValue)[idx];
  487. sOctet.Format(L"0x%02x ", b);
  488. sTemp += sOctet;
  489. if (dwMaxCharCount != 0 && sTemp.GetLength() > dwMaxCharCount)
  490. {
  491. break;
  492. }
  493. }
  494. }
  495. break;
  496. case ADSTYPE_LARGE_INTEGER :
  497. litow(pADsValue->LargeInteger, sTemp);
  498. break;
  499. case ADSTYPE_UTC_TIME :
  500. sTemp.Format(L"%02d/%02d/%04d %02d:%02d:%02d",
  501. pADsValue->UTCTime.wMonth,
  502. pADsValue->UTCTime.wDay,
  503. pADsValue->UTCTime.wYear,
  504. pADsValue->UTCTime.wHour,
  505. pADsValue->UTCTime.wMinute,
  506. pADsValue->UTCTime.wSecond);
  507. break;
  508. case ADSTYPE_NT_SECURITY_DESCRIPTOR: // I use the ACLEditor instead
  509. {
  510. }
  511. break;
  512. default :
  513. break;
  514. }
  515. szValue = sTemp;
  516. }
  517. //////////////////////////////////////////////////////////////////////////////////////////////////
  518. //
  519. // Function : GetStringFromADs
  520. //
  521. // Formats an ADS_ATTR_INFO structs values into strings and APPENDS them to a CStringList that is
  522. // passed in as a parameter.
  523. //
  524. ///////////////////////////////////////////////////////////////////////////////////////////////////
  525. void GetStringFromADs(const ADS_ATTR_INFO* pInfo, CStringList& sList, DWORD dwMaxCharCount)
  526. {
  527. CString sTemp;
  528. if ( pInfo == NULL )
  529. {
  530. return;
  531. }
  532. ADSVALUE *pValues = pInfo->pADsValues;
  533. for (DWORD x=0; x < pInfo->dwNumValues; x++)
  534. {
  535. if ( pInfo->dwADsType == ADSTYPE_INVALID )
  536. {
  537. continue;
  538. }
  539. sTemp.Empty();
  540. GetStringFromADsValue(pValues, sTemp, dwMaxCharCount);
  541. pValues++;
  542. sList.AddTail( sTemp );
  543. }
  544. }
  545. //////////////////////////////////////////////////////////////////////
  546. typedef struct tagSYNTAXTOADSMAP
  547. {
  548. LPCWSTR lpszAttr;
  549. ADSTYPE type;
  550. UINT nSyntaxResID;
  551. } SYNTAXTOADSMAP;
  552. SYNTAXTOADSMAP adsType[] =
  553. {
  554. L"2.5.5.0", ADSTYPE_INVALID, IDS_SYNTAX_UNKNOWN,
  555. L"2.5.5.1", ADSTYPE_DN_STRING, IDS_SYNTAX_DN,
  556. L"2.5.5.2", ADSTYPE_CASE_IGNORE_STRING, IDS_SYNTAX_OID,
  557. L"2.5.5.3", ADSTYPE_CASE_EXACT_STRING, IDS_SYNTAX_NOCASE_STR,
  558. L"2.5.5.4", ADSTYPE_CASE_IGNORE_STRING, IDS_SYNTAX_PRCS_STR,
  559. L"2.5.5.5", ADSTYPE_PRINTABLE_STRING, IDS_SYNTAX_I5_STR,
  560. L"2.5.5.6", ADSTYPE_NUMERIC_STRING, IDS_SYNTAX_NUMSTR,
  561. L"2.5.5.7", ADSTYPE_CASE_IGNORE_STRING, IDS_SYNTAX_DN_BINARY,
  562. L"2.5.5.8", ADSTYPE_BOOLEAN, IDS_SYNTAX_BOOLEAN,
  563. L"2.5.5.9", ADSTYPE_INTEGER, IDS_SYNTAX_INTEGER,
  564. L"2.5.5.10", ADSTYPE_OCTET_STRING, IDS_SYNTAX_OCTET,
  565. L"2.5.5.11", ADSTYPE_UTC_TIME, IDS_SYNTAX_UTC,
  566. L"2.5.5.12", ADSTYPE_CASE_IGNORE_STRING, IDS_SYNTAX_UNICODE,
  567. L"2.5.5.13", ADSTYPE_CASE_IGNORE_STRING, IDS_SYNTAX_ADDRESS,
  568. L"2.5.5.14", ADSTYPE_INVALID, IDS_SYNTAX_DNSTRING,
  569. L"2.5.5.15", ADSTYPE_NT_SECURITY_DESCRIPTOR, IDS_SYNTAX_SEC_DESC,
  570. L"2.5.5.16", ADSTYPE_LARGE_INTEGER, IDS_SYNTAX_LINT,
  571. L"2.5.5.17", ADSTYPE_OCTET_STRING, IDS_SYNTAX_SID,
  572. NULL, ADSTYPE_INVALID, IDS_SYNTAX_UNKNOWN
  573. };
  574. ADSTYPE GetADsTypeFromString(LPCWSTR lps, CString& szSyntaxName)
  575. {
  576. int idx=0;
  577. while( adsType[idx].lpszAttr )
  578. {
  579. if ( wcscmp(lps, adsType[idx].lpszAttr) == 0 )
  580. {
  581. szSyntaxName.LoadString(adsType[idx].nSyntaxResID);
  582. return adsType[idx].type;
  583. }
  584. idx++;
  585. }
  586. return ADSTYPE_INVALID;
  587. }
  588. ////////////////////////////////////////////////////////////////
  589. // Type conversions for LARGE_INTEGERs
  590. void wtoli(LPCWSTR p, LARGE_INTEGER& liOut)
  591. {
  592. liOut.QuadPart = 0;
  593. BOOL bNeg = FALSE;
  594. if (*p == L'-')
  595. {
  596. bNeg = TRUE;
  597. p++;
  598. }
  599. while (*p != L'\0')
  600. {
  601. liOut.QuadPart = 10 * liOut.QuadPart + (*p-L'0');
  602. p++;
  603. }
  604. if (bNeg)
  605. {
  606. liOut.QuadPart *= -1;
  607. }
  608. }
  609. void litow(LARGE_INTEGER& li, CString& sResult)
  610. {
  611. LARGE_INTEGER n;
  612. n.QuadPart = li.QuadPart;
  613. if (n.QuadPart == 0)
  614. {
  615. sResult = L"0";
  616. }
  617. else
  618. {
  619. CString sNeg;
  620. sResult = L"";
  621. if (n.QuadPart < 0)
  622. {
  623. sNeg = CString(L'-');
  624. n.QuadPart *= -1;
  625. }
  626. while (n.QuadPart > 0)
  627. {
  628. sResult += CString(L'0' + (n.QuadPart % 10));
  629. n.QuadPart = n.QuadPart / 10;
  630. }
  631. sResult = sResult + sNeg;
  632. }
  633. sResult.MakeReverse();
  634. }
  635. void ultow(ULONG ul, CString& sResult)
  636. {
  637. ULONG n;
  638. n = ul;
  639. if (n == 0)
  640. {
  641. sResult = L"0";
  642. }
  643. else
  644. {
  645. sResult = L"";
  646. while (n > 0)
  647. {
  648. sResult += CString(L'0' + (n % 10));
  649. n = n / 10;
  650. }
  651. }
  652. sResult.MakeReverse();
  653. }
  654. //+----------------------------------------------------------------------------
  655. //
  656. // Function: UnicodeToTchar
  657. //
  658. // Synopsis: Converts a Unicode string to a TCHAR string. Allocates memory
  659. // for the returned string using new. Callers must free the
  660. // string memory when done using delete.
  661. //
  662. // Returns: FALSE for out of memory failures.
  663. //
  664. //-----------------------------------------------------------------------------
  665. BOOL UnicodeToChar(LPWSTR pwszIn, LPSTR * ppszOut)
  666. {
  667. size_t len;
  668. len = WideCharToMultiByte(CP_ACP, 0, pwszIn, -1, NULL, 0, NULL, NULL);
  669. *ppszOut = new CHAR[len + 1];
  670. if (*ppszOut == NULL)
  671. {
  672. return FALSE;
  673. }
  674. if (WideCharToMultiByte(CP_ACP, 0, pwszIn, -1,
  675. *ppszOut, len, NULL, NULL) == 0)
  676. {
  677. delete[] *ppszOut;
  678. return FALSE;
  679. }
  680. return TRUE;
  681. }
  682. //+----------------------------------------------------------------------------
  683. //
  684. // Function: TcharToUnicode
  685. //
  686. // Synopsis: Converts a TCHAR string to a Unicode string. Allocates memory
  687. // for the returned string using new. Callers must free the
  688. // string memory when done using delete.
  689. //
  690. // Returns: FALSE for out of memory failures.
  691. //
  692. //-----------------------------------------------------------------------------
  693. BOOL CharToUnicode(LPSTR pszIn, LPWSTR * ppwszOut)
  694. {
  695. size_t len;
  696. len = MultiByteToWideChar(CP_ACP, 0, pszIn, -1, NULL, 0);
  697. *ppwszOut = new WCHAR[len + 1];
  698. if (*ppwszOut == NULL)
  699. {
  700. return FALSE;
  701. }
  702. if (MultiByteToWideChar(CP_ACP, 0, pszIn, -1, *ppwszOut, len) == 0)
  703. {
  704. delete[] *ppwszOut;
  705. return FALSE;
  706. }
  707. return TRUE;
  708. }
  709. /////////////////////////////////////////////////////////////////////
  710. // IO to/from Streams
  711. void SaveStringToStream(IStream* pStm, const CString& sString)
  712. {
  713. ULONG cbWrite;
  714. ULONG nLen;
  715. nLen = wcslen(sString)+1; // WCHAR including NULL
  716. VERIFY(SUCCEEDED(pStm->Write((void*)&nLen, sizeof(UINT),&cbWrite)));
  717. ASSERT(cbWrite == sizeof(UINT));
  718. VERIFY(SUCCEEDED(pStm->Write((void*)((LPCWSTR)sString), sizeof(WCHAR)*nLen,&cbWrite)));
  719. ASSERT(cbWrite == sizeof(WCHAR)*nLen);
  720. }
  721. HRESULT SaveStringListToStream(IStream* pStm, CStringList& sList)
  722. {
  723. // for each string in the list, write # of chars+NULL, and then the string
  724. ULONG cbWrite;
  725. ULONG nLen;
  726. UINT nCount;
  727. // write # of strings in list
  728. nCount = (UINT)sList.GetCount();
  729. VERIFY(SUCCEEDED(pStm->Write((void*)&nCount, sizeof(UINT),&cbWrite)));
  730. ASSERT(cbWrite == sizeof(UINT));
  731. POSITION pos = sList.GetHeadPosition();
  732. while (pos != NULL)
  733. {
  734. CString s = sList.GetNext(pos);
  735. SaveStringToStream(pStm, s);
  736. }
  737. return S_OK;
  738. }
  739. void LoadStringFromStream(IStream* pStm, CString& sString)
  740. {
  741. WCHAR szBuffer[256]; // REVIEW_MARCOC: hardcoded
  742. ULONG nLen; // WCHAR counting NULL
  743. ULONG cbRead;
  744. VERIFY(SUCCEEDED(pStm->Read((void*)&nLen,sizeof(UINT), &cbRead)));
  745. ASSERT(cbRead == sizeof(UINT));
  746. VERIFY(SUCCEEDED(pStm->Read((void*)szBuffer,sizeof(WCHAR)*nLen, &cbRead)));
  747. ASSERT(cbRead == sizeof(WCHAR)*nLen);
  748. sString = szBuffer;
  749. }
  750. HRESULT LoadStringListFromStream(IStream* pStm, CStringList& sList)
  751. {
  752. ULONG cbRead;
  753. ULONG nCount;
  754. VERIFY(SUCCEEDED(pStm->Read((void*)&nCount,sizeof(ULONG), &cbRead)));
  755. ASSERT(cbRead == sizeof(ULONG));
  756. for (int k=0; k< (int)nCount; k++)
  757. {
  758. CString sString;
  759. LoadStringFromStream(pStm, sString);
  760. sList.AddTail(sString);
  761. }
  762. if (sList.GetCount() == nCount)
  763. {
  764. return S_OK;
  765. }
  766. return E_FAIL;
  767. }
  768. /////////////////////////////////////////////////////////////////////
  769. /////////////////////// Message Boxes ///////////////////////////////
  770. /////////////////////////////////////////////////////////////////////
  771. int ADSIEditMessageBox(LPCTSTR lpszText, UINT nType)
  772. {
  773. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  774. return ::AfxMessageBox(lpszText, nType);
  775. }
  776. int ADSIEditMessageBox(UINT nIDPrompt, UINT nType)
  777. {
  778. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  779. return ::AfxMessageBox(nIDPrompt, nType);
  780. }
  781. void ADSIEditErrorMessage(PCWSTR pszMessage)
  782. {
  783. ADSIEditMessageBox(pszMessage, MB_OK);
  784. }
  785. void ADSIEditErrorMessage(HRESULT hr)
  786. {
  787. CString s;
  788. GetErrorMessage(hr, s);
  789. ADSIEditMessageBox(s, MB_OK);
  790. }
  791. void ADSIEditErrorMessage(HRESULT hr, UINT nIDPrompt, UINT nType)
  792. {
  793. CString s;
  794. GetErrorMessage(hr, s);
  795. CString szMessage;
  796. szMessage.Format(nIDPrompt, s);
  797. ADSIEditMessageBox(szMessage, MB_OK);
  798. }
  799. /////////////////////////////////////////////////////////////////////
  800. BOOL LoadStringsToComboBox(HINSTANCE hInstance, CComboBox* pCombo,
  801. UINT nStringID, UINT nMaxLen, UINT nMaxAddCount)
  802. {
  803. pCombo->ResetContent();
  804. ASSERT(hInstance != NULL);
  805. WCHAR* szBuf = (WCHAR*)malloc(sizeof(WCHAR)*nMaxLen);
  806. if (!szBuf)
  807. {
  808. return FALSE;
  809. }
  810. if ( ::LoadString(hInstance, nStringID, szBuf, nMaxLen) == 0)
  811. {
  812. free(szBuf);
  813. return FALSE;
  814. }
  815. LPWSTR* lpszArr = (LPWSTR*)malloc(sizeof(LPWSTR*)*nMaxLen);
  816. if (lpszArr)
  817. {
  818. int nArrEntries = 0;
  819. ParseNewLineSeparatedString(szBuf,lpszArr, &nArrEntries);
  820. if (nMaxAddCount < nArrEntries) nArrEntries = nMaxAddCount;
  821. for (int k=0; k<nArrEntries; k++)
  822. pCombo->AddString(lpszArr[k]);
  823. }
  824. if (szBuf)
  825. {
  826. free(szBuf);
  827. }
  828. if (lpszArr)
  829. {
  830. free(lpszArr);
  831. }
  832. return TRUE;
  833. }
  834. void ParseNewLineSeparatedString(LPWSTR lpsz,
  835. LPWSTR* lpszArr,
  836. int* pnArrEntries)
  837. {
  838. static WCHAR lpszSep[] = L"\n";
  839. *pnArrEntries = 0;
  840. int k = 0;
  841. lpszArr[k] = wcstok(lpsz, lpszSep);
  842. if (lpszArr[k] == NULL)
  843. return;
  844. while (TRUE)
  845. {
  846. WCHAR* lpszToken = wcstok(NULL, lpszSep);
  847. if (lpszToken != NULL)
  848. lpszArr[++k] = lpszToken;
  849. else
  850. break;
  851. }
  852. *pnArrEntries = k+1;
  853. }
  854. void LoadStringArrayFromResource(LPWSTR* lpszArr,
  855. UINT* nStringIDs,
  856. int nArrEntries,
  857. int* pnSuccessEntries)
  858. {
  859. CString szTemp;
  860. *pnSuccessEntries = 0;
  861. for (int k = 0;k < nArrEntries; k++)
  862. {
  863. if (!szTemp.LoadString(nStringIDs[k]))
  864. {
  865. lpszArr[k] = NULL;
  866. continue;
  867. }
  868. int iLength = szTemp.GetLength() + 1;
  869. lpszArr[k] = (LPWSTR)malloc(sizeof(WCHAR)*iLength);
  870. if (lpszArr[k] != NULL)
  871. {
  872. wcscpy(lpszArr[k], (LPWSTR)(LPCWSTR)szTemp);
  873. (*pnSuccessEntries)++;
  874. }
  875. }
  876. }
  877. ///////////////////////////////////////////////////////////////
  878. void GetStringArrayFromStringList(CStringList& sList, LPWSTR** ppStrArr, UINT* nCount)
  879. {
  880. *nCount = sList.GetCount();
  881. *ppStrArr = new LPWSTR[*nCount];
  882. UINT idx = 0;
  883. POSITION pos = sList.GetHeadPosition();
  884. while (pos != NULL)
  885. {
  886. CString szString = sList.GetNext(pos);
  887. (*ppStrArr)[idx] = new WCHAR[szString.GetLength() + 1];
  888. ASSERT((*ppStrArr)[idx] != NULL);
  889. wcscpy((*ppStrArr)[idx], szString);
  890. idx++;
  891. }
  892. *nCount = idx;
  893. }
  894. ////////////////////////////////////////////////////////////////
  895. ////////////////////////////////////////////////////////////////
  896. ////////////////////////////////////////////////////////////////
  897. BEGIN_MESSAGE_MAP(CByteArrayComboBox, CComboBox)
  898. ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelChange)
  899. END_MESSAGE_MAP()
  900. BOOL CByteArrayComboBox::Initialize(CByteArrayDisplay* pDisplay,
  901. DWORD dwDisplayFlags)
  902. {
  903. ASSERT(pDisplay != NULL);
  904. m_pDisplay = pDisplay;
  905. //
  906. // Load the combo box based on the flags given
  907. //
  908. if (dwDisplayFlags & BYTE_ARRAY_DISPLAY_HEX)
  909. {
  910. CString szHex;
  911. VERIFY(szHex.LoadString(IDS_HEXADECIMAL));
  912. int idx = AddString(szHex);
  913. if (idx != CB_ERR)
  914. {
  915. SetItemData(idx, BYTE_ARRAY_DISPLAY_HEX);
  916. }
  917. }
  918. if (dwDisplayFlags & BYTE_ARRAY_DISPLAY_OCT)
  919. {
  920. CString szOct;
  921. VERIFY(szOct.LoadString(IDS_OCTAL));
  922. int idx = AddString(szOct);
  923. if (idx != CB_ERR)
  924. {
  925. SetItemData(idx, BYTE_ARRAY_DISPLAY_OCT);
  926. }
  927. }
  928. if (dwDisplayFlags & BYTE_ARRAY_DISPLAY_DEC)
  929. {
  930. CString szDec;
  931. VERIFY(szDec.LoadString(IDS_DECIMAL));
  932. int idx = AddString(szDec);
  933. if (idx != CB_ERR)
  934. {
  935. SetItemData(idx, BYTE_ARRAY_DISPLAY_DEC);
  936. }
  937. }
  938. if (dwDisplayFlags & BYTE_ARRAY_DISPLAY_BIN)
  939. {
  940. CString szBin;
  941. VERIFY(szBin.LoadString(IDS_BINARY));
  942. int idx = AddString(szBin);
  943. if (idx != CB_ERR)
  944. {
  945. SetItemData(idx, BYTE_ARRAY_DISPLAY_BIN);
  946. }
  947. }
  948. return TRUE;
  949. }
  950. DWORD CByteArrayComboBox::GetCurrentDisplay()
  951. {
  952. DWORD dwRet = 0;
  953. int iSel = GetCurSel();
  954. if (iSel != CB_ERR)
  955. {
  956. dwRet = GetItemData(iSel);
  957. }
  958. return dwRet;
  959. }
  960. void CByteArrayComboBox::SetCurrentDisplay(DWORD dwSel)
  961. {
  962. int iCount = GetCount();
  963. for (int idx = 0; idx < iCount; idx++)
  964. {
  965. DWORD dwData = GetItemData(idx);
  966. if (dwData == dwSel)
  967. {
  968. SetCurSel(idx);
  969. return;
  970. }
  971. }
  972. }
  973. void CByteArrayComboBox::OnSelChange()
  974. {
  975. if (m_pDisplay != NULL)
  976. {
  977. int iSel = GetCurSel();
  978. if (iSel != CB_ERR)
  979. {
  980. DWORD dwData = GetItemData(iSel);
  981. m_pDisplay->OnTypeChange(dwData);
  982. }
  983. }
  984. }
  985. ////////////////////////////////////////////////////////////////
  986. CByteArrayEdit::CByteArrayEdit()
  987. : m_pData(NULL),
  988. m_dwLength(0),
  989. CEdit()
  990. {
  991. }
  992. CByteArrayEdit::~CByteArrayEdit()
  993. {
  994. }
  995. BEGIN_MESSAGE_MAP(CByteArrayEdit, CEdit)
  996. ON_CONTROL_REFLECT(EN_CHANGE, OnChange)
  997. END_MESSAGE_MAP()
  998. BOOL CByteArrayEdit::Initialize(CByteArrayDisplay* pDisplay)
  999. {
  1000. ASSERT(pDisplay != NULL);
  1001. m_pDisplay = pDisplay;
  1002. ConvertToFixedPitchFont(GetSafeHwnd());
  1003. return TRUE;
  1004. }
  1005. DWORD CByteArrayEdit::GetLength()
  1006. {
  1007. return m_dwLength;
  1008. }
  1009. BYTE* CByteArrayEdit::GetDataPtr()
  1010. {
  1011. return m_pData;
  1012. }
  1013. DWORD CByteArrayEdit::GetDataCopy(BYTE** ppData)
  1014. {
  1015. if (m_pData != NULL && m_dwLength > 0)
  1016. {
  1017. *ppData = new BYTE[m_dwLength];
  1018. if (*ppData != NULL)
  1019. {
  1020. memcpy(*ppData, m_pData, m_dwLength);
  1021. return m_dwLength;
  1022. }
  1023. }
  1024. *ppData = NULL;
  1025. return 0;
  1026. }
  1027. void CByteArrayEdit::SetData(BYTE* pData, DWORD dwLength)
  1028. {
  1029. if (m_pData != NULL)
  1030. {
  1031. delete[] m_pData;
  1032. m_pData = NULL;
  1033. m_dwLength = 0;
  1034. }
  1035. if (dwLength > 0 && pData != NULL)
  1036. {
  1037. //
  1038. // Set the new data
  1039. //
  1040. m_pData = new BYTE[dwLength];
  1041. if (m_pData != NULL)
  1042. {
  1043. memcpy(m_pData, pData, dwLength);
  1044. m_dwLength = dwLength;
  1045. }
  1046. }
  1047. }
  1048. void CByteArrayEdit::OnChangeDisplay()
  1049. {
  1050. CString szOldDisplay;
  1051. GetWindowText(szOldDisplay);
  1052. if (!szOldDisplay.IsEmpty())
  1053. {
  1054. BYTE* pByte = NULL;
  1055. DWORD dwLength = 0;
  1056. switch (m_pDisplay->GetPreviousDisplay())
  1057. {
  1058. case BYTE_ARRAY_DISPLAY_HEX :
  1059. dwLength = HexStringToByteArray(szOldDisplay, &pByte);
  1060. break;
  1061. case BYTE_ARRAY_DISPLAY_OCT :
  1062. dwLength = OctalStringToByteArray(szOldDisplay, &pByte);
  1063. break;
  1064. case BYTE_ARRAY_DISPLAY_DEC :
  1065. dwLength = DecimalStringToByteArray(szOldDisplay, &pByte);
  1066. break;
  1067. case BYTE_ARRAY_DISPLAY_BIN :
  1068. dwLength = BinaryStringToByteArray(szOldDisplay, &pByte);
  1069. break;
  1070. default :
  1071. ASSERT(FALSE);
  1072. break;
  1073. }
  1074. if (pByte != NULL && dwLength != (DWORD)-1)
  1075. {
  1076. SetData(pByte, dwLength);
  1077. delete[] pByte;
  1078. pByte = 0;
  1079. }
  1080. }
  1081. CString szDisplayValue;
  1082. switch (m_pDisplay->GetCurrentDisplay())
  1083. {
  1084. case BYTE_ARRAY_DISPLAY_HEX :
  1085. ByteArrayToHexString(GetDataPtr(), GetLength(), szDisplayValue);
  1086. break;
  1087. case BYTE_ARRAY_DISPLAY_OCT :
  1088. ByteArrayToOctalString(GetDataPtr(), GetLength(), szDisplayValue);
  1089. break;
  1090. case BYTE_ARRAY_DISPLAY_DEC :
  1091. ByteArrayToDecimalString(GetDataPtr(), GetLength(), szDisplayValue);
  1092. break;
  1093. case BYTE_ARRAY_DISPLAY_BIN :
  1094. ByteArrayToBinaryString(GetDataPtr(), GetLength(), szDisplayValue);
  1095. break;
  1096. default :
  1097. ASSERT(FALSE);
  1098. break;
  1099. }
  1100. SetWindowText(szDisplayValue);
  1101. }
  1102. void CByteArrayEdit::OnChange()
  1103. {
  1104. if (m_pDisplay != NULL)
  1105. {
  1106. m_pDisplay->OnEditChange();
  1107. }
  1108. }
  1109. ////////////////////////////////////////////////////////////////
  1110. BOOL CByteArrayDisplay::Initialize(UINT nEditCtrl,
  1111. UINT nComboCtrl,
  1112. DWORD dwDisplayFlags,
  1113. DWORD dwDefaultDisplay,
  1114. CWnd* pParent,
  1115. DWORD dwMaxSizeLimit,
  1116. UINT nMaxSizeMessageID)
  1117. {
  1118. //
  1119. // Initialize the edit control
  1120. //
  1121. VERIFY(m_edit.SubclassDlgItem(nEditCtrl, pParent));
  1122. VERIFY(m_edit.Initialize(this));
  1123. //
  1124. // Initialize the combo box
  1125. //
  1126. VERIFY(m_combo.SubclassDlgItem(nComboCtrl, pParent));
  1127. VERIFY(m_combo.Initialize(this, dwDisplayFlags));
  1128. m_dwMaxSizeBytes = dwMaxSizeLimit;
  1129. m_nMaxSizeMessage = nMaxSizeMessageID;
  1130. //
  1131. // Selects the default display in the combo box and
  1132. // populates the edit field
  1133. //
  1134. SetCurrentDisplay(dwDefaultDisplay);
  1135. m_dwPreviousDisplay = dwDefaultDisplay;
  1136. m_combo.SetCurrentDisplay(dwDefaultDisplay);
  1137. m_edit.OnChangeDisplay();
  1138. return TRUE;
  1139. }
  1140. void CByteArrayDisplay::OnEditChange()
  1141. {
  1142. }
  1143. void CByteArrayDisplay::OnTypeChange(DWORD dwDisplayType)
  1144. {
  1145. SetCurrentDisplay(dwDisplayType);
  1146. m_edit.OnChangeDisplay();
  1147. }
  1148. void CByteArrayDisplay::ClearData()
  1149. {
  1150. m_edit.SetData(NULL, 0);
  1151. m_edit.OnChangeDisplay();
  1152. }
  1153. void CByteArrayDisplay::SetData(BYTE* pData, DWORD dwLength)
  1154. {
  1155. if (dwLength > m_dwMaxSizeBytes)
  1156. {
  1157. //
  1158. // If the data is too large to load into the edit box
  1159. // load the provided message and set the edit box to read only
  1160. //
  1161. CString szMessage;
  1162. VERIFY(szMessage.LoadString(m_nMaxSizeMessage));
  1163. m_edit.SetWindowText(szMessage);
  1164. m_edit.SetReadOnly();
  1165. //
  1166. // Still need to set the data in the edit box even though we are not going to show it
  1167. //
  1168. m_edit.SetData(pData, dwLength);
  1169. }
  1170. else
  1171. {
  1172. m_edit.SetReadOnly(FALSE);
  1173. m_edit.SetData(pData, dwLength);
  1174. m_edit.OnChangeDisplay();
  1175. }
  1176. }
  1177. DWORD CByteArrayDisplay::GetData(BYTE** ppData)
  1178. {
  1179. CString szDisplay;
  1180. m_edit.GetWindowText(szDisplay);
  1181. if (!szDisplay.IsEmpty())
  1182. {
  1183. BYTE* pByte = NULL;
  1184. DWORD dwLength = 0;
  1185. switch (GetCurrentDisplay())
  1186. {
  1187. case BYTE_ARRAY_DISPLAY_HEX :
  1188. dwLength = HexStringToByteArray(szDisplay, &pByte);
  1189. break;
  1190. case BYTE_ARRAY_DISPLAY_OCT :
  1191. dwLength = OctalStringToByteArray(szDisplay, &pByte);
  1192. break;
  1193. case BYTE_ARRAY_DISPLAY_DEC :
  1194. dwLength = DecimalStringToByteArray(szDisplay, &pByte);
  1195. break;
  1196. case BYTE_ARRAY_DISPLAY_BIN :
  1197. dwLength = BinaryStringToByteArray(szDisplay, &pByte);
  1198. break;
  1199. default :
  1200. ASSERT(FALSE);
  1201. break;
  1202. }
  1203. if (pByte != NULL && dwLength != (DWORD)-1)
  1204. {
  1205. m_edit.SetData(pByte, dwLength);
  1206. delete[] pByte;
  1207. pByte = 0;
  1208. }
  1209. }
  1210. return m_edit.GetDataCopy(ppData);
  1211. }
  1212. void CByteArrayDisplay::SetCurrentDisplay(DWORD dwCurrentDisplay)
  1213. {
  1214. m_dwPreviousDisplay = m_dwCurrentDisplay;
  1215. m_dwCurrentDisplay = dwCurrentDisplay;
  1216. }
  1217. ////////////////////////////////////////////////////////////////////////////////
  1218. // String to byte array conversion routines
  1219. DWORD HexStringToByteArray(PCWSTR pszHexString, BYTE** ppByte)
  1220. {
  1221. CString szHexString = pszHexString;
  1222. BYTE* pToLargeArray = new BYTE[szHexString.GetLength()];
  1223. if (pToLargeArray == NULL)
  1224. {
  1225. *ppByte = NULL;
  1226. return (DWORD)-1;
  1227. }
  1228. UINT nByteCount = 0;
  1229. while (!szHexString.IsEmpty())
  1230. {
  1231. //
  1232. // Hex strings should always come 2 characters per byte
  1233. //
  1234. CString szTemp = szHexString.Left(2);
  1235. int iTempByte = 0;
  1236. swscanf(szTemp, L"%X", &iTempByte);
  1237. if (iTempByte <= 0xff)
  1238. {
  1239. pToLargeArray[nByteCount++] = iTempByte & 0xff;
  1240. }
  1241. else
  1242. {
  1243. //
  1244. // Format hex error
  1245. //
  1246. ADSIEditMessageBox(IDS_FORMAT_HEX_ERROR, MB_OK);
  1247. delete[] pToLargeArray;
  1248. pToLargeArray = NULL;
  1249. return (DWORD)-1;
  1250. }
  1251. //
  1252. // Take off the value retrieved and the trailing space
  1253. //
  1254. szHexString = szHexString.Right(szHexString.GetLength() - 3);
  1255. }
  1256. *ppByte = new BYTE[nByteCount];
  1257. if (*ppByte == NULL)
  1258. {
  1259. delete[] pToLargeArray;
  1260. pToLargeArray = NULL;
  1261. return (DWORD)-1;
  1262. }
  1263. memcpy(*ppByte, pToLargeArray, nByteCount);
  1264. delete[] pToLargeArray;
  1265. pToLargeArray = NULL;
  1266. return nByteCount;
  1267. }
  1268. void ByteArrayToHexString(BYTE* pByte, DWORD dwLength, CString& szHexString)
  1269. {
  1270. szHexString.Empty();
  1271. for (DWORD dwIdx = 0; dwIdx < dwLength; dwIdx++)
  1272. {
  1273. CString szTempString;
  1274. szTempString.Format(L"%2.2X", pByte[dwIdx]);
  1275. if (dwIdx != 0)
  1276. {
  1277. szHexString += L" ";
  1278. }
  1279. szHexString += szTempString;
  1280. }
  1281. }
  1282. DWORD OctalStringToByteArray(PCWSTR pszOctString, BYTE** ppByte)
  1283. {
  1284. CString szOctString = pszOctString;
  1285. BYTE* pToLargeArray = new BYTE[szOctString.GetLength()];
  1286. if (pToLargeArray == NULL)
  1287. {
  1288. *ppByte = NULL;
  1289. return (DWORD)-1;
  1290. }
  1291. UINT nByteCount = 0;
  1292. while (!szOctString.IsEmpty())
  1293. {
  1294. //
  1295. // Octal strings should always come 2 characters per byte
  1296. //
  1297. CString szTemp = szOctString.Left(3);
  1298. int iTempByte = 0;
  1299. swscanf(szTemp, L"%o", &iTempByte);
  1300. if (iTempByte <= 0xff)
  1301. {
  1302. pToLargeArray[nByteCount++] = iTempByte & 0xff;
  1303. }
  1304. else
  1305. {
  1306. //
  1307. // Format octal error
  1308. //
  1309. ADSIEditMessageBox(IDS_FORMAT_OCTAL_ERROR, MB_OK);
  1310. delete[] pToLargeArray;
  1311. pToLargeArray = NULL;
  1312. return (DWORD)-1;
  1313. }
  1314. //
  1315. // Take off the value retrieved and the trailing space
  1316. //
  1317. szOctString = szOctString.Right(szOctString.GetLength() - 4);
  1318. }
  1319. *ppByte = new BYTE[nByteCount];
  1320. if (*ppByte == NULL)
  1321. {
  1322. delete[] pToLargeArray;
  1323. pToLargeArray = NULL;
  1324. return (DWORD)-1;
  1325. }
  1326. memcpy(*ppByte, pToLargeArray, nByteCount);
  1327. delete[] pToLargeArray;
  1328. pToLargeArray = NULL;
  1329. return nByteCount;
  1330. }
  1331. void ByteArrayToOctalString(BYTE* pByte, DWORD dwLength, CString& szOctString)
  1332. {
  1333. szOctString.Empty();
  1334. for (DWORD dwIdx = 0; dwIdx < dwLength; dwIdx++)
  1335. {
  1336. CString szTempString;
  1337. szTempString.Format(L"%3.3o", pByte[dwIdx]);
  1338. if (dwIdx != 0)
  1339. {
  1340. szOctString += L" ";
  1341. }
  1342. szOctString += szTempString;
  1343. }
  1344. }
  1345. DWORD DecimalStringToByteArray(PCWSTR pszDecString, BYTE** ppByte)
  1346. {
  1347. CString szDecString = pszDecString;
  1348. BYTE* pToLargeArray = new BYTE[szDecString.GetLength()];
  1349. if (pToLargeArray == NULL)
  1350. {
  1351. *ppByte = NULL;
  1352. return 0;
  1353. }
  1354. UINT nByteCount = 0;
  1355. while (!szDecString.IsEmpty())
  1356. {
  1357. //
  1358. // Hex strings should always come 2 characters per byte
  1359. //
  1360. CString szTemp = szDecString.Left(3);
  1361. int iTempByte = 0;
  1362. swscanf(szTemp, L"%d", &iTempByte);
  1363. if (iTempByte <= 0xff)
  1364. {
  1365. pToLargeArray[nByteCount++] = iTempByte & 0xff;
  1366. }
  1367. else
  1368. {
  1369. //
  1370. // Format decimal error
  1371. //
  1372. ADSIEditMessageBox(IDS_FORMAT_DECIMAL_ERROR, MB_OK);
  1373. delete[] pToLargeArray;
  1374. pToLargeArray = NULL;
  1375. return (DWORD)-1;
  1376. }
  1377. //
  1378. // Take off the value retrieved and the trailing space
  1379. //
  1380. szDecString = szDecString.Right(szDecString.GetLength() - 4);
  1381. }
  1382. *ppByte = new BYTE[nByteCount];
  1383. if (*ppByte == NULL)
  1384. {
  1385. delete[] pToLargeArray;
  1386. pToLargeArray = NULL;
  1387. return (DWORD)-1;
  1388. }
  1389. memcpy(*ppByte, pToLargeArray, nByteCount);
  1390. delete[] pToLargeArray;
  1391. pToLargeArray = NULL;
  1392. return nByteCount;
  1393. }
  1394. void ByteArrayToDecimalString(BYTE* pByte, DWORD dwLength, CString& szDecString)
  1395. {
  1396. szDecString.Empty();
  1397. for (DWORD dwIdx = 0; dwIdx < dwLength; dwIdx++)
  1398. {
  1399. CString szTempString;
  1400. szTempString.Format(L"%3.3d", pByte[dwIdx]);
  1401. if (dwIdx != 0)
  1402. {
  1403. szDecString += L" ";
  1404. }
  1405. szDecString += szTempString;
  1406. }
  1407. }
  1408. DWORD BinaryStringToByteArray(PCWSTR pszBinString, BYTE** ppByte)
  1409. {
  1410. CString szBinString = pszBinString;
  1411. BYTE* pToLargeArray = new BYTE[szBinString.GetLength()];
  1412. if (pToLargeArray == NULL)
  1413. {
  1414. *ppByte = NULL;
  1415. return (DWORD)-1;
  1416. }
  1417. UINT nByteCount = 0;
  1418. while (!szBinString.IsEmpty())
  1419. {
  1420. //
  1421. // Binary strings should always come 8 characters per byte
  1422. //
  1423. BYTE chByte = 0;
  1424. CString szTemp = szBinString.Left(8);
  1425. for (int idx = 0; idx < 8; idx++)
  1426. {
  1427. if (szTemp[idx] == L'1')
  1428. {
  1429. chByte = 0x1 << (8 - idx);
  1430. }
  1431. }
  1432. pToLargeArray[nByteCount++] = chByte;
  1433. //
  1434. // Take off the value retrieved and the trailing space
  1435. //
  1436. szBinString = szBinString.Right(szBinString.GetLength() - 9);
  1437. }
  1438. *ppByte = new BYTE[nByteCount];
  1439. if (*ppByte == NULL)
  1440. {
  1441. delete[] pToLargeArray;
  1442. pToLargeArray = NULL;
  1443. return (DWORD)-1;
  1444. }
  1445. memcpy(*ppByte, pToLargeArray, nByteCount);
  1446. delete[] pToLargeArray;
  1447. pToLargeArray = NULL;
  1448. return nByteCount;
  1449. }
  1450. void ByteArrayToBinaryString(BYTE* pByte, DWORD dwLength, CString& szBinString)
  1451. {
  1452. szBinString.Empty();
  1453. for (DWORD dwIdx = 0; dwIdx < dwLength; dwIdx++)
  1454. {
  1455. CString szTempString;
  1456. BYTE chTemp = pByte[dwIdx];
  1457. for (size_t idx = 0; idx < sizeof(BYTE) * 8; idx++)
  1458. {
  1459. if ((chTemp & (0x1 << idx)) == 0)
  1460. {
  1461. szTempString = L'0' + szTempString;
  1462. }
  1463. else
  1464. {
  1465. szTempString = L'1' + szTempString;
  1466. }
  1467. }
  1468. if (dwIdx != 0)
  1469. {
  1470. szBinString += L" ";
  1471. }
  1472. szBinString += szTempString;
  1473. }
  1474. }
  1475. DWORD WCharStringToByteArray(PCWSTR pszWString, BYTE** ppByte)
  1476. {
  1477. DWORD dwSize = static_cast<DWORD>(wcslen(pszWString) * sizeof(WCHAR));
  1478. *ppByte = new BYTE[dwSize];
  1479. if (*ppByte != NULL)
  1480. {
  1481. memcpy(*ppByte, pszWString, dwSize);
  1482. }
  1483. else
  1484. {
  1485. dwSize = 0;
  1486. }
  1487. return dwSize;
  1488. }
  1489. void ByteArrayToWCharString(BYTE* pByte, DWORD dwLength, CString& szWString)
  1490. {
  1491. PWSTR pszValue = new WCHAR[(dwLength / sizeof(WCHAR)) + 1]; // +1 is for the /0 at the end
  1492. if (pszValue != NULL)
  1493. {
  1494. memset(pszValue, 0, dwLength + sizeof(WCHAR));
  1495. memcpy(pszValue, pByte, dwLength);
  1496. }
  1497. szWString = pszValue;
  1498. }
  1499. DWORD CharStringToByteArray(PCSTR pszCString, BYTE** ppByte)
  1500. {
  1501. DWORD dwSize = static_cast<DWORD>(strlen(pszCString) * sizeof(CHAR));
  1502. *ppByte = new BYTE[dwSize];
  1503. if (*ppByte != NULL)
  1504. {
  1505. memcpy(*ppByte, pszCString, dwSize);
  1506. }
  1507. else
  1508. {
  1509. dwSize = 0;
  1510. }
  1511. return dwSize;
  1512. }
  1513. void ByteArrayToCharString(BYTE* pByte, DWORD dwLength, CString& szCString)
  1514. {
  1515. PSTR pszValue = new CHAR[(dwLength / sizeof(CHAR)) + 1]; // +1 is for the /0 at the end
  1516. if (pszValue != NULL)
  1517. {
  1518. memset(pszValue, 0, dwLength + sizeof(CHAR));
  1519. memcpy(pszValue, pByte, dwLength);
  1520. }
  1521. PWSTR pwzValue = NULL;
  1522. if (CharToUnicode(pszValue, &pwzValue))
  1523. {
  1524. szCString = pwzValue;
  1525. delete[] pwzValue;
  1526. pwzValue = NULL;
  1527. }
  1528. }
  1529. //////////////////////////////////////////////////////////////////////////////
  1530. BOOL LoadFileAsByteArray(PCWSTR pszPath, LPBYTE* ppByteArray, DWORD* pdwSize)
  1531. {
  1532. if (ppByteArray == NULL ||
  1533. pdwSize == NULL)
  1534. {
  1535. return FALSE;
  1536. }
  1537. CFile file;
  1538. if (!file.Open(pszPath, CFile::modeRead | CFile::shareDenyNone | CFile::typeBinary))
  1539. {
  1540. return FALSE;
  1541. }
  1542. *pdwSize = file.GetLength();
  1543. *ppByteArray = new BYTE[*pdwSize];
  1544. if (*ppByteArray == NULL)
  1545. {
  1546. return FALSE;
  1547. }
  1548. UINT uiCount = file.Read(*ppByteArray, *pdwSize);
  1549. ASSERT(uiCount == *pdwSize);
  1550. return TRUE;
  1551. }
  1552. //+---------------------------------------------------------------------------
  1553. //
  1554. // Function: ConvertToFixedPitchFont
  1555. //
  1556. // Synopsis: Converts a windows font to a fixed pitch font.
  1557. //
  1558. // Arguments: [hwnd] -- IN window handle
  1559. //
  1560. // Returns: BOOL
  1561. //
  1562. // History: 7/15/1995 RaviR Created
  1563. //
  1564. //----------------------------------------------------------------------------
  1565. BOOL ConvertToFixedPitchFont(HWND hwnd)
  1566. {
  1567. LOGFONT lf;
  1568. HFONT hFont = reinterpret_cast<HFONT>(::SendMessage(hwnd, WM_GETFONT, 0, 0));
  1569. if (!GetObject(hFont, sizeof(LOGFONT), &lf))
  1570. {
  1571. return FALSE;
  1572. }
  1573. lf.lfQuality = PROOF_QUALITY;
  1574. lf.lfPitchAndFamily &= ~VARIABLE_PITCH;
  1575. lf.lfPitchAndFamily |= FIXED_PITCH;
  1576. lf.lfFaceName[0] = L'\0';
  1577. HFONT hf = CreateFontIndirect(&lf);
  1578. if (hf == NULL)
  1579. {
  1580. return FALSE;
  1581. }
  1582. ::SendMessage(hwnd, WM_SETFONT, (WPARAM)hf, (LPARAM)TRUE); // macro in windowsx.h
  1583. return TRUE;
  1584. }