Esempio n. 1
0
// Printer::EventHandler implementation
OSStatus
CSecondPage::OnAddPrinter(
				uint32_t		inInterfaceIndex,
				const char *	inName,	
				const char *	inType,	
				const char *	inDomain,
				bool			moreComing)
{
	Printer						*	printer;
	Service						*	service;
	CPrinterSetupWizardSheet	*	psheet;
	DWORD							printerNameCount;
	bool							newPrinter = false;
	OSStatus						err = kNoErr;

	check( IsWindow( m_hWnd ) );

	m_browseList.SetRedraw(FALSE);

	psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
	require_quiet( psheet, exit );

	printer = Lookup( inName );

	if (printer == NULL)
	{
		try
		{
			printer = new Printer;
		}
		catch (...)
		{
			printer = NULL;
		}

		require_action( printer, exit, err = E_OUTOFMEMORY );

		printer->window		=	this;
		printer->name		=	inName;
		
		err = UTF8StringToStringObject(inName, printer->displayName);
		check_noerr( err );
		printer->actualName	=	printer->displayName;
		printer->installed	=	false;
		printer->deflt		=	false;
		printer->resolving	=	0;

		//
		// Compare this name against printers that are already installed
		// to avoid name clashes.  Rename as necessary
		// to come up with a unique name.
		//
		printerNameCount = 2;

		for (;;)
		{
			PrinterNameMap::iterator it;

			it = m_printerNames.find(printer->actualName);

			if (it != m_printerNames.end())
			{
				printer->actualName.Format(L"%s (%d)", printer->displayName, printerNameCount);
			}
			else
			{
				break;
			}

			printerNameCount++;
		}

		newPrinter = true;
	}

	check( printer );

	service = printer->LookupService( inType );

	if ( service != NULL )
	{
		service->refs++;
	}
	else
	{
		try
		{
			service = new Service;
		}
		catch (...)
		{
			service = NULL;
		}

		require_action( service, exit, err = E_OUTOFMEMORY );
		
		service->printer	=	printer;
		service->ifi		=	inInterfaceIndex;
		service->type		=	inType;
		service->domain		=	inDomain;
		service->qtotal		=	1;
		service->refs		=	1;
		service->serviceRef	=	NULL;

		printer->services.push_back( service );

		//
		// if the printer is selected, then we'll want to start a
		// resolve on this guy
		//

		if ( m_selected == printer )
		{
			StartResolve( service );
		}
	}
	
	if ( newPrinter )
	{
		printer->item = m_browseList.InsertItem(printer->displayName);

		m_browseList.SetItemData( printer->item, (DWORD_PTR) printer );

		m_printers.push_back( printer );
		
		m_browseList.SortChildren(TVI_ROOT);
		
		if ( printer->name == m_selectedName )
		{
			m_browseList.SelectItem( printer->item );
		}

		//
		// if the searching item is still in the list
		// get rid of it
		//
		// note that order is important here.  Insert the printer
		// item before removing the placeholder so we always have
		// an item in the list to avoid experiencing the bug
		// in Microsoft's implementation of CTreeCtrl
		//
		if (m_emptyListItem != NULL)
		{
			m_browseList.DeleteItem(m_emptyListItem);
			m_emptyListItem = NULL;
			m_browseList.EnableWindow(TRUE);
		}
	}

exit:

	if (!moreComing)
	{
		m_browseList.SetRedraw(TRUE);
		m_browseList.Invalidate();
	}

	return err;
}
Esempio n. 2
0
OSStatus
CSecondPage::OnRemovePrinter(
				const char *	inName,	
				const char *	inType,	
				const char *	inDomain,
				bool			moreComing)
{
	DEBUG_UNUSED( inDomain );
	DEBUG_UNUSED( inType );

	Printer	*	printer;
	OSStatus	err = kNoErr;

	check( IsWindow( m_hWnd ) );

	m_browseList.SetRedraw(FALSE);

	printer = Lookup( inName );

	if ( printer )
	{
		Service * service;

		service = printer->LookupService( inType );

		if ( service && ( --service->refs == 0 ) )
		{
			if ( service->serviceRef != NULL )
			{
				err = StopResolve( service );
				require_noerr( err, exit );
			}

			printer->services.remove( service );

			delete service;
		}

		if ( printer->services.size() == 0 )
		{
			//
			// check to make sure if we're the only item in the control...i.e.
			// the list size is 1.
			//
			if (m_browseList.GetCount() > 1)
			{
				//
				// if we're not the only thing in the list, then
				// simply remove it from the list
				//
				m_browseList.DeleteItem( printer->item );
			}
			else
			{
				//
				// if we're the only thing in the list, then redisplay
				// it with the no rendezvous printers message
				//
				InitBrowseList();
			}

			m_printers.remove( printer );

			if ( m_selected == printer )
			{
				m_selected		= NULL;
				m_selectedName	= "";
			}

			delete printer;
		}
	}

exit:

	if (!moreComing)
	{
		m_browseList.SetRedraw(TRUE);
		m_browseList.Invalidate();
	}

	return err;
}
Esempio n. 3
0
void DNSSD_API
CPrinterSetupWizardSheet::OnBrowse(
							DNSServiceRef 			inRef,
							DNSServiceFlags 		inFlags,
							uint32_t 				inInterfaceIndex,
							DNSServiceErrorType 	inErrorCode,
							const char *			inName,	
							const char *			inType,	
							const char *			inDomain,	
							void *					inContext )
{
	DEBUG_UNUSED(inRef);

	CPrinterSetupWizardSheet	*	self;
	bool							moreComing = (bool) (inFlags & kDNSServiceFlagsMoreComing);
	CPropertyPage				*	active;
	Printer						*	printer = NULL;
	Service						*	service = NULL;
	OSStatus						err = kNoErr;

	require_noerr( inErrorCode, exit );
	
	self = reinterpret_cast <CPrinterSetupWizardSheet*>( inContext );
	require_quiet( self, exit );

	active = self->GetActivePage();
	require_quiet( active, exit );

	// Have we seen this printer before?

	printer = self->Lookup( inName );

	if ( printer )
	{
		service = printer->LookupService( inType );
	}

	if ( inFlags & kDNSServiceFlagsAdd )
	{
		if (printer == NULL)
		{
			// If not, then create a new one

			printer = self->OnAddPrinter( inInterfaceIndex, inName, inType, inDomain, moreComing );
			require_action( printer, exit, err = kUnknownErr );
		}

		if ( !service )
		{
			err = self->OnAddService( printer, inInterfaceIndex, inName, inType, inDomain );
			require_noerr( err, exit );
		}
		else
		{
			service->refs++;
		}
	}
	else if ( printer )
	{
		check( service );

		err = self->OnRemoveService( service );
		require_noerr( err, exit );

		if ( printer->services.size() == 0 )
		{
			err = self->OnRemovePrinter( printer, moreComing );
			require_noerr( err, exit );
		}
	}

exit:
	
	return;
}