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.

493 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. // Initialize the elements to be returned
  153. //
  154. for (l=0; l<ulNumElementsRequested; l++){
  155. VariantInit(&pvar[l]);
  156. }
  157. if(!_pbFileShares ||(_lCurrentPosition == _lLBound +(LONG)_cElements)){
  158. if (_pbFileShares){
  159. NetApiBufferFree(_pbFileShares);
  160. _pbFileShares = NULL;
  161. }
  162. if(_dwTotalEntries == _cElements && (_dwTotalEntries !=0)){
  163. //
  164. // we got all elements already, no need to do another call
  165. //
  166. RRETURN(S_FALSE);
  167. }
  168. if(!(ValidateFilterValue(_vFilter))){
  169. RRETURN(S_FALSE);
  170. }
  171. hresult = WinNTEnumFileShares(_pszServerName,
  172. &_cElements,
  173. &_dwTotalEntries,
  174. &_dwResumeHandle,
  175. &_pbFileShares
  176. );
  177. if(hresult == S_FALSE){
  178. goto cleanup;
  179. }
  180. _lLBound = 0;
  181. _lCurrentPosition = _lLBound;
  182. }
  183. //
  184. // Get each element and place it into the return array
  185. // Don't request more than we have
  186. //
  187. lNumFetched = 0;
  188. lNewCurrent = _lCurrentPosition;
  189. while((lNumFetched < ulNumElementsRequested) &&
  190. (lNewCurrent< _lLBound +_cElements))
  191. {
  192. lpShareInfo = (LPSHARE_INFO_1)(_pbFileShares +
  193. lNewCurrent*sizeof(SHARE_INFO_1));
  194. if(lpShareInfo->shi1_type == STYPE_DISKTREE){
  195. //
  196. // file share object
  197. //
  198. hresult = CWinNTFileShare::Create(_pszADsPath,
  199. _pszServerName,
  200. FILESHARE_CLASS_NAME,
  201. lpShareInfo->shi1_netname,
  202. ADS_OBJECT_BOUND,
  203. IID_IDispatch,
  204. _Credentials,
  205. (void **)&pDispatch);
  206. BAIL_IF_ERROR(hresult);
  207. VariantInit(&v);
  208. V_VT(&v) = VT_DISPATCH;
  209. V_DISPATCH(&v) = pDispatch;
  210. pvar[lNumFetched] = v;
  211. lNumFetched++;
  212. }
  213. lNewCurrent++;
  214. if(lNumFetched == ulNumElementsRequested){
  215. //
  216. // we got all elements
  217. //
  218. break;
  219. }
  220. if(lNewCurrent==(_lLBound+_cElements)){
  221. //
  222. // first free our current buffer
  223. //
  224. if(_pbFileShares){
  225. NetApiBufferFree(_pbFileShares);
  226. _pbFileShares = NULL;
  227. }
  228. if(_cElements < _dwTotalEntries){
  229. hresult = WinNTEnumFileShares(_pszServerName,
  230. &_cElements,
  231. &_dwTotalEntries,
  232. &_dwResumeHandle,
  233. &_pbFileShares);
  234. if(hresult == S_FALSE){
  235. if (pulNumFetched != NULL){
  236. *pulNumFetched = lNumFetched;
  237. }
  238. goto cleanup;
  239. }
  240. _lLBound = 0;
  241. _lCurrentPosition = _lLBound;
  242. lNewCurrent = _lCurrentPosition;
  243. }
  244. else{
  245. //
  246. // you have gone through every share object
  247. // return S_FALSE
  248. //
  249. hresult = S_FALSE;
  250. if (pulNumFetched != NULL){
  251. *pulNumFetched = lNumFetched;
  252. }
  253. goto cleanup;
  254. }
  255. lNewCurrent = _lCurrentPosition;
  256. }
  257. }
  258. //
  259. // Tell the caller how many we got (which may be less than the number
  260. // requested), and save the current position
  261. //
  262. if (pulNumFetched != NULL)
  263. *pulNumFetched = lNumFetched;
  264. _lCurrentPosition = lNewCurrent;
  265. //
  266. // If we're returning less than they asked for return S_FALSE, but
  267. // they still have the data (S_FALSE is a success code)
  268. //
  269. return (lNumFetched < ulNumElementsRequested) ?
  270. S_FALSE
  271. : S_OK;
  272. cleanup:
  273. if(_pbFileShares){
  274. NetApiBufferFree(_pbFileShares);
  275. }
  276. if(FAILED(hresult)){
  277. #if DBG
  278. EnumFileShareDebugOut((DEB_TRACE,
  279. "hresult Failed with value: %ld \n", hresult ));
  280. #endif
  281. RRETURN(S_FALSE);
  282. } else {
  283. if(hresult == S_FALSE)
  284. RRETURN(S_FALSE);
  285. RRETURN(S_OK);
  286. }
  287. }
  288. HRESULT
  289. WinNTEnumFileShares(LPTSTR pszServerName,
  290. PDWORD pdwElements,
  291. PDWORD pdwTotalEntries,
  292. PDWORD pdwResumeHandle,
  293. LPBYTE * ppMem
  294. )
  295. {
  296. NET_API_STATUS nasStatus;
  297. nasStatus = NetShareEnum(pszServerName,
  298. 1,
  299. ppMem,
  300. MAX_PREFERRED_LENGTH,
  301. pdwElements,
  302. pdwTotalEntries,
  303. pdwResumeHandle
  304. );
  305. if(*ppMem == NULL || (nasStatus!= NERR_Success)){
  306. //
  307. //no more entries returned by FileShares
  308. //
  309. RRETURN(S_FALSE);
  310. }
  311. RRETURN(S_OK);
  312. }
  313. BOOL
  314. ValidateFilterValue(VARIANT vFilter)
  315. {
  316. // this function unpacks vFilter and scans the safearray to investigate
  317. // whether or not it contains the string "fileshare". If it does,
  318. // we return true so that enumeration can proceed.
  319. BOOL fRetval = FALSE;
  320. HRESULT hr = S_OK;
  321. LONG lIndices;
  322. ULONG cElements;
  323. SAFEARRAY *psa = NULL;
  324. VARIANT vElement;
  325. ULONG i;
  326. VariantInit(&vElement);
  327. if(V_VT(&vFilter) == VT_EMPTY){
  328. //
  329. // if no filter is set, you can still enumerate
  330. //
  331. fRetval = TRUE;
  332. goto cleanup;
  333. }else if (!(V_VT(&vFilter) == (VT_VARIANT|VT_ARRAY))) {
  334. fRetval = FALSE;
  335. goto cleanup;
  336. }
  337. psa = V_ARRAY(&vFilter);
  338. //
  339. // Check that there is only one dimension in this array
  340. //
  341. if (psa->cDims != 1) {
  342. fRetval = FALSE;
  343. goto cleanup;
  344. }
  345. //
  346. // Check that there is atleast one element in this array
  347. //
  348. cElements = psa->rgsabound[0].cElements;
  349. if (cElements == 0){
  350. fRetval = TRUE;
  351. //
  352. // If filter is set and is empty, then
  353. // we return all objects.
  354. //
  355. goto cleanup;
  356. }
  357. //
  358. // We know that this is a valid single dimension array
  359. //
  360. for(lIndices=0; lIndices< (LONG)cElements; lIndices++){
  361. VariantInit(&vElement);
  362. hr = SafeArrayGetElement(psa, &lIndices, &vElement);
  363. BAIL_IF_ERROR(hr);
  364. if(!(V_VT(&vElement) == VT_BSTR)){
  365. hr = E_FAIL;
  366. goto cleanup;
  367. }
  368. if ( _tcsicmp(vElement.bstrVal, TEXT("fileshare")) == 0){
  369. //
  370. // found it, you can return TRUE now
  371. //
  372. fRetval = TRUE;
  373. goto cleanup;
  374. }
  375. VariantClear(&vElement);
  376. }
  377. cleanup:
  378. //
  379. // In success case as well as error if we tripped after
  380. // getting the value but not clearing it in the for loop.
  381. //
  382. VariantClear(&vElement);
  383. if(FAILED(hr)){
  384. return FALSE;
  385. }
  386. return fRetval;
  387. }