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.

499 lines
12 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. cenumfsh.cxx
  5. Abstract:
  6. Contains methods for implementing the Enumeration of session on a
  7. server. Has methods for the CWinNTFileSharesEnumVar object.
  8. Author:
  9. Ram Viswanathan (ramv) 11-28-95
  10. Revision History:
  11. --*/
  12. #include "winnt.hxx"
  13. #pragma hdrstop
  14. #if DBG
  15. DECLARE_INFOLEVEL(EnumFileShare);
  16. DECLARE_DEBUG(EnumFileShare);
  17. #define EnumFileShareDebugOut(x) EnumFileShareInlineDebugOut x
  18. #endif
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: CWinNTFileSharesEnumVar::CWinNTFileSharesEnumVar
  22. //
  23. // Synopsis:
  24. //
  25. //
  26. // Arguments:
  27. //
  28. //
  29. // Returns:
  30. //
  31. // Modifies:
  32. //
  33. // History: 11-22-95 RamV Created.
  34. //
  35. //----------------------------------------------------------------------------
  36. CWinNTFileSharesEnumVar::CWinNTFileSharesEnumVar()
  37. {
  38. _pszADsPath = NULL;
  39. _pszServerName = NULL;
  40. _pbFileShares = NULL;
  41. _cElements = 0;
  42. _lLBound = 0;
  43. _lCurrentPosition = _lLBound;
  44. _dwTotalEntries = 0;
  45. _dwResumeHandle = 0;
  46. VariantInit(&_vFilter);
  47. }
  48. //+---------------------------------------------------------------------------
  49. //
  50. // Function: CWinNTFileSharesEnumVar::~CWinNTFileSharesEnumVar
  51. //
  52. // Synopsis:
  53. //
  54. //
  55. // Arguments:
  56. //
  57. // Returns:
  58. //
  59. // Modifies:
  60. //
  61. // History: 11-22-95 RamV Created.
  62. //
  63. //----------------------------------------------------------------------------
  64. CWinNTFileSharesEnumVar::~CWinNTFileSharesEnumVar()
  65. {
  66. if(_pszADsPath){
  67. FreeADsStr(_pszADsPath);
  68. }
  69. if(_pszServerName){
  70. FreeADsStr(_pszServerName);
  71. }
  72. if(_pbFileShares){
  73. NetApiBufferFree(_pbFileShares);
  74. }
  75. VariantClear(&_vFilter);
  76. }
  77. HRESULT CWinNTFileSharesEnumVar::Create(LPTSTR pszServerName,
  78. LPTSTR pszADsPath,
  79. CWinNTFileSharesEnumVar **ppCFileSharesEnumVar,
  80. VARIANT vFilter,
  81. CWinNTCredentials& Credentials
  82. )
  83. {
  84. HRESULT hr = S_OK;
  85. BOOL fStatus = FALSE;
  86. CWinNTFileSharesEnumVar FAR* pCFileSharesEnumVar = NULL;
  87. *ppCFileSharesEnumVar = NULL;
  88. pCFileSharesEnumVar = new CWinNTFileSharesEnumVar();
  89. if (pCFileSharesEnumVar == NULL){
  90. hr = E_OUTOFMEMORY;
  91. goto error;
  92. }
  93. pCFileSharesEnumVar->_pszServerName =
  94. AllocADsStr(pszServerName);
  95. if(!(pCFileSharesEnumVar->_pszServerName)){
  96. hr = E_OUTOFMEMORY;
  97. goto error;
  98. }
  99. pCFileSharesEnumVar->_pszADsPath =
  100. AllocADsStr(pszADsPath);
  101. if(!(pCFileSharesEnumVar->_pszADsPath)){
  102. hr = E_OUTOFMEMORY;
  103. goto error;
  104. }
  105. hr = VariantCopy(&(pCFileSharesEnumVar->_vFilter), &vFilter);
  106. BAIL_ON_FAILURE(hr);
  107. pCFileSharesEnumVar->_Credentials = Credentials;
  108. hr = pCFileSharesEnumVar->_Credentials.RefServer(pszServerName);
  109. BAIL_ON_FAILURE(hr);
  110. *ppCFileSharesEnumVar = pCFileSharesEnumVar;
  111. RRETURN(hr);
  112. error:
  113. delete pCFileSharesEnumVar;
  114. RRETURN_EXP_IF_ERR(hr);
  115. }
  116. //+---------------------------------------------------------------------------
  117. //
  118. // Function: CWinNTFileSharesEnumVar::Next
  119. //
  120. // Synopsis: Returns cElements number of requested Share objects in the
  121. // array supplied in pvar.
  122. //
  123. // Arguments: [cElements] -- The number of elements requested by client
  124. // [pvar] -- ptr to array of VARIANTs to for return objects
  125. // [ulNumFetched] -- if non-NULL, then number of elements
  126. // -- actually returned is placed here
  127. //
  128. // Returns: HRESULT -- S_OK if number of elements requested are returned
  129. // -- S_FALSE if number of elements is < requested
  130. //
  131. // Modifies:
  132. //
  133. // History: 11-27-95 RamV Created.
  134. //
  135. //----------------------------------------------------------------------------
  136. STDMETHODIMP
  137. CWinNTFileSharesEnumVar::Next(ULONG ulNumElementsRequested,
  138. VARIANT FAR* pvar,
  139. ULONG FAR* pulNumFetched)
  140. {
  141. HRESULT hresult = S_OK;
  142. ULONG l;
  143. ULONG lNewCurrent;
  144. ULONG lNumFetched;
  145. LPSHARE_INFO_1 lpShareInfo = NULL;
  146. VARIANT v;
  147. IDispatch * pDispatch = NULL;
  148. if (pulNumFetched != NULL){
  149. *pulNumFetched = 0;
  150. }
  151. //
  152. // Check the out parameter to ensure it is valid
  153. //
  154. if (!pvar)
  155. return S_FALSE;
  156. //
  157. // Initialize the elements to be returned
  158. //
  159. for (l=0; l<ulNumElementsRequested; l++){
  160. VariantInit(&pvar[l]);
  161. }
  162. if(!_pbFileShares ||(_lCurrentPosition == _lLBound +(LONG)_cElements)){
  163. if (_pbFileShares){
  164. NetApiBufferFree(_pbFileShares);
  165. _pbFileShares = NULL;
  166. }
  167. if(_dwTotalEntries == _cElements && (_dwTotalEntries !=0)){
  168. //
  169. // we got all elements already, no need to do another call
  170. //
  171. RRETURN(S_FALSE);
  172. }
  173. if(!(ValidateFilterValue(_vFilter))){
  174. RRETURN(S_FALSE);
  175. }
  176. hresult = WinNTEnumFileShares(_pszServerName,
  177. &_cElements,
  178. &_dwTotalEntries,
  179. &_dwResumeHandle,
  180. &_pbFileShares
  181. );
  182. if(hresult == S_FALSE){
  183. goto cleanup;
  184. }
  185. _lLBound = 0;
  186. _lCurrentPosition = _lLBound;
  187. }
  188. //
  189. // Get each element and place it into the return array
  190. // Don't request more than we have
  191. //
  192. lNumFetched = 0;
  193. lNewCurrent = _lCurrentPosition;
  194. while((lNumFetched < ulNumElementsRequested) &&
  195. (lNewCurrent< _lLBound +_cElements))
  196. {
  197. lpShareInfo = (LPSHARE_INFO_1)(_pbFileShares +
  198. lNewCurrent*sizeof(SHARE_INFO_1));
  199. if(lpShareInfo->shi1_type == STYPE_DISKTREE){
  200. //
  201. // file share object
  202. //
  203. hresult = CWinNTFileShare::Create(_pszADsPath,
  204. _pszServerName,
  205. FILESHARE_CLASS_NAME,
  206. lpShareInfo->shi1_netname,
  207. ADS_OBJECT_BOUND,
  208. IID_IDispatch,
  209. _Credentials,
  210. (void **)&pDispatch);
  211. BAIL_IF_ERROR(hresult);
  212. VariantInit(&v);
  213. V_VT(&v) = VT_DISPATCH;
  214. V_DISPATCH(&v) = pDispatch;
  215. pvar[lNumFetched] = v;
  216. lNumFetched++;
  217. }
  218. lNewCurrent++;
  219. if(lNumFetched == ulNumElementsRequested){
  220. //
  221. // we got all elements
  222. //
  223. break;
  224. }
  225. if(lNewCurrent==(_lLBound+_cElements)){
  226. //
  227. // first free our current buffer
  228. //
  229. if(_pbFileShares){
  230. NetApiBufferFree(_pbFileShares);
  231. _pbFileShares = NULL;
  232. }
  233. if(_cElements < _dwTotalEntries){
  234. hresult = WinNTEnumFileShares(_pszServerName,
  235. &_cElements,
  236. &_dwTotalEntries,
  237. &_dwResumeHandle,
  238. &_pbFileShares);
  239. if(hresult == S_FALSE){
  240. if (pulNumFetched != NULL){
  241. *pulNumFetched = lNumFetched;
  242. }
  243. goto cleanup;
  244. }
  245. _lLBound = 0;
  246. _lCurrentPosition = _lLBound;
  247. lNewCurrent = _lCurrentPosition;
  248. }
  249. else{
  250. //
  251. // you have gone through every share object
  252. // return S_FALSE
  253. //
  254. hresult = S_FALSE;
  255. if (pulNumFetched != NULL){
  256. *pulNumFetched = lNumFetched;
  257. }
  258. goto cleanup;
  259. }
  260. lNewCurrent = _lCurrentPosition;
  261. }
  262. }
  263. //
  264. // Tell the caller how many we got (which may be less than the number
  265. // requested), and save the current position
  266. //
  267. if (pulNumFetched != NULL)
  268. *pulNumFetched = lNumFetched;
  269. _lCurrentPosition = lNewCurrent;
  270. //
  271. // If we're returning less than they asked for return S_FALSE, but
  272. // they still have the data (S_FALSE is a success code)
  273. //
  274. return (lNumFetched < ulNumElementsRequested) ?
  275. S_FALSE
  276. : S_OK;
  277. cleanup:
  278. if(_pbFileShares){
  279. NetApiBufferFree(_pbFileShares);
  280. }
  281. if(FAILED(hresult)){
  282. #if DBG
  283. EnumFileShareDebugOut((DEB_TRACE,
  284. "hresult Failed with value: %ld \n", hresult ));
  285. #endif
  286. RRETURN(S_FALSE);
  287. } else {
  288. if(hresult == S_FALSE)
  289. RRETURN(S_FALSE);
  290. RRETURN(S_OK);
  291. }
  292. }
  293. HRESULT
  294. WinNTEnumFileShares(LPTSTR pszServerName,
  295. PDWORD pdwElements,
  296. PDWORD pdwTotalEntries,
  297. PDWORD pdwResumeHandle,
  298. LPBYTE * ppMem
  299. )
  300. {
  301. NET_API_STATUS nasStatus;
  302. nasStatus = NetShareEnum(pszServerName,
  303. 1,
  304. ppMem,
  305. MAX_PREFERRED_LENGTH,
  306. pdwElements,
  307. pdwTotalEntries,
  308. pdwResumeHandle
  309. );
  310. if(*ppMem == NULL || (nasStatus!= NERR_Success)){
  311. //
  312. //no more entries returned by FileShares
  313. //
  314. RRETURN(S_FALSE);
  315. }
  316. RRETURN(S_OK);
  317. }
  318. BOOL
  319. ValidateFilterValue(VARIANT vFilter)
  320. {
  321. // this function unpacks vFilter and scans the safearray to investigate
  322. // whether or not it contains the string "fileshare". If it does,
  323. // we return true so that enumeration can proceed.
  324. BOOL fRetval = FALSE;
  325. HRESULT hr = S_OK;
  326. LONG lIndices;
  327. ULONG cElements;
  328. SAFEARRAY *psa = NULL;
  329. VARIANT vElement;
  330. ULONG i;
  331. VariantInit(&vElement);
  332. if(V_VT(&vFilter) == VT_EMPTY){
  333. //
  334. // if no filter is set, you can still enumerate
  335. //
  336. fRetval = TRUE;
  337. goto cleanup;
  338. }else if (!(V_VT(&vFilter) == (VT_VARIANT|VT_ARRAY))) {
  339. fRetval = FALSE;
  340. goto cleanup;
  341. }
  342. psa = V_ARRAY(&vFilter);
  343. //
  344. // Check that there is only one dimension in this array
  345. //
  346. if (psa->cDims != 1) {
  347. fRetval = FALSE;
  348. goto cleanup;
  349. }
  350. //
  351. // Check that there is atleast one element in this array
  352. //
  353. cElements = psa->rgsabound[0].cElements;
  354. if (cElements == 0){
  355. fRetval = TRUE;
  356. //
  357. // If filter is set and is empty, then
  358. // we return all objects.
  359. //
  360. goto cleanup;
  361. }
  362. //
  363. // We know that this is a valid single dimension array
  364. //
  365. for(lIndices=0; lIndices< (LONG)cElements; lIndices++){
  366. VariantInit(&vElement);
  367. hr = SafeArrayGetElement(psa, &lIndices, &vElement);
  368. BAIL_IF_ERROR(hr);
  369. if(!(V_VT(&vElement) == VT_BSTR)){
  370. hr = E_FAIL;
  371. goto cleanup;
  372. }
  373. if ( _tcsicmp(vElement.bstrVal, TEXT("fileshare")) == 0){
  374. //
  375. // found it, you can return TRUE now
  376. //
  377. fRetval = TRUE;
  378. goto cleanup;
  379. }
  380. VariantClear(&vElement);
  381. }
  382. cleanup:
  383. //
  384. // In success case as well as error if we tripped after
  385. // getting the value but not clearing it in the for loop.
  386. //
  387. VariantClear(&vElement);
  388. if(FAILED(hr)){
  389. return FALSE;
  390. }
  391. return fRetval;
  392. }