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.

321 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 _COMSTATIC
  6. #include <comprop.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. CInheritanceDlg dlgInherit(
  63. TRUE, // Look in table first
  64. dwMDIdentifier,
  65. dwMDAttributes,
  66. dwMDUserType,
  67. dwMDDataType,
  68. strTitle,
  69. FROM_WRITE_PROPERTY,
  70. pszServer,
  71. pszInheritRoot
  72. );
  73. // if it worked, then run the dialog
  74. if ( !dlgInherit.IsEmpty() )
  75. dlgInherit.DoModal();
  76. }
  77. // notice that the dwords and generic blobs are handled seperately even though
  78. // we count route the dwords through the blob mechanisms. This is done for two
  79. // reasone. 1) Handling dwords is much more efficient than handling blobs.
  80. // and 2) Most of the values are dwords.
  81. //----------------------------------------------------------------
  82. // opens the metabase, writes out the value, then uses the inheritence
  83. // checking functionality from the iisui.dll to check for the inherited
  84. // properties and propt the user for what to do
  85. BOOL SetMetaDword(IMSAdminBase* pMB, LPCTSTR pszServer, LPCTSTR pszMetaRoot, LPCTSTR pszSub, DWORD idData, DWORD iType, DWORD dwValue, BOOL fCheckInheritence)
  86. {
  87. BOOL fAnswer = FALSE;
  88. BOOL fChanged = TRUE;
  89. DWORD dword;
  90. CWrapMetaBase mbWrap;
  91. if ( !mbWrap.FInit(pMB) ) return FALSE;
  92. // open the target
  93. if ( OpenAndCreate( &mbWrap, pszMetaRoot,
  94. METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ, TRUE ) )
  95. {
  96. // attempt to get the current value - no inheritence
  97. if ( mbWrap.GetDword(pszSub, idData, iType, &dword, 0) )
  98. {
  99. // set the changed flag
  100. fChanged = (dwValue != dword);
  101. }
  102. // save it out, if it changed or is not there
  103. if ( fChanged )
  104. fAnswer = mbWrap.SetDword( pszSub, idData, iType, dwValue );
  105. // close the metabase
  106. mbWrap.Close();
  107. }
  108. else
  109. fChanged = FALSE;
  110. // set up and run the inheritence checking dialog
  111. if ( fCheckInheritence && fChanged )
  112. {
  113. CString szInheritRoot = pszMetaRoot;
  114. szInheritRoot += pszSub;
  115. CheckInheritence( pszServer, szInheritRoot, idData, DWORD_METADATA, iType);
  116. }
  117. return fAnswer;
  118. }
  119. //----------------------------------------------------------------
  120. // assumes that the metabase is actually open to the parent of the one we are interested
  121. // and that the real target name is passed into szSub
  122. BOOL SetMetaData(IMSAdminBase* pMB, LPCTSTR pszServer, LPCTSTR pszMetaRoot, LPCTSTR pszSub, DWORD idData, DWORD iType, DWORD iDataType, PVOID pData, DWORD cbData, BOOL fCheckInheritence, BOOL fSecure )
  123. {
  124. BOOL fAnswer = FALSE;
  125. BOOL fChanged = TRUE;
  126. DWORD cbTestData;
  127. DWORD flags = METADATA_INHERIT;
  128. CWrapMetaBase mbWrap;
  129. if ( !mbWrap.FInit(pMB) ) return FALSE;
  130. // open the target
  131. if ( OpenAndCreate( &mbWrap, pszMetaRoot,
  132. METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ, TRUE ) )
  133. {
  134. // attempt to get the current value - no inheritence
  135. PVOID pTestData = mbWrap.GetData( pszSub, idData, iType,
  136. iDataType, &cbTestData, 0 );
  137. if ( pTestData )
  138. {
  139. // set the changed flag
  140. if ( cbData == cbTestData )
  141. {
  142. fChanged = (memcmp(pData, pTestData, cbData) != 0);
  143. }
  144. mbWrap.FreeWrapData( pTestData );
  145. }
  146. // set security if requested
  147. if ( fSecure )
  148. flags |= METADATA_SECURE;
  149. // save it out, if it changed or is not there
  150. if ( fChanged )
  151. fAnswer = mbWrap.SetData( pszSub, idData, iType, iDataType, pData, cbData, flags );
  152. // close the metabase
  153. mbWrap.Close();
  154. }
  155. else
  156. fChanged = FALSE;
  157. // set up and run the inheritence checking dialog
  158. if ( fCheckInheritence && fChanged )
  159. {
  160. CString szInheritRoot = pszMetaRoot;
  161. szInheritRoot += pszSub;
  162. CheckInheritence( pszServer, szInheritRoot, idData , iDataType, iType);
  163. }
  164. return fAnswer;
  165. }
  166. //----------------------------------------------------------------
  167. BOOL SetMetaString(IMSAdminBase* pMB, LPCTSTR pszServer, LPCTSTR pszMetaRoot, LPCTSTR pszSub, DWORD idData, DWORD iType, CString sz, BOOL fCheckInheritence, BOOL fSecure)
  168. {
  169. return SetMetaData(pMB, pszServer, pszMetaRoot, pszSub, idData,
  170. iType, STRING_METADATA, (LPTSTR)(LPCTSTR)sz,
  171. (sz.GetLength()+1)*sizeof(TCHAR), fCheckInheritence, fSecure );
  172. }
  173. //----------------------------------------------------------------
  174. BOOL SetMetaMultiSz(IMSAdminBase* pMB, LPCTSTR pszServer, LPCTSTR pszMetaRoot, LPCTSTR pszSub, DWORD idData, DWORD iType, PVOID pData, DWORD cchmsz, BOOL fCheckInheritence )
  175. {
  176. return SetMetaData(pMB, pszServer, pszMetaRoot, pszSub, idData,
  177. iType, MULTISZ_METADATA, pData, cchmsz*2, fCheckInheritence, FALSE );
  178. }
  179. //----------------------------------------------------------------
  180. BOOL SetMBData(CWrapMetaBase* pMB, CCheckInheritList* pInheritList, LPCTSTR pszSub, DWORD idData, DWORD iType, DWORD iDataType, PVOID pData, DWORD cbData, BOOL fSecure )
  181. {
  182. BOOL fAnswer = FALSE;
  183. BOOL fChanged = TRUE;
  184. DWORD cbTestData;
  185. DWORD flags = METADATA_INHERIT;
  186. // attempt to get the current value - no inheritence
  187. PVOID pTestData = pMB->GetData( pszSub, idData, iType,
  188. iDataType, &cbTestData, 0 );
  189. if ( pTestData )
  190. {
  191. // set the changed flag
  192. if ( cbData == cbTestData )
  193. {
  194. fChanged = (memcmp(pData, pTestData, cbData) != 0);
  195. }
  196. pMB->FreeWrapData( pTestData );
  197. }
  198. // set security if requested
  199. if ( fSecure )
  200. flags |= METADATA_SECURE;
  201. // save it out, if it changed or is not there
  202. if ( fChanged )
  203. {
  204. fAnswer = pMB->SetData( pszSub, idData, iType, iDataType, pData, cbData, flags );
  205. }
  206. // add it to the change list
  207. if ( pInheritList && fChanged && fAnswer )
  208. {
  209. // prep the inheritence check record
  210. pInheritList->Add( idData, iDataType, iType, flags );
  211. }
  212. return fAnswer;
  213. }
  214. //----------------------------------------------------------------
  215. BOOL SetMBDword(CWrapMetaBase* pMB, CCheckInheritList* pInheritList, LPCTSTR pszSub, DWORD idData, DWORD iType, DWORD dwValue)
  216. {
  217. return SetMBData(pMB, pInheritList, pszSub, idData,
  218. iType, DWORD_METADATA, &dwValue,
  219. sizeof(DWORD), FALSE );
  220. }
  221. //----------------------------------------------------------------
  222. BOOL SetMBString(CWrapMetaBase* pMB, CCheckInheritList* pInheritList, LPCTSTR pszSub, DWORD idData, DWORD iType, CString sz, BOOL fSecure)
  223. {
  224. return SetMBData(pMB, pInheritList, pszSub, idData,
  225. iType, STRING_METADATA, (LPTSTR)(LPCTSTR)sz,
  226. (sz.GetLength()+1)*sizeof(TCHAR), fSecure );
  227. }
  228. //----------------------------------------------------------------
  229. BOOL SetMBMultiSz(CWrapMetaBase* pMB, CCheckInheritList* pInheritList, LPCTSTR pszSub, DWORD idData, DWORD iType, PVOID pData, DWORD cchmsz )
  230. {
  231. return SetMBData(pMB, pInheritList, pszSub, idData,
  232. iType, MULTISZ_METADATA, pData, cchmsz*2, FALSE );
  233. }
  234. //-------------------------------------------------------------
  235. void CCheckInheritList::CheckInheritence( LPCTSTR pszServer, LPCTSTR pszInheritRoot )
  236. {
  237. // get the number of items to check
  238. DWORD cItems = (DWORD)rgbItems.GetSize();
  239. // loop through the items, checking each
  240. for ( DWORD iItem = 0; iItem < cItems; iItem++ )
  241. {
  242. // check the inheritence on the item
  243. ::CheckInheritence( pszServer, pszInheritRoot,
  244. rgbItems[iItem].dwMDIdentifier,
  245. rgbItems[iItem].dwMDDataType,
  246. rgbItems[iItem].dwMDUserType,
  247. rgbItems[iItem].dwMDAttributes );
  248. }
  249. }
  250. //-------------------------------------------------------------
  251. INT CCheckInheritList::Add( DWORD dwMDIdentifier, DWORD dwMDDataType, DWORD dwMDUserType, DWORD dwMDAttributes )
  252. {
  253. INHERIT_CHECK_ITEM item;
  254. item.dwMDIdentifier = dwMDIdentifier;
  255. item.dwMDDataType = dwMDDataType;
  256. item.dwMDUserType = dwMDUserType;
  257. item.dwMDAttributes = dwMDAttributes;
  258. return (INT)rgbItems.Add( item );
  259. }