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.

380 lines
8.5 KiB

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