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.

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