Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2059 lines
67 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name :
  4. admutil.cpp
  5. Abstract:
  6. IADMCOM interface WRAPPER functions implemetation
  7. Environment:
  8. Win32 User Mode
  9. Author:
  10. jaroslad (jan 1997)
  11. --*/
  12. #define INITGUID
  13. #include <tchar.h>
  14. #include <afx.h>
  15. #include <debnot.h>
  16. #ifdef UNICODE
  17. #include <iadmw.h>
  18. #define IADM_PBYTE
  19. #else
  20. #include "ansimeta.h"
  21. //convert when using ANSI interface
  22. #define IADM_PBYTE (PBYTE)
  23. #endif
  24. //#define SPECIAL_SHOW_ALL_METABASE
  25. #include <iiscnfg.h>
  26. #include <ole2.h>
  27. #include <ctype.h> //import toupper
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <conio.h>
  31. #include "admutil.h"
  32. #include "tables.h"
  33. #include <jd_misc.h>
  34. #undef SHOW_SECURE
  35. //////////////////////////////
  36. //global variable definition
  37. DWORD g_dwTIMEOUT_VALUE =30000;
  38. DWORD g_dwDELAY_AFTER_OPEN_VALUE=0;
  39. //////////////////////////////
  40. //*********************
  41. CString FindCommonPath(CString a_strPath1, CString a_strPath2)
  42. {
  43. CString strCommonPath=_TEXT("");
  44. int MinLength=a_strPath1.GetLength();
  45. int i;
  46. //find shorter from strings
  47. if(a_strPath2.GetLength() < MinLength)
  48. MinLength=a_strPath2.GetLength();
  49. for(i=0; i<MinLength; i++)
  50. {
  51. if(a_strPath1.GetAt(i)!=a_strPath2.GetAt(i) )
  52. // common path cannot be any longer;
  53. break;
  54. }
  55. // now find the previous '/' and all before '/' is the common path
  56. for(i=i-1; i>=0;i--)
  57. {
  58. if(a_strPath1.GetAt(i)==_T('/'))
  59. {
  60. strCommonPath=a_strPath1.Left(i+1);//take the trailing '/' with you
  61. //strRelSrcPath=strPath1.Mid(i+1);
  62. //strRelDstPath=strPath2.Mid(i+1);
  63. break;
  64. }
  65. }
  66. return strCommonPath;
  67. }
  68. //**********************************************************************
  69. //IMPLEMENTATION of CAdmNode
  70. //**********************************************************************
  71. //return the position of '/' that is iSeqNumber in the order
  72. //e.g: GetSlashIndex("aaa/bbb/ccc/ddd",2) returns position of 2nd index that equals 7)
  73. INT CAdmNode::GetSlashIndex(const CString& strPath, INT iSeqNumber)
  74. {
  75. INT count=0;
  76. if (iSeqNumber==0)
  77. return 0;
  78. for(INT i=0; i<strPath.GetLength();i++)
  79. {
  80. if(strPath[i]==_T('/'))
  81. if((++count)==iSeqNumber)
  82. return i;
  83. }
  84. return -1;
  85. }
  86. //return the count of '/' in strPath
  87. INT CAdmNode::GetCountOfSlashes(const CString& strPath)
  88. {
  89. INT count=0;
  90. for(INT i=0; i<strPath.GetLength();i++)
  91. {
  92. if(strPath[i]==_T('/'))
  93. count++;
  94. }
  95. return count;
  96. }
  97. //return selement within the given string with sequence number wIndex
  98. //e.g.: GetPartOfPath("aaa/bbb/ccc",1,1) will return "bbb"
  99. //e.g.: GetPartOfPath("aaa/bbb/ccc",1) will return "bbb/ccc"
  100. //e.g.: GetPartOfPath("aaa/bbb/ccc",0,1) will return "aaa/bbb"
  101. //iStart- sequence number of first slash
  102. //iEnd- sequence number of last slash
  103. CString CAdmNode::GetPartOfPath(const CString& strPath, INT iStart, INT iEnd)
  104. {
  105. if(iEnd!=-1 && iEnd <= iStart)
  106. return _TEXT("");
  107. INT i=0;
  108. INT iPosBegin = GetSlashIndex(strPath,iStart);
  109. if(iPosBegin==-1) //not found (exceeds number of slashes available in strPath
  110. {
  111. return _TEXT("");
  112. }
  113. iPosBegin+=((iStart==0)?0:1); //adjust iPosBegin
  114. INT iPosEnd = GetSlashIndex(strPath,iEnd);
  115. CString strToReturn;
  116. if(iEnd==-1 || iPosEnd==-1)
  117. strToReturn = strPath.Mid(iPosBegin);
  118. else
  119. strToReturn = strPath.Mid(iPosBegin,iPosEnd-iPosBegin);
  120. if(iStart==0 && strToReturn==_TEXT("") && strPath!=_TEXT(""))
  121. return _TEXT("/"); //this had to be root
  122. else
  123. return strToReturn;
  124. }
  125. //within path can be given computer name, service, instance number
  126. // function will split the path to Computer, Service, Instance, Path relative to instance
  127. //
  128. void CAdmNode::SetPath(CString a_strPath)
  129. {
  130. if(a_strPath.IsEmpty())
  131. return;
  132. // change backslashes
  133. for(int i=0; i<a_strPath.GetLength(); i++)
  134. {
  135. // skip DBCS
  136. if(IsDBCSLeadByte(a_strPath[i]))
  137. {
  138. i++;
  139. continue;
  140. }
  141. if(a_strPath[i]==_T('\\'))
  142. a_strPath.SetAt(i,_T('/'));
  143. }
  144. //trim leading '/'
  145. while (a_strPath.GetLength()!=0 && a_strPath[0]==_T('/'))
  146. a_strPath=a_strPath.Mid(1);
  147. int iSvc=-1;
  148. if( IsServiceName(GetPartOfPath(a_strPath,1,2))) //get the second name within path
  149. { //if second is service then first has to be computer name
  150. strComputer = GetPartOfPath(a_strPath,0,1);
  151. strService = GetPartOfPath(a_strPath,1,2);
  152. if( IsNumber(GetPartOfPath(a_strPath,2,3))) {
  153. strInstance = GetPartOfPath(a_strPath,2,3);
  154. strIPath = GetPartOfPath(a_strPath,3); //store the rest
  155. }
  156. else {
  157. strIPath = GetPartOfPath(a_strPath,2); //store the rest
  158. }
  159. }
  160. else if( IsServiceName(GetPartOfPath(a_strPath,0,1))) //get the second name within path
  161. { //if second is service then first has to be computer name
  162. strComputer = _TEXT("");
  163. strService = GetPartOfPath(a_strPath,0,1);
  164. if( IsNumber(GetPartOfPath(a_strPath,1,2))) {
  165. strInstance = GetPartOfPath(a_strPath,1,2);
  166. strIPath = GetPartOfPath(a_strPath,2); //store the rest
  167. }
  168. else {
  169. strIPath = GetPartOfPath(a_strPath,1); //store the rest
  170. }
  171. }
  172. else
  173. {
  174. strIPath = a_strPath;
  175. }
  176. //in IPath there can be Property name at the end
  177. INT iCount= GetCountOfSlashes(strIPath);
  178. CString LastName= GetPartOfPath(strIPath,iCount); //get last name within path;
  179. if(MapPropertyNameToCode(LastName)!=NAME_NOT_FOUND)
  180. { //the Last name in the path is valid Property name
  181. strProperty = LastName;
  182. strIPath = GetPartOfPath(strIPath,0,iCount); //Strip Last name from IPath
  183. }
  184. }
  185. CString CAdmNode::GetLMRootPath(void)
  186. {
  187. #ifdef SPECIAL_SHOW_ALL_METABASE
  188. return _T("/");
  189. #else
  190. return _T("/")+CString(IIS_MD_LOCAL_MACHINE_PATH);
  191. #endif
  192. }
  193. CString CAdmNode::GetLMServicePath(void)
  194. {
  195. if(strService.IsEmpty())
  196. return GetLMRootPath();
  197. else
  198. return GetLMRootPath()+_T("/")+strService;
  199. }
  200. CString CAdmNode::GetLMInstancePath(void)
  201. {
  202. if(strInstance.IsEmpty())
  203. return GetLMServicePath();
  204. else
  205. return GetLMServicePath()+_T("/")+strInstance;
  206. }
  207. CString CAdmNode::GetLMNodePath(void)
  208. {
  209. if(strIPath.IsEmpty())
  210. return GetLMInstancePath();
  211. else
  212. return GetLMInstancePath()+_T("/")+strIPath;
  213. }
  214. CString CAdmNode::GetServicePath(void)
  215. {
  216. if(strService.IsEmpty())
  217. return _TEXT("");
  218. else
  219. return _T("/")+strService;
  220. }
  221. CString CAdmNode::GetInstancePath(void)
  222. {
  223. if(!strInstance.IsEmpty())
  224. return GetServicePath() + _T("/")+ strInstance;
  225. else
  226. return GetServicePath();
  227. }
  228. CString CAdmNode::GetNodePath(void)
  229. {
  230. if(!strIPath.IsEmpty())
  231. return GetInstancePath() + _T("/")+ strIPath;
  232. else
  233. return GetInstancePath();
  234. }
  235. CString CAdmNode::GetParentNodePath(void)
  236. {
  237. CString strNodePath;
  238. strNodePath = GetNodePath();
  239. if(strNodePath.IsEmpty())
  240. return strNodePath;
  241. else
  242. {
  243. INT i= strNodePath.GetLength()-1; //point to the end of strNodePath
  244. if (strNodePath.Right(1)==_T("/"))
  245. i--;
  246. for(; i>=0; i--)
  247. {
  248. if(strNodePath.GetAt(i)==_T('/'))
  249. return strNodePath.Left(i+1);
  250. }
  251. return _TEXT("");
  252. }
  253. }
  254. //can return _TEXT("") for nonamed
  255. CString CAdmNode::GetCurrentNodeName(void)
  256. {
  257. CString strNodePath;
  258. strNodePath = GetNodePath();
  259. if(strNodePath.IsEmpty())
  260. return strNodePath;
  261. else
  262. {
  263. INT i= strNodePath.GetLength()-1; //point to the end of strNodePath
  264. if (strNodePath.Right(1)==_T("/"))
  265. i--;
  266. for(int count=0; i>=0; i--, count++) //search backward for '/'
  267. {
  268. if(strNodePath.GetAt(i)==_T('/'))
  269. return strNodePath.Mid(i+1,count);
  270. }
  271. return strNodePath;
  272. }
  273. }
  274. CString CAdmNode::GetRelPathFromService(void)
  275. {
  276. CString str=strService;
  277. if (!strInstance.IsEmpty())
  278. str=str+_T("/")+strInstance;
  279. if (!strIPath.IsEmpty())
  280. str=str+_T("/")+strIPath;
  281. return str;
  282. }
  283. CString CAdmNode::GetRelPathFromInstance(void)
  284. {
  285. if(strInstance.IsEmpty())
  286. return strIPath;
  287. else
  288. return strInstance+_T("/")+strIPath;
  289. }
  290. //**********************************************************************
  291. //**********************************************************************
  292. //IMPLEMENTATION of CAdmProp object
  293. //**********************************************************************
  294. //**********************************************************************
  295. CAdmProp::CAdmProp(METADATA_RECORD &a_mdr)
  296. {
  297. memcpy (&mdr,&a_mdr,sizeof(METADATA_RECORD));
  298. }
  299. void CAdmProp::SetValue(DWORD a_dwValue)
  300. {
  301. if(mdr.pbMDData!=0)
  302. delete mdr.pbMDData;
  303. mdr.dwMDDataLen= sizeof(DWORD);
  304. mdr.pbMDData = (PBYTE) new char[mdr.dwMDDataLen];
  305. memcpy(mdr.pbMDData,&a_dwValue,mdr.dwMDDataLen);
  306. }
  307. void CAdmProp::SetValue(CString a_strValue)
  308. {
  309. if(mdr.pbMDData!=0)
  310. delete mdr.pbMDData;
  311. mdr.dwMDDataLen = (a_strValue.GetLength()+1)*sizeof(_TCHAR);
  312. mdr.pbMDData = (PBYTE) new _TCHAR [mdr.dwMDDataLen/sizeof(_TCHAR)];
  313. memcpy(mdr.pbMDData,LPCTSTR(a_strValue),mdr.dwMDDataLen-sizeof(_TCHAR));
  314. ((_TCHAR *)mdr.pbMDData)[mdr.dwMDDataLen/sizeof(_TCHAR)-1]=0; //terminate with zero
  315. }
  316. void CAdmProp::SetValue(LPCTSTR *a_lplpszValue, DWORD a_dwValueCount)
  317. {
  318. if(mdr.pbMDData!=NULL)
  319. {
  320. delete mdr.pbMDData;
  321. mdr.pbMDData=0;
  322. }
  323. mdr.dwMDDataLen=0;
  324. for(DWORD i=0; i< a_dwValueCount; i++)
  325. {
  326. if(a_lplpszValue[i]==NULL)
  327. break;
  328. mdr.dwMDDataLen += (DWORD)(_tcslen(a_lplpszValue[i])+1)*sizeof(_TCHAR);
  329. }
  330. mdr.dwMDDataLen+=sizeof(_TCHAR); // two 0 at the end
  331. mdr.pbMDData = (PBYTE) new char[mdr.dwMDDataLen];
  332. //merge strings in one area of memory
  333. DWORD j=0; //index to destination where stings will be merged
  334. for( i=0; i< a_dwValueCount; i++) //index to aray of strings
  335. {
  336. if(a_lplpszValue[i]==NULL)
  337. break;
  338. DWORD k=0; //index within string
  339. while(a_lplpszValue[i][k]!=0)
  340. ((_TCHAR *)mdr.pbMDData)[j++]=a_lplpszValue[i][k++];
  341. ((_TCHAR *)mdr.pbMDData)[j++]=0;
  342. }
  343. ((_TCHAR *)mdr.pbMDData)[j++]=0;
  344. }
  345. void
  346. CAdmProp::SetValue(
  347. LPBYTE pbValue,
  348. DWORD dwValueLength
  349. )
  350. {
  351. if( mdr.pbMDData != NULL )
  352. {
  353. delete mdr.pbMDData;
  354. }
  355. mdr.dwMDDataLen = dwValueLength;
  356. mdr.pbMDData = (PBYTE) new BYTE[mdr.dwMDDataLen];
  357. memcpy( mdr.pbMDData, pbValue, mdr.dwMDDataLen );
  358. }
  359. //sets the value depending on GetDataType()
  360. BOOL CAdmProp::SetValueByDataType(LPCTSTR *a_lplpszPropValue, DWORD* a_lpdwPropValueLength, WORD a_wPropValueCount)
  361. {
  362. //process the value
  363. WORD i;
  364. if(a_wPropValueCount!=0)
  365. { DWORD dwValue=0;
  366. switch(GetDataType())
  367. {
  368. case DWORD_METADATA:
  369. {
  370. for (i=0;i<a_wPropValueCount;i++)
  371. {
  372. if( _tcslen(a_lplpszPropValue[i]) > 2 && a_lplpszPropValue[i][0]==_T('0') && _toupper(a_lplpszPropValue[i][1])==_T('X'))
  373. { _TCHAR * lpszX;
  374. dwValue += _tcstoul(a_lplpszPropValue[i]+2, &lpszX, 16);
  375. }
  376. else if(IsNumber(a_lplpszPropValue[i]))
  377. dwValue += _ttol(a_lplpszPropValue[i]);
  378. else
  379. {
  380. DWORD dwMapped=MapValueNameToCode(a_lplpszPropValue[i],GetIdentifier());
  381. if(dwMapped==NAME_NOT_FOUND)
  382. {
  383. printf/*Print*/(_TEXT("value not resolved: %s\n"),a_lplpszPropValue[i]);
  384. return FALSE;
  385. }
  386. else
  387. // it has to be checked if adding can be performed
  388. dwValue |= dwMapped;
  389. }
  390. }
  391. SetValue(dwValue);
  392. }
  393. break;
  394. case STRING_METADATA:
  395. case EXPANDSZ_METADATA:
  396. {
  397. CString strValue=_TEXT("");
  398. for (i=0;i<a_wPropValueCount;i++)
  399. {
  400. strValue += a_lplpszPropValue[i];
  401. }
  402. SetValue(strValue);
  403. }
  404. break;
  405. case MULTISZ_METADATA:
  406. {
  407. SetValue(a_lplpszPropValue, a_wPropValueCount);
  408. }
  409. break;
  410. case BINARY_METADATA:
  411. SetValue( (LPBYTE)a_lplpszPropValue[0], a_lpdwPropValueLength[0] );
  412. break;
  413. default:
  414. return FALSE;
  415. }
  416. }
  417. return TRUE;
  418. }
  419. void CAdmProp::Print(const _TCHAR * format,...)
  420. {
  421. _TCHAR buffer[2000];
  422. va_list marker;
  423. va_start( marker, format ); /* Initialize variable arguments. */
  424. //_vstprintf(buffer,format, marker);
  425. _vsnprintf(buffer,1500,format, marker);
  426. _tprintf(_TEXT("%s"),buffer);
  427. va_end( marker ); /* Reset variable arguments. */
  428. }
  429. void CAdmProp::PrintProperty(void)
  430. {
  431. CString strPropName=tPropertyNameTable::MapCodeToName(mdr.dwMDIdentifier);
  432. BOOL fSecure =(mdr.dwMDAttributes&METADATA_SECURE);
  433. //print code or name of property
  434. if(strPropName.IsEmpty())
  435. printf/*Print*/(_TEXT("%-30ld: "), mdr.dwMDIdentifier);
  436. else
  437. {
  438. if(getenv("MDUTIL_PRINT_ID")!=NULL) //let's print out Identifier numeric values when environment variable is set
  439. printf/*Print*/(_TEXT("%ld %-25s: "), mdr.dwMDIdentifier,LPCTSTR(strPropName));
  440. else
  441. printf/*Print*/(_TEXT("%-30s: "), LPCTSTR(strPropName));
  442. }
  443. CString strFlagsToPrint=_TEXT("");
  444. strFlagsToPrint+=_TEXT("[");
  445. if(mdr.dwMDAttributes&METADATA_INHERIT)
  446. strFlagsToPrint+=_TEXT("I");
  447. if(mdr.dwMDAttributes&METADATA_SECURE)
  448. strFlagsToPrint+=_TEXT("P");
  449. if(mdr.dwMDAttributes&METADATA_REFERENCE)
  450. strFlagsToPrint+=_TEXT("R");
  451. if(mdr.dwMDUserType==IIS_MD_UT_SERVER)
  452. strFlagsToPrint+=_TEXT("S");
  453. if(mdr.dwMDUserType==IIS_MD_UT_FILE)
  454. strFlagsToPrint+=_TEXT("F");
  455. if(mdr.dwMDUserType==IIS_MD_UT_WAM)
  456. strFlagsToPrint+=_TEXT("W");
  457. if(mdr.dwMDUserType==ASP_MD_UT_APP)
  458. strFlagsToPrint+=_TEXT("A");
  459. strFlagsToPrint+=_TEXT("]");
  460. printf/*Print*/(_TEXT("%-8s"),LPCTSTR(strFlagsToPrint));
  461. //print property value
  462. DWORD i;
  463. switch (mdr.dwMDDataType) {
  464. case DWORD_METADATA:
  465. #ifndef SHOW_SECURE
  466. if ( fSecure && getenv("MDUTIL_PRINT_SECURE")==NULL)
  467. {
  468. printf/*Print*/(_TEXT("(DWORD) ********")); // *(DWORD *)(mdr.pbMDData));
  469. }
  470. else
  471. #endif
  472. {
  473. printf/*Print*/(_TEXT("(DWORD) 0x%x"), *(DWORD *)(mdr.pbMDData));
  474. // try to convert to readable info
  475. CString strNiceContent;
  476. strNiceContent=tValueTable::MapValueContentToString(*(DWORD *)(mdr.pbMDData), mdr.dwMDIdentifier);
  477. if(!strNiceContent.IsEmpty())
  478. printf/*Print*/(_TEXT("={%s}"),LPCTSTR(strNiceContent));
  479. else //at least decimal value can be useful
  480. printf/*Print*/(_TEXT("={%ld}"),*(DWORD *)(mdr.pbMDData));
  481. }
  482. break;
  483. case BINARY_METADATA:
  484. printf/*Print*/(_TEXT("(BINARY) 0x"));
  485. #ifndef SHOW_SECURE
  486. if ( fSecure && getenv("MDUTIL_PRINT_SECURE")==NULL)
  487. {
  488. printf/*Print*/(_TEXT(" * " ));
  489. }
  490. else
  491. #endif
  492. {
  493. for (i = 0; i < mdr.dwMDDataLen; i++)
  494. {
  495. printf/*Print*/(_TEXT("%02x "), ((PBYTE)(mdr.pbMDData))[i]);
  496. }
  497. }
  498. break;
  499. case STRING_METADATA:
  500. case EXPANDSZ_METADATA:
  501. if(mdr.dwMDDataType==STRING_METADATA)
  502. printf/*Print*/(_TEXT("(STRING) "));
  503. else
  504. printf/*Print*/(_TEXT("(EXPANDSZ) "));
  505. #ifndef SHOW_SECURE
  506. if( fSecure && getenv("MDUTIL_PRINT_SECURE")==NULL)
  507. { //do not expose the length of secure data
  508. printf/*Print*/( _TEXT("\"********************\"" ));
  509. }
  510. else
  511. #endif
  512. {
  513. printf/*Print*/(_TEXT("\""));
  514. for (i = 0; i < mdr.dwMDDataLen/sizeof(_TCHAR); i++) {
  515. if(((_TCHAR *)(mdr.pbMDData))[i]==0)
  516. {
  517. if( i+1 == mdr.dwMDDataLen/sizeof(_TCHAR))
  518. { //we are at the end print only terminating "
  519. printf/*Print*/(_TEXT("\""));
  520. }
  521. else
  522. {
  523. printf/*Print*/(_TEXT("\" \""));
  524. }
  525. }
  526. else
  527. {
  528. if(((_TCHAR *)(mdr.pbMDData))[i]=='\r')
  529. printf/*Print*/(_TEXT("\t"));
  530. else
  531. {
  532. printf/*Print*/( _TEXT("%c"), ((_TCHAR *)(mdr.pbMDData))[i]);
  533. }
  534. }
  535. }
  536. }
  537. break;
  538. case MULTISZ_METADATA:
  539. printf/*Print*/(_TEXT("(MULTISZ) ")); //0 should be separator of mulisz strings
  540. #ifndef SHOW_SECURE
  541. if( fSecure && getenv("MDUTIL_PRINT_SECURE")==NULL)
  542. { //do not expose the length of secure data
  543. printf/*Print*/( _TEXT("\"********************\"" ));
  544. }
  545. else
  546. #endif
  547. {
  548. printf/*Print*/(_TEXT("\""));
  549. for (i = 0; i < mdr.dwMDDataLen/sizeof(_TCHAR); i++) {
  550. if(((_TCHAR *)(mdr.pbMDData))[i]==0)
  551. {
  552. if( i+1 == mdr.dwMDDataLen/sizeof(_TCHAR) || (mdr.dwMDDataLen/sizeof(_TCHAR)-i==2 && ((_TCHAR *)(mdr.pbMDData))[i]==0 && ((_TCHAR *)(mdr.pbMDData))[i+1]==0))
  553. { //we are at the end print only terminating "
  554. printf/*Print*/(_TEXT("\"")); break;
  555. }
  556. else
  557. {
  558. printf/*Print*/(_TEXT("\" \""));
  559. }
  560. }
  561. else
  562. printf/*Print*/(_TEXT("%c"),((_TCHAR *)(mdr.pbMDData))[i]);
  563. }
  564. }
  565. break;
  566. default:
  567. printf/*Print*/(_TEXT("(UNKNOWN) "));
  568. break;
  569. }
  570. printf/*Print*/(_TEXT("\n"));
  571. }
  572. //**********************************************************************
  573. //**********************************************************************
  574. //IMPLEMENTATION of CAdmUtil object
  575. //**********************************************************************
  576. //**********************************************************************
  577. //nesting for recursive enumeration
  578. static void nest_print(BYTE bLevel)
  579. {
  580. for(int i=0; i<=bLevel;i++)
  581. _tprintf(_T(" "));
  582. }
  583. CAdmUtil::CAdmUtil (const CString & strComputer)
  584. {
  585. UNREFERENCED_PARM(strComputer);
  586. EnablePrint(); // by default print error messages
  587. pIWamAdm=0; //interface pointer to Wam Admin
  588. pIWamAdm2=0; //interface pointer to Wam Admin2
  589. pcAdmCom=0;
  590. m_hmd=0;
  591. pbDataBuffer=new BYTE [DEFAULTBufferSize];
  592. wDataBufferSize=DEFAULTBufferSize;
  593. #if UNICODE
  594. pcAdmCom=0;
  595. #else
  596. pcAdmCom=new ANSI_smallIMSAdminBase; //we will access metabase through wrapper class
  597. #endif
  598. //Open (strComputer);
  599. }
  600. void CAdmUtil::Open (const CString & strComputer)
  601. {
  602. IClassFactory * pcsfFactory = NULL;
  603. COSERVERINFO csiMachineName;
  604. COSERVERINFO *pcsiParam = NULL;
  605. OLECHAR rgchMachineName[MAX_PATH];
  606. #if UNICODE
  607. //release previous interface if needed
  608. if(pcAdmCom!=0)
  609. {
  610. if (m_hmd!=0) CloseObject(m_hmd);
  611. m_hmd=0;
  612. pcAdmCom->Release();
  613. pcAdmCom=0;
  614. }
  615. //convert to OLECHAR[];
  616. if (!strComputer.IsEmpty())
  617. {
  618. wsprintf( rgchMachineName, L"%s", LPCTSTR(strComputer));
  619. #else
  620. //release previous interface if needed
  621. if(pcAdmCom!=0 &&pcAdmCom->m_pcAdmCom!=0)
  622. {
  623. if (m_hmd!=0) CloseObject(m_hmd);
  624. m_hmd=0;
  625. pcAdmCom->m_pcAdmCom->Release();
  626. pcAdmCom->m_pcAdmCom=0;
  627. }
  628. //convert to OLECHAR[];
  629. if (!strComputer.IsEmpty())
  630. {
  631. wsprintfW( rgchMachineName, L"%S", LPCTSTR(strComputer));
  632. #endif
  633. }
  634. //fill the structure for CoGetClassObject
  635. ZeroMemory( &csiMachineName, sizeof(csiMachineName) );
  636. // csiMachineName.pAuthInfo = NULL;
  637. // csiMachineName.dwFlags = 0;
  638. // csiMachineName.pServerInfoExt = NULL;
  639. pcsiParam = &csiMachineName;
  640. csiMachineName.pwszName = (strComputer.IsEmpty())?NULL:rgchMachineName;
  641. hresError = CoGetClassObject(GETAdminBaseCLSID(TRUE), CLSCTX_SERVER, pcsiParam,
  642. IID_IClassFactory, (void**) &pcsfFactory);
  643. if (FAILED(hresError))
  644. {
  645. Error(_TEXT("CoGetClassObject"));
  646. }
  647. else {
  648. hresError = pcsfFactory->CreateInstance(NULL, IID_IMSAdminBase,
  649. #if UNICODE
  650. (void **) &pcAdmCom);
  651. #else
  652. (void **) &pcAdmCom->m_pcAdmCom);
  653. #endif
  654. if (FAILED(hresError)) Error(_TEXT("CreateInstance"));
  655. pcsfFactory->Release();
  656. }
  657. }
  658. void CAdmUtil::Close (void)
  659. {
  660. //release the interface
  661. #if UNICODE
  662. if(pcAdmCom!=0)
  663. {
  664. if (m_hmd!=0) CloseObject(m_hmd);
  665. m_hmd=0;
  666. pcAdmCom->Release();
  667. pcAdmCom=0;
  668. }
  669. #else
  670. if(pcAdmCom!=0 &&pcAdmCom->m_pcAdmCom!=0)
  671. {
  672. if (m_hmd!=0) CloseObject(m_hmd);
  673. m_hmd=0;
  674. pcAdmCom->m_pcAdmCom->Release();
  675. pcAdmCom->m_pcAdmCom=0;
  676. }
  677. #endif
  678. }
  679. CAdmUtil::~CAdmUtil (void)
  680. {
  681. //release the interface
  682. if(pbDataBuffer!=NULL)
  683. delete [] pbDataBuffer;
  684. //the following may fail if class is static
  685. #if UNICODE
  686. if(pcAdmCom!=0)
  687. {
  688. if (m_hmd!=0) CloseObject(m_hmd);
  689. m_hmd=0;
  690. pcAdmCom->Release();
  691. pcAdmCom=0;
  692. }
  693. #else
  694. if(pcAdmCom!=0 &&pcAdmCom->m_pcAdmCom!=0)
  695. {
  696. if (m_hmd!=0) CloseObject(m_hmd);
  697. m_hmd=0;
  698. pcAdmCom->m_pcAdmCom->Release();
  699. pcAdmCom->m_pcAdmCom=0;
  700. }
  701. #endif
  702. }
  703. //*******************************************************************************
  704. //with fCreate set to TRUE the node will be created if it doesn't exist
  705. METADATA_HANDLE CAdmUtil::OpenObject(CAdmNode & a_AdmNode, DWORD dwPermission, BOOL fCreate)
  706. {
  707. METADATA_HANDLE hmdToReturn = 0;
  708. //try to open the full path
  709. CString strPathToOpen=a_AdmNode.GetLMNodePath();
  710. hresError = pcAdmCom->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  711. IADM_PBYTE LPCTSTR(strPathToOpen), dwPermission, g_dwTIMEOUT_VALUE, &hmdToReturn);
  712. if (FAILED(hresError)) {
  713. if ( ((dwPermission==(dwPermission|METADATA_PERMISSION_READ)) || fCreate==FALSE) ||(hresError != RETURNCODETOHRESULT(ERROR_PATH_NOT_FOUND))) {
  714. CString strErrMsg=_TEXT("OpenKey");
  715. strErrMsg += _TEXT("(\"")+a_AdmNode.GetNodePath()+_TEXT("\")");
  716. Error(LPCTSTR(strErrMsg));
  717. }
  718. else {
  719. //!!!!!!!!!!!!!Place the dialog to ask to create the path
  720. // open the service object for write
  721. METADATA_HANDLE hmdServicePathHandle;
  722. hresError = pcAdmCom->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  723. IADM_PBYTE LPCTSTR(a_AdmNode.GetLMServicePath()), METADATA_PERMISSION_WRITE, g_dwTIMEOUT_VALUE, &hmdServicePathHandle);
  724. if (FAILED(hresError))
  725. {
  726. CString strErrMsg=_TEXT("OpenKey");
  727. strErrMsg += _TEXT("(\"")+a_AdmNode.GetServicePath()+_TEXT(",WRITE")+_TEXT("\")");
  728. Error(LPCTSTR(strErrMsg));
  729. }
  730. else {
  731. // create the node
  732. hresError = pcAdmCom->AddKey(hmdServicePathHandle,
  733. IADM_PBYTE LPCTSTR(a_AdmNode.GetRelPathFromInstance()));
  734. if (FAILED(hresError)) {
  735. CString strErrMsg=_TEXT("AddKey");
  736. strErrMsg += _TEXT("(\"")+a_AdmNode.GetRelPathFromInstance()+_TEXT("\")");
  737. Error(LPCTSTR(strErrMsg));
  738. }
  739. //close the service object
  740. pcAdmCom->CloseKey(hmdServicePathHandle);
  741. if (FAILED(hresError)) Error(_TEXT("CloseKey"));
  742. else {
  743. // now finally we can open the full path
  744. hresError = pcAdmCom->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  745. IADM_PBYTE LPCTSTR(strPathToOpen), dwPermission, g_dwTIMEOUT_VALUE, &hmdToReturn);
  746. if (FAILED(hresError))
  747. {
  748. CString strErrMsg=_TEXT("OpenKey");
  749. strErrMsg += _TEXT("(\"")+a_AdmNode.GetServicePath()+_TEXT(",WRITE")+_TEXT("\")");
  750. Error(LPCTSTR(strErrMsg));
  751. }
  752. }
  753. }
  754. }
  755. }
  756. Sleep(g_dwDELAY_AFTER_OPEN_VALUE);
  757. return hmdToReturn;
  758. }
  759. //*******************************************************************************
  760. void CAdmUtil::CloseObject(METADATA_HANDLE hmd)
  761. {
  762. HRESULT hresStore=hresError;
  763. hresError=pcAdmCom->CloseKey(hmd);
  764. if (FAILED(hresError)) Error(_TEXT("CloseData"));
  765. else hresError=hresStore; //restore the previous hresError
  766. }
  767. //*******************************************************************************
  768. void CAdmUtil::CreateObject(CAdmNode & a_AdmNode)
  769. {
  770. OpenObjectTo_hmd(a_AdmNode, METADATA_PERMISSION_WRITE, TRUE/* fCreate*/);
  771. }
  772. #if 0
  773. METADATA_HANDLE hmdToReturn = 0;
  774. //try to open the full path
  775. CString strPathToOpen=a_AdmNode.GetLMNodePath();
  776. METADATA_HANDLE hmdServicePathHandle;
  777. hresError = pcAdmCom->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  778. IADM_PBYTE LPCTSTR(a_AdmNode.GetLMServicePath()), METADATA_PERMISSION_WRITE, g_dwTIMEOUT_VALUE, &hmdServicePathHandle);
  779. if (FAILED(hresError))
  780. {
  781. CString strErrMsg=_TEXT("OpenKey");
  782. strErrMsg += _TEXT("(\"")+a_AdmNode.GetServicePath()+_TEXT(",WRITE")+_TEXT("\")");
  783. Error(LPCTSTR(strErrMsg));
  784. }
  785. else
  786. {
  787. // create the node
  788. hresError = pcAdmCom->AddKey(hmdServicePathHandle,
  789. IADM_PBYTE LPCTSTR(a_AdmNode.GetRelPathFromInstance()));
  790. if (FAILED(hresError)) {
  791. CString strErrMsg=_TEXT("AddKey");
  792. strErrMsg += _TEXT("(\"")+a_AdmNode.GetRelPathFromInstance()+_TEXT("\")");
  793. Error(LPCTSTR(strErrMsg));
  794. }
  795. //close the service object
  796. CloseObject(hmdServicePathHandle);
  797. }
  798. #endif
  799. // This function enables to reuse open handles in order to improve performance
  800. // !!it supports only one acticve handle (otherwise the processing may fail)
  801. METADATA_HANDLE CAdmUtil::OpenObjectTo_hmd(CAdmNode & a_AdmNode, DWORD dwPermission, BOOL fCreate)
  802. {
  803. CString strPathToOpen=a_AdmNode.GetLMNodePath();
  804. if(m_hmd!=0 && strPathToOpen.CompareNoCase(m_strNodePath)==0 && m_dwPermissionOfhmd == dwPermission )
  805. { //we can reuse already opened node
  806. }
  807. else
  808. {
  809. if(m_hmd != 0)
  810. {
  811. CloseObject(m_hmd);
  812. m_hmd=0;
  813. }
  814. m_hmd = OpenObject(a_AdmNode, dwPermission, fCreate);
  815. m_dwPermissionOfhmd = dwPermission;
  816. m_strNodePath = strPathToOpen;
  817. }
  818. return m_hmd;
  819. }
  820. void CAdmUtil::CloseObject_hmd(void)
  821. {
  822. if(m_hmd != 0)
  823. {
  824. CloseObject(m_hmd);
  825. m_hmd=0;
  826. }
  827. }
  828. //*******************************************************************************
  829. void CAdmUtil::GetProperty(CAdmNode& a_AdmNode, CAdmProp& a_AdmProp)
  830. {
  831. DWORD dwRequiredDataLen=0;
  832. WORD wDataBufferSize=0;
  833. PBYTE DataBuffer=0;
  834. DWORD dwPropertyCode=a_AdmProp.GetIdentifier();
  835. if(dwPropertyCode==0) Error(_TEXT("Property name not found"));
  836. else
  837. {
  838. //MD_SET_DATA_RECORD(&a_AdmProp.mdr,
  839. // 0,
  840. // METADATA_INHERIT | METADATA_PARTIAL_PATH,
  841. // 0,
  842. // 0,
  843. // wDataBufferSize,
  844. // pbDataBuffer);
  845. //a_AdmProp.SetIdentifier(dwPropertyCode); //has to be set beforehand
  846. a_AdmProp.SetDataType(0);
  847. a_AdmProp.SetUserType(0);
  848. a_AdmProp.SetAttrib(0);
  849. METADATA_HANDLE hmd = OpenObjectTo_hmd(a_AdmNode,
  850. METADATA_PERMISSION_READ);
  851. if (SUCCEEDED(hresError))
  852. {
  853. hresError = pcAdmCom->GetData(hmd,
  854. IADM_PBYTE _TEXT(""),
  855. &a_AdmProp.mdr, &dwRequiredDataLen);
  856. if (FAILED(hresError)) {
  857. if (hresError == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER)) {
  858. /////////// delete []pbDataBuffer;
  859. pbDataBuffer=new BYTE[dwRequiredDataLen];
  860. if (pbDataBuffer==0) {
  861. hresError = RETURNCODETOHRESULT(ERROR_NOT_ENOUGH_MEMORY);
  862. Error(_TEXT("Buffer resize failed"));
  863. }
  864. else {
  865. a_AdmProp.mdr.dwMDDataLen = dwRequiredDataLen;
  866. a_AdmProp.mdr.pbMDData = pbDataBuffer;
  867. hresError = pcAdmCom->GetData(hmd,
  868. IADM_PBYTE _TEXT(""), &a_AdmProp.mdr, &dwRequiredDataLen);
  869. if (FAILED(hresError)) Error(_TEXT("GetData"));
  870. }
  871. }
  872. else
  873. Error(_TEXT("GetData"));;
  874. }
  875. //CloseObject (hmd); we might reuse it
  876. }
  877. }
  878. }
  879. //if lplpszPropertyValue[1]==NULL it means there is only one value (it is not a multistring)
  880. void CAdmUtil::SetProperty(CAdmNode& a_AdmNode, CAdmProp& a_AdmProp)
  881. {
  882. METADATA_HANDLE hmd = OpenObjectTo_hmd(a_AdmNode,
  883. METADATA_PERMISSION_WRITE,TRUE/*create node if doesn't exist*/);
  884. if (SUCCEEDED(hresError))
  885. {
  886. SetProperty(&a_AdmProp.mdr,hmd);
  887. //CloseObject(hmd); we will reuse it
  888. }
  889. }
  890. void CAdmUtil::SetProperty(PMETADATA_RECORD a_pmdrData,METADATA_HANDLE a_hmd)
  891. {
  892. hresError = pcAdmCom->SetData(a_hmd,
  893. IADM_PBYTE _TEXT(""), a_pmdrData);
  894. if (FAILED(hresError)) Error(_TEXT("SetData"));
  895. }
  896. void CAdmUtil::SaveData(void)
  897. {
  898. if (m_hmd!=0)
  899. { //we have to close reusable handle in order to save successfully
  900. CloseObject(m_hmd);
  901. m_hmd=0;
  902. }
  903. hresError = pcAdmCom->SaveData();
  904. if (FAILED(hresError)) Error(_TEXT("SaveData"));
  905. }
  906. //****************************************************************************
  907. //DELETE PROPERTY
  908. void CAdmUtil::DeleteProperty(CAdmNode& a_AdmNode, CAdmProp& a_AdmProp)
  909. {
  910. METADATA_HANDLE hmd = OpenObjectTo_hmd(a_AdmNode,
  911. METADATA_PERMISSION_WRITE,TRUE/*create node if doesn't exist*/);
  912. if (SUCCEEDED(hresError))
  913. {
  914. DeleteProperty(&a_AdmProp.mdr,hmd);
  915. // CloseObject(hmd); we will reuse it
  916. }
  917. }
  918. void CAdmUtil::DeleteProperty(PMETADATA_RECORD a_pmdrData,METADATA_HANDLE a_hmd)
  919. {
  920. hresError = pcAdmCom->DeleteData(a_hmd,
  921. IADM_PBYTE _TEXT(""), a_pmdrData->dwMDIdentifier,ALL_METADATA);
  922. if (FAILED(hresError)) Error(_TEXT("DeleteData"));
  923. }
  924. //****************************************************************************
  925. //DELETE OBJECT
  926. void CAdmUtil::DeleteObject(CAdmNode& a_AdmNode, CAdmProp& a_AdmProp)
  927. {
  928. CAdmNode NodeToOpen = a_AdmNode.GetParentNodePath();
  929. METADATA_HANDLE hmd = OpenObjectTo_hmd(NodeToOpen,
  930. METADATA_PERMISSION_WRITE,FALSE/*create node if doesn't exist*/);
  931. UNREFERENCED_PARM(a_AdmProp);
  932. if (SUCCEEDED(hresError))
  933. {
  934. CString strToDelete=a_AdmNode.GetCurrentNodeName();
  935. if(strToDelete==_TEXT(""))
  936. strToDelete=_TEXT("//"); //empty name has to be wrapped with '/'
  937. DeleteObject(hmd,strToDelete);
  938. //CloseObject(hmd); we will reuse it
  939. }
  940. }
  941. void CAdmUtil::DeleteObject(METADATA_HANDLE a_hmd, CString& a_strObjectName)
  942. {
  943. hresError = pcAdmCom->DeleteKey(a_hmd, IADM_PBYTE LPCTSTR(a_strObjectName));
  944. if (FAILED(hresError)) Error(_TEXT("DeleteKey"));
  945. }
  946. void CAdmUtil::EnumPropertiesAndPrint(CAdmNode& a_AdmNode,
  947. CAdmProp a_AdmProp, //cannot be passed by reference
  948. BYTE bRecurLevel,
  949. METADATA_HANDLE a_hmd,
  950. CString & a_strRelPath)
  951. {
  952. CAdmProp mdrData=a_AdmProp;
  953. DWORD dwRequiredDataLen=0;
  954. PBYTE DataBuffer=0;
  955. METADATA_HANDLE hmdMain;
  956. if(a_hmd==0) //if handle was not passed then open one
  957. {
  958. hmdMain = OpenObjectTo_hmd(a_AdmNode, METADATA_PERMISSION_READ);
  959. if (FAILED(hresError))
  960. return;
  961. }
  962. else
  963. hmdMain = a_hmd;
  964. for (int j=0;;j++) { //cycle for properties
  965. MD_SET_DATA_RECORD(&mdrData.mdr,
  966. 0,
  967. a_AdmProp.mdr.dwMDAttributes,
  968. a_AdmProp.mdr.dwMDUserType,
  969. a_AdmProp.mdr.dwMDDataType,
  970. dwRequiredDataLen,
  971. pbDataBuffer);
  972. hresError = pcAdmCom->EnumData(hmdMain,
  973. IADM_PBYTE LPCTSTR(a_strRelPath), &mdrData.mdr,j, &dwRequiredDataLen);
  974. if (FAILED(hresError))
  975. {
  976. if(hresError == RETURNCODETOHRESULT(ERROR_NO_MORE_ITEMS))
  977. {
  978. hresError=0; //NO MORE ITEMS IS NOT ERROR FOR US
  979. break; //end of items
  980. }
  981. else if (hresError == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER))
  982. {
  983. delete pbDataBuffer;
  984. pbDataBuffer=new BYTE[dwRequiredDataLen];
  985. if (pbDataBuffer==0)
  986. {
  987. hresError = RETURNCODETOHRESULT(ERROR_NOT_ENOUGH_MEMORY);
  988. Error(_TEXT("Buffer resize failed"));
  989. }
  990. else
  991. {
  992. mdrData.mdr.dwMDDataLen = dwRequiredDataLen;
  993. mdrData.mdr.pbMDData = pbDataBuffer;
  994. hresError = pcAdmCom->EnumData(hmdMain,
  995. IADM_PBYTE LPCTSTR(a_strRelPath), &mdrData.mdr,j, &dwRequiredDataLen);
  996. if (FAILED(hresError)) Error(_TEXT("GetData"));
  997. }
  998. }
  999. else
  1000. Error(_TEXT("EnumData"));
  1001. }
  1002. //else
  1003. // Error(_TEXT("EnumData"));
  1004. if(SUCCEEDED(hresError)) //we enumerated successfully, let's print
  1005. {
  1006. nest_print(bRecurLevel+1);
  1007. mdrData.PrintProperty();
  1008. }
  1009. else
  1010. {
  1011. break;
  1012. }
  1013. } //end for j - cycle for properties
  1014. //if(a_hmd==0)
  1015. // CloseObject(hmdMain); we will reuse it //close only if we opened at the beginning
  1016. }
  1017. void CAdmUtil::EnumAndPrint(CAdmNode& a_AdmNode,
  1018. CAdmProp& a_AdmProp,
  1019. BOOL a_fRecursive,
  1020. BYTE a_bRecurLevel,
  1021. METADATA_HANDLE a_hmd,
  1022. CString& a_strRelPath)
  1023. {
  1024. _TCHAR NameBuf[METADATA_MAX_NAME_LEN];
  1025. METADATA_HANDLE hmdMain;
  1026. if(a_hmd==0) //if handle was not passed then open one
  1027. {
  1028. hmdMain = OpenObjectTo_hmd(a_AdmNode, METADATA_PERMISSION_READ);
  1029. if (FAILED(hresError))
  1030. return;
  1031. }
  1032. else
  1033. hmdMain = a_hmd;
  1034. //printf("[RELATIVE PATH : \"%s\"]\n",LPCTSTR(a_strRelPath));
  1035. //print the properties of the node
  1036. EnumPropertiesAndPrint(a_AdmNode,a_AdmProp,a_bRecurLevel,hmdMain,a_strRelPath);
  1037. for (int i=0; ;i++) { //cycle for subnodes
  1038. hresError = pcAdmCom->EnumKeys(hmdMain,
  1039. IADM_PBYTE LPCTSTR(a_strRelPath), IADM_PBYTE NameBuf, i);
  1040. if(FAILED(hresError)) {
  1041. if(hresError == RETURNCODETOHRESULT(ERROR_NO_MORE_ITEMS)) {
  1042. hresError=0; //NO MORE ITEMS IS NOT ERROR FOR US
  1043. break; //end of cycle
  1044. }
  1045. else
  1046. {
  1047. Error(_TEXT("EnumKeys"));
  1048. break;
  1049. }
  1050. }
  1051. else {
  1052. //process and print node info
  1053. CString strNewRelPath( a_strRelPath );
  1054. if(NameBuf[0]==0) //empty name
  1055. strNewRelPath+=_TEXT("//"); //add two slashes -> this is required by metabase
  1056. else
  1057. {
  1058. UINT nLen;
  1059. //if(strNewRelPath.GetLength()>=1 && strNewRelPath.Right(1)==_TEXT("/")) {
  1060. if( (nLen=strNewRelPath.GetLength())>=1 && (strNewRelPath.GetAt(nLen-1)=='/') ) {
  1061. }
  1062. else {
  1063. strNewRelPath+=_TEXT("/"); //add only if it is not at the end of string.
  1064. }
  1065. strNewRelPath+=NameBuf;
  1066. }
  1067. CString strStringToPrint( a_AdmNode.GetNodePath() );
  1068. UINT nLen = strStringToPrint.GetLength();
  1069. //if (strStringToPrint.Right(2)==_TEXT("//"))
  1070. if ((nLen > 2) && strStringToPrint.GetAt(nLen-1)=='/'
  1071. && strStringToPrint.GetAt(nLen-2)=='/' )
  1072. {
  1073. strStringToPrint += strNewRelPath.Mid(1); //strip first '/'
  1074. }
  1075. else
  1076. {
  1077. strStringToPrint += strNewRelPath;
  1078. }
  1079. LPCTSTR lpszStr=LPCTSTR(strStringToPrint);
  1080. this->Print(_TEXT("[%s]\n"),lpszStr );
  1081. if(a_fRecursive)
  1082. {
  1083. EnumAndPrint(a_AdmNode,a_AdmProp ,a_fRecursive, a_bRecurLevel+1, hmdMain,strNewRelPath);
  1084. }
  1085. else
  1086. { //no recursion
  1087. }
  1088. }
  1089. } //end for i - cycle for nodes
  1090. //if(a_hmd==0)
  1091. // CloseObject(hmdMain); //we will reuse it //close only if we opened at the beginning
  1092. }
  1093. //****************************************************************
  1094. // the following function is somehow complicated because
  1095. // metadata copy function doesn't support copying of one object to another place with different name
  1096. // e.g. ComAdmCopyKey will copy /W3SVC/1//scripts/oldscripts1 /W3SVC/1//oldscripts2
  1097. // will create /W3SVC/1//oldscripts2/oldscripts1
  1098. //
  1099. void CAdmUtil::CopyObject(CAdmNode& a_AdmNode,
  1100. CAdmNode& a_AdmNodeDst)
  1101. {
  1102. CString strSrcPath=a_AdmNode.GetNodePath();
  1103. CString strDstPath=a_AdmNodeDst.GetNodePath();
  1104. CString strCommonPath; //=_TEXT("");
  1105. CString strRelSrcPath=strSrcPath; //relative to common path
  1106. CString strRelDstPath=strDstPath; //relative to common path
  1107. //we cannot open Source Path for reading because if will diable wrining to all parent nodes
  1108. //e.g. copy /W3SVC/1//scripts/oldscripts /W3SVC/1//oldscripts would fail
  1109. //It is necessary to find common partial path and open metabase object for that common partial path for READ/WRITE
  1110. //!!!!!!!!!!!!!!!!! assume that paths are not case sensitive
  1111. int MinLength=strSrcPath.GetLength();
  1112. int i;
  1113. //find shorter from strings
  1114. if(strDstPath.GetLength() < MinLength)
  1115. MinLength=strDstPath.GetLength();
  1116. for(i=0; i<MinLength; i++)
  1117. {
  1118. if(strSrcPath.GetAt(i)!=strDstPath.GetAt(i) )
  1119. // common path cannot be any longer;
  1120. break;
  1121. }
  1122. // now find the previous '/' and all before '/' is the common path
  1123. for(i=i-1; i>=0;i--)
  1124. {
  1125. if(strSrcPath.GetAt(i)==_T('/'))
  1126. {
  1127. strCommonPath=strSrcPath.Left(i+1);//take the trailing '/' with you
  1128. strRelSrcPath=strSrcPath.Mid(i+1);
  1129. strRelDstPath=strDstPath.Mid(i+1);
  1130. break;
  1131. }
  1132. }
  1133. METADATA_HANDLE hmdCommon=0;
  1134. CAdmNode CommonNode;
  1135. CommonNode.SetPath(strCommonPath);
  1136. hmdCommon = OpenObjectTo_hmd(CommonNode, METADATA_PERMISSION_READ+METADATA_PERMISSION_WRITE);
  1137. if (FAILED(hresError))
  1138. return;
  1139. // Altered by Adam Stone on 30-Jan-97 The following code was changed to comply with
  1140. // the changes to the metabase ComMDCopyKey function.
  1141. // Copy the metadata to the destination
  1142. hresError = pcAdmCom->CopyKey (hmdCommon,
  1143. IADM_PBYTE LPCTSTR(strRelSrcPath),
  1144. hmdCommon,
  1145. IADM_PBYTE LPCTSTR(strRelDstPath),
  1146. FALSE, // Do NOT overwrite
  1147. TRUE); // Copy do NOT move
  1148. if (FAILED(hresError)) // if the node already exists, it is error
  1149. {
  1150. CString strErrMsg=_TEXT("CopyKey");
  1151. strErrMsg += _TEXT("(\"")+a_AdmNodeDst.GetRelPathFromInstance()+_TEXT("\")");
  1152. Error(LPCTSTR(strErrMsg));
  1153. }
  1154. // All of the commented out code has become unneccessary as of 30-Jan-97 because of a change
  1155. // in the metabase. ComMDCopyKey now copies to the destination, overwriting if
  1156. // requested. It used to copy to a child of the destination object.
  1157. /* // create the node
  1158. * hresError = pcAdmCom->AddKey(hmdCommon,
  1159. * IADM_PBYTE LPCTSTR(strRelDstPath));
  1160. * if (FAILED(hresError)) { //if the node exists, it is error)
  1161. * CString strErrMsg=_TEXT("AddKey");
  1162. * strErrMsg += _TEXT("(\"")+a_AdmNodeDst.GetRelPathFromInstance()+_TEXT("\")");
  1163. * Error(LPCTSTR(strErrMsg));
  1164. * }
  1165. * else //no error when creating new node
  1166. * {
  1167. * for (i=0; ;i++) { //cycle for subnodes
  1168. * hresError = pcAdmCom->EnumKeys(hmdCommon,
  1169. * IADM_PBYTE LPCTSTR(strRelSrcPath), (PBYTE)NameBuf, i);
  1170. * if(FAILED(hresError)) {
  1171. * if(hresError == RETURNCODETOHRESULT(ERROR_NO_MORE_ITEMS)) {
  1172. * hresError=0; //this is not an error
  1173. * break; //end of cycle
  1174. * }
  1175. * else
  1176. * {
  1177. * Error(_TEXT("EnumKeys"));
  1178. * break;
  1179. * }
  1180. *
  1181. * }
  1182. * else {
  1183. *
  1184. * //process and copy node child node
  1185. *
  1186. * CString strNewRelSrcPath=strRelSrcPath;
  1187. * if(NameBuf[0]==0) //empty name
  1188. * strNewRelSrcPath+=_TEXT("//"); //add two slashes -> this is required by metabase
  1189. * else
  1190. * { if(strNewRelSrcPath.GetLength()>=1 && strNewRelSrcPath.Right(1)==_TEXT("/")) {
  1191. * }
  1192. * else {
  1193. * strNewRelSrcPath+=_TEXT("/"); //add only if it is not at the end of string.
  1194. * }
  1195. * strNewRelSrcPath+=NameBuf;
  1196. * }
  1197. * hresError = pcAdmCom->CopyKey(
  1198. * hmdCommon, (PBYTE) LPCTSTR(strNewRelSrcPath),
  1199. * hmdCommon, (PBYTE) LPCTSTR(strRelDstPath),TRUE,TRUE);
  1200. * if(FAILED(hresError)) {
  1201. * Error(_TEXT("CopyKey"));
  1202. * }
  1203. *
  1204. *
  1205. * }
  1206. * } //end for i - cycle for nodes
  1207. *
  1208. *
  1209. * //WE COPIED ALL NODES, COPY PARAMETERS NOW
  1210. * CAdmProp mdrData;
  1211. * DWORD dwRequiredDataLen=0;
  1212. * PBYTE DataBuffer=0;
  1213. *
  1214. *
  1215. *
  1216. * for (int j=0;;j++) { //cycle for properties
  1217. * MD_SET_DATA_RECORD(&mdrData.mdr,
  1218. * 0,
  1219. * 0,
  1220. * 0,
  1221. * 0,
  1222. * dwRequiredDataLen,
  1223. * pbDataBuffer);
  1224. *
  1225. * hresError = pcAdmCom->EnumData(hmdCommon,
  1226. * (PBYTE) LPCTSTR(strRelSrcPath)
  1227. * , &mdrData.mdr,j, &dwRequiredDataLen);
  1228. * if (FAILED(hresError))
  1229. * {
  1230. * if(hresError == RETURNCODETOHRESULT(ERROR_NO_MORE_ITEMS))
  1231. * {
  1232. * hresError=0; //NO MORE ITEMS IS NOT ERROR FOR US
  1233. * break; //end of items
  1234. * }
  1235. * else if (hresError == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER))
  1236. * {
  1237. /////////// delete pbDataBuffer;
  1238. * pbDataBuffer=new BYTE[dwRequiredDataLen];
  1239. * if (pbDataBuffer==0)
  1240. * {
  1241. * hresError = RETURNCODETOHRESULT(ERROR_NOT_ENOUGH_MEMORY);
  1242. * Error(_TEXT("Buffer resize failed"));
  1243. * }
  1244. * else
  1245. * {
  1246. * mdrData.mdr.dwMDDataLen = dwRequiredDataLen;
  1247. * mdrData.mdr.pbMDData = pbDataBuffer;
  1248. * hresError = pcAdmCom->EnumData(hmdCommon,
  1249. * (PBYTE) LPCTSTR(strRelSrcPath)
  1250. * , &mdrData.mdr,j, &dwRequiredDataLen);
  1251. * if (FAILED(hresError)) Error(_TEXT("GetData"));
  1252. * }
  1253. * }
  1254. * else
  1255. * Error(_TEXT("EnumData"));
  1256. * }
  1257. * else
  1258. * Error(_TEXT("EnumData"));
  1259. *
  1260. * if(SUCCEEDED(hresError)) //we enumerated successfully, let's print
  1261. * {
  1262. * hresError = pcAdmCom->SetData(hmdCommon, (PBYTE) LPCTSTR(strRelDstPath),&mdrData.mdr);
  1263. * if (FAILED(hresError)) Error(_TEXT("SetData"));
  1264. * }
  1265. * else
  1266. * {
  1267. * break;
  1268. * }
  1269. * } //end for j - cycle for properties
  1270. * }
  1271. */
  1272. //CloseObject(hmdCommon); //we will reuse handle //close only if we opened at the beginning
  1273. }
  1274. void CAdmUtil::RenameObject(CAdmNode& a_AdmNode,
  1275. CAdmNode& a_AdmNodeDst)
  1276. {
  1277. CString strSrcPath=a_AdmNode.GetNodePath();
  1278. CString strDstPath=a_AdmNodeDst.GetNodePath();
  1279. CString strCommonPath=_TEXT("");
  1280. CString strRelSrcPath=strSrcPath; //relative to common path
  1281. CString strRelDstPath=strDstPath; //relative to common path
  1282. //we cannot open Source Path for reading because if will diable wrining to all parent nodes
  1283. //e.g. copy /W3SVC/1//scripts/oldscripts /W3SVC/1//oldscripts would fail
  1284. //It is necessary to find common partial path and open metabase object for that common partial path for READ/WRITE
  1285. //!!!!!!!!!!!!!!!!! assume that paths are not case sensitive
  1286. int MinLength=strSrcPath.GetLength();
  1287. int i;
  1288. //find shorter from strings
  1289. if(strDstPath.GetLength() < MinLength)
  1290. MinLength=strDstPath.GetLength();
  1291. for(i=0; i<MinLength; i++)
  1292. {
  1293. if(strSrcPath.GetAt(i)!=strDstPath.GetAt(i) )
  1294. // common path cannot be any longer;
  1295. break;
  1296. }
  1297. // now find the previous '/' and all before '/' is the common path
  1298. for(i=i-1; i>=0;i--)
  1299. {
  1300. if(strSrcPath.GetAt(i)==_T('/'))
  1301. {
  1302. strCommonPath=strSrcPath.Left(i+1);//take the trailing '/' with you
  1303. strRelSrcPath=strSrcPath.Mid(i); // keep the trailing '/' in case it's "//"
  1304. strRelDstPath=strDstPath.Mid(i+1);
  1305. break;
  1306. }
  1307. }
  1308. METADATA_HANDLE hmdCommon=0;
  1309. CAdmNode CommonNode;
  1310. CommonNode.SetPath(strCommonPath);
  1311. hmdCommon = OpenObjectTo_hmd(CommonNode, METADATA_PERMISSION_READ+METADATA_PERMISSION_WRITE);
  1312. if (FAILED(hresError))
  1313. return;
  1314. hresError = pcAdmCom->RenameKey (hmdCommon,
  1315. IADM_PBYTE LPCTSTR(strRelSrcPath),
  1316. IADM_PBYTE LPCTSTR(strRelDstPath)
  1317. );
  1318. if (FAILED(hresError)) // if the node already exists, it is error
  1319. {
  1320. CString strErrMsg=_TEXT("RenameKey");
  1321. strErrMsg += _TEXT("(\"")+a_AdmNodeDst.GetRelPathFromInstance()+_TEXT("\")");
  1322. Error(LPCTSTR(strErrMsg));
  1323. }
  1324. //CloseObject(hmdCommon); //we will reuse it//close only if we opened at the beginning
  1325. }
  1326. //**********************************************************************
  1327. //IMPLEMENTATION of AdmUtil
  1328. //**********************************************************************
  1329. void CAdmUtil::Run(CString& strCommand, CAdmNode& a_AdmNode, CAdmProp& a_AdmProp, CAdmNode& a_AdmDstNode,
  1330. LPCTSTR *a_lplpszPropValue,
  1331. DWORD *a_lpdwPropValueLength,
  1332. WORD wPropValueCount)
  1333. {
  1334. DWORD dwCommandCode=0;
  1335. dwCommandCode = tCommandNameTable::MapNameToCode(strCommand);
  1336. switch(dwCommandCode)
  1337. {
  1338. case CMD_SAVE:
  1339. SaveData();
  1340. if (FAILED(hresError)) {}
  1341. else{
  1342. printf/*Print*/(_TEXT("saved\n"));
  1343. }
  1344. break;
  1345. case CMD_CREATE:
  1346. {
  1347. if (a_AdmNode.GetProperty()!=_TEXT("")) //property name cannot be used
  1348. Error(_TEXT("property name for CREATE not supported"));
  1349. // else if (a_AdmNode.GetService()==_TEXT("")) //property name cannot be used
  1350. // Error(_TEXT("service name for CREATE is missing"));
  1351. else
  1352. {
  1353. CreateObject(a_AdmNode);
  1354. if( SUCCEEDED(QueryLastHresError()))
  1355. {
  1356. // SaveData(); //end of transaction
  1357. if( SUCCEEDED(QueryLastHresError()))
  1358. {
  1359. printf/*Print*/(_TEXT("created \"%s\"\n"), LPCTSTR(a_AdmNode.GetNodePath()));
  1360. }
  1361. }
  1362. }
  1363. }
  1364. break;
  1365. case CMD_SET:
  1366. {
  1367. CAdmProp AdmPropToGet;
  1368. AdmPropToGet = a_AdmProp;
  1369. AdmPropToGet.SetAttrib(0);
  1370. AdmPropToGet.SetUserType(0);
  1371. AdmPropToGet.SetDataType(0);
  1372. DisablePrint(); //do not print any error message
  1373. GetProperty(a_AdmNode, AdmPropToGet);
  1374. EnablePrint(); //continue printing error messages
  1375. //*************************SETTING ATTRIB, DATATYPE, USERTYPE
  1376. // if the parameter exists in the metabase, then existing ATTRIB, DATATYPE, USERTYPE
  1377. // will be used , but this can be overwritten from a_AdmProp
  1378. // if the parameter doesn't exists in the metabase, then default ATTRIB, DATATYPE, USERTYPE
  1379. // (see tables.cpp) will be used , but this can be overwritten from a_AdmProp
  1380. if(FAILED(QueryLastHresError()))
  1381. { //store the value to be set into a_AdmProp
  1382. //FIND DEFAULT SETTINGS
  1383. DWORD dwPropCode=a_AdmProp.GetIdentifier();
  1384. tPropertyNameTable * PropNameTableRecord = tPropertyNameTable::FindRecord(dwPropCode);
  1385. if (PropNameTableRecord!=NULL)
  1386. {
  1387. AdmPropToGet.SetIdentifier(PropNameTableRecord->dwCode);
  1388. AdmPropToGet.SetAttrib(PropNameTableRecord->dwDefAttributes) ;
  1389. AdmPropToGet.SetUserType(PropNameTableRecord->dwDefUserType);
  1390. AdmPropToGet.SetDataType(PropNameTableRecord->dwDefDataType);
  1391. }
  1392. }
  1393. else
  1394. { //reuse the existing settings
  1395. if( a_AdmProp.GetDataType()!=0 &&(a_AdmProp.GetDataType()!= AdmPropToGet.GetDataType()))
  1396. {
  1397. Error(_TEXT("Cannot redefine data type from %s to %s"),
  1398. tDataTypeNameTable::MapCodeToName(AdmPropToGet.GetDataType()),
  1399. tDataTypeNameTable::MapCodeToName(a_AdmProp.GetDataType()));
  1400. break;
  1401. }
  1402. }
  1403. // use settings passed to the function if set
  1404. if(!a_AdmProp.IsSetDataType())
  1405. a_AdmProp.SetDataType(AdmPropToGet.GetDataType()); //reuse existing data type
  1406. if(!a_AdmProp.IsSetUserType())
  1407. a_AdmProp.SetUserType(AdmPropToGet.GetUserType()); //reuse existing user type
  1408. if(!a_AdmProp.IsSetAttrib())
  1409. a_AdmProp.SetAttrib(AdmPropToGet.GetAttrib()); //reuse exixting attrib
  1410. if(a_AdmProp.SetValueByDataType( (LPCTSTR *)a_lplpszPropValue, a_lpdwPropValueLength, wPropValueCount)==0)
  1411. Error(_TEXT("SetValueByDataType failed"));
  1412. else
  1413. {
  1414. // if (a_AdmNode.GetService()==_TEXT("")) //property name cannot be used
  1415. // Error(_TEXT("service name for SET is missing"));
  1416. // else
  1417. if (a_AdmNode.GetProperty()!=_TEXT(""))
  1418. {
  1419. SetProperty(a_AdmNode, a_AdmProp);
  1420. if( SUCCEEDED(QueryLastHresError()))
  1421. {
  1422. //SaveData(); //end of transaction
  1423. if( SUCCEEDED(QueryLastHresError()))
  1424. {
  1425. GetProperty(a_AdmNode, a_AdmProp);
  1426. if(SUCCEEDED(QueryLastHresError()))
  1427. a_AdmProp.PrintProperty();
  1428. }
  1429. }
  1430. }else
  1431. Error(_TEXT("property name missing for SET command"));
  1432. }
  1433. break;
  1434. }
  1435. case CMD_DELETE:
  1436. //if (a_AdmNode.GetService()==_TEXT("")) //property name cannot be used
  1437. // Error(_TEXT("service name for DELETE is missing"));
  1438. if (IsServiceName(a_AdmNode.GetService()) && a_AdmNode.GetInstance()==_TEXT("") && a_AdmNode.GetIPath()==_TEXT("") && a_AdmNode.GetProperty()==_TEXT(""))
  1439. Error(_TEXT("cannot delete service"));
  1440. else if (a_AdmNode.GetInstance()==_TEXT("1") && a_AdmNode.GetIPath()==_TEXT("") && a_AdmNode.GetProperty()==_TEXT("")) //property name cannot be used
  1441. Error(_TEXT("cannot delete 1. instance"));
  1442. else if (a_AdmNode.GetProperty()!=_TEXT(""))
  1443. {
  1444. DeleteProperty(a_AdmNode, a_AdmProp);
  1445. }
  1446. else
  1447. {
  1448. DeleteObject(a_AdmNode, a_AdmProp);
  1449. }
  1450. //if( SUCCEEDED(QueryLastHresError()))
  1451. //{
  1452. // GetProperty(a_AdmNode, a_AdmProp);
  1453. // if(SUCCEEDED(QueryLastHresError()))
  1454. // a_AdmProp.PrintProperty();
  1455. //}
  1456. if(SUCCEEDED(QueryLastHresError()))
  1457. {
  1458. //SaveData(); //end of transaction
  1459. if( SUCCEEDED(QueryLastHresError()))
  1460. {
  1461. printf/*Print*/(_TEXT("deleted \"%s"), LPCTSTR(a_AdmNode.GetNodePath()));
  1462. if(a_AdmNode.GetProperty()!=_TEXT(""))
  1463. printf/*Print*/(_TEXT("%s"),LPCTSTR(((a_AdmNode.GetNodePath().Right(1)==_TEXT("/"))?_TEXT(""):_TEXT("/"))+
  1464. a_AdmNode.GetProperty()));
  1465. printf/*Print*/(_TEXT("\"\n"));
  1466. }
  1467. }
  1468. break;
  1469. case CMD_GET:
  1470. // if (a_AdmNode.GetService()==_TEXT("")) //property name cannot be used
  1471. // Error(_TEXT("service name for GET is missing"));
  1472. // else
  1473. if (a_AdmNode.GetProperty()!=_TEXT(""))
  1474. {
  1475. GetProperty(a_AdmNode, a_AdmProp);
  1476. if(SUCCEEDED(QueryLastHresError()))
  1477. a_AdmProp.PrintProperty();
  1478. }
  1479. else
  1480. {
  1481. CString strT("");
  1482. EnumPropertiesAndPrint(a_AdmNode, a_AdmProp, 0 , 0, strT);
  1483. }
  1484. break;
  1485. case CMD_COPY:
  1486. if(a_AdmDstNode.GetNodePath()==_TEXT(""))
  1487. Error(_TEXT("destination path is missing"));
  1488. else if(a_AdmNode.GetProperty()!=_TEXT("") || a_AdmDstNode.GetProperty()!=_TEXT(""))
  1489. Error(_TEXT("copying of properties (parameters) not supported\n"));
  1490. //else if (a_AdmNode.GetService()==_TEXT("")) //property name cannot be used
  1491. // Error(_TEXT("service name in source path for COPY is missing"));
  1492. //else if (a_AdmDstNode.GetService()==_TEXT("")) //property name cannot be used
  1493. // Error(_TEXT("service name for destination path COPY is missing"));
  1494. //else if (a_AdmNode.GetInstance()==_TEXT("")) //property name cannot be used
  1495. // Error(_TEXT("instance number in source path for COPY is missing"));
  1496. //else if (a_AdmDstNode.GetInstance()==_TEXT("")) //property name cannot be used
  1497. // Error(_TEXT("instance number in destination path for COPY is missing"));
  1498. else
  1499. {
  1500. CopyObject(a_AdmNode,a_AdmDstNode);
  1501. if(SUCCEEDED(QueryLastHresError()))
  1502. {
  1503. //SaveData(); //end of transaction
  1504. if( SUCCEEDED(QueryLastHresError()))
  1505. {
  1506. printf/*Print*/(_TEXT("copied from %s to %s\n"), LPCTSTR(a_AdmNode.GetNodePath()),LPCTSTR(a_AdmDstNode.GetNodePath()));
  1507. }
  1508. }
  1509. break;
  1510. }
  1511. break;
  1512. case CMD_RENAME:
  1513. if(a_AdmDstNode.GetNodePath()==_TEXT(""))
  1514. Error(_TEXT("destination path is missing"));
  1515. else if(a_AdmNode.GetProperty()!=_TEXT("") || a_AdmDstNode.GetProperty()!=_TEXT(""))
  1516. Error(_TEXT("renaming of properties (parameters) not supported"));
  1517. //else if (a_AdmNode.GetService()==_TEXT("")) //property name cannot be used
  1518. // Error(_TEXT("service name in source path for RENAME is missing"));
  1519. //else if (a_AdmDstNode.GetService()==_TEXT(""))
  1520. // Error(_TEXT("service name for destination path RENAME is missing"));
  1521. //else if (a_AdmNode.GetInstance()==_TEXT(""))
  1522. // Error(_TEXT("instance number in source path for RENAME is missing"));
  1523. //else if (a_AdmDstNode.GetInstance()==_TEXT(""))
  1524. // Error(_TEXT("instance number in destination path for RENAME is missing"));
  1525. else if (a_AdmNode.GetInstance()==_TEXT("1") && a_AdmNode.GetIPath()==_TEXT(""))
  1526. Error(_TEXT("cannot rename 1. instance"));
  1527. else if (a_AdmNode.GetRelPathFromService().CompareNoCase(a_AdmDstNode.GetRelPathFromService())==0)
  1528. Error(_TEXT("cannot rename to itself"));
  1529. else
  1530. { //check if one of the paths is not the child of the other one
  1531. CString str1=a_AdmNode.GetRelPathFromService();
  1532. CString str2=a_AdmDstNode.GetRelPathFromService();
  1533. CString strCommonPath=FindCommonPath(str1,str2);
  1534. if(strCommonPath.CompareNoCase(str1)==0 ||
  1535. strCommonPath.CompareNoCase(str1)==0)
  1536. Error(_TEXT("cannot rename - one path is the child of the other"));
  1537. else
  1538. { //O.K.
  1539. //CopyObject(a_AdmNode,a_AdmDstNode);
  1540. //if(SUCCEEDED(QueryLastHresError()))
  1541. //{
  1542. // DeleteObject(a_AdmNode,a_AdmProp);
  1543. // if(SUCCEEDED(QueryLastHresError()))
  1544. // {
  1545. // // SaveData(); //end of transaction
  1546. // if( SUCCEEDED(QueryLastHresError()))
  1547. // {
  1548. // printf/*Print*/("renamed from %s to %s\n", LPCTSTR(a_AdmNode.GetNodePath()),LPCTSTR(a_AdmDstNode.GetNodePath()));
  1549. // }
  1550. // }
  1551. // }
  1552. RenameObject(a_AdmNode,a_AdmDstNode);
  1553. if(SUCCEEDED(QueryLastHresError()))
  1554. {
  1555. // SaveData(); //end of transaction
  1556. if( SUCCEEDED(QueryLastHresError()))
  1557. {
  1558. printf/*Print*/(_TEXT("renamed from %s to %s\n"), LPCTSTR(a_AdmNode.GetNodePath()),LPCTSTR(a_AdmDstNode.GetNodePath()));
  1559. }
  1560. }
  1561. }
  1562. }
  1563. break;
  1564. case CMD_ENUM:
  1565. {
  1566. CString strT("");
  1567. EnumAndPrint(a_AdmNode, a_AdmProp, FALSE/*no recursion*/, 0, 0, strT);
  1568. }
  1569. break;
  1570. case CMD_ENUM_ALL:
  1571. {
  1572. CString strT("");
  1573. EnumAndPrint(a_AdmNode, a_AdmProp,TRUE/*no recursion*/, 0, 0, strT);
  1574. }
  1575. break;
  1576. case CMD_APPCREATEINPROC:
  1577. AppCreateInProc(LPCTSTR(a_AdmNode.GetLMNodePath()),a_AdmNode.GetComputer());
  1578. break;
  1579. case CMD_APPCREATEOUTPOOL:
  1580. AppCreateOutPool(LPCTSTR(a_AdmNode.GetLMNodePath()),a_AdmNode.GetComputer());
  1581. break;
  1582. case CMD_APPDELETE:
  1583. AppDelete(LPCTSTR(a_AdmNode.GetLMNodePath()),a_AdmNode.GetComputer());
  1584. break;
  1585. case CMD_APPRENAME:
  1586. AppRename(a_AdmNode,a_AdmDstNode,a_AdmNode.GetComputer());
  1587. break;
  1588. case CMD_APPCREATEOUTPROC:
  1589. AppCreateOutProc(LPCTSTR(a_AdmNode.GetLMNodePath()),a_AdmNode.GetComputer());
  1590. break;
  1591. case CMD_APPGETSTATUS:
  1592. AppGetStatus(LPCTSTR(a_AdmNode.GetLMNodePath()),a_AdmNode.GetComputer());
  1593. break;
  1594. case CMD_APPUNLOAD:
  1595. AppUnLoad(LPCTSTR(a_AdmNode.GetLMNodePath()),a_AdmNode.GetComputer());
  1596. break;
  1597. default:
  1598. printf/*Print*/(_TEXT("Command not recognized: %s\n"),strCommand.operator LPCTSTR());
  1599. hresError=RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER);
  1600. return ;
  1601. }
  1602. return;
  1603. }
  1604. //if hresError is 0, we will set it to invalid parameter
  1605. void CAdmUtil::Error(const _TCHAR * format,...)
  1606. {
  1607. _TCHAR buffer[2000];
  1608. va_list marker;
  1609. va_start( marker, format ); /* Initialize variable arguments. */
  1610. int x=_vstprintf(buffer, format, marker);
  1611. va_end( marker ); /* Reset variable arguments. */
  1612. if(hresError==0)
  1613. {
  1614. if(fPrint)
  1615. {
  1616. _ftprintf(stderr,_TEXT("Error: %s\n"),buffer);
  1617. }
  1618. hresError=RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER); //little trick
  1619. }
  1620. else
  1621. {
  1622. if(fPrint)
  1623. {
  1624. _ftprintf(stderr,_TEXT("Error: %s - HRES(0x%x) %s\n"), buffer, hresError/*, ConvertHresToDword(hresError),ConvertHresToDword(hresError)*/,ConvertReturnCodeToString(ConvertHresToDword(hresError)));
  1625. if(getenv("MDUTIL_ASCENT_LOG")!=NULL)
  1626. {
  1627. //we got to do some ascent logging
  1628. FILE *fpAscent;
  1629. fpAscent=fopen("Ascent.log","a");
  1630. if (fpAscent)
  1631. {
  1632. //new variation description
  1633. fprintf(fpAscent,"Variation1: METADATA ACCESS (by mdutil.exe)\n");
  1634. fprintf(fpAscent,"Explain: READ OR WRITE OPERATION TO METADATA \n");
  1635. //variation summary
  1636. fprintf(fpAscent,"Attempted: 1 \n");
  1637. fprintf(fpAscent,"Passed: 0 \n");
  1638. fprintf(fpAscent,"Failed: 1 \n");
  1639. _ftprintf(fpAscent,_TEXT("Error: Operation failed with HRES(0x%x)\n"), hresError);
  1640. fclose(fpAscent);
  1641. }
  1642. }
  1643. }
  1644. }
  1645. if(fPrint)
  1646. {
  1647. if(getenv("MDUTIL_BLOCK_ON_ERROR")!=NULL && hresError!=0x80070003) //path not found
  1648. {
  1649. _ftprintf(stdout,_TEXT("\nHit SPACE to continue or Ctrl-C to abort.\n"));
  1650. while(1)
  1651. {
  1652. while(!_kbhit())
  1653. {
  1654. ;
  1655. }
  1656. if(_getch()==' ')
  1657. {
  1658. _ftprintf(stdout,_TEXT("Continuing...\n"));
  1659. break;
  1660. }
  1661. }
  1662. }
  1663. }
  1664. }
  1665. void CAdmUtil::Print(const _TCHAR * format,...)
  1666. {
  1667. va_list marker;
  1668. va_start( marker, format ); /* Initialize variable arguments. */
  1669. if(fPrint)
  1670. _vtprintf(format, marker);
  1671. va_end( marker ); /* Reset variable arguments. */
  1672. }
  1673. LPTSTR ConvertReturnCodeToString(DWORD ReturnCode)
  1674. {
  1675. LPTSTR RetCode = NULL;
  1676. switch (ReturnCode) {
  1677. case ERROR_SUCCESS:
  1678. RetCode = _TEXT("ERROR_SUCCESS");
  1679. break;
  1680. case ERROR_PATH_NOT_FOUND:
  1681. RetCode = _TEXT("ERROR_PATH_NOT_FOUND");
  1682. break;
  1683. case ERROR_INVALID_HANDLE:
  1684. RetCode = _TEXT("ERROR_INVALID_HANDLE");
  1685. break;
  1686. case ERROR_INVALID_DATA:
  1687. RetCode =_TEXT("ERROR_INVALID_DATA");
  1688. break;
  1689. case ERROR_INVALID_PARAMETER:
  1690. RetCode =_TEXT("ERROR_INVALID_PARAMETER");
  1691. break;
  1692. case ERROR_NOT_SUPPORTED:
  1693. RetCode =_TEXT("ERROR_NOT_SUPPORTED");
  1694. break;
  1695. case ERROR_ACCESS_DENIED:
  1696. RetCode =_TEXT("ERROR_ACCESS_DENIED");
  1697. break;
  1698. case ERROR_NOT_ENOUGH_MEMORY:
  1699. RetCode =_TEXT("ERROR_NOT_ENOUGH_MEMORY");
  1700. break;
  1701. case ERROR_FILE_NOT_FOUND:
  1702. RetCode =_TEXT("ERROR_FILE_NOT_FOUND");
  1703. break;
  1704. case ERROR_DUP_NAME:
  1705. RetCode =_TEXT("ERROR_DUP_NAME");
  1706. break;
  1707. case ERROR_PATH_BUSY:
  1708. RetCode =_TEXT("ERROR_PATH_BUSY");
  1709. break;
  1710. case ERROR_NO_MORE_ITEMS:
  1711. RetCode =_TEXT("ERROR_NO_MORE_ITEMS");
  1712. break;
  1713. case ERROR_INSUFFICIENT_BUFFER:
  1714. RetCode =_TEXT("ERROR_INSUFFICIENT_BUFFER");
  1715. break;
  1716. case ERROR_PROC_NOT_FOUND:
  1717. RetCode =_TEXT("ERROR_PROC_NOT_FOUND");
  1718. break;
  1719. case ERROR_INTERNAL_ERROR:
  1720. RetCode =_TEXT("ERROR_INTERNAL_ERROR");
  1721. break;
  1722. case MD_ERROR_NOT_INITIALIZED:
  1723. RetCode =_TEXT("MD_ERROR_NOT_INITIALIZED");
  1724. break;
  1725. case MD_ERROR_DATA_NOT_FOUND:
  1726. RetCode =_TEXT("MD_ERROR_DATA_NOT_FOUND");
  1727. break;
  1728. case ERROR_ALREADY_EXISTS:
  1729. RetCode =_TEXT("ERROR_ALREADY_EXISTS");
  1730. break;
  1731. case MD_WARNING_PATH_NOT_FOUND:
  1732. RetCode =_TEXT("MD_WARNING_PATH_NOT_FOUND");
  1733. break;
  1734. case MD_WARNING_DUP_NAME:
  1735. RetCode =_TEXT("MD_WARNING_DUP_NAME");
  1736. break;
  1737. case MD_WARNING_INVALID_DATA:
  1738. RetCode =_TEXT("MD_WARNING_INVALID_DATA");
  1739. break;
  1740. case ERROR_INVALID_NAME:
  1741. RetCode =_TEXT("ERROR_INVALID_NAME");
  1742. break;
  1743. default:
  1744. RetCode= _TEXT("");//RetCode = "Unrecognized Error Code");
  1745. break;
  1746. }
  1747. return (RetCode);
  1748. }
  1749. DWORD ConvertHresToDword(HRESULT hRes)
  1750. {
  1751. return HRESULTTOWIN32(hRes);
  1752. }
  1753. LPTSTR ConvertHresToString(HRESULT hRes)
  1754. {
  1755. LPTSTR strReturn = NULL;
  1756. if ((HRESULT_FACILITY(hRes) == FACILITY_WIN32) ||
  1757. (HRESULT_FACILITY(hRes) == FACILITY_ITF) ||
  1758. (hRes == 0)) {
  1759. strReturn = ConvertReturnCodeToString(ConvertHresToDword(hRes));
  1760. }
  1761. else {
  1762. switch (hRes) {
  1763. case CO_E_SERVER_EXEC_FAILURE:
  1764. strReturn =_TEXT("CO_E_SERVER_EXEC_FAILURE");
  1765. break;
  1766. default:
  1767. strReturn =_TEXT("Unrecognized hRes facility");
  1768. }
  1769. }
  1770. return(strReturn);
  1771. }