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.

1304 lines
26 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 1999
  3. All rights reserved.
  4. Module Name:
  5. prtshare.cxx
  6. Abstract:
  7. Printer Share class
  8. Author:
  9. Steve Kiraly (SteveKi) 17-Mar-1996
  10. Revision History:
  11. --*/
  12. #include "precomp.hxx"
  13. #pragma hdrstop
  14. #include "prtshare.hxx"
  15. #include "persist.hxx"
  16. /********************************************************************
  17. Class statics.
  18. ********************************************************************/
  19. LPCTSTR TPrtShare::_gszIllegalDosChars = TEXT( " *?/\\|,;:+=<>[]\"" );
  20. LPCTSTR TPrtShare::_gszIllegalNtChars = TEXT( ",\\/" );
  21. /*++
  22. Routine Name:
  23. PrtShare constructor
  24. Routine Description:
  25. Initializes the printer share object.
  26. Arguments:
  27. Pointer to the print server name to build a
  28. share enumeration for.
  29. Return Value:
  30. Nothing.
  31. --*/
  32. TPrtShare::
  33. TPrtShare(
  34. IN LPCTSTR pszServerName
  35. ) : _PrtPrinter( pszServerName ),
  36. _pNetResBuf( NULL ),
  37. _dwNetResCount( 0 ),
  38. _strServerName( pszServerName ),
  39. _bValid( FALSE ),
  40. _pfNetShareEnum( NULL ),
  41. _pfNetApiBufferFree( NULL ),
  42. _pLibrary( NULL )
  43. {
  44. DBGMSG( DBG_TRACE, ( "TPrtShare::ctor.\n" ) );
  45. //
  46. // Check if members were constructed successfuly.
  47. //
  48. if( _strServerName.bValid() &&
  49. _PrtPrinter.bValid() &&
  50. bLoad() &&
  51. bGetEnumData() ){
  52. _bValid = TRUE;
  53. }
  54. //
  55. // Dump debug information.
  56. //
  57. #if DBG
  58. if( _bValid ){
  59. vPrint();
  60. }
  61. #endif
  62. }
  63. /*++
  64. Routine Name:
  65. PrtShare destructor.
  66. Routine Description:
  67. Releases resources owned by this class.
  68. Arguments:
  69. None.
  70. Return Value:
  71. Nothing.
  72. --*/
  73. TPrtShare::
  74. ~TPrtShare(
  75. VOID
  76. )
  77. {
  78. DBGMSG( DBG_TRACE, ( "TPrtShare::dtor.\n" ) );
  79. vDestroy();
  80. vUnload();
  81. }
  82. /*++
  83. Routine Name:
  84. bValid
  85. Routine Description:
  86. Indicates if the object is in a valid state.
  87. Arguments:
  88. Nothing.
  89. Return Value:
  90. TRUE object is valid, FALSE object is not valid.
  91. --*/
  92. TPrtShare::
  93. bValid(
  94. VOID
  95. ) const
  96. {
  97. DBGMSG( DBG_TRACE, ( "TPrtShare::bValid.\n" ) );
  98. return _bValid;
  99. }
  100. /*++
  101. Routine Name:
  102. bIsValidShareNameForThisPrinter
  103. Routine Description:
  104. Indicates if the specified share name is valid for the specified
  105. share name provided as the first argument. If the printer name is
  106. not provided then this routine returns an indication if the name is
  107. unique.
  108. Arguments:
  109. pszShareName - Pointer to new share name.
  110. pszPrinterName - Printer name to check against.
  111. Return Value:
  112. TRUE if name is a usable sharen name for this printer.
  113. FALSE if error occurred.
  114. --*/
  115. BOOL
  116. TPrtShare::
  117. bIsValidShareNameForThisPrinter(
  118. IN LPCTSTR pszShareName,
  119. IN LPCTSTR pszPrinterName
  120. ) const
  121. {
  122. DBGMSG( DBG_TRACE, ( "TPrtShare::bIsValidShareNameForThisPrinter.\n" ) );
  123. //
  124. // Ensure we are in a valid state.
  125. //
  126. SPLASSERT( bValid() );
  127. SPLASSERT( pszShareName );
  128. SPLASSERT( pszPrinterName );
  129. BOOL bStatus;
  130. //
  131. // Check if the share name is currently in use.
  132. //
  133. bStatus = !bIsShareNameUsedW( pszShareName );
  134. //
  135. // If we failed to find a match from the network shares.
  136. // Check for printer name matches, since they are exist in
  137. // the same namespace.
  138. //
  139. if( bStatus ){
  140. bStatus = _PrtPrinter.bIsValidShareNameForThisPrinter( pszShareName,
  141. pszPrinterName );
  142. }
  143. return bStatus;
  144. }
  145. /*++
  146. Routine Name:
  147. bRefresh
  148. Routine Description:
  149. Will refresh the share enumeration structure.
  150. Arguments:
  151. None.
  152. Return Value:
  153. TRUE if enumeration was refreshed and object is still valid,
  154. FALSE if error occurred.
  155. --*/
  156. BOOL
  157. TPrtShare::
  158. bRefresh(
  159. VOID
  160. )
  161. {
  162. DBGMSG( DBG_TRACE, ( "TPrtShare::bRefresh\n" ) );
  163. //
  164. // Ensure we are in a valid state.
  165. //
  166. SPLASSERT( bValid() );
  167. //
  168. // Release the current resources.
  169. //
  170. vDestroy();
  171. //
  172. // Refresh the share names and the printer names.
  173. //
  174. _bValid = bGetEnumData() && _PrtPrinter.bRefresh();
  175. return _bValid;
  176. }
  177. /*++
  178. Routine Name:
  179. bNewShareName
  180. Routine Description:
  181. Creates a new share name from the given name.
  182. Arguments:
  183. Place where to return the new share name.
  184. Base share name to create new name from.
  185. Return Value:
  186. TRUE new unique share name returned, FALSE error occurred.
  187. --*/
  188. BOOL
  189. TPrtShare::
  190. bNewShareName(
  191. IN TString &strShareName,
  192. IN const TString &strBaseShareName
  193. ) const
  194. {
  195. DBGMSG( DBG_TRACE, ( "TPrtShare::bNewShareName\n" ) );
  196. //
  197. // Ensure we are in a valid state.
  198. //
  199. SPLASSERT( bValid() );
  200. UINT i;
  201. BOOL bStatus = FALSE;
  202. TCHAR szTempShareName[kPrinterShareNameBufMax];
  203. TCHAR szShareName[kPrinterShareNameBufMax];
  204. PTSTR pDst = szTempShareName;
  205. PTSTR pSrc = (LPTSTR)(LPCTSTR)strBaseShareName;
  206. //
  207. // Truncate the base name and filter illegal characters.
  208. //
  209. for( i = 0; i < 8 && *pSrc; i++, pSrc++ ){
  210. //
  211. // Replace illegal characters with underscore.
  212. //
  213. if( _tcschr( _gszIllegalDosChars, *pSrc ) ){
  214. i--; // Collapse spaces.
  215. } else {
  216. *pDst++ = *pSrc;
  217. }
  218. }
  219. //
  220. // Null terminate.
  221. //
  222. *pDst = 0;
  223. //
  224. // If the share name does not have length then
  225. // get the default printer share name.
  226. //
  227. if( !_tcslen( szTempShareName ) ){
  228. bStatus = LoadString( ghInst,
  229. IDS_DEFAULT_SHARE,
  230. szTempShareName,
  231. COUNTOF( szTempShareName ) - 1 );
  232. if( !bStatus ){
  233. DBGMSG( DBG_WARN, ( "Unable loaded default share name resource.\n" ) );
  234. szTempShareName[0] = 0;
  235. }
  236. }
  237. //
  238. // Copy share name from temp buffer.
  239. //
  240. StringCchCopy( szShareName, ARRAYSIZE(szShareName), szTempShareName );
  241. //
  242. // Generate a share name until it is unique.
  243. //
  244. for( i = 2; i < 1000; i++ ){
  245. //
  246. // If unique name has been found.
  247. //
  248. if( bIsValidShareNameForThisPrinter( szShareName,
  249. strBaseShareName ) ){
  250. break;
  251. }
  252. //
  253. // Build formated share name.
  254. //
  255. StringCchPrintf( szShareName, ARRAYSIZE(szShareName), TEXT( "%s.%d" ), szTempShareName, i );
  256. }
  257. //
  258. // Copy back the share name.
  259. //
  260. bStatus = strShareName.bUpdate( szShareName );
  261. return bStatus;
  262. }
  263. /*++
  264. Routine Name:
  265. iIsValidDosShare(
  266. Routine Description:
  267. Indicates the spcified share name is valid.
  268. Arguments:
  269. Point to share name to check.
  270. Return Value:
  271. Status indicates the validity of the share name.
  272. kSuccess - share name is valid.
  273. kInvalidLength - share name is too long,
  274. kInvalidChar - share name has invalid characters.
  275. kInvalidDosFormat - share name does not conform to dos file name.
  276. --*/
  277. INT
  278. TPrtShare::
  279. iIsValidDosShare(
  280. IN LPCTSTR pszShareName
  281. ) const
  282. {
  283. DBGMSG( DBG_TRACE, ( "TPrtShare::iIsValidDosShare\n" ) );
  284. //
  285. // Ensure we are in a valid state.
  286. //
  287. SPLASSERT( bValid() );
  288. INT iStatus = kInvalidLength;
  289. INT iExtLen = 0;
  290. INT iExtInc = 0;
  291. INT iMbsLen = 0;
  292. BOOL bDotFound = FALSE;
  293. //
  294. // Check the share name pointer.
  295. //
  296. if( pszShareName ){
  297. //
  298. // Scan for any illegal characters.
  299. //
  300. iStatus = kSuccess;
  301. for( UINT i = 0; *pszShareName; pszShareName++, i++ ){
  302. //
  303. // Count the DOS char length for each character. For ASCII char, the
  304. // DOS char length is 1; for most DBCS chars, the DOS char length is 2.
  305. //
  306. UINT ichLen = _mbstrlen( reinterpret_cast<const char *>(pszShareName) );
  307. if( ichLen > sizeof(TCHAR) ) {
  308. ichLen = sizeof(TCHAR);
  309. }
  310. //
  311. // Check if the extenstion length is greater than three.
  312. //
  313. if( iExtInc ) {
  314. iExtLen += ichLen;
  315. if( iExtLen > 3 ) {
  316. iStatus = kInvalidDosFormat;
  317. break;
  318. }
  319. }
  320. //
  321. // Check the share name length
  322. //
  323. iMbsLen += ichLen;
  324. if( iMbsLen > kPrinterDosShareNameMax ) {
  325. iStatus = kInvalidLength;
  326. break;
  327. }
  328. //
  329. // If an illegal character found.
  330. //
  331. if( _tcschr( _gszIllegalDosChars, *pszShareName ) ){
  332. iStatus = kInvalidChar;
  333. break;
  334. }
  335. //
  336. // Check for the dot.
  337. //
  338. if( *pszShareName == TEXT( '.' ) ){
  339. //
  340. // We exclude leading dots
  341. //
  342. if( i == 0 ){
  343. iStatus = kInvalidDosFormat;
  344. break;
  345. }
  346. //
  347. // If a second dot found, indicate failure.
  348. //
  349. if( bDotFound ){
  350. iStatus = kInvalidDosFormat;
  351. break;
  352. }
  353. //
  354. // Indicate dot found.
  355. // Set extension count.
  356. //
  357. bDotFound = TRUE;
  358. iExtInc = 1;
  359. }
  360. }
  361. }
  362. return iStatus;
  363. }
  364. /*++
  365. Routine Name:
  366. iIsValidNtShare(
  367. Routine Description:
  368. Indicates the spcified share name is valid.
  369. Arguments:
  370. Point to share name to check.
  371. Return Value:
  372. Status indicates the validity of the share name.
  373. kSuccess - share name is valid.
  374. kInvalidLength - share name is too long,
  375. kInvalidChar - share name has invalid characters.
  376. --*/
  377. INT
  378. TPrtShare::
  379. iIsValidNtShare(
  380. IN LPCTSTR pszShareName
  381. ) const
  382. {
  383. DBGMSG( DBG_TRACE, ( "TPrtShare::iIsValidNtShare\n" ) );
  384. //
  385. // Ensure we are in a valid state.
  386. //
  387. SPLASSERT( bValid() );
  388. INT iStatus = kInvalidLength;
  389. //
  390. // Check the share name pointer.
  391. //
  392. if( pszShareName ){
  393. //
  394. // Scan for any illegal characters.
  395. //
  396. iStatus = kSuccess;
  397. for( UINT i = 0 ; *pszShareName; pszShareName++, i++ ){
  398. //
  399. // If an illegal character found.
  400. //
  401. if( _tcschr( _gszIllegalNtChars, *pszShareName ) ){
  402. iStatus = kInvalidChar;
  403. break;
  404. //
  405. // If the share name is too long.
  406. //
  407. } else if( i >= kPrinterShareNameBufMax ){
  408. iStatus = kInvalidLength;
  409. break;
  410. }
  411. }
  412. }
  413. return iStatus;
  414. }
  415. /*++
  416. Routine Name:
  417. bNetworkInstalled.
  418. Routine Description:
  419. Checks if the network has been installed and functional.
  420. Arguments:
  421. Nothing.
  422. Return Value:
  423. TRUE network is installed, FALSE if network is not installed.
  424. --*/
  425. BOOL
  426. TPrtShare::
  427. bNetworkInstalled(
  428. VOID
  429. )
  430. {
  431. BOOL bNetwork = FALSE;
  432. TPersist Persist( gszNetworkProvider, TPersist::kOpen|TPersist::kRead, HKEY_LOCAL_MACHINE );
  433. if( VALID_OBJ( Persist ) )
  434. {
  435. TStatusB bStatus;
  436. TString strProvider;
  437. bStatus DBGCHK = Persist.bRead( gszProviderOrder, strProvider );
  438. DBGMSG( DBG_TRACE, ("Network Provider order " TSTR "\n", (LPCTSTR)strProvider ) );
  439. if( bStatus && strProvider.uLen() > 1 )
  440. {
  441. bNetwork = TRUE;
  442. }
  443. }
  444. return bNetwork;
  445. }
  446. #if DBG
  447. /*++
  448. Routine Name:
  449. vPrint
  450. Routine Description:
  451. Displays the net resource structure.
  452. Arguments:
  453. Nothing.
  454. Return Value:
  455. Nothing.
  456. --*/
  457. VOID
  458. TPrtShare::
  459. vPrint(
  460. VOID
  461. ) const
  462. {
  463. DBGMSG( DBG_TRACE, ( "TPrtShare::vPrint\n" ) );
  464. PSHARE_INFO_0 pShare = (PSHARE_INFO_0)_pNetResBuf;
  465. for( UINT i = 0; i < _dwNetResCount; i++ ){
  466. DBGMSG( DBG_TRACE, ( "Share name %ws\n", pShare[i].shi0_netname ) );
  467. }
  468. _PrtPrinter.vPrint();
  469. }
  470. #endif
  471. /********************************************************************
  472. Private member functions.
  473. ********************************************************************/
  474. /*++
  475. Routine Name:
  476. bIsShareNameUsed
  477. Routine Description:
  478. Checks if the specified share name is in use.
  479. Arguments:
  480. pszShareName - share name to check.
  481. Return Value:
  482. TRUE the specified share name is used.
  483. FALSE share name is not currently used.
  484. --*/
  485. BOOL
  486. TPrtShare::
  487. bIsShareNameUsedW(
  488. IN PCWSTR pszShareName
  489. ) const
  490. {
  491. DBGMSG( DBG_TRACE, ( "TPrtShare::bIsShareNameUsedW\n" ) );
  492. PSHARE_INFO_0 pShare = (PSHARE_INFO_0)_pNetResBuf;
  493. for( UINT i = 0; i < _dwNetResCount; i++ ){
  494. //
  495. // Compare the share names case is ignored.
  496. //
  497. if(!_wcsicmp( pszShareName, (PCWSTR)pShare[i].shi0_netname ) ){
  498. return TRUE;
  499. }
  500. }
  501. return FALSE;
  502. }
  503. /*++
  504. Routine Name:
  505. bGetEnumData
  506. Routine Description:
  507. Retrieve the shared resources.
  508. Arguments:
  509. Nothing.
  510. Return Value:
  511. TRUE the share name resources fetched successfuly.
  512. FALSE error occured and data is not available.
  513. --*/
  514. BOOL
  515. TPrtShare::
  516. bGetEnumData(
  517. VOID
  518. )
  519. {
  520. DBGMSG( DBG_TRACE, ( "TPrtShare::bGetEnumData.\n" ) );
  521. BOOL bStatus = TRUE;
  522. LPCTSTR pszServerName = NULL;
  523. TString strMachineName;
  524. //
  525. // If the server name is empty then use the local machine name.
  526. //
  527. if( _strServerName.bEmpty() && bGetMachineName( strMachineName ) ){
  528. pszServerName = (LPTSTR)(LPCTSTR)strMachineName;
  529. } else {
  530. pszServerName = (LPTSTR)(LPCTSTR)_strServerName;
  531. }
  532. DBGMSG( DBG_TRACE, ( "Enumerating shares for " TSTR "\n", DBGSTR( pszServerName ) ) );
  533. //
  534. // We sould never get here with a null function pointer.
  535. //
  536. SPLASSERT( _pfNetShareEnum );
  537. //
  538. // Enumerate all the shares.
  539. //
  540. DWORD dwEntriesRead = 0;
  541. DWORD dwTotalEntries = 0;
  542. DWORD dwError = _pfNetShareEnum(
  543. (LPTSTR)pszServerName, // Server Name
  544. 0,
  545. &_pNetResBuf,
  546. 0xffffffff, // no buffer limit; get them all!
  547. &dwEntriesRead,
  548. &dwTotalEntries,
  549. NULL); // no resume handle 'cause we're getting all
  550. if( dwError != NERR_Success){
  551. //
  552. // Just in case NetShareEnum munged it
  553. //
  554. _pNetResBuf = NULL;
  555. _dwNetResCount = 0;
  556. DBGMSG( DBG_WARN, ( "Error enumerating shares: %x with %d\n", dwError, GetLastError() ) );
  557. } else {
  558. //
  559. // Check if we read partial data.
  560. //
  561. SPLASSERT( dwEntriesRead == dwTotalEntries );
  562. //
  563. // Set network share resource count.
  564. //
  565. _dwNetResCount = dwEntriesRead;
  566. }
  567. return bStatus;
  568. }
  569. /*++
  570. vDestroy
  571. Routine Description:
  572. Destroys this class and any allocated resources.
  573. Arguments:
  574. None.
  575. Return Value:
  576. Nothing.
  577. --*/
  578. VOID
  579. TPrtShare::
  580. vDestroy(
  581. VOID
  582. )
  583. {
  584. DBGMSG( DBG_TRACE, ( "TPrtShare::vDestroy.\n" ) );
  585. if( _pfNetApiBufferFree ){
  586. _pfNetApiBufferFree( _pNetResBuf );
  587. }
  588. _pNetResBuf = NULL;
  589. _dwNetResCount = 0;
  590. }
  591. /*++
  592. bLoad
  593. Routine Description:
  594. Loads the library initializes all procedure addresses
  595. Arguments:
  596. None.
  597. Return Value:
  598. TRUE library loaded and usable, FALSE if error occurred.
  599. --*/
  600. BOOL
  601. TPrtShare::
  602. bLoad(
  603. VOID
  604. )
  605. {
  606. DBGMSG( DBG_TRACE, ( "TPrtShare::bLoad.\n" ) );
  607. BOOL bStatus = FALSE;
  608. //
  609. // If the library is not loaded then load it.
  610. //
  611. if( !_pLibrary ){
  612. //
  613. // Load the library.
  614. //
  615. _pLibrary = new TLibrary( TEXT( NETAPI32_LIB ) );
  616. //
  617. // If library is load is in a constant state.
  618. //
  619. if( VALID_PTR( _pLibrary ) ){
  620. _pfNetShareEnum = (PF_NETSHAREENUM) _pLibrary->pfnGetProc( NETSHAREENUM );
  621. _pfNetApiBufferFree = (PF_NETAPIBUFFERFREE) _pLibrary->pfnGetProc( NETAPIBUFFERFREE );
  622. //
  623. // Ensure all the procedure address were initialized.
  624. //
  625. if( _pfNetShareEnum &&
  626. _pfNetApiBufferFree ){
  627. bStatus = TRUE;
  628. } else {
  629. DBGMSG( DBG_WARN, ( "TPrtShare::Failed fetching proc address.\n" ) );
  630. }
  631. }
  632. //
  633. // If something failed return to a consistent state.
  634. //
  635. if( !bStatus ){
  636. vUnload();
  637. }
  638. //
  639. // Return true the library is already loaded.
  640. //
  641. } else {
  642. bStatus = TRUE;
  643. }
  644. return bStatus;
  645. }
  646. /*++
  647. vUnload
  648. Routine Description:
  649. Unloads the library and release any procedure address
  650. Arguments:
  651. None.
  652. Return Value:
  653. Nothing.
  654. --*/
  655. VOID
  656. TPrtShare::
  657. vUnload(
  658. VOID
  659. )
  660. {
  661. DBGMSG( DBG_TRACE, ( "TPrtShare::vUnload.\n" ) );
  662. delete _pLibrary;
  663. _pLibrary = NULL;
  664. _pfNetShareEnum = NULL;
  665. _pfNetApiBufferFree = NULL;
  666. }
  667. /********************************************************************
  668. Printer and Shares exist in the same name space. To check for
  669. a valid printer share name we must look at all the existing
  670. printers.
  671. ********************************************************************/
  672. /*++
  673. TPrtPrinter
  674. Routine Description:
  675. Shared Printer constructor.
  676. Arguments:
  677. Pointer to server name to check.
  678. Return Value:
  679. Nothing.
  680. --*/
  681. TPrtPrinter::
  682. TPrtPrinter(
  683. IN LPCTSTR pszServerName
  684. ) : _bValid( FALSE ),
  685. _pPrinterInfo2( NULL ),
  686. _cPrinterInfo2( 0 )
  687. {
  688. DBGMSG( DBG_TRACE, ( "TPrtPrinter::ctor.\n" ) );
  689. TStatusB bStatus;
  690. //
  691. // Update the server name and gather the
  692. // printer enumeration data.
  693. //
  694. bStatus DBGCHK = _strServerName.bUpdate( pszServerName ) &&
  695. bGetEnumData();
  696. //
  697. // Set valid class indication.
  698. //
  699. _bValid = bStatus;
  700. }
  701. /*++
  702. TPrtPrinter
  703. Routine Description:
  704. Shared Printer destructor.
  705. Arguments:
  706. None.
  707. Return Value:
  708. Nothing.
  709. --*/
  710. TPrtPrinter::
  711. ~TPrtPrinter(
  712. VOID
  713. )
  714. {
  715. DBGMSG( DBG_TRACE, ( "TPrtPrinter::dtor.\n" ) );
  716. FreeMem( _pPrinterInfo2 );
  717. }
  718. /*++
  719. Routine Name:
  720. bValid
  721. Routine Description:
  722. Indicates if the object is in a valid state.
  723. Arguments:
  724. None.
  725. Return Value:
  726. TRUE object is valid, FALSE object is not valid.
  727. --*/
  728. BOOL
  729. TPrtPrinter::
  730. bValid(
  731. VOID
  732. ) const
  733. {
  734. DBGMSG( DBG_TRACE, ( "TPrtPrinter::bValid.\n" ) );
  735. return _bValid;
  736. }
  737. /*++
  738. Routine Name:
  739. bRefresh
  740. Routine Description:
  741. Updates the printer enumeration with the system.
  742. Arguments:
  743. Nothing.
  744. Return Value:
  745. TRUE updated was successful, FALSE if error occurred.
  746. --*/
  747. BOOL
  748. TPrtPrinter::
  749. bRefresh(
  750. VOID
  751. )
  752. {
  753. DBGMSG( DBG_TRACE, ( "TPrtPrinter::bRefresh.\n" ) );
  754. //
  755. // Ensure we are in a valid state.
  756. //
  757. SPLASSERT( bValid() );
  758. //
  759. // Refresh the printer enumeration data.
  760. //
  761. _bValid = bGetEnumData();
  762. return _bValid;
  763. }
  764. /*++
  765. Routine Name:
  766. bIsValidShareNameForThisPrinter
  767. Routine Description:
  768. Indicates if the specified share name is valid for the specified
  769. share name provided as the first argument. If the printer name is
  770. not provided then this routine returns an indication if the name is
  771. unique.
  772. Arguments:
  773. pszShareName - Printer share name to check.
  774. pszPrinterName - Printer name to check against.
  775. Return Value:
  776. TRUE if name is a usable sharen name for this printer.
  777. FALSE if error occurred.
  778. --*/
  779. BOOL
  780. TPrtPrinter::
  781. bIsValidShareNameForThisPrinter(
  782. IN LPCTSTR pszShareName,
  783. IN LPCTSTR pszPrinterName
  784. ) const
  785. {
  786. DBGMSG( DBG_TRACE, ( "TPrtPrinter::bIsValidShareNameForThisPrinter.\n" ) );
  787. BOOL bStatus = TRUE;
  788. //
  789. // Ensure we are in a valid state.
  790. //
  791. SPLASSERT( bValid() );
  792. SPLASSERT( pszShareName );
  793. //
  794. // Traverse all the enumerated shares.
  795. //
  796. for( UINT i = 0; i < _cPrinterInfo2; i++ ){
  797. //
  798. // If nobody has access to this printer then spooler doesn't really share
  799. // the printer out even if it has the shared bit up and eating up a name in
  800. // the namespace, so we need to do an additionbal check here to make sure
  801. // the proposed share name doesn't collide with an existing printer share name.
  802. //
  803. if( _pPrinterInfo2[i].pShareName && !_tcsicmp( pszShareName, _pPrinterInfo2[i].pShareName ) ){
  804. bStatus = FALSE;
  805. break;
  806. }
  807. LPCTSTR pszServer;
  808. LPCTSTR pszPrinter;
  809. TCHAR szScratch[kPrinterBufMax];
  810. //
  811. // Split the printer name into its components.
  812. //
  813. vPrinterSplitFullName( szScratch,
  814. ARRAYSIZE(szScratch),
  815. _pPrinterInfo2[i].pPrinterName,
  816. &pszServer,
  817. &pszPrinter );
  818. //
  819. // If the share name is a fully qualified name then use the fully
  820. // qualified printer name.
  821. //
  822. if( pszShareName[0] == TEXT( '\\' ) &&
  823. pszShareName[1] == TEXT( '\\' ) ){
  824. pszPrinter = _pPrinterInfo2[i].pPrinterName;
  825. }
  826. //
  827. // Compare the share name to the printer name.
  828. //
  829. if( !_tcsicmp( pszShareName, pszPrinter ) ){
  830. bStatus = FALSE;
  831. break;
  832. }
  833. }
  834. //
  835. // If the share name is not unique check if happens to be the
  836. // same as the printer name. It's ok for the printer name
  837. // and the share name to be the same. The spooler allows this.
  838. //
  839. if( !bStatus && pszPrinterName ){
  840. LPCTSTR pszServer;
  841. LPCTSTR pszPrinter;
  842. TCHAR szScratch[kPrinterBufMax];
  843. //
  844. // Split the printer name into its components.
  845. //
  846. vPrinterSplitFullName( szScratch,
  847. ARRAYSIZE(szScratch),
  848. pszPrinterName,
  849. &pszServer,
  850. &pszPrinter );
  851. //
  852. // If the share name is a fully qualified name then use the fully
  853. // qualified printer name.
  854. //
  855. if( pszShareName[0] == TEXT( '\\' ) &&
  856. pszShareName[1] == TEXT( '\\' ) ){
  857. pszPrinter = pszPrinterName;
  858. }
  859. DBGMSG( DBG_TRACE, ( "Comparing like share " TSTR " with printer " TSTR "\n",
  860. pszShareName, DBGSTR( pszPrinter ) ) );
  861. //
  862. // Check if the printer name matches the share name
  863. //
  864. if( !_tcsicmp( pszShareName, pszPrinter ) ){
  865. DBGMSG( DBG_TRACE, ("The printer name matches the share name.\n") );
  866. bStatus = TRUE;
  867. }
  868. }
  869. return bStatus;
  870. }
  871. /*++
  872. Routine Name:
  873. bGetEnumData
  874. Routine Description:
  875. Fetches the printer enumeration data.
  876. Arguments:
  877. None.
  878. Return Value:
  879. TRUE enumeration data fetched, FALSE if error occurred.
  880. --*/
  881. BOOL
  882. TPrtPrinter::
  883. bGetEnumData(
  884. VOID
  885. )
  886. {
  887. DBGMSG( DBG_TRACE, ( "TPrtPrinter::bGetEnumData.\n" ) );
  888. //
  889. // Release any previously allocated structure.
  890. //
  891. FreeMem( _pPrinterInfo2 );
  892. //
  893. // Reset the variables.
  894. //
  895. _pPrinterInfo2 = NULL;
  896. _cPrinterInfo2 = 0;
  897. DWORD cbPrinterInfo2 = 0;
  898. //
  899. // Enumerate the current printers.
  900. //
  901. TStatusB bEnumStatus;
  902. bEnumStatus DBGCHK = VDataRefresh::bEnumPrinters(
  903. PRINTER_ENUM_NAME,
  904. (LPTSTR)(LPCTSTR)_strServerName,
  905. 2,
  906. (PVOID *)&_pPrinterInfo2,
  907. &cbPrinterInfo2,
  908. &_cPrinterInfo2 );
  909. return bEnumStatus;
  910. }
  911. #if DBG
  912. /*++
  913. Routine Name:
  914. vPrint
  915. Routine Description:
  916. Prints the printer enumeration data.
  917. Arguments:
  918. None.
  919. Return Value:
  920. Nothing.
  921. --*/
  922. VOID
  923. TPrtPrinter::
  924. vPrint(
  925. VOID
  926. ) const
  927. {
  928. DBGMSG( DBG_TRACE, ( "TPrtPrinter::vPrint.\n" ) );
  929. SPLASSERT( bValid() );
  930. DBGMSG( DBG_TRACE, ( "_pPrinterInfo2 %x.\n", _pPrinterInfo2 ) );
  931. DBGMSG( DBG_TRACE, ( "_cPrinterInfo2 %d\n", _cPrinterInfo2 ) );
  932. for( UINT i = 0; i < _cPrinterInfo2; i++ ){
  933. DBGMSG( DBG_TRACE, ( "PrinterInfo2.pPrinterName " TSTR "\n", _pPrinterInfo2[i].pPrinterName ) );
  934. }
  935. }
  936. #endif