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.

1420 lines
41 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corp., 1991 **/
  4. /**********************************************************************/
  5. /*
  6. ENUMNODE.CXX
  7. This file contains the implementation of
  8. NPOpenEnum - open a resource handle
  9. NPEnumResource - walk through all the resource
  10. NPCloseEnum - end of walk through
  11. FILE HISTORY:
  12. terryk 12-Nov-91 Created
  13. terryk 18-Nov-91 Code review changed. Attend: chuckc
  14. johnl davidhov terryk
  15. terryk 10-Dec-91 Fixed DOMAIN_ENUMNODE bug
  16. terryk 10-Dec-91 Added server name in front of the sharename
  17. terryk 28-Dec-91 changed DWORD to UINT
  18. terryk 03-Jan-92 Capitalize Resource_XXX manifest and
  19. add lpProvider field to NetResource
  20. Yi-HsinS 3-Jan-92 Unicode work
  21. terryk 10-Jan-92 Don't return resource with remotename
  22. ended with '$'
  23. JohnL 02-Apr-92 Added support for returning the required
  24. buffer size if WN_MORE_DATA is returned
  25. Johnl 29-Jul-92 Added backup support when buffer fills up
  26. AnirudhS 22-Mar-95 Added CONTEXT_ENUMNODE
  27. MilanS 15-Mar-96 Added Dfs functionality
  28. jschwart 16-Mar-99 Added RESOURCE_SHAREABLE
  29. */
  30. #define INCL_WINDOWS
  31. #define INCL_DOSERRORS
  32. #define INCL_NETERRORS
  33. #define INCL_NETCONS
  34. #define INCL_NETMESSAGE
  35. #define INCL_NETUSE
  36. #define INCL_NETACCESS // NetPasswordSet declaration
  37. #define INCL_NETCONFIG
  38. #define INCL_NETREMUTIL
  39. #define INCL_NETSHARE
  40. #define INCL_NETSERVER
  41. #define INCL_NETSERVICE
  42. #define INCL_NETLIB
  43. #define _WINNETWK_
  44. #include <lmui.hxx>
  45. #undef _WINNETWK_
  46. #include <winnetwk.h>
  47. #include <winnetp.h>
  48. #include <npapi.h>
  49. #include <wnetenum.h>
  50. #include <winlocal.h>
  51. #include <lmobj.hxx>
  52. #include <lmoshare.hxx>
  53. #include <lmoesh.hxx>
  54. #include <lmoeuse.hxx>
  55. #include <lmodev.hxx>
  56. #include <lmosrv.hxx>
  57. #include <lmoesrv.hxx>
  58. #include <lmsvc.hxx>
  59. #include <uibuffer.hxx>
  60. #include <uitrace.hxx>
  61. #include <uiassert.hxx>
  62. #include <array.hxx>
  63. #include <string.hxx>
  64. #include <strchlit.hxx> // for string and character literals
  65. #include <wnetenum.hxx>
  66. /*******************************************************************
  67. Global variables
  68. ********************************************************************/
  69. DEFINE_ARRAY_OF( PNET_ENUMNODE )
  70. NET_ENUM_HANDLE_TABLE *vpNetEnumArray;
  71. /*******************************************************************
  72. NAME: NET_ENUM_HANDLE_TABLE::NET_ENUM_HANDLE_TABLE
  73. SYNOPSIS: constructor
  74. ENTRY: UINT cNumEntry - number of elements in the array
  75. HISTORY:
  76. terryk 05-Nov-91 Created
  77. ********************************************************************/
  78. NET_ENUM_HANDLE_TABLE::NET_ENUM_HANDLE_TABLE( UINT cNumEntry )
  79. : _cNumEntry ( cNumEntry ),
  80. _apNetEnumArray( cNumEntry )
  81. {
  82. if ( _apNetEnumArray.QueryCount() != cNumEntry )
  83. {
  84. ReportError( ERROR_NOT_ENOUGH_MEMORY );
  85. }
  86. else
  87. {
  88. for ( UINT i = 0 ; i < cNumEntry ; i++ )
  89. {
  90. _apNetEnumArray[i] = NULL ;
  91. }
  92. }
  93. }
  94. /*******************************************************************
  95. NAME: NET_ENUM_HANDLE_TABLE::~NET_ENUM_HANDLE_TABLE
  96. SYNOPSIS: destructor
  97. NOTES: It will destroy all the elements in the array.
  98. HISTORY:
  99. terryk 05-Nov-91 Created
  100. ********************************************************************/
  101. NET_ENUM_HANDLE_TABLE::~NET_ENUM_HANDLE_TABLE()
  102. {
  103. for ( UINT i=0; i < _cNumEntry; i++ )
  104. {
  105. NET_ENUMNODE * ptmp = _apNetEnumArray[i];
  106. delete ptmp ;
  107. _apNetEnumArray[i] = NULL;
  108. }
  109. }
  110. /*******************************************************************
  111. NAME: NET_ENUM_HANDLE_TABLE::QueryNextAvail
  112. SYNOPSIS: return the next available slot in the array
  113. RETURNS: if the return value is -1, then no slot is available.
  114. HISTORY:
  115. terryk 05-Nov-91 Created
  116. ********************************************************************/
  117. INT NET_ENUM_HANDLE_TABLE::QueryNextAvail()
  118. {
  119. // find the next available slot
  120. for ( UINT i=0; i < _cNumEntry; i++ )
  121. {
  122. if ( _apNetEnumArray[i] == NULL )
  123. {
  124. return i;
  125. }
  126. }
  127. return -1;
  128. }
  129. /*******************************************************************
  130. NAME: NET_ENUM_HANDLE_TABLE::QueryNode
  131. SYNOPSIS: return the NET_ENUMNODE in the specified slot
  132. ENTRY: UINT iIndex - slot index
  133. RETURNS: NET_ENUMNODE * - return the pointer to the element in
  134. the array
  135. NOTES: It will check whether the given handle is out of range
  136. or not
  137. HISTORY:
  138. terryk 05-Nov-91 Created
  139. ********************************************************************/
  140. NET_ENUMNODE * NET_ENUM_HANDLE_TABLE::QueryNode( UINT iIndex ) const
  141. {
  142. NET_ENUMNODE * pnetenumnode = NULL ;
  143. if ( IsValidHandle( iIndex ))
  144. {
  145. pnetenumnode = _apNetEnumArray[ iIndex ] ;
  146. }
  147. else
  148. {
  149. // the index is either out of range or the index position is NULL
  150. TRACEEOL( "NET_ENUM_HANDLE_TABLE::QueryNode: invalid handle" );
  151. }
  152. return pnetenumnode ;
  153. }
  154. /*******************************************************************
  155. NAME: NET_ENUM_NODE::SetNode
  156. SYNOPSIS: set the slot in the array to the given element
  157. ENTRY: UINT iIndex - slot index
  158. NET_ENUMNODE * pNetEnumNode - pointer to the element to
  159. be stored.
  160. HISTORY:
  161. terryk 05-Nov-91 Created
  162. ********************************************************************/
  163. VOID NET_ENUM_HANDLE_TABLE::SetNode( UINT iIndex, NET_ENUMNODE *pNetEnumNode )
  164. {
  165. if ( IsValidRange( iIndex ))
  166. {
  167. _apNetEnumArray[ iIndex ] = pNetEnumNode;
  168. }
  169. else
  170. {
  171. // the index is out of range
  172. UIASSERT( FALSE );
  173. }
  174. }
  175. /*******************************************************************
  176. NAME: NET_ENUM_HANDLE_TABLE::ClearNode
  177. SYNOPSIS: delete the node object and free up the memory
  178. ENTRY: UINT iIndex - index location
  179. HISTORY:
  180. terryk 12-Nov-91 Created
  181. ********************************************************************/
  182. VOID NET_ENUM_HANDLE_TABLE::ClearNode( UINT iIndex )
  183. {
  184. if ( IsValidRange( iIndex ))
  185. {
  186. if ( _apNetEnumArray[ iIndex ] == NULL )
  187. {
  188. // the node is empty
  189. UIASSERT( FALSE )
  190. }
  191. else
  192. {
  193. NET_ENUMNODE * ptmp = _apNetEnumArray[iIndex];
  194. delete ptmp ;
  195. _apNetEnumArray[iIndex] = NULL;
  196. }
  197. }
  198. else
  199. {
  200. // out of range
  201. UIASSERT( FALSE );
  202. }
  203. }
  204. /*******************************************************************
  205. NAME: NET_ENUMNODE::NET_ENUMNODE
  206. SYNOPSIS: enumeration node constructor
  207. ENTRY: UINT dwScope - the scope
  208. UINT dwType - type of the node
  209. UINT dwUsage - usage
  210. LPNETRESOURCE lpNetResource - pointer to the resource structure
  211. HISTORY:
  212. terryk 24-Oct-91 Created
  213. ********************************************************************/
  214. NET_ENUMNODE::NET_ENUMNODE( UINT dwScope, UINT dwType, UINT dwUsage,
  215. const LPNETRESOURCE lpNetResource )
  216. : BASE(),
  217. _dwType( dwType ),
  218. _dwScope( dwScope ),
  219. _dwUsage( dwUsage ),
  220. _lpNetResource( lpNetResource ),
  221. _fFirstGetInfo( TRUE )
  222. {
  223. }
  224. NET_ENUMNODE::~NET_ENUMNODE()
  225. {
  226. /* Nothing to do
  227. */
  228. }
  229. /*******************************************************************
  230. NAME: NET_ENUMNODE::PackString
  231. SYNOPSIS: pack the string to the end of the buffer
  232. ENTRY: BYTE * pBuf - beginning of the buffer
  233. UINT &cbBufSize - orginial buffer size in BYTE
  234. TCHAR * pszString - the string to be copied
  235. EXIT: UINT &cbBufSize - the new bufsize - the string size
  236. RETURNS: the location of the new string inside the buffer
  237. HISTORY:
  238. terryk 31-Oct-91 Created
  239. ********************************************************************/
  240. TCHAR * NET_ENUMNODE::PackString(BYTE * pBuf, UINT *cbBufSize,
  241. const TCHAR * pszString )
  242. {
  243. UINT cStrLen = (::strlenf( pszString ) + 1) * sizeof( TCHAR );
  244. UIASSERT( cStrLen < *cbBufSize );
  245. TCHAR *pszLoc =(TCHAR *)(( pBuf )+ ((*cbBufSize)- cStrLen ));
  246. ::strcpyf( pszLoc, pszString );
  247. *cbBufSize -=( cStrLen );
  248. return pszLoc;
  249. }
  250. /*******************************************************************
  251. NAME: SHARE_ENUMNODE::SHARE_ENUMNODE
  252. SYNOPSIS: constructor
  253. ENTRY: UINT dwScope - the scope
  254. UINT dwType - type of the node
  255. UINT dwUsage - usage
  256. LPNETRESOURCE lpNetResource - pointer to the resource structure
  257. NOTE: lpNetResource must not be NULL
  258. HISTORY:
  259. terryk 05-Nov-91 Created
  260. jschwart 16-Mar-99 Added support for RESOURCE_SHAREABLE
  261. ********************************************************************/
  262. SHARE_ENUMNODE::SHARE_ENUMNODE( UINT dwScope, UINT dwType, UINT
  263. dwUsage, const LPNETRESOURCE lpNetResource )
  264. : NET_ENUMNODE( dwScope, dwType, dwUsage, lpNetResource ),
  265. _ShareEnum( lpNetResource->lpRemoteName ),
  266. _pShareIter( NULL )
  267. {
  268. if (QueryError() == NERR_Success && _ShareEnum.QueryError() != NERR_Success)
  269. {
  270. ReportError(_ShareEnum.QueryError());
  271. }
  272. }
  273. /*******************************************************************
  274. NAME: SHARE_ENUMNODE::~SHARE_ENUMNODE
  275. SYNOPSIS: destructor
  276. HISTORY:
  277. terryk 05-Nov-91 Created
  278. ********************************************************************/
  279. SHARE_ENUMNODE::~SHARE_ENUMNODE()
  280. {
  281. delete _pShareIter;
  282. _pShareIter = NULL;
  283. }
  284. /*******************************************************************
  285. NAME: SHARE_ENUMNODE::GetInfo
  286. SYNOPSIS: Get the Share enum info and create the share enum
  287. interator
  288. RETURNS: APIERR - NERR_Success for success. Failure otherwise.
  289. HISTORY:
  290. terryk 05-Nov-91 Created
  291. ********************************************************************/
  292. APIERR SHARE_ENUMNODE::GetInfo()
  293. {
  294. APIERR err = _ShareEnum.GetInfo();
  295. if ( err != NERR_Success )
  296. {
  297. return err;
  298. }
  299. if ( _pShareIter != NULL )
  300. {
  301. delete _pShareIter;
  302. _pShareIter = NULL;
  303. }
  304. _pShareIter = new SHARE1_ENUM_ITER ( _ShareEnum );
  305. if ( _pShareIter == NULL )
  306. {
  307. return ERROR_NOT_ENOUGH_MEMORY;
  308. }
  309. SetFirstTime();
  310. return NERR_Success;
  311. }
  312. /*******************************************************************
  313. NAME: SHARE_ENUMNODE::GetNetResource
  314. SYNOPSIS: construct a NetResource data object and store it in the
  315. buffer
  316. ENTRY: BYTE *pBuffer - beginning of the buffer
  317. UINT *pdwBufferSize - the current buffer size
  318. EXIT: UINT *pdwBufferSize - the orginial buffer size minus
  319. the string size allocated during construction
  320. RETURNS: UINT - WN_SUCCESS for success. Failure otherwise
  321. HISTORY:
  322. terryk 05-Nov-91 Created
  323. terryk 10-Dec-91 Added ServerName in front of the
  324. share name
  325. beng 06-Apr-92 Remove wsprintf
  326. ********************************************************************/
  327. #define DOLLAR_CHAR TCH('$')
  328. UINT SHARE_ENUMNODE::GetNetResource( BYTE *pBuffer, UINT *pdwBufferSize)
  329. {
  330. APIERR err = GetLMProviderName();
  331. if (err != WN_SUCCESS)
  332. return err;
  333. if ( QueryUsage() == RESOURCEUSAGE_CONTAINER )
  334. {
  335. // if the net usage is a container, return no more entries
  336. // becuase share cannot have child level
  337. return WN_NO_MORE_ENTRIES;
  338. }
  339. const SHARE1_ENUM_OBJ *pseo1;
  340. while ( TRUE )
  341. {
  342. for ( pseo1 = (*_pShareIter)(); pseo1 != NULL; pseo1 = (*_pShareIter)())
  343. {
  344. if (( QueryType() == RESOURCETYPE_ANY ) ||
  345. (( pseo1->QueryResourceType() == STYPE_DISKTREE ) &&
  346. (( QueryType() & RESOURCETYPE_DISK ))) ||
  347. (( pseo1->QueryResourceType() == STYPE_PRINTQ ) &&
  348. (( QueryType() & RESOURCETYPE_PRINT ))))
  349. {
  350. // break the for loop if we find the matched share object
  351. break;
  352. }
  353. }
  354. if ( pseo1 == NULL )
  355. {
  356. return WN_NO_MORE_ENTRIES;
  357. }
  358. ALIAS_STR nlsRemoteName = pseo1->QueryName();
  359. ISTR istrRemoteName( nlsRemoteName );
  360. istrRemoteName += nlsRemoteName.QueryTextLength() - 1;
  361. if (QueryScope() != RESOURCE_SHAREABLE)
  362. {
  363. if (nlsRemoteName.QueryChar (istrRemoteName ) != DOLLAR_CHAR)
  364. {
  365. // We're looking for non-shareable resource and this is
  366. // a non-shareable resource
  367. break;
  368. }
  369. }
  370. else
  371. {
  372. if (nlsRemoteName.QueryChar( istrRemoteName ) == DOLLAR_CHAR
  373. &&
  374. wcslen(nlsRemoteName) == 2)
  375. {
  376. // We're looking for shareable resources and this is
  377. // a shareable resource (ends in $ and is a drive
  378. // letter + $ (e.g., C$, D$, etc.) )
  379. break;
  380. }
  381. }
  382. }
  383. UINT cbShareLength = (::strlenf(pseo1->QueryName()) +
  384. ::strlenf(_ShareEnum.QueryServer())) * sizeof(TCHAR);
  385. UINT cbMinBuffSize = sizeof( NETRESOURCE ) + cbShareLength +
  386. (::strlenf( pseo1->QueryComment()) +
  387. ::strlenf( pszNTLanMan ) + 4) * sizeof( TCHAR ) ;
  388. //
  389. // Add in the backslash and NULL character
  390. //
  391. cbShareLength += sizeof(PATHSEP_STRING);
  392. if ( *pdwBufferSize < cbMinBuffSize )
  393. {
  394. *pdwBufferSize = cbMinBuffSize ;
  395. _pShareIter->Backup() ;
  396. return WN_MORE_DATA;
  397. }
  398. LPNETRESOURCE pNetResource = (LPNETRESOURCE) pBuffer;
  399. pNetResource->dwScope = RESOURCE_GLOBALNET;
  400. if ( pseo1->QueryResourceType() == STYPE_DISKTREE )
  401. {
  402. pNetResource->dwType = RESOURCETYPE_DISK;
  403. }
  404. else if ( pseo1->QueryResourceType() == STYPE_PRINTQ )
  405. {
  406. pNetResource->dwType = RESOURCETYPE_PRINT;
  407. }
  408. else
  409. {
  410. pNetResource->dwType = RESOURCETYPE_ANY;
  411. }
  412. pNetResource->lpLocalName = NULL;
  413. pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE ;
  414. LPTSTR pszName = (LPTSTR) LocalAlloc(LMEM_FIXED, cbShareLength);
  415. if (pszName == NULL)
  416. {
  417. _pShareIter->Backup();
  418. return WN_OUT_OF_MEMORY;
  419. }
  420. ::strcpyf(pszName, _ShareEnum.QueryServer());
  421. ::strcatf(pszName, PATHSEP_STRING);
  422. ::strcatf(pszName, pseo1->QueryName());
  423. pNetResource->lpRemoteName = PackString((BYTE *)pNetResource,
  424. pdwBufferSize, pszName );
  425. pNetResource->lpComment = PackString((BYTE *)pNetResource,
  426. pdwBufferSize, pseo1->QueryComment() );
  427. pNetResource->lpProvider = PackString((BYTE *)pNetResource,
  428. pdwBufferSize, pszNTLanMan );
  429. pNetResource->dwUsage = RESOURCEUSAGE_CONNECTABLE;
  430. LocalFree(pszName);
  431. return WN_SUCCESS;
  432. }
  433. /*******************************************************************
  434. NAME: SERVER_ENUMNODE::SERVER_ENUMNODE
  435. SYNOPSIS: constructor
  436. ENTRY: UINT dwScope - the scope
  437. UINT dwType - type of the node
  438. UINT dwUsage - usage
  439. LPNETRESOURCE lpNetResource - pointer to the resource structure
  440. NOTE: lpNetResource must not be NULL
  441. HISTORY:
  442. terryk 05-Nov-91 Created
  443. ********************************************************************/
  444. SERVER_ENUMNODE::SERVER_ENUMNODE( UINT dwScope, UINT dwType, UINT
  445. dwUsage, const LPNETRESOURCE lpNetResource )
  446. : NET_ENUMNODE( dwScope, dwType, dwUsage, lpNetResource ),
  447. _ServerEnum( NULL, lpNetResource->lpRemoteName ),
  448. _pServerIter( NULL )
  449. {
  450. if (QueryError() == NERR_Success && _ServerEnum.QueryError() != NERR_Success)
  451. {
  452. ReportError(_ServerEnum.QueryError());
  453. }
  454. }
  455. /*******************************************************************
  456. NAME: SERVER_ENUMNODE::~SERVER_ENUMNODE
  457. SYNOPSIS: destructor
  458. HISTORY:
  459. terryk 05-Nov-91 Created
  460. ********************************************************************/
  461. SERVER_ENUMNODE::~SERVER_ENUMNODE()
  462. {
  463. delete _pServerIter;
  464. _pServerIter = NULL;
  465. }
  466. /*******************************************************************
  467. NAME: SERVER_ENUMNODE::GetInfo
  468. SYNOPSIS: Get the Share enum info and create the share enum
  469. interator
  470. RETURNS: APIERR - NERR_Success for success. Failure otherwise.
  471. HISTORY:
  472. terryk 05-Nov-91 Created
  473. ********************************************************************/
  474. APIERR SERVER_ENUMNODE::GetInfo()
  475. {
  476. APIERR err = _ServerEnum.GetInfo();
  477. if ( err != NERR_Success )
  478. {
  479. if (err == WN_MORE_DATA)
  480. {
  481. // This is a workaround for a browser design limitation.
  482. // If the browse server is pre-NT 4.0 it can return an
  483. // incomplete enumeration with a status of ERROR_MORE_DATA.
  484. // Treat this as a success.
  485. err = WN_SUCCESS;
  486. }
  487. else
  488. {
  489. return err;
  490. }
  491. }
  492. if ( _pServerIter != NULL )
  493. {
  494. delete _pServerIter;
  495. _pServerIter = NULL;
  496. }
  497. _pServerIter = new SERVER1_ENUM_ITER( _ServerEnum );
  498. if ( _pServerIter == NULL )
  499. {
  500. return ERROR_NOT_ENOUGH_MEMORY;
  501. }
  502. SetFirstTime();
  503. return NERR_Success;
  504. }
  505. /*******************************************************************
  506. NAME: SERVER_ENUMNODE::GetNetResource
  507. SYNOPSIS: construct a NetResource data object and store it in the
  508. buffer
  509. ENTRY: BYTE *pBuffer - beginning of the buffer
  510. UINT *pdwBufferSize - the current buffer size
  511. EXIT: UINT *pdwBufferSize - the orginial buffer size minus
  512. the string size allocated during construction
  513. RETURNS: APIERR - WN_SUCCESS for success. Failure otherwise
  514. HISTORY:
  515. terryk 05-Nov-91 Created
  516. Yi-HsinS 12-Nov-92 Filter for print servers
  517. ********************************************************************/
  518. // The following lanman version number is the first release that
  519. // the server will announce whether it is a print server or not.
  520. #define LM_MAJOR_VER 2
  521. #define LM_MINOR_VER 1
  522. UINT SERVER_ENUMNODE::GetNetResource( BYTE *pBuffer, UINT *pdwBufferSize)
  523. {
  524. APIERR err = GetLMProviderName ();
  525. if (err != WN_SUCCESS)
  526. return err;
  527. if ( QueryUsage() == RESOURCEUSAGE_CONNECTABLE )
  528. {
  529. return WN_NO_MORE_ENTRIES;
  530. }
  531. const SERVER1_ENUM_OBJ *pseo1 = NULL;
  532. for ( pseo1 = (*_pServerIter)(); pseo1 != NULL; pseo1 = (*_pServerIter)() )
  533. {
  534. if ( QueryType() != RESOURCETYPE_PRINT )
  535. break;
  536. UINT svType = pseo1->QueryServerType();
  537. UINT svMajorVer = pseo1->QueryMajorVer();
  538. UINT svMinorVer = pseo1->QueryMinorVer();
  539. // RESOURCETYPE_PRINT only
  540. if ( ( ( svMajorVer > LM_MAJOR_VER )
  541. || ( ( svMajorVer == LM_MAJOR_VER )
  542. && ( svMinorVer >= LM_MINOR_VER )
  543. )
  544. )
  545. && ( svType & SV_TYPE_PRINTQ_SERVER )
  546. )
  547. {
  548. break;
  549. }
  550. }
  551. if ( pseo1 == NULL )
  552. {
  553. return WN_NO_MORE_ENTRIES;
  554. }
  555. STACK_NLS_STR(astrRemoteName, MAX_PATH + 1 );
  556. astrRemoteName = SERVER_INIT_STRING ;
  557. astrRemoteName.strcat( pseo1->QueryName());
  558. if ( astrRemoteName.QueryError() != NERR_Success )
  559. {
  560. // probably out of memory
  561. return WN_OUT_OF_MEMORY;
  562. }
  563. UINT cbMinBuffSize = ( sizeof( NETRESOURCE ) +
  564. astrRemoteName.QueryTextSize() +
  565. (::strlenf( pszNTLanMan ) +
  566. ::strlenf( pseo1->QueryComment() ) + 2 )
  567. * sizeof(TCHAR)) ;
  568. if ( *pdwBufferSize < cbMinBuffSize )
  569. {
  570. *pdwBufferSize = cbMinBuffSize ;
  571. _pServerIter->Backup() ;
  572. return WN_MORE_DATA;
  573. }
  574. LPNETRESOURCE pNetResource = (LPNETRESOURCE) pBuffer;
  575. pNetResource->dwScope = RESOURCE_GLOBALNET;
  576. pNetResource->dwType = QueryType();
  577. pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER ;
  578. pNetResource->lpLocalName = NULL;
  579. pNetResource->lpRemoteName = PackString((BYTE *)pNetResource,
  580. pdwBufferSize, astrRemoteName.QueryPch());
  581. pNetResource->lpComment = PackString((BYTE *)pNetResource,
  582. pdwBufferSize, pseo1->QueryComment() );
  583. pNetResource->lpProvider = PackString(( BYTE *) pNetResource,
  584. pdwBufferSize, pszNTLanMan );
  585. pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
  586. return WN_SUCCESS;
  587. }
  588. /*******************************************************************
  589. NAME: CONTEXT_ENUMNODE::CONTEXT_ENUMNODE
  590. SYNOPSIS: constructor
  591. ENTRY: UINT dwScope - the scope
  592. UINT dwType - type of the node
  593. UINT dwUsage - usage
  594. LPNETRESOURCE lpNetResource - pointer to the resource structure
  595. NOTE: lpNetResource must not be NULL
  596. HISTORY:
  597. anirudhs 22-Mar-1995 Created from SERVER_ENUMNODE
  598. ********************************************************************/
  599. CONTEXT_ENUMNODE::CONTEXT_ENUMNODE( UINT dwScope, UINT dwType, UINT
  600. dwUsage, const LPNETRESOURCE lpNetResource )
  601. : NET_ENUMNODE( dwScope, dwType, dwUsage, lpNetResource ),
  602. _ServerEnum(
  603. (dwScope == RESOURCE_CONTEXT && dwType != 0) // flServerType
  604. ?
  605. ((dwType & RESOURCETYPE_DISK) ? SV_TYPE_SERVER : 0)
  606. |
  607. ((dwType & RESOURCETYPE_PRINT) ?
  608. (SV_TYPE_PRINTQ_SERVER | SV_TYPE_WFW) : 0)
  609. :
  610. SV_TYPE_ALL
  611. ),
  612. _pServerIter( NULL )
  613. {
  614. if (QueryError() == NERR_Success && _ServerEnum.QueryError() != NERR_Success)
  615. {
  616. ReportError(_ServerEnum.QueryError());
  617. }
  618. }
  619. /*******************************************************************
  620. NAME: CONTEXT_ENUMNODE::~CONTEXT_ENUMNODE
  621. SYNOPSIS: destructor
  622. HISTORY:
  623. anirudhs 22-Mar-1995 Created
  624. ********************************************************************/
  625. CONTEXT_ENUMNODE::~CONTEXT_ENUMNODE()
  626. {
  627. delete _pServerIter;
  628. _pServerIter = NULL;
  629. }
  630. /*******************************************************************
  631. NAME: CONTEXT_ENUMNODE::GetInfo
  632. SYNOPSIS: Get the Share enum info and create the share enum
  633. interator
  634. RETURNS: APIERR - NERR_Success for success. Failure otherwise.
  635. HISTORY:
  636. anirudhs 22-Mar-1995 Created
  637. ********************************************************************/
  638. APIERR CONTEXT_ENUMNODE::GetInfo()
  639. {
  640. APIERR err = _ServerEnum.GetInfo();
  641. if ( err != NERR_Success )
  642. {
  643. if (err == WN_MORE_DATA)
  644. {
  645. // This is a workaround for a browser design limitation.
  646. // If the browse server is pre-NT 4.0 it can return an
  647. // incomplete enumeration with a status of ERROR_MORE_DATA.
  648. // Treat this as a success.
  649. err = WN_SUCCESS;
  650. }
  651. else
  652. {
  653. return err;
  654. }
  655. }
  656. if ( _pServerIter != NULL )
  657. {
  658. delete _pServerIter;
  659. _pServerIter = NULL;
  660. }
  661. _pServerIter = new CONTEXT_ENUM_ITER( _ServerEnum );
  662. if ( _pServerIter == NULL )
  663. {
  664. return ERROR_NOT_ENOUGH_MEMORY;
  665. }
  666. SetFirstTime();
  667. return NERR_Success;
  668. }
  669. /*******************************************************************
  670. NAME: CONTEXT_ENUMNODE::GetNetResource
  671. SYNOPSIS: construct a NetResource data object and store it in the
  672. buffer
  673. ENTRY: BYTE *pBuffer - beginning of the buffer
  674. UINT *pdwBufferSize - the current buffer size
  675. EXIT: UINT *pdwBufferSize - the orginial buffer size minus
  676. the string size allocated during construction
  677. RETURNS: APIERR - WN_SUCCESS for success. Failure otherwise
  678. HISTORY:
  679. anirudhs 22-Mar-1995 Created from SERVER_ENUMNODE
  680. ********************************************************************/
  681. // The following lanman version number is the first release that
  682. // the server will announce whether it is a print server or not.
  683. #define LM_MAJOR_VER 2
  684. #define LM_MINOR_VER 1
  685. UINT CONTEXT_ENUMNODE::GetNetResource( BYTE *pBuffer, UINT *pdwBufferSize)
  686. {
  687. APIERR err = GetLMProviderName ();
  688. if (err != WN_SUCCESS)
  689. return err;
  690. if ( QueryUsage() == RESOURCEUSAGE_CONNECTABLE )
  691. {
  692. return WN_NO_MORE_ENTRIES;
  693. }
  694. const CONTEXT_ENUM_OBJ *pseo1 = NULL;
  695. for ( pseo1 = (*_pServerIter)(); pseo1 != NULL; pseo1 = (*_pServerIter)() )
  696. {
  697. if ( QueryType() != RESOURCETYPE_PRINT )
  698. break;
  699. UINT svType = pseo1->QueryServerType();
  700. UINT svMajorVer = pseo1->QueryMajorVer();
  701. UINT svMinorVer = pseo1->QueryMinorVer();
  702. // RESOURCETYPE_PRINT only
  703. if ( ( ( svMajorVer > LM_MAJOR_VER )
  704. || ( ( svMajorVer == LM_MAJOR_VER )
  705. && ( svMinorVer >= LM_MINOR_VER )
  706. )
  707. )
  708. && ( svType & SV_TYPE_PRINTQ_SERVER )
  709. )
  710. {
  711. break;
  712. }
  713. }
  714. if ( pseo1 == NULL )
  715. {
  716. return WN_NO_MORE_ENTRIES;
  717. }
  718. STACK_NLS_STR(astrRemoteName, MAX_PATH + 1 );
  719. astrRemoteName = SERVER_INIT_STRING ;
  720. astrRemoteName.strcat( pseo1->QueryName());
  721. if ( astrRemoteName.QueryError() != NERR_Success )
  722. {
  723. // probably out of memory
  724. return WN_OUT_OF_MEMORY;
  725. }
  726. UINT cbMinBuffSize = ( sizeof( NETRESOURCE ) +
  727. astrRemoteName.QueryTextSize() +
  728. (::strlenf( pszNTLanMan ) +
  729. ::strlenf( pseo1->QueryComment() ) + 2 )
  730. * sizeof(TCHAR)) ;
  731. if ( *pdwBufferSize < cbMinBuffSize )
  732. {
  733. *pdwBufferSize = cbMinBuffSize ;
  734. _pServerIter->Backup() ;
  735. return WN_MORE_DATA;
  736. }
  737. LPNETRESOURCE pNetResource = (LPNETRESOURCE) pBuffer;
  738. pNetResource->dwScope = RESOURCE_GLOBALNET;
  739. pNetResource->dwType = QueryType();
  740. pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER ;
  741. pNetResource->lpLocalName = NULL;
  742. pNetResource->lpRemoteName = PackString((BYTE *)pNetResource,
  743. pdwBufferSize, astrRemoteName.QueryPch());
  744. pNetResource->lpComment = PackString((BYTE *)pNetResource,
  745. pdwBufferSize, pseo1->QueryComment() );
  746. pNetResource->lpProvider = PackString(( BYTE *) pNetResource,
  747. pdwBufferSize, pszNTLanMan );
  748. pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
  749. return WN_SUCCESS;
  750. }
  751. /*******************************************************************
  752. NAME: USE_ENUMNODE::USE_ENUMNODE
  753. SYNOPSIS: constructor
  754. ENTRY: UINT dwScope - the scope
  755. UINT dwType - type of the node
  756. UINT dwUsage - usage
  757. LPNETRESOURCE lpNetResource - pointer to the resource structure
  758. HISTORY:
  759. terryk 05-Nov-91 Created
  760. ********************************************************************/
  761. USE_ENUMNODE::USE_ENUMNODE( UINT dwScope, UINT dwType, UINT dwUsage,
  762. const LPNETRESOURCE lpNetResource )
  763. : NET_ENUMNODE( dwScope, dwType, dwUsage, lpNetResource ),
  764. _UseEnum( NULL ),
  765. _pUseIter( NULL ),
  766. _dfsEnum( dwScope, dwType, dwUsage, pszNTLanMan, lpNetResource )
  767. {
  768. if (QueryError() == NERR_Success && _UseEnum.QueryError() != NERR_Success)
  769. {
  770. ReportError(_UseEnum.QueryError());
  771. }
  772. }
  773. /*******************************************************************
  774. NAME: USE_ENUMNODE::~USE_ENUMNODE
  775. SYNOPSIS: destructor
  776. HISTORY:
  777. terryk 05-Nov-91 Created
  778. ********************************************************************/
  779. USE_ENUMNODE::~USE_ENUMNODE()
  780. {
  781. delete _pUseIter;
  782. _pUseIter = NULL;
  783. }
  784. /*******************************************************************
  785. NAME: USE_ENUMNODE::GetInfo
  786. SYNOPSIS: Get the use enum info and create the use enum
  787. interator
  788. RETURNS: APIERR - NERR_Success for success. Failure otherwise.
  789. HISTORY:
  790. terryk 05-Nov-91 Created
  791. Yi-HsinS 9-Jun-92 Use USE1_ENUM
  792. ********************************************************************/
  793. APIERR USE_ENUMNODE::GetInfo()
  794. {
  795. APIERR err = _UseEnum.GetInfo();
  796. if ( err != NERR_Success )
  797. return err;
  798. if ( _pUseIter != NULL )
  799. {
  800. delete _pUseIter;
  801. }
  802. _pUseIter = new USE1_ENUM_ITER( _UseEnum );
  803. if ( _pUseIter == NULL )
  804. {
  805. return ERROR_NOT_ENOUGH_MEMORY;
  806. }
  807. SetFirstTime();
  808. return NERR_Success;
  809. }
  810. /*******************************************************************
  811. NAME: USE_ENUMNODE::GetNetResource
  812. SYNOPSIS: construct a NetResource data object and store it in the
  813. buffer
  814. ENTRY: BYTE *pBuffer - beginning of the buffer
  815. UINT *pdwBufferSize - the current buffer size
  816. EXIT: UINT *pdwBufferSize - the orginial buffer size minus
  817. the string size allocated during construction
  818. RETURNS: UINT - WN_SUCCESS for success. Failure otherwise
  819. HISTORY:
  820. terryk 05-Nov-91 Created
  821. ********************************************************************/
  822. UINT USE_ENUMNODE::GetNetResource( BYTE *pBuffer, UINT *pdwBufferSize)
  823. {
  824. APIERR err = GetLMProviderName ();
  825. if (err != WN_SUCCESS)
  826. return err;
  827. err = _dfsEnum.GetNetResource(pBuffer, (LPDWORD) pdwBufferSize);
  828. if (err != WN_NO_MORE_ENTRIES ) {
  829. return( err );
  830. }
  831. if ( QueryUsage() == RESOURCEUSAGE_CONTAINER )
  832. {
  833. // if it is CONTAINER, it cannot have used device
  834. return WN_NO_MORE_ENTRIES;
  835. }
  836. const USE1_ENUM_OBJ *pueo1 = NULL;
  837. for ( pueo1 = (*_pUseIter)(); pueo1 != NULL; pueo1 = (*_pUseIter)() )
  838. {
  839. UINT uiResourceType = pueo1->QueryResourceType();
  840. if ( ( QueryType() == RESOURCETYPE_ANY )
  841. //&& ( ( uiResourceType == USE_DISKDEV )
  842. // || ( uiResourceType == USE_SPOOLDEV)))
  843. || ( ( QueryType() & RESOURCETYPE_DISK )
  844. && ( uiResourceType == USE_DISKDEV ))
  845. || ( ( QueryType() & RESOURCETYPE_PRINT )
  846. && ( uiResourceType == USE_SPOOLDEV ))
  847. )
  848. {
  849. if ( ( pueo1->QueryRefCount() != 0 )
  850. || ( pueo1->QueryUseCount() != 0 )
  851. || (QueryType() == RESOURCETYPE_ANY)
  852. )
  853. {
  854. break;
  855. }
  856. }
  857. }
  858. if ( pueo1 == NULL )
  859. {
  860. return WN_NO_MORE_ENTRIES;
  861. }
  862. UINT cbMinBuffSize;
  863. BOOL fDeviceLess;
  864. if ( ( pueo1->QueryLocalDevice() != NULL )
  865. && ( ::strlenf( pueo1->QueryLocalDevice()) != 0 )
  866. )
  867. {
  868. cbMinBuffSize = sizeof( NETRESOURCE )+
  869. (::strlenf( pueo1->QueryLocalDevice()) +
  870. ::strlenf( pueo1->QueryRemoteResource()) +
  871. ::strlenf( pszNTLanMan ) + 3 )
  872. * sizeof( TCHAR ) ;
  873. fDeviceLess = FALSE;
  874. }
  875. else
  876. {
  877. cbMinBuffSize = sizeof( NETRESOURCE )+
  878. (::strlenf( pueo1->QueryRemoteResource()) +
  879. ::strlenf( pszNTLanMan ) + 2 )
  880. * sizeof( TCHAR ) ;
  881. fDeviceLess = TRUE;
  882. }
  883. if ( *pdwBufferSize < cbMinBuffSize )
  884. {
  885. *pdwBufferSize = cbMinBuffSize ;
  886. _pUseIter->Backup() ;
  887. return WN_MORE_DATA;
  888. }
  889. LPNETRESOURCE pNetResource = (LPNETRESOURCE) pBuffer;
  890. pNetResource->lpRemoteName = PackString((BYTE *) pNetResource,
  891. pdwBufferSize, pueo1->QueryRemoteResource());
  892. pNetResource->dwScope = RESOURCE_CONNECTED;
  893. pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_GENERIC;
  894. if (pueo1->QueryResourceType() == USE_DISKDEV)
  895. {
  896. pNetResource->dwType = RESOURCETYPE_DISK;
  897. pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
  898. }
  899. else if (pueo1->QueryResourceType() == USE_SPOOLDEV)
  900. {
  901. pNetResource->dwType = RESOURCETYPE_PRINT;
  902. pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
  903. }
  904. else
  905. {
  906. pNetResource->dwType = RESOURCETYPE_UNKNOWN;
  907. }
  908. if ( fDeviceLess )
  909. {
  910. pNetResource->lpLocalName = NULL;
  911. }
  912. else
  913. {
  914. pNetResource->lpLocalName = PackString((BYTE *)pNetResource,
  915. pdwBufferSize, pueo1->QueryLocalDevice());
  916. }
  917. /* Unfortunately we don't get the comment when we do a device
  918. * enumeration, so we will just set a null comment for now.
  919. */
  920. pNetResource->lpComment = NULL;
  921. pNetResource->lpProvider = PackString(( BYTE * ) pNetResource,
  922. pdwBufferSize, pszNTLanMan );
  923. pNetResource->dwUsage = 0;
  924. return WN_SUCCESS;
  925. }
  926. /*******************************************************************
  927. NAME: DOMAIN_ENUMNODE::DOMAIN_ENUMNODE
  928. SYNOPSIS: constructor
  929. ENTRY: UINT dwScope - the scope
  930. UINT dwType - type of the node
  931. UINT dwUsage - usage
  932. LPNETRESOURCE lpNetResource - pointer to the resource structure
  933. HISTORY:
  934. terryk 05-Nov-91 Created
  935. KeithMo 03-Aug-1992 Now uses new BROWSE_DOMAIN_ENUM
  936. whiz-bang domain enumerator.
  937. ********************************************************************/
  938. DOMAIN_ENUMNODE::DOMAIN_ENUMNODE( UINT dwScope, UINT dwType, UINT dwUsage,
  939. const LPNETRESOURCE lpNetResource )
  940. : NET_ENUMNODE( dwScope, dwType, dwUsage, lpNetResource ),
  941. _enumDomains( BROWSE_ALL_DOMAINS ),
  942. _pbdiNext( NULL )
  943. {
  944. APIERR err = QueryError();
  945. if( err == NERR_Success )
  946. {
  947. err = _enumDomains.QueryError();
  948. if( err != NERR_Success )
  949. {
  950. ReportError( err );
  951. }
  952. }
  953. }
  954. /*******************************************************************
  955. NAME: DOMAIN_ENUMNODE::GetInfo
  956. SYNOPSIS: Get the local domain info
  957. RETURNS: APIERR - NERR_Success for success. Failure otherwise.
  958. HISTORY:
  959. terryk 05-Nov-91 Created
  960. KeithMo 03-Aug-1992 Now uses new BROWSE_DOMAIN_ENUM
  961. whiz-bang domain enumerator.
  962. ********************************************************************/
  963. APIERR DOMAIN_ENUMNODE::GetInfo()
  964. {
  965. // We don't bother working around the browser design limitation
  966. // in this case
  967. SetFirstTime();
  968. return NERR_Success;
  969. }
  970. /*******************************************************************
  971. NAME: DOMAIN_ENUMNODE::GetNetResource
  972. SYNOPSIS: construct a NetResource data object and store it in the
  973. buffer
  974. ENTRY: BYTE *pBuffer - beginning of the buffer
  975. UINT *pdwBufferSize - the current buffer size
  976. EXIT: UINT *pdwBufferSize - the orginial buffer size minus
  977. the string size allocated during construction
  978. RETURNS: UINT - WN_SUCCESS for success. Failure otherwise
  979. HISTORY:
  980. terryk 05-Nov-91 Created
  981. KeithMo 03-Aug-1992 Now uses new BROWSE_DOMAIN_ENUM
  982. whiz-bang domain enumerator.
  983. ********************************************************************/
  984. UINT DOMAIN_ENUMNODE::GetNetResource( BYTE *pBuffer, UINT *pdwBufferSize)
  985. {
  986. APIERR err = GetLMProviderName ();
  987. if (err != WN_SUCCESS)
  988. return err;
  989. //
  990. // Let's see if there are any more domains in the enumerator.
  991. //
  992. if( _pbdiNext == NULL )
  993. {
  994. _pbdiNext = _enumDomains.Next();
  995. if( _pbdiNext == NULL )
  996. {
  997. return WN_NO_MORE_ENTRIES;
  998. }
  999. }
  1000. //
  1001. // Calculate the minimum buffer requirements.
  1002. //
  1003. UINT cbMinBuffSize = sizeof( NETRESOURCE) +
  1004. ( ::strlenf( _pbdiNext->QueryDomainName() ) +
  1005. ::strlenf( pszNTLanMan ) + 2 ) * sizeof(TCHAR);
  1006. if( *pdwBufferSize < cbMinBuffSize )
  1007. {
  1008. *pdwBufferSize = cbMinBuffSize;
  1009. return WN_MORE_DATA;
  1010. }
  1011. //
  1012. // Save the data for the current domain.
  1013. //
  1014. LPNETRESOURCE pNetRes = (LPNETRESOURCE)pBuffer;
  1015. pNetRes->lpRemoteName = PackString( (BYTE *)pNetRes,
  1016. pdwBufferSize,
  1017. _pbdiNext->QueryDomainName() );
  1018. pNetRes->lpComment = NULL;
  1019. pNetRes->lpLocalName = NULL;
  1020. pNetRes->dwScope = RESOURCE_GLOBALNET;
  1021. pNetRes->dwType = 0;
  1022. pNetRes->dwDisplayType = RESOURCEDISPLAYTYPE_DOMAIN;
  1023. pNetRes->dwUsage = RESOURCEUSAGE_CONTAINER;
  1024. pNetRes->lpProvider = PackString( (BYTE *)pNetRes,
  1025. pdwBufferSize,
  1026. pszNTLanMan );
  1027. _pbdiNext = NULL;
  1028. //
  1029. // Success!
  1030. //
  1031. return WN_SUCCESS;
  1032. }
  1033. /*******************************************************************
  1034. NAME: EMPTY_ENUMNODE::EMPTY_ENUMNODE
  1035. SYNOPSIS: constructor
  1036. ENTRY: UINT dwScope - the scope
  1037. UINT dwType - type of the node
  1038. UINT dwUsage - usage
  1039. LPNETRESOURCE lpNetResource - pointer to the resource structure
  1040. NOTE: lpNetResource must not be NULL
  1041. HISTORY:
  1042. chuckc 01-Aug-92 Created
  1043. ********************************************************************/
  1044. EMPTY_ENUMNODE::EMPTY_ENUMNODE( UINT dwScope, UINT dwType, UINT
  1045. dwUsage, const LPNETRESOURCE lpNetResource )
  1046. : NET_ENUMNODE( dwScope, dwType, dwUsage, lpNetResource )
  1047. {
  1048. }
  1049. /*******************************************************************
  1050. NAME: EMPTY_ENUMNODE::~EMPTY_ENUMNODE
  1051. SYNOPSIS: destructor
  1052. HISTORY:
  1053. chuckc 01-Aug-92 Created
  1054. ********************************************************************/
  1055. EMPTY_ENUMNODE::~EMPTY_ENUMNODE()
  1056. {
  1057. }
  1058. /*******************************************************************
  1059. NAME: EMPTY_ENUMNODE::GetInfo
  1060. SYNOPSIS: Get the Share enum info and create the share enum
  1061. interator
  1062. RETURNS: APIERR - NERR_Success for success. Failure otherwise.
  1063. HISTORY:
  1064. chuckc 01-Aug-92 Created
  1065. ********************************************************************/
  1066. APIERR EMPTY_ENUMNODE::GetInfo()
  1067. {
  1068. SetFirstTime();
  1069. return NERR_Success;
  1070. }
  1071. /*******************************************************************
  1072. NAME: EMPTY_ENUMNODE::GetNetResource
  1073. SYNOPSIS: construct a NetResource data object and store it in the
  1074. buffer
  1075. ENTRY: BYTE *pBuffer - beginning of the buffer
  1076. UINT *pdwBufferSize - the current buffer size
  1077. EXIT: UINT *pdwBufferSize - the orginial buffer size minus
  1078. the string size allocated during construction
  1079. RETURNS: APIERR - WN_SUCCESS for success. Failure otherwise
  1080. HISTORY:
  1081. chuckc 01-Aug-92 Created
  1082. ********************************************************************/
  1083. UINT EMPTY_ENUMNODE::GetNetResource( BYTE *pBuffer, UINT *pdwBufferSize)
  1084. {
  1085. UNREFERENCED( pBuffer ) ;
  1086. UNREFERENCED( pdwBufferSize ) ;
  1087. return WN_NO_MORE_ENTRIES;
  1088. }