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.

367 lines
8.2 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1997
  5. //
  6. // File: cenumt.cxx
  7. //
  8. // Contents: IIS Object Enumeration Code
  9. //
  10. // CIISTreeEnum::CIISTreeEnum()
  11. // CIISTreeEnum::CIISTreeEnum
  12. // CIISTreeEnum::EnumObjects
  13. // CIISTreeEnum::EnumObjects
  14. //
  15. // History: 25-Feb-97 SophiaC Created.
  16. //----------------------------------------------------------------------------
  17. #include "iis.hxx"
  18. #pragma hdrstop
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: CIISEnumVariant::Create
  22. //
  23. // Synopsis:
  24. //
  25. // Arguments: [pCollection]
  26. // [ppEnumVariant]
  27. //
  28. // Returns: HRESULT
  29. //
  30. // Modifies:
  31. //
  32. //
  33. //----------------------------------------------------------------------------
  34. /* INTRINSA suppress=null_pointers, uninitialized */
  35. HRESULT
  36. CIISTreeEnum::Create(
  37. CIISTreeEnum FAR* FAR* ppenumvariant,
  38. BSTR ADsPath,
  39. VARIANT var,
  40. CCredentials& Credentials
  41. )
  42. {
  43. COSERVERINFO csiName;
  44. COSERVERINFO *pcsiParam = &csiName;
  45. IClassFactory * pcsfFactory = NULL;
  46. HRESULT hr = NOERROR;
  47. CIISTreeEnum FAR* penumvariant = NULL;
  48. LPWSTR pszIISPathName = NULL;
  49. OBJECTINFO ObjectInfo;
  50. POBJECTINFO pObjectInfo = NULL;
  51. CLexer Lexer(ADsPath);
  52. *ppenumvariant = NULL;
  53. penumvariant = new CIISTreeEnum();
  54. if (!penumvariant) {
  55. hr = E_OUTOFMEMORY;
  56. BAIL_ON_FAILURE(hr);
  57. }
  58. hr = ADsAllocString( ADsPath, &penumvariant->_ADsPath);
  59. BAIL_ON_FAILURE(hr);
  60. //
  61. // Parse the pathname
  62. //
  63. pObjectInfo = &ObjectInfo;
  64. memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  65. hr = ADsObject(&Lexer, pObjectInfo);
  66. BAIL_ON_FAILURE(hr);
  67. penumvariant->_Credentials = Credentials;
  68. *ppenumvariant = penumvariant;
  69. //
  70. // Store ServerName
  71. //
  72. penumvariant->_pszServerName = AllocADsStr(pObjectInfo->TreeName);
  73. if (!(penumvariant->_pszServerName)) {
  74. hr = E_OUTOFMEMORY;
  75. BAIL_ON_FAILURE(hr);
  76. }
  77. hr = InitServerInfo(penumvariant->_pszServerName,
  78. &(penumvariant->_pAdminBase),
  79. &(penumvariant->_pSchema));
  80. BAIL_ON_FAILURE(hr);
  81. pszIISPathName = AllocADsStr(ADsPath);
  82. if (!pszIISPathName) {
  83. hr = E_OUTOFMEMORY;
  84. BAIL_ON_FAILURE(hr);
  85. }
  86. memset(pszIISPathName, 0, sizeof(pszIISPathName));
  87. hr = BuildIISPathFromADsPath(
  88. pObjectInfo,
  89. pszIISPathName
  90. );
  91. BAIL_ON_FAILURE(hr);
  92. penumvariant->_pszMetaBasePath = AllocADsStr(pszIISPathName);
  93. if (!(penumvariant->_pszMetaBasePath)) {
  94. hr = E_OUTOFMEMORY;
  95. BAIL_ON_FAILURE(hr);
  96. }
  97. error:
  98. if (FAILED(hr)) {
  99. if (penumvariant) {
  100. delete penumvariant;
  101. *ppenumvariant = NULL;
  102. }
  103. }
  104. if (pszIISPathName) {
  105. FreeADsStr(pszIISPathName);
  106. }
  107. FreeObjectInfo(pObjectInfo);
  108. RRETURN(hr);
  109. }
  110. CIISTreeEnum::CIISTreeEnum():
  111. _ADsPath(NULL),
  112. _pszServerName(NULL),
  113. _pSchema(NULL),
  114. _pAdminBase(NULL),
  115. _pszMetaBasePath(NULL)
  116. {
  117. _dwObjectCurrentEntry = 0;
  118. }
  119. CIISTreeEnum::~CIISTreeEnum()
  120. {
  121. if (_ADsPath) {
  122. ADsFreeString(_ADsPath);
  123. }
  124. if (_pszServerName) {
  125. FreeADsStr(_pszServerName);
  126. }
  127. if (_pszMetaBasePath){
  128. FreeADsStr(_pszMetaBasePath);
  129. }
  130. //
  131. // Release everything
  132. //
  133. }
  134. HRESULT
  135. CIISTreeEnum::EnumGenericObjects(
  136. ULONG cElements,
  137. VARIANT FAR* pvar,
  138. ULONG FAR* pcElementFetched
  139. )
  140. {
  141. HRESULT hr = S_OK;
  142. IDispatch *pDispatch = NULL;
  143. DWORD i = 0;
  144. while (i < cElements ) {
  145. hr = GetGenericObject(&pDispatch);
  146. if (FAILED(hr)) {
  147. continue;
  148. }
  149. if (hr == S_FALSE) {
  150. break;
  151. }
  152. VariantInit(&pvar[i]);
  153. pvar[i].vt = VT_DISPATCH;
  154. pvar[i].pdispVal = pDispatch;
  155. (*pcElementFetched)++;
  156. i++;
  157. }
  158. return(hr);
  159. }
  160. /* #pragma INTRINSA suppress=all */
  161. HRESULT
  162. CIISTreeEnum::GetGenericObject(
  163. IDispatch ** ppDispatch
  164. )
  165. {
  166. HRESULT hr = S_OK;
  167. WCHAR NameBuf[MAX_PATH];
  168. WCHAR DataBuf[MAX_PATH];
  169. DWORD dwStatus = 0;
  170. DWORD dwReqdBufferLen;
  171. METADATA_HANDLE hObjHandle = NULL;
  172. METADATA_RECORD mdrData;
  173. *ppDispatch = NULL;
  174. hr = OpenAdminBaseKey(
  175. _pszServerName,
  176. _pszMetaBasePath,
  177. METADATA_PERMISSION_READ,
  178. &_pAdminBase,
  179. &hObjHandle
  180. );
  181. BAIL_ON_FAILURE(hr);
  182. hr = _pAdminBase->EnumKeys(
  183. hObjHandle,
  184. L"",
  185. (LPWSTR)NameBuf,
  186. _dwObjectCurrentEntry
  187. );
  188. BAIL_ON_FAILURE(hr);
  189. //
  190. // Find out Class Name
  191. //
  192. mdrData.dwMDIdentifier = MD_KEY_TYPE;
  193. mdrData.dwMDDataType = STRING_METADATA;
  194. mdrData.dwMDUserType = ALL_METADATA;
  195. mdrData.dwMDAttributes = METADATA_INHERIT;
  196. mdrData.dwMDDataLen = MAX_PATH;
  197. mdrData.pbMDData = (PBYTE)DataBuf;
  198. hr = _pAdminBase->GetData(
  199. hObjHandle,
  200. (LPWSTR)NameBuf,
  201. &mdrData,
  202. &dwReqdBufferLen
  203. );
  204. if (FAILED(hr)) {
  205. if (hr == MD_ERROR_DATA_NOT_FOUND) {
  206. LPWSTR pszIISPath;
  207. pszIISPath = _wcsupr((LPWSTR)_pszMetaBasePath);
  208. if (wcsstr(_pszMetaBasePath, L"W3SVC") != NULL) {
  209. memcpy((LPWSTR)DataBuf, WEBDIR_CLASS_W,
  210. SIZEOF_WEBDIR_CLASS_W);
  211. }
  212. else if (wcsstr(_pszMetaBasePath, L"MSFTPSVC") != NULL) {
  213. memcpy((LPWSTR)DataBuf, FTPVDIR_CLASS_W,
  214. SIZEOF_FTPVDIR_CLASS_W);
  215. }
  216. else {
  217. memcpy((LPWSTR)DataBuf, DEFAULT_SCHEMA_CLASS_W,
  218. SIZEOF_DEFAULT_CLASS_W);
  219. }
  220. }
  221. else {
  222. BAIL_ON_FAILURE(hr);
  223. }
  224. }
  225. else {
  226. hr = _pSchema->ValidateClassName((LPWSTR)DataBuf);
  227. if (hr == E_ADS_SCHEMA_VIOLATION) {
  228. memcpy((LPWSTR)DataBuf, DEFAULT_SCHEMA_CLASS_W,
  229. SIZEOF_DEFAULT_CLASS_W);
  230. }
  231. }
  232. // Bump up the object count. The instantiation of this object
  233. // may fail; if we come into this function again, we do not want
  234. // to pick up the same object.
  235. //
  236. _dwObjectCurrentEntry++;
  237. hr = CIISGenObject::CreateGenericObject(
  238. _ADsPath,
  239. (LPWSTR)NameBuf,
  240. (LPWSTR)DataBuf,
  241. _Credentials,
  242. ADS_OBJECT_BOUND,
  243. IID_IDispatch,
  244. (void **)ppDispatch
  245. );
  246. BAIL_ON_FAILURE(hr);
  247. error:
  248. if (_pAdminBase && hObjHandle) {
  249. CloseAdminBaseKey(_pAdminBase, hObjHandle);
  250. }
  251. //
  252. // GetTree returns only S_FALSE
  253. //
  254. if (FAILED(hr)) {
  255. hr = S_FALSE;
  256. }
  257. RRETURN(hr);
  258. }
  259. //+---------------------------------------------------------------------------
  260. //
  261. // Function: CIISTreeEnum::Next
  262. //
  263. // Synopsis: Returns cElements number of requested NetOle objects in the
  264. // array supplied in pvar.
  265. //
  266. // Arguments: [cElements] -- The number of elements requested by client
  267. // [pvar] -- ptr to array of VARIANTs to for return objects
  268. // [pcElementFetched] -- if non-NULL, then number of elements
  269. // -- actually returned is placed here
  270. //
  271. // Returns: HRESULT -- S_OK if number of elements requested are returned
  272. // -- S_FALSE if number of elements is < requested
  273. //
  274. // Modifies:
  275. //
  276. // History:
  277. //
  278. //----------------------------------------------------------------------------
  279. STDMETHODIMP
  280. CIISTreeEnum::Next(
  281. ULONG cElements,
  282. VARIANT FAR* pvar,
  283. ULONG FAR* pcElementFetched
  284. )
  285. {
  286. ULONG cElementFetched = 0;
  287. HRESULT hr = S_OK;
  288. hr = EnumGenericObjects(
  289. cElements,
  290. pvar,
  291. &cElementFetched
  292. );
  293. if (pcElementFetched) {
  294. *pcElementFetched = cElementFetched;
  295. }
  296. RRETURN(hr);
  297. }