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.

261 lines
8.5 KiB

  1. /*---------------------------------------------------------------------------
  2. File: NetObjEnumerator.cpp
  3. Comments: Implementation of NetObjectEnumerator COM object.
  4. (c) Copyright 1999, Mission Critical Software, Inc., All Rights Reserved
  5. Proprietary and confidential to Mission Critical Software, Inc.
  6. REVISION LOG ENTRY
  7. Revision By: Sham Chauthani
  8. Revised on 07/02/99 12:40:00
  9. ---------------------------------------------------------------------------
  10. */
  11. #include "stdafx.h"
  12. #include "NetEnum.h"
  13. #include "ObjEnum.h"
  14. #include "Win2KDom.h"
  15. #include "NT4DOm.h"
  16. #include <lmaccess.h>
  17. #include <lmwksta.h>
  18. #include <lmapibuf.h>
  19. #include "GetDcName.h"
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CNetObjEnumerator
  27. //---------------------------------------------------------------------------
  28. // SetQuery: This function sets all the parameters necessary for a query
  29. // to be executed. User can not call Execute without first calling
  30. // this method.
  31. //---------------------------------------------------------------------------
  32. STDMETHODIMP CNetObjEnumerator::SetQuery(
  33. BSTR sContainer, //in -Container name
  34. BSTR sDomain, //in -Domain name
  35. BSTR sQuery, //in -Query in LDAP syntax
  36. long nSearchScope, //in -Scope of the search. ADS_ATTR_SUBTREE/ADS_ATTR_ONELEVEL
  37. long bMultiVal //in- Do we need to return multivalued properties?
  38. )
  39. {
  40. Cleanup();
  41. // Save all the settings in member variables.
  42. m_sDomain = sDomain;
  43. m_sContainer = sContainer;
  44. m_sQuery = sQuery;
  45. m_bSetQuery = true;
  46. m_bMultiVal = bMultiVal;
  47. if ( nSearchScope < 0 || nSearchScope > 2 )
  48. return E_INVALIDARG;
  49. prefInfo.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  50. prefInfo.vValue.dwType = ADSTYPE_INTEGER;
  51. prefInfo.vValue.Integer = nSearchScope;
  52. return S_OK;
  53. }
  54. //---------------------------------------------------------------------------
  55. // SetColumns: This function sets all the columns that the user wants to be
  56. // returned when query is executed.
  57. //---------------------------------------------------------------------------
  58. STDMETHODIMP CNetObjEnumerator::SetColumns(
  59. SAFEARRAY * colNames //in -Pointer to a SafeArray that contains all the columns
  60. )
  61. {
  62. // We require that the SetQuery method be called before SetColumns is called. Hence we will return E_FAIL
  63. // If we expose these interface we should document this.
  64. if (!m_bSetQuery)
  65. return E_FAIL;
  66. if ( m_bSetCols )
  67. {
  68. Cleanup();
  69. m_bSetQuery = true;
  70. }
  71. SAFEARRAY * pcolNames = colNames;
  72. long dwLB;
  73. long dwUB;
  74. BSTR HUGEP * pBSTR;
  75. HRESULT hr;
  76. // Get the bounds of the column Array
  77. hr = ::SafeArrayGetLBound(pcolNames, 1, &dwLB);
  78. if (FAILED(hr))
  79. return hr;
  80. hr = ::SafeArrayGetUBound(pcolNames, 1, &dwUB);
  81. if (FAILED(hr))
  82. return hr;
  83. m_nCols = dwUB-dwLB + 1;
  84. // We dont support empty columns request atleast one column.
  85. if ( m_nCols == 0 )
  86. return E_FAIL;
  87. hr = ::SafeArrayAccessData(pcolNames, (void **) &pBSTR);
  88. if ( FAILED(hr) )
  89. return hr;
  90. // Allocate space for the array. It is deallocated by Cleanup()
  91. m_pszAttr = new LPWSTR[m_nCols];
  92. if (m_pszAttr == NULL)
  93. {
  94. ::SafeArrayUnaccessData(pcolNames);
  95. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  96. }
  97. // Each column is now put into the Array
  98. for ( long dw = 0; dw < m_nCols; dw++)
  99. {
  100. m_pszAttr[dw] = SysAllocString(pBSTR[dw]);
  101. if (!m_pszAttr[dw] && pBSTR[dw] && *(pBSTR[dw]))
  102. {
  103. for (long i = 0; i < dw; i++) {
  104. SysFreeString(m_pszAttr[i]);
  105. }
  106. delete [] m_pszAttr;
  107. m_pszAttr = NULL;
  108. ::SafeArrayUnaccessData(pcolNames);
  109. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  110. }
  111. }
  112. hr = ::SafeArrayUnaccessData(pcolNames);
  113. m_bSetCols = true;
  114. return hr;
  115. }
  116. //---------------------------------------------------------------------------
  117. // Cleanup: This function cleans up all the allocations and the member vars.
  118. //---------------------------------------------------------------------------
  119. void CNetObjEnumerator::Cleanup()
  120. {
  121. if ( m_nCols > 0 )
  122. {
  123. if ( m_pszAttr )
  124. {
  125. // delete the contents of the array
  126. for ( int i = 0 ; i < m_nCols ; i++ )
  127. {
  128. SysFreeString(m_pszAttr[i]);
  129. }
  130. // Dealloc the array itself
  131. delete [] m_pszAttr;
  132. m_pszAttr = NULL;
  133. }
  134. // Reset all counts and flags.
  135. m_nCols = 0;
  136. m_bSetQuery = false;
  137. m_bSetCols = false;
  138. }
  139. }
  140. //---------------------------------------------------------------------------
  141. // Execute: This function actually executes the query and then builds an
  142. // enumerator object and returns it.
  143. //---------------------------------------------------------------------------
  144. STDMETHODIMP CNetObjEnumerator::Execute(
  145. IEnumVARIANT **pEnumerator //out -Pointer to the enumerator object.
  146. )
  147. {
  148. // This function will take the options set in SetQuery and SetColumns to enumerate objects
  149. // for the given domain. This could be a NT4 domain or a Win2K domain. Although at the moment
  150. // NT4 domains simply enumerate all objects in the given container, we could later implement
  151. // certain features to support queries etc.
  152. if ( !m_bSetCols )
  153. return E_FAIL;
  154. HRESULT hr = S_OK;
  155. *pEnumerator = NULL;
  156. //if we have not yet create the Domain-specific class object, for doing the
  157. //actual enumeration, then create it now
  158. if (!m_pDom)
  159. {
  160. hr = CreateDomainObject();
  161. }//end if no domain object yet
  162. //if we encountered a problem getting the domain object, return
  163. if ((hr != S_OK) || (!m_pDom))
  164. return hr;
  165. //call the enumeration function on the domain object
  166. try
  167. {
  168. hr = m_pDom->GetEnumeration(m_sContainer, m_sDomain, m_sQuery, m_nCols, m_pszAttr, prefInfo, m_bMultiVal, pEnumerator);
  169. }
  170. catch ( _com_error &e)
  171. {
  172. return e.Error();
  173. }
  174. return hr;
  175. }
  176. /*********************************************************************
  177. * *
  178. * Written by: Paul Thompson *
  179. * Date: 13 JUNE 2001 *
  180. * *
  181. * This function is responsible for try to instantiate one of the*
  182. * OS-specific classes and storing that object in the m_pDom class *
  183. * variable. This function returns an HRESULT that indicates success*
  184. * or failure. *
  185. * *
  186. *********************************************************************/
  187. //BEGIN CreateDomainObject
  188. HRESULT CNetObjEnumerator::CreateDomainObject()
  189. {
  190. /* local variables */
  191. HRESULT hr = S_OK;
  192. /* function body */
  193. _bstr_t strDc;
  194. DWORD rc = GetAnyDcName5(m_sDomain, strDc);
  195. //if we got the DC, get the OS version of that DC
  196. if ( !rc )
  197. {
  198. WKSTA_INFO_100 * pInfo = NULL;
  199. rc = NetWkstaGetInfo(strDc,100,(LPBYTE*)&pInfo);
  200. if ( ! rc )
  201. {
  202. //if NT 4.0, create an NT 4.0 class object
  203. if ( pInfo->wki100_ver_major < 5 )
  204. m_pDom = new CNT4Dom();
  205. else //else create a W2K class object
  206. m_pDom = new CWin2000Dom();
  207. if (!m_pDom)
  208. hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  209. NetApiBufferFree(pInfo);
  210. }
  211. else
  212. {
  213. hr = HRESULT_FROM_WIN32(rc);
  214. }
  215. }//end if got DC
  216. else
  217. {
  218. hr = HRESULT_FROM_WIN32(rc);
  219. }
  220. return hr;
  221. }
  222. //END CreateDomainObject