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.

322 lines
11 KiB

  1. // metatool.cpp : implementation file
  2. //
  3. // some common tools used for "smart" writing to the metabase
  4. #include "stdafx.h"
  5. #define _COMIMPORT
  6. #include <common.h>
  7. #include <idlg.h>
  8. #include <resource.h>
  9. #include "wrapmb.h"
  10. #include "metatool.h"
  11. //----------------------------------------------------------------
  12. // open the metabase with an option to create the directory if it doesn't
  13. // exist. It would be nice to move this into wrapmb, but that is too big
  14. // a change for now. Maybe we can do that later.
  15. BOOL OpenAndCreate( CWrapMetaBase* pmb, LPCTSTR pszTarget, DWORD perm, BOOL fCreate )
  16. {
  17. BOOL f;
  18. CString szTarget = pszTarget;
  19. // start by just trying to open it. easy easy.
  20. if ( pmb->Open(szTarget, perm) )
  21. return TRUE;
  22. // if requested, try to create the key if it doesn't exist
  23. if ( fCreate )
  24. {
  25. // find the nearest openable parent directory and open it
  26. CString szPartial;
  27. CString szBase = szTarget;
  28. do
  29. {
  30. szBase = szBase.Left( szBase.ReverseFind(_T('/')) );
  31. szPartial = szTarget.Right( szTarget.GetLength() - szBase.GetLength() - 1 );
  32. f = pmb->Open( szBase, METADATA_PERMISSION_WRITE | perm );
  33. } while (!f && !szBase.IsEmpty());
  34. // if all that failed, fail
  35. if ( !f ) return FALSE;
  36. // create the key that we really want
  37. f = pmb->AddObject( szPartial );
  38. pmb->Close();
  39. // if all that failed, fail
  40. if ( !f ) return FALSE;
  41. // try again
  42. if ( pmb->Open(szTarget, perm) )
  43. return TRUE;
  44. }
  45. // total washout
  46. return FALSE;
  47. }
  48. //----------------------------------------------------------------
  49. // starting at the root, check for values set on sub-keys that may need to be overridden
  50. // and propmt the user for what to do
  51. void CheckInheritence( LPCTSTR pszServer, LPCTSTR pszInheritRoot,
  52. DWORD dwMDIdentifier,
  53. DWORD dwMDDataType,
  54. DWORD dwMDUserType = IIS_MD_UT_SERVER,
  55. DWORD dwMDAttributes = METADATA_INHERIT)
  56. {
  57. //
  58. // Build a generic title in case this property is custom
  59. //
  60. CString strTitle;
  61. strTitle.Format(IDS_GENERIC_INHERITANCE_TITLE, dwMDIdentifier);
  62. CComAuthInfo auth(pszServer);
  63. CInheritanceDlg dlgInherit(
  64. TRUE, // Look in table first
  65. dwMDIdentifier,
  66. dwMDAttributes,
  67. dwMDUserType,
  68. dwMDDataType,
  69. strTitle,
  70. FROM_WRITE_PROPERTY,
  71. &auth,
  72. pszInheritRoot
  73. );
  74. // if it worked, then run the dialog
  75. if ( !dlgInherit.IsEmpty() )
  76. dlgInherit.DoModal();
  77. }
  78. // notice that the dwords and generic blobs are handled seperately even though
  79. // we count route the dwords through the blob mechanisms. This is done for two
  80. // reasone. 1) Handling dwords is much more efficient than handling blobs.
  81. // and 2) Most of the values are dwords.
  82. //----------------------------------------------------------------
  83. // opens the metabase, writes out the value, then uses the inheritence
  84. // checking functionality from the iisui.dll to check for the inherited
  85. // properties and propt the user for what to do
  86. BOOL SetMetaDword(IMSAdminBase* pMB, LPCTSTR pszServer, LPCTSTR pszMetaRoot, LPCTSTR pszSub, DWORD idData, DWORD iType, DWORD dwValue, BOOL fCheckInheritence)
  87. {
  88. BOOL fAnswer = FALSE;
  89. BOOL fChanged = TRUE;
  90. DWORD dword;
  91. CWrapMetaBase mbWrap;
  92. if ( !mbWrap.FInit(pMB) ) return FALSE;
  93. // open the target
  94. if ( OpenAndCreate( &mbWrap, pszMetaRoot,
  95. METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ, TRUE ) )
  96. {
  97. // attempt to get the current value - no inheritence
  98. if ( mbWrap.GetDword(pszSub, idData, iType, &dword, 0) )
  99. {
  100. // set the changed flag
  101. fChanged = (dwValue != dword);
  102. }
  103. // save it out, if it changed or is not there
  104. if ( fChanged )
  105. fAnswer = mbWrap.SetDword( pszSub, idData, iType, dwValue );
  106. // close the metabase
  107. mbWrap.Close();
  108. }
  109. else
  110. fChanged = FALSE;
  111. // set up and run the inheritence checking dialog
  112. if ( fCheckInheritence && fChanged )
  113. {
  114. CString szInheritRoot = pszMetaRoot;
  115. szInheritRoot += pszSub;
  116. CheckInheritence( pszServer, szInheritRoot, idData, DWORD_METADATA, iType);
  117. }
  118. return fAnswer;
  119. }
  120. //----------------------------------------------------------------
  121. // assumes that the metabase is actually open to the parent of the one we are interested
  122. // and that the real target name is passed into szSub
  123. BOOL SetMetaData(IMSAdminBase* pMB, LPCTSTR pszServer, LPCTSTR pszMetaRoot, LPCTSTR pszSub, DWORD idData, DWORD iType, DWORD iDataType, PVOID pData, DWORD cbData, BOOL fCheckInheritence, BOOL fSecure )
  124. {
  125. BOOL fAnswer = FALSE;
  126. BOOL fChanged = TRUE;
  127. DWORD cbTestData;
  128. DWORD flags = METADATA_INHERIT;
  129. CWrapMetaBase mbWrap;
  130. if ( !mbWrap.FInit(pMB) ) return FALSE;
  131. // open the target
  132. if ( OpenAndCreate( &mbWrap, pszMetaRoot,
  133. METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ, TRUE ) )
  134. {
  135. // attempt to get the current value - no inheritence
  136. PVOID pTestData = mbWrap.GetData( pszSub, idData, iType,
  137. iDataType, &cbTestData, 0 );
  138. if ( pTestData )
  139. {
  140. // set the changed flag
  141. if ( cbData == cbTestData )
  142. {
  143. fChanged = (memcmp(pData, pTestData, cbData) != 0);
  144. }
  145. mbWrap.FreeWrapData( pTestData );
  146. }
  147. // set security if requested
  148. if ( fSecure )
  149. flags |= METADATA_SECURE;
  150. // save it out, if it changed or is not there
  151. if ( fChanged )
  152. fAnswer = mbWrap.SetData( pszSub, idData, iType, iDataType, pData, cbData, flags );
  153. // close the metabase
  154. mbWrap.Close();
  155. }
  156. else
  157. fChanged = FALSE;
  158. // set up and run the inheritence checking dialog
  159. if ( fCheckInheritence && fChanged )
  160. {
  161. CString szInheritRoot = pszMetaRoot;
  162. szInheritRoot += pszSub;
  163. CheckInheritence( pszServer, szInheritRoot, idData , iDataType, iType);
  164. }
  165. return fAnswer;
  166. }
  167. //----------------------------------------------------------------
  168. BOOL SetMetaString(IMSAdminBase* pMB, LPCTSTR pszServer, LPCTSTR pszMetaRoot, LPCTSTR pszSub, DWORD idData, DWORD iType, CString sz, BOOL fCheckInheritence, BOOL fSecure)
  169. {
  170. return SetMetaData(pMB, pszServer, pszMetaRoot, pszSub, idData,
  171. iType, STRING_METADATA, (LPTSTR)(LPCTSTR)sz,
  172. (sz.GetLength()+1)*sizeof(TCHAR), fCheckInheritence, fSecure );
  173. }
  174. //----------------------------------------------------------------
  175. BOOL SetMetaMultiSz(IMSAdminBase* pMB, LPCTSTR pszServer, LPCTSTR pszMetaRoot, LPCTSTR pszSub, DWORD idData, DWORD iType, PVOID pData, DWORD cchmsz, BOOL fCheckInheritence )
  176. {
  177. return SetMetaData(pMB, pszServer, pszMetaRoot, pszSub, idData,
  178. iType, MULTISZ_METADATA, pData, cchmsz*2, fCheckInheritence, FALSE );
  179. }
  180. //----------------------------------------------------------------
  181. BOOL SetMBData(CWrapMetaBase* pMB, CCheckInheritList* pInheritList, LPCTSTR pszSub, DWORD idData, DWORD iType, DWORD iDataType, PVOID pData, DWORD cbData, BOOL fSecure )
  182. {
  183. BOOL fAnswer = FALSE;
  184. BOOL fChanged = TRUE;
  185. DWORD cbTestData;
  186. DWORD flags = METADATA_INHERIT;
  187. // attempt to get the current value - no inheritence
  188. PVOID pTestData = pMB->GetData( pszSub, idData, iType,
  189. iDataType, &cbTestData, 0 );
  190. if ( pTestData )
  191. {
  192. // set the changed flag
  193. if ( cbData == cbTestData )
  194. {
  195. fChanged = (memcmp(pData, pTestData, cbData) != 0);
  196. }
  197. pMB->FreeWrapData( pTestData );
  198. }
  199. // set security if requested
  200. if ( fSecure )
  201. flags |= METADATA_SECURE;
  202. // save it out, if it changed or is not there
  203. if ( fChanged )
  204. {
  205. fAnswer = pMB->SetData( pszSub, idData, iType, iDataType, pData, cbData, flags );
  206. }
  207. // add it to the change list
  208. if ( pInheritList && fChanged && fAnswer )
  209. {
  210. // prep the inheritence check record
  211. pInheritList->Add( idData, iDataType, iType, flags );
  212. }
  213. return fAnswer;
  214. }
  215. //----------------------------------------------------------------
  216. BOOL SetMBDword(CWrapMetaBase* pMB, CCheckInheritList* pInheritList, LPCTSTR pszSub, DWORD idData, DWORD iType, DWORD dwValue)
  217. {
  218. return SetMBData(pMB, pInheritList, pszSub, idData,
  219. iType, DWORD_METADATA, &dwValue,
  220. sizeof(DWORD), FALSE );
  221. }
  222. //----------------------------------------------------------------
  223. BOOL SetMBString(CWrapMetaBase* pMB, CCheckInheritList* pInheritList, LPCTSTR pszSub, DWORD idData, DWORD iType, CString sz, BOOL fSecure)
  224. {
  225. return SetMBData(pMB, pInheritList, pszSub, idData,
  226. iType, STRING_METADATA, (LPTSTR)(LPCTSTR)sz,
  227. (sz.GetLength()+1)*sizeof(TCHAR), fSecure );
  228. }
  229. //----------------------------------------------------------------
  230. BOOL SetMBMultiSz(CWrapMetaBase* pMB, CCheckInheritList* pInheritList, LPCTSTR pszSub, DWORD idData, DWORD iType, PVOID pData, DWORD cchmsz )
  231. {
  232. return SetMBData(pMB, pInheritList, pszSub, idData,
  233. iType, MULTISZ_METADATA, pData, cchmsz*2, FALSE );
  234. }
  235. //-------------------------------------------------------------
  236. void CCheckInheritList::CheckInheritence( LPCTSTR pszServer, LPCTSTR pszInheritRoot )
  237. {
  238. // get the number of items to check
  239. DWORD cItems = (DWORD)rgbItems.GetSize();
  240. // loop through the items, checking each
  241. for ( DWORD iItem = 0; iItem < cItems; iItem++ )
  242. {
  243. // check the inheritence on the item
  244. ::CheckInheritence( pszServer, pszInheritRoot,
  245. rgbItems[iItem].dwMDIdentifier,
  246. rgbItems[iItem].dwMDDataType,
  247. rgbItems[iItem].dwMDUserType,
  248. rgbItems[iItem].dwMDAttributes );
  249. }
  250. }
  251. //-------------------------------------------------------------
  252. INT CCheckInheritList::Add( DWORD dwMDIdentifier, DWORD dwMDDataType, DWORD dwMDUserType, DWORD dwMDAttributes )
  253. {
  254. INHERIT_CHECK_ITEM item;
  255. item.dwMDIdentifier = dwMDIdentifier;
  256. item.dwMDDataType = dwMDDataType;
  257. item.dwMDUserType = dwMDUserType;
  258. item.dwMDAttributes = dwMDAttributes;
  259. return (INT)rgbItems.Add( item );
  260. }