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.

1476 lines
42 KiB

  1. // MdKey.cpp
  2. #include "stdafx.h"
  3. #define INITGUID
  4. #define _WIN32_DCOM
  5. #undef DEFINE_GUID // Added for NT5 migration
  6. #include <ole2.h>
  7. #include <coguid.h>
  8. #include "iadmw.h"
  9. #include "iiscnfg.h"
  10. #include "mdkey.h"
  11. #include "iwamreg.h"
  12. #include "strfn.h"
  13. #define TIMEOUT_VALUE 5000
  14. INT_PTR CALLBACK pSecureRetryIgnoreAllDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
  15. extern BOOL g_bGlobalWriteUnSecuredIfFailed_All;
  16. CMDKey::CMDKey():
  17. m_cCoInits(0)
  18. {
  19. m_pcCom = NULL;
  20. m_hKey = NULL;
  21. _tcscpy(m_szCurrentNodeName, _T(""));
  22. }
  23. CMDKey::~CMDKey()
  24. {
  25. this->Close();
  26. // while there are outstanding coinits, close them
  27. while ( m_cCoInits > 0 && !(m_cCoInits < 0) )
  28. DoCoUnInit();
  29. }
  30. HRESULT CMDKey::DoCoInitEx()
  31. {
  32. HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  33. // track our calls to coinit
  34. if ( SUCCEEDED(hRes) )
  35. {
  36. m_cCoInits++;
  37. }
  38. return hRes;
  39. }
  40. void CMDKey::DoCoUnInit()
  41. {
  42. HRESULT hRes = NOERROR;
  43. // if there are outstanding coinits, uninit one
  44. if ( m_cCoInits > 0 )
  45. {
  46. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoUninitialize().Start.")));
  47. CoUninitialize();
  48. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoUninitialize().End.")));
  49. m_cCoInits--;
  50. }
  51. // we shouldn't ever have a negative count. But just in case...
  52. ASSERT( m_cCoInits >= 0 );
  53. if ( m_cCoInits < 0 )
  54. {
  55. // something is seriously wrong here. Prevent looping
  56. // by going straight to zero, and write an error to the log.
  57. m_cCoInits = 0;
  58. iisDebugOut((LOG_TYPE_WARN, _T("WARNING: CoInits in mdkey have gone negative")));
  59. }
  60. }
  61. HRESULT CMDKey::OpenNode(LPCTSTR pchSubKeyPath)
  62. {
  63. HRESULT hRes = ERROR_SUCCESS;
  64. IClassFactory * pcsfFactory = NULL;
  65. BOOL b = FALSE;
  66. m_pcCom = NULL;
  67. m_hKey = NULL;
  68. WCHAR szSubKeyPath[_MAX_PATH];
  69. pszFailedAPI = NULL;
  70. _tcscpy(m_szCurrentNodeName, pchSubKeyPath);
  71. if ( !pchSubKeyPath || !(*pchSubKeyPath) )
  72. {
  73. *szSubKeyPath = L'\0';
  74. }
  75. else
  76. {
  77. #if defined(UNICODE) || defined(_UNICODE)
  78. _tcscpy(szSubKeyPath, pchSubKeyPath);
  79. #else
  80. MultiByteToWideChar( CP_ACP, 0, pchSubKeyPath, -1, szSubKeyPath, _MAX_PATH);
  81. #endif
  82. }
  83. hRes = DoCoInitEx();
  84. if (FAILED(hRes))
  85. {
  86. iisDebugOut((LOG_TYPE_ERROR, _T("CoInitializeEx() failed, hRes=%x\n"), hRes));
  87. }
  88. hRes = CoGetClassObject(GETAdminBaseCLSID(TRUE), CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pcsfFactory);
  89. if (FAILED(hRes))
  90. {
  91. MyMessageBox(NULL, _T("CoGetClassObject"), hRes, MB_OK | MB_SETFOREGROUND);
  92. }
  93. else
  94. {
  95. hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminBase, (void **) &m_pcCom);
  96. pcsfFactory->Release();
  97. if (FAILED(hRes))
  98. {
  99. MyMessageBox(NULL, _T("CoCreateInstance"), hRes, MB_OK | MB_SETFOREGROUND);
  100. }
  101. else
  102. {
  103. _tcscpy(m_szCurrentNodeName, pchSubKeyPath);
  104. hRes = m_pcCom->OpenKey(METADATA_MASTER_ROOT_HANDLE,szSubKeyPath,METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,TIMEOUT_VALUE,&m_hKey);
  105. if (FAILED(hRes))
  106. {
  107. if (hRes != RETURNCODETOHRESULT(ERROR_PATH_NOT_FOUND))
  108. {
  109. MyMessageBox(NULL, _T("OpenKey"), hRes, MB_OK | MB_SETFOREGROUND);
  110. }
  111. }
  112. else
  113. {
  114. b = TRUE;
  115. }
  116. } // end of CoCreateInstance
  117. } // end of CoGetClassObject
  118. if (!b) {this->Close();}
  119. return hRes;
  120. }
  121. HRESULT CMDKey::CreateNode(METADATA_HANDLE hKeyBase, LPCTSTR pchSubKeyPath)
  122. {
  123. HRESULT hRes = ERROR_SUCCESS;
  124. IClassFactory * pcsfFactory = NULL;
  125. BOOL b = FALSE;
  126. m_pcCom = NULL;
  127. m_hKey = NULL;
  128. WCHAR szSubKeyPath[_MAX_PATH];
  129. _tcscpy(m_szCurrentNodeName, pchSubKeyPath);
  130. pszFailedAPI = NULL;
  131. if ( !pchSubKeyPath || !(*pchSubKeyPath) )
  132. {
  133. *szSubKeyPath = L'\0';
  134. }
  135. else
  136. {
  137. #if defined(UNICODE) || defined(_UNICODE)
  138. _tcscpy(szSubKeyPath, pchSubKeyPath);
  139. #else
  140. MultiByteToWideChar( CP_ACP, 0, pchSubKeyPath, -1, szSubKeyPath, _MAX_PATH);
  141. #endif
  142. }
  143. hRes = DoCoInitEx();
  144. if (FAILED(hRes))
  145. {
  146. iisDebugOut((LOG_TYPE_ERROR, _T("CoInitializeEx() failed, hRes=%x\n"), hRes));
  147. }
  148. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoGetClassObject().Start.")));
  149. hRes = CoGetClassObject(GETAdminBaseCLSID(TRUE), CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pcsfFactory);
  150. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoGetClassObject().End.")));
  151. if (FAILED(hRes))
  152. {
  153. MyMessageBox(NULL, _T("CoGetClassObject"), hRes, MB_OK | MB_SETFOREGROUND);
  154. }
  155. else
  156. {
  157. hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminBase, (void **) &m_pcCom);
  158. pcsfFactory->Release();
  159. if (FAILED(hRes))
  160. {
  161. MyMessageBox(NULL, _T("CreateInstance"), hRes, MB_OK | MB_SETFOREGROUND);
  162. }
  163. else
  164. {
  165. _tcscpy(m_szCurrentNodeName, pchSubKeyPath);
  166. hRes = m_pcCom->OpenKey(hKeyBase,szSubKeyPath,METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,TIMEOUT_VALUE,&m_hKey);
  167. if (FAILED(hRes))
  168. {
  169. if (hRes == RETURNCODETOHRESULT(ERROR_PATH_NOT_FOUND))
  170. {
  171. METADATA_HANDLE RootHandle;
  172. _tcscpy(m_szCurrentNodeName, pchSubKeyPath);
  173. hRes = m_pcCom->OpenKey(hKeyBase,L"",METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,TIMEOUT_VALUE,&RootHandle);
  174. hRes = m_pcCom->AddKey(RootHandle, szSubKeyPath);
  175. if (FAILED(hRes))
  176. {
  177. MyMessageBox(NULL, _T("AddKey"), hRes, MB_OK | MB_SETFOREGROUND);
  178. }
  179. hRes = m_pcCom->CloseKey(RootHandle);
  180. if (FAILED(hRes))
  181. {
  182. MyMessageBox(NULL, _T("CloseKey of the AddKey"), hRes, MB_OK | MB_SETFOREGROUND);
  183. }
  184. else
  185. {
  186. // open it again to set m_hKey
  187. _tcscpy(m_szCurrentNodeName, pchSubKeyPath);
  188. hRes = m_pcCom->OpenKey(hKeyBase,szSubKeyPath,METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,TIMEOUT_VALUE,&m_hKey);
  189. if (FAILED(hRes))
  190. {
  191. MyMessageBox(NULL, _T("OpenKey"), hRes, MB_OK | MB_SETFOREGROUND);
  192. }
  193. else
  194. {
  195. b = TRUE;
  196. }
  197. }
  198. }
  199. else
  200. {
  201. iisDebugOut((LOG_TYPE_ERROR, _T("calling OpenKey()...failed....something other than ERROR_PATH_NOT_FOUND\n")));
  202. MyMessageBox(NULL, _T("OpenKey"), hRes, MB_OK | MB_SETFOREGROUND);
  203. }
  204. }
  205. else
  206. {
  207. b = TRUE;
  208. } // end of OpenKey
  209. } // end of CoCreateInstance
  210. } // end of CoGetClassObject
  211. if (!b) {this->Close();}
  212. return hRes;
  213. }
  214. HRESULT CMDKey::ForceWriteMetabaseToDisk()
  215. {
  216. HRESULT hRes = ERROR_SUCCESS;
  217. IClassFactory * pcsfFactory = NULL;
  218. m_pcCom = NULL;
  219. hRes = DoCoInitEx();
  220. if (FAILED(hRes))
  221. {
  222. iisDebugOut((LOG_TYPE_ERROR, _T("CoInitializeEx() failed, hRes=%x\n"), hRes));
  223. }
  224. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoGetClassObject().Start.")));
  225. hRes = CoGetClassObject(GETAdminBaseCLSID(TRUE), CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pcsfFactory);
  226. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoGetClassObject().End.")));
  227. if (FAILED(hRes))
  228. {
  229. MyMessageBox(NULL, _T("CoGetClassObject"), hRes, MB_OK | MB_SETFOREGROUND);
  230. }
  231. else
  232. {
  233. hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminBase, (void **) &m_pcCom);
  234. pcsfFactory->Release();
  235. if (FAILED(hRes))
  236. {
  237. MyMessageBox(NULL, _T("CoCreateInstance"), hRes, MB_OK | MB_SETFOREGROUND);
  238. }
  239. else
  240. {
  241. if (m_pcCom)
  242. {
  243. hRes = m_pcCom->SaveData();
  244. iisDebugOut((LOG_TYPE_TRACE, _T("CMDKey::ForceWriteMetabaseToDisk():Return=0x%x.\n"),hRes));
  245. }
  246. } // end of CoCreateInstance
  247. } // end of CoGetClassObject
  248. return hRes;
  249. }
  250. HRESULT CMDKey::Close()
  251. {
  252. HRESULT hRes = ERROR_SUCCESS;
  253. if (m_pcCom)
  254. {
  255. if (m_hKey){hRes = m_pcCom->CloseKey(m_hKey);}
  256. hRes = m_pcCom->Release();
  257. }
  258. DoCoUnInit();
  259. m_pcCom = NULL;
  260. m_hKey = NULL;
  261. _tcscpy(m_szCurrentNodeName, _T(""));
  262. return hRes;
  263. }
  264. BOOL CMDKey::IsEmpty( PWCHAR pszSubString )
  265. {
  266. int ReturnIndex;
  267. METADATA_RECORD mdrData;
  268. DWORD dwRequiredDataLen = 0;
  269. HRESULT hRes = ERROR_SUCCESS;
  270. UCHAR ReturnBuf[256];
  271. for(ReturnIndex=0;ReturnIndex<sizeof(ReturnBuf);ReturnIndex++)ReturnBuf[ReturnIndex]=0xff;
  272. MD_SET_DATA_RECORD(&mdrData, 0, METADATA_NO_ATTRIBUTES, 0, 0, sizeof(ReturnBuf), (PBYTE) ReturnBuf)
  273. hRes = m_pcCom->EnumData(m_hKey, pszSubString, &mdrData, 0, &dwRequiredDataLen);
  274. if (FAILED(hRes))
  275. {
  276. if(hRes == RETURNCODETOHRESULT(ERROR_NO_MORE_ITEMS) || hRes == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER) )
  277. {
  278. return TRUE;
  279. }
  280. else
  281. {
  282. MyMessageBox(NULL, _T("EnumData"), hRes, MB_OK | MB_SETFOREGROUND);
  283. }
  284. }
  285. return (hRes != ERROR_SUCCESS);
  286. }
  287. int CMDKey::GetNumberOfSubKeys( PWCHAR pszSubString )
  288. {
  289. int i=0;
  290. HRESULT hRes = ERROR_SUCCESS;
  291. WCHAR NameBuf[METADATA_MAX_NAME_LEN];
  292. while (hRes == ERROR_SUCCESS)
  293. {
  294. hRes = m_pcCom->EnumKeys(m_hKey, pszSubString, NameBuf, i++);
  295. }
  296. if (hRes == RETURNCODETOHRESULT(ERROR_NO_MORE_ITEMS))
  297. {
  298. return (--i);
  299. }
  300. else
  301. {
  302. MyMessageBox(NULL, _T("EnumKeys"), hRes, MB_OK | MB_SETFOREGROUND);
  303. return (0);
  304. }
  305. }
  306. #if !defined(UNICODE) && !defined(_UNICODE)
  307. void MyMultiByteToWideChar( char *sData, WCHAR *wData, int cbBufSize, BOOL fMultiSZ)
  308. {
  309. MultiByteToWideChar( CP_ACP, 0, sData, -1, wData, cbBufSize );
  310. while (fMultiSZ)
  311. {
  312. sData = _tcsninc( sData, _tcslen(sData)) + 1;
  313. while (*wData++);
  314. if (*sData)
  315. {
  316. MultiByteToWideChar( CP_ACP, 0, sData, -1, wData, cbBufSize );
  317. }
  318. else
  319. {
  320. *wData = L'\0';
  321. break;
  322. }
  323. }
  324. return;
  325. }
  326. void MyWideCharToMultiByte( WCHAR *wData, char *sData, int cbBufSize, BOOL fMultiSZ)
  327. {
  328. WideCharToMultiByte( CP_ACP, 0, wData, -1, sData, cbBufSize, NULL, NULL );
  329. while (fMultiSZ)
  330. {
  331. while (*wData++);
  332. sData = _tcsninc( sData, _tcslen(sData)) + 1;
  333. if (*wData)
  334. {
  335. WideCharToMultiByte( CP_ACP, 0, wData, -1, sData, cbBufSize, NULL, NULL );
  336. }
  337. else
  338. {
  339. *sData = '\0';
  340. break;
  341. }
  342. }
  343. return;
  344. }
  345. #endif // not unicode
  346. HRESULT CMDKey::SetData(DWORD id,DWORD attr,DWORD uType,DWORD dType,DWORD cbLen, LPBYTE pbData,PWCHAR pszSubString )
  347. {
  348. HRESULT hRes = ERROR_SUCCESS;
  349. METADATA_RECORD mdrData;
  350. BUFFER bufData;
  351. WCHAR *pData = (WCHAR *)pbData;
  352. int iPlsDoNoEncryption = FALSE;
  353. switch (dType)
  354. {
  355. case STRING_METADATA:
  356. case EXPANDSZ_METADATA:
  357. #if defined(UNICODE) || defined(_UNICODE)
  358. pData = (WCHAR *)pbData;
  359. #else
  360. if ( ! (bufData.Resize(cbLen * sizeof(WCHAR))) )
  361. {
  362. // insufficient memory
  363. iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::SetData() failed to allocate memory.\n")));
  364. hRes = RETURNCODETOHRESULT(GetLastError());
  365. goto SetData_Exit;
  366. }
  367. pData = (WCHAR *)(bufData.QueryPtr());
  368. MyMultiByteToWideChar( (LPTSTR)pbData, pData, cbLen, FALSE);
  369. cbLen = cbLen * sizeof(WCHAR);
  370. #endif
  371. break;
  372. case MULTISZ_METADATA:
  373. #if defined(UNICODE) || defined(_UNICODE)
  374. pData = (WCHAR *)pbData;
  375. #else
  376. if ( ! (bufData.Resize(cbLen * sizeof(WCHAR))) )
  377. {
  378. // insufficient memory
  379. iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::SetData() failed to allocate memory.\n")));
  380. hRes = RETURNCODETOHRESULT(GetLastError());
  381. goto SetData_Exit;
  382. }
  383. pData = (WCHAR *)(bufData.QueryPtr());
  384. MyMultiByteToWideChar( (LPTSTR)pbData, pData, cbLen, TRUE );
  385. cbLen = cbLen * sizeof(WCHAR);
  386. #endif
  387. break;
  388. default:
  389. break;
  390. }
  391. //DisplayStringForMetabaseID(id);
  392. //_tcscpy(m_szCurrentNodeName, _T(""));
  393. TCHAR lpReturnString[50];
  394. ReturnStringForMetabaseID(id, lpReturnString);
  395. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("CMDKey::SetData[%s:%d:%s].\n"), m_szCurrentNodeName, id, lpReturnString));
  396. MD_SET_DATA_RECORD(&mdrData, id, attr, uType, dType, cbLen, (LPBYTE)pData);
  397. hRes = m_pcCom->SetData(m_hKey, pszSubString, &mdrData);
  398. if (FAILED(hRes))
  399. {
  400. // Check if it failed...
  401. // if it failed and the METADATA_SECURE flag is set, then
  402. // check if we can retry without the METADATA_SECURE flag!
  403. if ( attr & METADATA_SECURE )
  404. {
  405. if (TRUE == g_bGlobalWriteUnSecuredIfFailed_All)
  406. {
  407. iPlsDoNoEncryption = TRUE;
  408. }
  409. else
  410. {
  411. if (TRUE == DialogBoxParam((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDD_ENCRYPTED_WRITE_ERROR_DIALOG), NULL, pSecureRetryIgnoreAllDlgProc, (LPARAM)hRes))
  412. {
  413. iPlsDoNoEncryption = TRUE;
  414. }
  415. }
  416. if (TRUE == iPlsDoNoEncryption)
  417. {
  418. iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::SetData() failed on a encrypt entry. try to write it out unencrypted.\n")));
  419. attr &= ~METADATA_SECURE;
  420. MD_SET_DATA_RECORD(&mdrData, id, attr, uType, dType, cbLen, (LPBYTE)pData);
  421. hRes = m_pcCom->SetData(m_hKey, pszSubString, &mdrData);
  422. if (FAILED(hRes))
  423. {
  424. iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::SetData() failed on write on encrypt entry as unencrypted.\n")));
  425. }
  426. else
  427. {
  428. iisDebugOut((LOG_TYPE_TRACE, _T("CMDKey::SetData() success on write on encrypt entry as unencrypted.\n")));
  429. }
  430. // set the attr back to what it was
  431. attr &= ~METADATA_SECURE;
  432. }
  433. }
  434. }
  435. goto SetData_Exit;
  436. SetData_Exit:
  437. if (FAILED(hRes))
  438. {
  439. MyMessageBox(NULL, IDS_SETDATA_ERROR, (int) hRes, MB_OK | MB_SETFOREGROUND);
  440. }
  441. return hRes;
  442. }
  443. BOOL CMDKey::GetData(DWORD id,DWORD *pdwAttr,DWORD *pdwUType,DWORD *pdwDType,DWORD *pcbLen,LPBYTE pbData,DWORD BufSize,PWCHAR pszSubString )
  444. {
  445. return GetData(id,pdwAttr,pdwUType,pdwDType,pcbLen,pbData,BufSize,0,0,0,pszSubString);
  446. }
  447. BOOL
  448. CMDKey::GetData(CMDValue &Value, DWORD dwId, PWCHAR pszSubString )
  449. {
  450. DWORD dwAttr;
  451. DWORD dwUType;
  452. DWORD dwDType;
  453. DWORD cbLen;
  454. BUFFER bufData;
  455. if (!GetData(dwId,&dwAttr,&dwUType,&dwDType,&cbLen,(LPBYTE) bufData.QueryPtr(),bufData.QuerySize(),0,0,0,pszSubString))
  456. {
  457. // Resize to Accomodate the big value
  458. if (!bufData.Resize(cbLen))
  459. {
  460. return FALSE;
  461. }
  462. if (!GetData(dwId,&dwAttr,&dwUType,&dwDType,&cbLen,(LPBYTE) bufData.QueryPtr(),bufData.QuerySize(),0,0,0,pszSubString))
  463. {
  464. // Even with the new size buffer we could not retrieve the value
  465. return FALSE;
  466. }
  467. }
  468. return ( Value.SetValue(dwId,dwAttr,dwUType,dwDType,cbLen,(LPVOID) bufData.QueryPtr()) );
  469. }
  470. BOOL
  471. CMDKey::SetData(CMDValue &Value, DWORD dwId, PWCHAR pszSubString )
  472. {
  473. return SUCCEEDED( SetData(dwId,
  474. Value.GetAttributes(),
  475. Value.GetUserType(),
  476. Value.GetDataType(),
  477. Value.GetDataLen(),
  478. (LPBYTE) Value.GetData(),
  479. pszSubString ) );
  480. }
  481. // Note: only use to access the AnonyName and AnonyPassword,
  482. // buffer size 256 is big enough here
  483. BOOL CMDKey::GetData(DWORD id,DWORD *pdwAttr,DWORD *pdwUType,DWORD *pdwDType,DWORD *pcbLen,LPBYTE pbData,DWORD BufSize,DWORD dwAttributes,DWORD dwUType,DWORD dwDType,PWCHAR pszSubString )
  484. {
  485. int ReturnIndex;
  486. BOOL fReturn = FALSE;
  487. HRESULT hRes = ERROR_SUCCESS;
  488. METADATA_RECORD mdrData;
  489. DWORD dwRequiredDataLen = 0;
  490. LPBYTE ReturnBuf=NULL;
  491. int ReturnBufSize;
  492. // if we are just trying to get the size of the field, just do that.
  493. if ( !pbData || (BufSize == 0) )
  494. {
  495. MD_SET_DATA_RECORD(&mdrData, id, dwAttributes, dwUType, dwDType, 0, NULL);
  496. hRes = m_pcCom->GetData(m_hKey, pszSubString, &mdrData, &dwRequiredDataLen);
  497. *pcbLen = dwRequiredDataLen;
  498. fReturn = (hRes == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER));
  499. goto GetData_Exit;
  500. }
  501. #if defined(UNICODE) || defined(_UNICODE)
  502. ReturnBufSize = BufSize;
  503. #else
  504. ReturnBufSize = 2 * BufSize;
  505. #endif
  506. ReturnBuf = (LPBYTE)LocalAlloc(LPTR, ReturnBufSize);
  507. if (!ReturnBuf)
  508. {
  509. iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::GetData() failed to allocate memory.\n")));
  510. ReturnBuf = NULL;
  511. goto GetData_Exit;
  512. }
  513. //DisplayStringForMetabaseID(id);
  514. TCHAR lpReturnString[50];
  515. ReturnStringForMetabaseID(id, lpReturnString);
  516. iisDebugOut((LOG_TYPE_TRACE, _T("CMDKey::GetData[%s:%d:%s].\n"), m_szCurrentNodeName, id, lpReturnString));
  517. MD_SET_DATA_RECORD(&mdrData, id, dwAttributes, dwUType, dwDType, ReturnBufSize, (PBYTE) ReturnBuf);
  518. hRes = m_pcCom->GetData(m_hKey, pszSubString, &mdrData, &dwRequiredDataLen);
  519. if (FAILED(hRes))
  520. {
  521. if (hRes == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER))
  522. {
  523. #if defined(UNICODE) || defined(_UNICODE)
  524. *pcbLen = dwRequiredDataLen;
  525. #else
  526. *pcbLen = dwRequiredDataLen / 2;
  527. #endif
  528. }
  529. else
  530. {
  531. *pcbLen = 0;
  532. if (hRes != MD_ERROR_DATA_NOT_FOUND)
  533. {
  534. MyMessageBox(NULL, IDS_GETDATA_ERROR, (int) hRes, MB_OK | MB_SETFOREGROUND);
  535. }
  536. }
  537. goto GetData_Exit;
  538. }
  539. // --------
  540. // We have successfully retrieved the data at this point
  541. // --------
  542. *pdwAttr = mdrData.dwMDAttributes;
  543. *pdwUType = mdrData.dwMDUserType;
  544. *pdwDType = mdrData.dwMDDataType;
  545. *pcbLen = mdrData.dwMDDataLen; // number of SBCS chars + ending \0
  546. switch (*pdwDType)
  547. {
  548. case STRING_METADATA:
  549. case EXPANDSZ_METADATA:
  550. #if defined(UNICODE) || defined(_UNICODE)
  551. memcpy(pbData, mdrData.pbMDData, *pcbLen);
  552. #else
  553. *pcbLen = (*pcbLen) / sizeof(WCHAR);
  554. WideCharToMultiByte(CP_ACP,0,(WCHAR *)(mdrData.pbMDData),-1,(LPSTR)pbData,*pcbLen, NULL, NULL);
  555. #endif
  556. fReturn = TRUE;
  557. break;
  558. case MULTISZ_METADATA:
  559. #if defined(UNICODE) || defined(_UNICODE)
  560. memcpy(pbData, mdrData.pbMDData, *pcbLen);
  561. #else
  562. *pcbLen = (*pcbLen) / sizeof(WCHAR);
  563. MyWideCharToMultiByte((WCHAR *)(mdrData.pbMDData),(LPSTR)pbData, *pcbLen, TRUE);
  564. #endif
  565. fReturn = TRUE;
  566. break;
  567. default:
  568. memcpy(pbData, mdrData.pbMDData, *pcbLen);
  569. fReturn = TRUE;
  570. break;
  571. }
  572. GetData_Exit:
  573. if(ReturnBuf) {LocalFree(ReturnBuf);}
  574. return fReturn;
  575. }
  576. HRESULT CMDKey::DeleteData(DWORD id, DWORD dType, PWCHAR pszSubString)
  577. {
  578. HRESULT hRes = ERROR_SUCCESS;
  579. TCHAR lpReturnString[50];
  580. ReturnStringForMetabaseID(id, lpReturnString);
  581. iisDebugOut((LOG_TYPE_TRACE, _T("CMDKey::DeleteData[%s:%d:%s].\n"), m_szCurrentNodeName, id, lpReturnString));
  582. hRes = m_pcCom->DeleteData(m_hKey, pszSubString, id, dType);
  583. return hRes;
  584. }
  585. HRESULT CMDKey::DeleteNode(LPCTSTR pchSubKeyPath)
  586. {
  587. HRESULT hRes = ERROR_SUCCESS;
  588. WCHAR szSubKeyPath[_MAX_PATH];
  589. if ( pchSubKeyPath && (*pchSubKeyPath) )
  590. {
  591. #if defined(UNICODE) || defined(_UNICODE)
  592. _tcscpy(szSubKeyPath, pchSubKeyPath);
  593. #else
  594. MultiByteToWideChar( CP_ACP, 0, pchSubKeyPath, -1, szSubKeyPath, _MAX_PATH );
  595. #endif
  596. iisDebugOut((LOG_TYPE_TRACE, _T("CMDKey::DeleteNode[%s:%s].\n"), m_szCurrentNodeName, szSubKeyPath));
  597. hRes = m_pcCom->DeleteKey(m_hKey, szSubKeyPath);
  598. }
  599. return hRes;
  600. }
  601. CMDKeyIter::CMDKeyIter(CMDKey &cmdKey)
  602. {
  603. m_hKey = cmdKey.GetMDKeyHandle();
  604. m_pcCom = cmdKey.GetMDKeyICOM();
  605. m_dwBuffer = _MAX_PATH;
  606. Reset();
  607. m_pBuffer = new WCHAR [m_dwBuffer];
  608. }
  609. CMDKeyIter::~CMDKeyIter()
  610. {
  611. delete [] m_pBuffer;
  612. }
  613. LONG CMDKeyIter::Next(CString *pcsName, PWCHAR pwcsSubString)
  614. {
  615. TCHAR tchData[_MAX_PATH];
  616. HRESULT hRes = ERROR_SUCCESS;
  617. hRes = m_pcCom->EnumKeys(m_hKey, pwcsSubString, m_pBuffer, m_index);
  618. if (FAILED(hRes))
  619. {
  620. return 1;
  621. }
  622. else
  623. {
  624. #if defined(UNICODE) || defined(_UNICODE)
  625. _tcscpy(tchData, m_pBuffer);
  626. #else
  627. WideCharToMultiByte(CP_ACP,0,m_pBuffer,-1,(LPSTR)tchData,_MAX_PATH, NULL, NULL);
  628. #endif
  629. *pcsName = tchData;
  630. m_index++;
  631. return 0;
  632. }
  633. }
  634. int CreateInProc(LPCTSTR lpszPath, int iUseOOPPool)
  635. {
  636. int iReturn = FALSE;
  637. TCHAR lpszKeyPath[_MAX_PATH];
  638. WCHAR wchKeyPath[_MAX_PATH];
  639. HRESULT hr = NOERROR;
  640. IWamAdmin2* pIWamAdmin = NULL;
  641. DWORD dwAppMode = eAppRunInProc;
  642. if (iUseOOPPool) {dwAppMode = eAppRunOutProcInDefaultPool;}
  643. if (lpszPath[0] == _T('/'))
  644. {
  645. _tcscpy(lpszKeyPath, lpszPath);
  646. }
  647. else
  648. {
  649. lpszKeyPath[0] = _T('/');
  650. _tcscpy(_tcsinc(lpszKeyPath), lpszPath);
  651. }
  652. if (lpszKeyPath[(_tcslen(lpszKeyPath)-1)] != _T('/')) {_tcscat(lpszKeyPath, _T("/"));}
  653. #if defined(UNICODE) || defined(_UNICODE)
  654. _tcscpy(wchKeyPath, lpszKeyPath);
  655. #else
  656. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpszKeyPath, -1, (LPWSTR)wchKeyPath, _MAX_PATH);
  657. #endif
  658. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoInitializeEx().Start.")));
  659. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  660. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoInitializeEx().End.")));
  661. if (FAILED(hr))
  662. {
  663. iisDebugOut((LOG_TYPE_ERROR, _T("CreateInProc: CoInitializeEx() failed, hr=%x\n"), hr));
  664. MesssageBoxErrors_MTS(IDS_MTS_DOING_CREATEINPROC,hr);
  665. }
  666. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoCreateInstance().Start.")));
  667. hr = CoCreateInstance(CLSID_WamAdmin,NULL,CLSCTX_SERVER,IID_IWamAdmin2,(void **)&pIWamAdmin);
  668. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoCreateInstance().End.")));
  669. if (SUCCEEDED(hr))
  670. {
  671. hr = pIWamAdmin->AppCreate2(wchKeyPath, dwAppMode);
  672. pIWamAdmin->Release();
  673. if (FAILED(hr))
  674. {
  675. iisDebugOut((LOG_TYPE_ERROR, _T("Create in-proc(type=%d) app on path %s failed, err=%x.\n"), dwAppMode, lpszKeyPath, hr));
  676. MyMessageBox(NULL, _T("CreateInProc:Error Creating Transaction Server InProc App."), hr, MB_OK | MB_SETFOREGROUND);
  677. MesssageBoxErrors_MTS(IDS_MTS_DOING_CREATEINPROC,hr);
  678. }
  679. else
  680. {
  681. iReturn = TRUE;
  682. }
  683. }
  684. else
  685. {
  686. iisDebugOut((LOG_TYPE_ERROR, _T("Failed to CoCreateInstance of WamAdmin object. err=%x.\n"), hr));
  687. MyMessageBox(NULL, _T("CreateInProc:CoCreateInstance"), hr, MB_OK | MB_SETFOREGROUND);
  688. MesssageBoxErrors_MTS(IDS_MTS_DOING_CREATEINPROC,hr);
  689. }
  690. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoUninitialize().Start.")));
  691. CoUninitialize();
  692. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoUninitialize().End.")));
  693. return iReturn;
  694. }
  695. void CreateInProc_Wrap(LPCTSTR lpszPath, int iUseOOPPool)
  696. {
  697. BOOL bDisplayMsgOnErrFlag = TRUE;
  698. int iReturn = FALSE;
  699. int bFinishedFlag = FALSE;
  700. UINT iMsg = NULL;
  701. do
  702. {
  703. iisDebugOut((LOG_TYPE_TRACE, _T("CreateInProc_Wrap(): %s\n"), lpszPath));
  704. iReturn = CreateInProc(lpszPath, iUseOOPPool);
  705. if (iReturn == TRUE)
  706. {
  707. break;
  708. }
  709. else
  710. {
  711. if (bDisplayMsgOnErrFlag == TRUE)
  712. {
  713. iMsg = MyMessageBox( NULL, IDS_RETRY, MB_ABORTRETRYIGNORE | MB_SETFOREGROUND );
  714. switch ( iMsg )
  715. {
  716. case IDIGNORE:
  717. iReturn = TRUE;
  718. goto CreateInProc_Wrap_Exit;
  719. case IDABORT:
  720. iReturn = FALSE;
  721. goto CreateInProc_Wrap_Exit;
  722. case IDRETRY:
  723. break;
  724. default:
  725. break;
  726. }
  727. }
  728. else
  729. {
  730. // return whatever err happened
  731. goto CreateInProc_Wrap_Exit;
  732. }
  733. }
  734. } while (iReturn != TRUE);
  735. CreateInProc_Wrap_Exit:
  736. return;
  737. }
  738. void DeleteInProc(LPCTSTR lpszPath)
  739. {
  740. TCHAR lpszKeyPath[_MAX_PATH];
  741. WCHAR wchKeyPath[_MAX_PATH];
  742. HRESULT hr = NOERROR;
  743. IWamAdmin* pIWamAdmin = NULL;
  744. iisDebugOut((LOG_TYPE_TRACE, _T("DeleteInProc():Start.%s\n"), lpszPath));
  745. if (lpszPath[0] == _T('/'))
  746. {
  747. _tcscpy(lpszKeyPath, lpszPath);
  748. }
  749. else
  750. {
  751. lpszKeyPath[0] = _T('/');
  752. _tcscpy(_tcsinc(lpszKeyPath), lpszPath);
  753. }
  754. #if defined(UNICODE) || defined(_UNICODE)
  755. _tcscpy(wchKeyPath, lpszKeyPath);
  756. #else
  757. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpszKeyPath, -1, (LPWSTR)wchKeyPath, _MAX_PATH);
  758. #endif
  759. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoInitializeEx().Start.")));
  760. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  761. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoInitializeEx().End.")));
  762. if (FAILED(hr))
  763. {
  764. iisDebugOut((LOG_TYPE_ERROR, _T("DeleteInProc: CoInitializeEx() failed, hr=%x\n"), hr));
  765. }
  766. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoCreateInstance().Start.")));
  767. hr = CoCreateInstance(CLSID_WamAdmin,NULL,CLSCTX_SERVER,IID_IWamAdmin,(void **)&pIWamAdmin);
  768. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoCreateInstance().End.")));
  769. if (SUCCEEDED(hr))
  770. {
  771. iisDebugOut((LOG_TYPE_TRACE, _T("DeleteInProc():Calling AppDelete now.%s\n"), lpszKeyPath));
  772. hr = pIWamAdmin->AppDelete(wchKeyPath, TRUE);
  773. pIWamAdmin->Release();
  774. if (FAILED(hr))
  775. {
  776. iisDebugOut((LOG_TYPE_ERROR, _T("Delete in-proc app on path %s failed, err=%x.\n"), lpszKeyPath, hr));
  777. }
  778. }
  779. else
  780. {
  781. iisDebugOut((LOG_TYPE_ERROR, _T("DeleteInProc:CoCreateInstance() failed. err=%x.\n"), hr));
  782. }
  783. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoUninitialize().Start.")));
  784. CoUninitialize();
  785. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoUninitialize().End.")));
  786. iisDebugOut_End1(_T("DeleteInProc"),(LPTSTR) lpszPath,LOG_TYPE_TRACE);
  787. return;
  788. }
  789. INT_PTR CALLBACK pSecureRetryIgnoreAllDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  790. {
  791. HWND hTextWording = NULL;
  792. CString csErrMsg;
  793. HRESULT hErrorCode;
  794. TCHAR pMsg[_MAX_PATH] = _T("");
  795. HRESULT nNetErr;
  796. DWORD dwFormatReturn = 0;
  797. switch (msg)
  798. {
  799. case WM_INITDIALOG:
  800. uiCenterDialog(hDlg);
  801. hTextWording = GetDlgItem(hDlg, IDC_STATIC2);
  802. hErrorCode = (HRESULT) lParam;
  803. nNetErr = (HRESULT) hErrorCode;
  804. dwFormatReturn = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,NULL, hErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),pMsg, _MAX_PATH, NULL);
  805. if ( dwFormatReturn == 0)
  806. {
  807. if (nNetErr >= NERR_BASE)
  808. {
  809. HMODULE hDll = (HMODULE)LoadLibrary(_T("netmsg.dll"));
  810. if (hDll)
  811. {
  812. dwFormatReturn = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE,hDll, hErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),pMsg, _MAX_PATH, NULL);
  813. FreeLibrary(hDll);
  814. }
  815. }
  816. }
  817. if (dwFormatReturn) {csErrMsg.Format(_T("0x%x=%s"), hErrorCode, pMsg);}
  818. else{csErrMsg.Format(_T("%s\n\nErrorCode=0x%x."), hErrorCode);}
  819. SetWindowText(hTextWording, csErrMsg);
  820. UpdateWindow(hDlg);
  821. break;
  822. case WM_COMMAND:
  823. switch (wParam)
  824. {
  825. case IDCANCEL:
  826. EndDialog(hDlg, (int)wParam);
  827. return FALSE;
  828. case IDRETRY:
  829. EndDialog(hDlg, (int)wParam);
  830. return FALSE;
  831. break;
  832. case IDWRITEUNENCRYPTED:
  833. EndDialog(hDlg, (int)wParam);
  834. return TRUE;
  835. break;
  836. case IDWRITEUNENCRYPTEDALL:
  837. g_bGlobalWriteUnSecuredIfFailed_All = TRUE;
  838. EndDialog(hDlg, (int)wParam);
  839. return TRUE;
  840. break;
  841. }
  842. break;
  843. }
  844. return FALSE;
  845. }
  846. //-----------------------------------------------------------------------------
  847. // get a multi-sz data block and immediately parse it into a CStringList
  848. HRESULT CMDKey::GetMultiSzAsStringList (
  849. DWORD dwMDIdentifier,
  850. DWORD *uType,
  851. DWORD *attributes,
  852. CStringList& szStrList,
  853. PWCHAR pszSubString OPTIONAL )
  854. {
  855. HRESULT hRes = ERROR_SUCCESS;
  856. METADATA_RECORD mdrData;
  857. DWORD cbBuffer;
  858. // make sure the key is open
  859. if ( NULL == m_hKey )
  860. {
  861. iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: GetMultiSzAsStringList on unopened node.%s\n"), _T("")));
  862. return -1;
  863. }
  864. // get the paths. The loop accounts for a buffer that is too small...
  865. DWORD dwMDBufferSize = 1024;
  866. PWCHAR pwchBuffer = NULL;
  867. do
  868. {
  869. if ( pwchBuffer )
  870. {
  871. delete pwchBuffer;
  872. pwchBuffer = NULL;
  873. }
  874. pwchBuffer = new WCHAR[dwMDBufferSize];
  875. if (pwchBuffer == NULL)
  876. {
  877. return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  878. }
  879. // prepare the metadata parameter block
  880. MD_SET_DATA_RECORD(&mdrData, dwMDIdentifier, *attributes,
  881. *uType, MULTISZ_METADATA, dwMDBufferSize, pwchBuffer);
  882. // make the call to get the data
  883. // If the buffer is too small, the correct size will be put into dwMDBufferSize
  884. hRes = m_pcCom->GetData(
  885. m_hKey,
  886. pszSubString,
  887. &mdrData,
  888. &dwMDBufferSize
  889. );
  890. // Set the attributes return.
  891. *attributes = mdrData.dwMDAttributes;
  892. *uType = mdrData.dwMDUserType;
  893. }
  894. while( HRESULT_CODE(hRes) == ERROR_INSUFFICIENT_BUFFER);
  895. // if there were any failures, go to the cleanup code now...
  896. if ( SUCCEEDED(hRes) )
  897. {
  898. // at this point, we have the data we want. Time to convert it into a CString list.
  899. if (pwchBuffer)
  900. {
  901. // to make prefix stop yelling at me
  902. if (pwchBuffer[0])
  903. {
  904. ConvertWDoubleNullListToStringList(pwchBuffer, szStrList);
  905. }
  906. }
  907. }
  908. // clean up
  909. if ( pwchBuffer )
  910. delete pwchBuffer;
  911. if ( FAILED(hRes) )
  912. {
  913. iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::GetMultiSzAsStringList() failed. err=%x.\n"), hRes));
  914. }
  915. return hRes;
  916. }
  917. //-----------------------------------------------------------------------------
  918. // take a CStringList and set it into metadata as a multi-sz
  919. HRESULT CMDKey::SetMultiSzAsStringList (
  920. DWORD dwMDIdentifier,
  921. DWORD uType,
  922. DWORD attributes,
  923. CStringList& szStrList,
  924. PWCHAR pszSubString OPTIONAL )
  925. {
  926. HRESULT hRes = ERROR_SUCCESS;
  927. METADATA_RECORD mdrData;
  928. DWORD cbBuffer;
  929. // make sure the key is open
  930. if ( NULL == m_hKey )
  931. {
  932. iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: SetMultiSzAsStringList on unopened node.%s\n"), _T("")));
  933. return -1;
  934. }
  935. DWORD dwMDBufferSize = 0;
  936. PWCHAR pwchBuffer = NULL;
  937. // convert the cstringlist into a wide multisz data block.
  938. hRes = ConvertStringListToWDoubleNullList(
  939. szStrList,
  940. dwMDBufferSize,
  941. pwchBuffer
  942. );
  943. if ( FAILED(hRes) )
  944. {
  945. iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: SetMultiSzAsStringList Convert to null list.%x\n"), hRes));
  946. return hRes;
  947. }
  948. // the buffer is expressed in wide characters. Change it to bytes...
  949. dwMDBufferSize *= sizeof(WCHAR);
  950. // prepare the metadata parameter block
  951. MD_SET_DATA_RECORD(&mdrData, dwMDIdentifier, attributes,
  952. uType, MULTISZ_METADATA, dwMDBufferSize, pwchBuffer);
  953. // make the call to get the data
  954. hRes = m_pcCom->SetData(
  955. m_hKey,
  956. pszSubString,
  957. &mdrData
  958. );
  959. // clean up
  960. FreeMem( pwchBuffer );
  961. if ( FAILED(hRes) )
  962. {
  963. iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::SetMultiSzAsStringList()-SetData failed. err=%x.\n"), hRes));
  964. }
  965. return hRes;
  966. }
  967. //-----------------------------------------------------------------------------
  968. // get all the sub keys that have a certain property on them and return the
  969. // sub-paths in a cstring list object. The cstring list should be instantiated
  970. // by the caller and deleted by the same.
  971. HRESULT CMDKey::GetDataPaths(
  972. DWORD dwMDIdentifier,
  973. DWORD dwMDDataType,
  974. CStringList& szPathList,
  975. PWCHAR pszSubString )
  976. {
  977. HRESULT hRes = ERROR_SUCCESS;
  978. DWORD cbBuffer;
  979. // make sure the key is open
  980. if ( NULL == m_hKey )
  981. {
  982. iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: GetDataPaths on unopened node.%s\n"), _T("")));
  983. return -1;
  984. }
  985. // get the paths. The loop accounts for a buffer that is too small...
  986. DWORD dwMDBufferSize = 512;
  987. PWCHAR pwchBuffer = NULL;
  988. do
  989. {
  990. if ( pwchBuffer )
  991. {
  992. delete pwchBuffer;
  993. pwchBuffer = NULL;
  994. }
  995. pwchBuffer = new WCHAR[dwMDBufferSize];
  996. if (pwchBuffer == NULL)
  997. {
  998. return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  999. }
  1000. // If the buffer is too small, the correct size will be put into dwMDBufferSize
  1001. hRes = m_pcCom->GetDataPaths(
  1002. m_hKey,
  1003. pszSubString,
  1004. dwMDIdentifier,
  1005. dwMDDataType,
  1006. dwMDBufferSize,
  1007. pwchBuffer,
  1008. &dwMDBufferSize
  1009. );
  1010. }
  1011. while( HRESULT_CODE(hRes) == ERROR_INSUFFICIENT_BUFFER);
  1012. // if there were any failures, go to the cleanup code now...
  1013. if ( SUCCEEDED(hRes) )
  1014. {
  1015. // at this point, we have the data we want. Time to convert it into a CString list.
  1016. ConvertWDoubleNullListToStringList(pwchBuffer, szPathList);
  1017. }
  1018. // clean up
  1019. if ( pwchBuffer )
  1020. delete pwchBuffer;
  1021. if ( FAILED(hRes) )
  1022. {
  1023. iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::GetDataPaths() failed. err=%x.\n"), hRes));
  1024. }
  1025. return hRes;
  1026. }
  1027. //-----------------------------------------------------------------------------
  1028. // get a multi-sz data block and immediately parse it into a CStringList
  1029. HRESULT CMDKey::GetStringAsCString (
  1030. DWORD dwMDIdentifier,
  1031. DWORD uType,
  1032. DWORD attributes,
  1033. CString& szStr,
  1034. PWCHAR pszSubString OPTIONAL,
  1035. int iStringType OPTIONAL)
  1036. {
  1037. HRESULT hRes = ERROR_SUCCESS;
  1038. METADATA_RECORD mdrData;
  1039. DWORD cbBuffer;
  1040. // make sure the key is open
  1041. if ( NULL == m_hKey )
  1042. {
  1043. iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: GetStringAsCString on unopened node.%s\n"), _T("")));
  1044. return -1;
  1045. }
  1046. // get the string. The loop accounts for a buffer that is too small...
  1047. DWORD dwMDBufferSize = 255;
  1048. PWCHAR pwchBuffer = NULL;
  1049. do
  1050. {
  1051. if ( pwchBuffer )
  1052. {
  1053. delete pwchBuffer;
  1054. pwchBuffer = NULL;
  1055. }
  1056. pwchBuffer = new WCHAR[dwMDBufferSize + 1];
  1057. ZeroMemory( pwchBuffer, (dwMDBufferSize + 1) * sizeof(WCHAR) );
  1058. if (pwchBuffer == NULL)
  1059. {
  1060. return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  1061. }
  1062. // prepare the metadata parameter block
  1063. MD_SET_DATA_RECORD(&mdrData, dwMDIdentifier, attributes,
  1064. uType, STRING_METADATA, dwMDBufferSize, pwchBuffer);
  1065. // make the call to get the data
  1066. // If the buffer is too small, the correct size will be put into dwMDBufferSize
  1067. hRes = m_pcCom->GetData(
  1068. m_hKey,
  1069. pszSubString,
  1070. &mdrData,
  1071. &dwMDBufferSize
  1072. );
  1073. }
  1074. while( HRESULT_CODE(hRes) == ERROR_INSUFFICIENT_BUFFER);
  1075. // if there were any failures, go to the cleanup code now...
  1076. if ( SUCCEEDED(hRes) )
  1077. {
  1078. // at this point, we have the data we want. Time to convert it into a CString.
  1079. szStr = pwchBuffer;
  1080. }
  1081. // clean up
  1082. if ( pwchBuffer )
  1083. delete pwchBuffer;
  1084. if ( FAILED(hRes) && !MD_ERROR_DATA_NOT_FOUND)
  1085. {
  1086. iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::GetStringAsCString() failed. err=%x.\n"), hRes));
  1087. }
  1088. return hRes;
  1089. }
  1090. //-----------------------------------------------------------------------------
  1091. // take a CStringList and set it into metadata as a multi-sz
  1092. HRESULT CMDKey::SetCStringAsString (
  1093. DWORD dwMDIdentifier,
  1094. DWORD uType,
  1095. DWORD attributes,
  1096. CString& szStr,
  1097. PWCHAR pszSubString OPTIONAL,
  1098. int iStringType OPTIONAL)
  1099. {
  1100. HRESULT hRes = ERROR_SUCCESS;
  1101. METADATA_RECORD mdrData;
  1102. DWORD cbBuffer;
  1103. // make sure the key is open
  1104. if ( NULL == m_hKey )
  1105. {
  1106. iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: SetCStringAsString on unopened node.%s\n"), _T("")));
  1107. return -1;
  1108. }
  1109. DWORD dwMDBufferSize = 0;
  1110. PWCHAR pwchBuffer = NULL;
  1111. // convert the cstring into a wide string data block.
  1112. pwchBuffer = AllocWideString( (LPCTSTR)szStr );
  1113. // Calculate the size of the buffer in bytes, not wide characters....
  1114. dwMDBufferSize = (szStr.GetLength() + 1) * sizeof(WCHAR);
  1115. // prepare the metadata parameter block
  1116. MD_SET_DATA_RECORD(&mdrData, dwMDIdentifier, attributes,
  1117. uType, STRING_METADATA, dwMDBufferSize, pwchBuffer);
  1118. // make the call to get the data
  1119. hRes = m_pcCom->SetData(
  1120. m_hKey,
  1121. pszSubString,
  1122. &mdrData
  1123. );
  1124. // clean up
  1125. FreeMem( pwchBuffer );
  1126. if ( FAILED(hRes) )
  1127. {
  1128. iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::SetCStringAsString()-SetData failed. err=%x.\n"), hRes));
  1129. }
  1130. return hRes;
  1131. }
  1132. HRESULT CMDKey::GetDword(
  1133. DWORD dwMDIdentifier,
  1134. DWORD uType,
  1135. DWORD attributes,
  1136. DWORD& MyDword,
  1137. PWCHAR pszSubString OPTIONAL
  1138. )
  1139. {
  1140. HRESULT hRes = ERROR_SUCCESS;
  1141. METADATA_RECORD mdrData;
  1142. DWORD cbBuffer;
  1143. DWORD dwMDBufferSize = 255;
  1144. LPBYTE Buffer = NULL;
  1145. // make sure the key is open
  1146. if ( NULL == m_hKey )
  1147. {
  1148. iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: GetDword on unopened node.\n")));
  1149. return -1;
  1150. }
  1151. // get the data. The loop accounts for a buffer that is too small...
  1152. do
  1153. {
  1154. if ( Buffer )
  1155. {
  1156. delete Buffer;
  1157. Buffer = NULL;
  1158. }
  1159. Buffer = (LPBYTE)LocalAlloc(LPTR, dwMDBufferSize);
  1160. if (Buffer == NULL)
  1161. {
  1162. return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  1163. }
  1164. // prepare the metadata parameter block
  1165. MD_SET_DATA_RECORD(&mdrData, dwMDIdentifier, attributes, uType, DWORD_METADATA, dwMDBufferSize, Buffer);
  1166. // make the call to get the data
  1167. // If the buffer is too small, the correct size will be put into dwMDBufferSize
  1168. hRes = m_pcCom->GetData(m_hKey,pszSubString,&mdrData,&dwMDBufferSize);
  1169. }
  1170. while( HRESULT_CODE(hRes) == ERROR_INSUFFICIENT_BUFFER);
  1171. // if there were any failures, go to the cleanup code now...
  1172. if ( SUCCEEDED(hRes) )
  1173. {
  1174. // at this point, we have the data we want. Time to convert it into a dword.
  1175. MyDword = (DWORD) *mdrData.pbMDData;
  1176. }
  1177. // clean up
  1178. if ( Buffer )
  1179. delete Buffer;
  1180. if ( FAILED(hRes) && !MD_ERROR_DATA_NOT_FOUND)
  1181. {
  1182. iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::GetDword() failed. err=%x.\n"), hRes));
  1183. }
  1184. return hRes;
  1185. }
  1186. HRESULT CMDKey::RenameNode(LPCTSTR pszMDPath,LPCTSTR pszMDNewName)
  1187. {
  1188. HRESULT hRes = ERROR_SUCCESS;
  1189. if (m_pcCom)
  1190. {
  1191. WCHAR wszPath1[_MAX_PATH];
  1192. WCHAR wszPath2[_MAX_PATH];
  1193. #if defined(UNICODE) || defined(_UNICODE)
  1194. _tcscpy(wszPath1, pszMDPath);
  1195. _tcscpy(wszPath2, pszMDNewName);
  1196. #else
  1197. MultiByteToWideChar( CP_ACP, 0, pszMDPath, -1, wszPath1, _MAX_PATH);
  1198. MultiByteToWideChar( CP_ACP, 0, pszMDNewName, -1, wszPath2, _MAX_PATH);
  1199. #endif
  1200. hRes = m_pcCom->RenameKey(m_hKey,wszPath1,wszPath2);
  1201. if ( FAILED(hRes) && !MD_ERROR_DATA_NOT_FOUND)
  1202. {
  1203. iisDebugOut((LOG_TYPE_WARN, _T("CMDKey::RenameNode(%s,%s) failed. err=%x.\n"), pszMDPath,pszMDNewName,hRes));
  1204. }
  1205. }
  1206. return hRes;
  1207. };
  1208. CMDValue::CMDValue()
  1209. :
  1210. m_dwId(0),
  1211. m_dwAttributes(0),
  1212. m_dwUserType(0),
  1213. m_dwDataType(0),
  1214. m_cbDataLen(0)
  1215. {
  1216. }
  1217. CMDValue::~CMDValue()
  1218. {
  1219. }
  1220. // function: CMDValue::SetValue
  1221. //
  1222. // Set the value of the class to what the pointer points to
  1223. //
  1224. DWORD
  1225. CMDValue::SetValue(DWORD dwId,
  1226. DWORD dwAttributes,
  1227. DWORD dwUserType,
  1228. DWORD dwDataType,
  1229. DWORD cbDataLen,
  1230. LPVOID pbData)
  1231. {
  1232. if ( cbDataLen > m_bufData.QuerySize() )
  1233. {
  1234. if (!m_bufData.Resize(cbDataLen))
  1235. {
  1236. // Failed to Resize Data
  1237. return FALSE;
  1238. }
  1239. }
  1240. memcpy( m_bufData.QueryPtr(), pbData, cbDataLen );
  1241. m_dwId = dwId;
  1242. m_dwAttributes = dwAttributes;
  1243. m_dwUserType = dwUserType;
  1244. m_dwDataType = dwDataType;
  1245. m_cbDataLen = cbDataLen;
  1246. return TRUE;
  1247. }
  1248. // function: CMDValue::SetValue
  1249. //
  1250. // Set the value of the class the value of the string. So if
  1251. // dwDataType is DWORD, we must first convert to DWORD before
  1252. // Setting the value
  1253. //
  1254. DWORD
  1255. CMDValue::SetValue(DWORD dwId,
  1256. DWORD dwAttributes,
  1257. DWORD dwUserType,
  1258. DWORD dwDataType,
  1259. DWORD cbDataLen,
  1260. LPTSTR szDataString)
  1261. {
  1262. if (dwDataType == DWORD_METADATA)
  1263. {
  1264. DWORD dwValue;
  1265. dwValue = _ttoi(szDataString);
  1266. return SetValue(dwId, dwAttributes, dwUserType, dwDataType, sizeof(DWORD), (LPVOID) &dwValue);
  1267. }
  1268. return SetValue(dwId, dwAttributes, dwUserType, dwDataType, cbDataLen, (LPVOID) szDataString);
  1269. }
  1270. BOOL
  1271. CMDValue::IsEqual(DWORD dwDataType, DWORD cbDataLen, LPVOID pbData)
  1272. {
  1273. if ( (dwDataType != m_dwDataType) ||
  1274. ( cbDataLen != m_cbDataLen )
  1275. )
  1276. {
  1277. return FALSE;
  1278. }
  1279. return ( memcmp(pbData,m_bufData.QueryPtr(),cbDataLen) == 0 );
  1280. }
  1281. BOOL
  1282. CMDValue::IsEqual(DWORD dwDataType, DWORD cbDataLen, DWORD dwData)
  1283. {
  1284. return IsEqual(dwDataType,cbDataLen,(LPVOID) &dwData);
  1285. }