2 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 Change History (most recent first):
25 $Log: SecondPage.cpp,v $
26 Revision 1.10 2005/01/20 19:54:38 shersche
27 Fix parse error when text record is NULL
29 Revision 1.9 2005/01/06 08:13:50 shersche
30 Don't use moreComing flag to determine number of text record, disregard queue name if qtotal isn't defined, don't disregard queue name if "rp" is the only key specified
32 Revision 1.8 2005/01/04 21:09:14 shersche
33 Fix problems in parsing text records. Fix problems in remove event handling. Ensure that the same service can't be resolved more than once.
35 Revision 1.7 2004/12/31 07:25:27 shersche
36 Tidy up printer management, and fix memory leaks when hitting 'Cancel'
38 Revision 1.6 2004/12/30 01:24:02 shersche
39 <rdar://problem/3906182> Remove references to description key
42 Revision 1.5 2004/12/30 01:02:47 shersche
43 <rdar://problem/3734478> Add Printer information box that displays description and location information when printer name is selected
46 Revision 1.4 2004/12/29 18:53:38 shersche
47 <rdar://problem/3725106>
48 <rdar://problem/3737413> Added support for LPR and IPP protocols as well as support for obtaining multiple text records. Reorganized and simplified codebase.
49 Bug #: 3725106, 3737413
51 Revision 1.3 2004/09/13 21:26:15 shersche
52 <rdar://problem/3796483> Use the moreComing flag to determine whether drawing should take place in OnAddPrinter and OnRemovePrinter callbacks
55 Revision 1.2 2004/06/26 03:19:57 shersche
56 clean up warning messages
58 Submitted by: herscher
60 Revision 1.1 2004/06/18 04:36:57 rpantos
67 #include "PrinterSetupWizardApp.h"
68 #include "PrinterSetupWizardSheet.h"
69 #include "SecondPage.h"
70 #include "DebugServices.h"
71 #include "WinServices.h"
74 // local variable is initialize but not referenced
75 #pragma warning(disable:4189)
77 #define WM_SERVICE_EVENT ( WM_USER + 0x101 )
81 IMPLEMENT_DYNAMIC(CSecondPage
, CPropertyPage
)
82 CSecondPage::CSecondPage()
83 : CPropertyPage(CSecondPage::IDD
),
89 m_psp
.dwFlags
&= ~(PSP_HASHELP
);
90 m_psp
.dwFlags
|= PSP_DEFAULT
|PSP_USEHEADERTITLE
|PSP_USEHEADERSUBTITLE
;
92 m_psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_BROWSE_TITLE
);
93 m_psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_BROWSE_SUBTITLE
);
96 m_emptyListItem
= NULL
;
97 m_initialized
= false;
104 CSecondPage::~CSecondPage()
111 CSecondPage::LoadPrinterNames()
117 // rdar://problem/3701926 - Printer can't be installed twice
119 // First thing we want to do is make sure the printer isn't already installed.
120 // If the printer name is found, we'll try and rename it until we
121 // find a unique name
123 DWORD dwNeeded
= 0, dwNumPrinters
= 0;
125 BOOL ok
= EnumPrinters(PRINTER_ENUM_LOCAL
, NULL
, 4, NULL
, 0, &dwNeeded
, &dwNumPrinters
);
126 err
= translate_errno( ok
, errno_compat(), kUnknownErr
);
128 if ((err
== ERROR_INSUFFICIENT_BUFFER
) && (dwNeeded
> 0))
132 buffer
= new unsigned char[dwNeeded
];
139 require_action( buffer
, exit
, kNoMemoryErr
);
140 ok
= EnumPrinters(PRINTER_ENUM_LOCAL
, NULL
, 4, buffer
, dwNeeded
, &dwNeeded
, &dwNumPrinters
);
141 err
= translate_errno( ok
, errno_compat(), kUnknownErr
);
142 require_noerr( err
, exit
);
144 for (DWORD index
= 0; index
< dwNumPrinters
; index
++)
146 PRINTER_INFO_4
* lppi4
= (PRINTER_INFO_4
*) (buffer
+ index
* sizeof(PRINTER_INFO_4
));
148 m_printerNames
[lppi4
->pPrinterName
] = lppi4
->pPrinterName
;
164 CSecondPage::InitBrowseList()
166 CPrinterSetupWizardSheet
* psheet
;
169 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
170 require_quiet( psheet
, exit
);
173 // load the no rendezvous printers message until something shows up in the browse list
175 text
.LoadString(IDS_NO_RENDEZVOUS_PRINTERS
);
177 LoadTextAndDisableWindow( text
);
180 // disable the next button until there's a printer to select
182 psheet
->SetWizardButtons(PSWIZB_BACK
);
185 // disable the printer information box
187 SetPrinterInformationState( FALSE
);
196 CSecondPage::StartOperation( DNSServiceRef ref
)
200 err
= WSAAsyncSelect((SOCKET
) DNSServiceRefSockFD(ref
), m_hWnd
, WM_SERVICE_EVENT
, FD_READ
|FD_CLOSE
);
201 require_noerr( err
, exit
);
203 m_serviceRefList
.push_back( ref
);
212 CSecondPage::StopOperation( DNSServiceRef
& ref
)
214 OSStatus err
= kNoErr
;
218 m_serviceRefList
.remove( ref
);
220 if ( IsWindow( m_hWnd
) )
222 err
= WSAAsyncSelect((SOCKET
) DNSServiceRefSockFD( ref
), m_hWnd
, 0, 0 );
223 require_noerr( err
, exit
);
226 DNSServiceRefDeallocate( ref
);
237 CSecondPage::Lookup(const char * inName
)
239 check( IsWindow( m_hWnd
) );
242 HTREEITEM item
= m_browseList
.GetChildItem( TVI_ROOT
);
248 data
= m_browseList
.GetItemData( item
);
249 printer
= reinterpret_cast<Printer
*>(data
);
251 if ( printer
&& ( printer
->name
== inName
) )
256 item
= m_browseList
.GetNextItem( item
, TVGN_NEXT
);
264 CSecondPage::StartBrowse()
269 // setup the DNS-SD browsing
271 err
= DNSServiceBrowse( &m_pdlBrowser
, 0, 0, kPDLServiceType
, NULL
, OnBrowse
, this );
272 require_noerr( err
, exit
);
274 err
= StartOperation( m_pdlBrowser
);
275 require_noerr( err
, exit
);
277 err
= DNSServiceBrowse( &m_lprBrowser
, 0, 0, kLPRServiceType
, NULL
, OnBrowse
, this );
278 require_noerr( err
, exit
);
280 err
= StartOperation( m_lprBrowser
);
281 require_noerr( err
, exit
);
283 err
= DNSServiceBrowse( &m_ippBrowser
, 0, 0, kIPPServiceType
, NULL
, OnBrowse
, this );
284 require_noerr( err
, exit
);
286 err
= StartOperation( m_ippBrowser
);
287 require_noerr( err
, exit
);
296 CSecondPage::StopBrowse()
300 err
= StopOperation( m_pdlBrowser
);
301 require_noerr( err
, exit
);
303 err
= StopOperation( m_lprBrowser
);
304 require_noerr( err
, exit
);
306 err
= StopOperation( m_ippBrowser
);
307 require_noerr( err
, exit
);
309 while ( m_printers
.size() > 0 )
311 Printer
* printer
= m_printers
.front();
313 m_printers
.pop_front();
315 if ( printer
->resolving
)
317 StopResolve( printer
);
330 CSecondPage::StartResolve( Printer
* printer
)
332 CPrinterSetupWizardSheet
* psheet
;
333 OSStatus err
= kNoErr
;
334 Services::iterator it
;
336 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
337 require_quiet( psheet
, exit
);
341 for ( it
= printer
->services
.begin(); it
!= printer
->services
.end(); it
++ )
343 if ( (*it
)->serviceRef
== NULL
)
345 err
= StartResolve( *it
);
346 require_noerr( err
, exit
);
357 CSecondPage::StartResolve( Service
* service
)
359 CPrinterSetupWizardSheet
* psheet
;
360 OSStatus err
= kNoErr
;
362 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
363 require_quiet( psheet
, exit
);
365 check( service
->serviceRef
== NULL
);
368 // clean out any queues that were collected during a previous
372 service
->EmptyQueues();
375 // now start the new resolve
378 err
= DNSServiceResolve( &service
->serviceRef
, 0, 0, service
->printer
->name
.c_str(), service
->type
.c_str(), service
->domain
.c_str(), (DNSServiceResolveReply
) OnResolve
, service
);
379 require_noerr( err
, exit
);
381 err
= StartOperation( service
->serviceRef
);
382 require_noerr( err
, exit
);
385 // If we're not currently resolving, then disable the next button
386 // and set the cursor to hourglass
389 if ( !service
->printer
->resolving
)
391 psheet
->SetWizardButtons( PSWIZB_BACK
);
393 psheet
->m_active
= psheet
->m_wait
;
394 SetCursor(psheet
->m_active
);
397 service
->printer
->resolving
++;
406 CSecondPage::StopResolve(Printer
* printer
)
408 OSStatus err
= kNoErr
;
412 Services::iterator it
;
414 for ( it
= printer
->services
.begin(); it
!= printer
->services
.end(); it
++ )
416 if ( (*it
)->serviceRef
)
418 err
= StopResolve( *it
);
419 require_noerr( err
, exit
);
430 CSecondPage::StopResolve( Service
* service
)
434 check( service
->serviceRef
);
436 err
= StopOperation( service
->serviceRef
);
437 require_noerr( err
, exit
);
439 service
->printer
->resolving
--;
447 void CSecondPage::DoDataExchange(CDataExchange
* pDX
)
449 CPropertyPage::DoDataExchange(pDX
);
450 DDX_Control(pDX
, IDC_BROWSE_LIST
, m_browseList
);
451 DDX_Control(pDX
, IDC_PRINTER_INFORMATION
, m_printerInformation
);
452 DDX_Control(pDX
, IDC_DESCRIPTION_LABEL
, m_descriptionLabel
);
453 DDX_Control(pDX
, IDC_DESCRIPTION_FIELD
, m_descriptionField
);
454 DDX_Control(pDX
, IDC_LOCATION_LABEL
, m_locationLabel
);
455 DDX_Control(pDX
, IDC_LOCATION_FIELD
, m_locationField
);
460 CSecondPage::OnSetCursor(CWnd
* pWnd
, UINT nHitTest
, UINT message
)
463 DEBUG_UNUSED(nHitTest
);
464 DEBUG_UNUSED(message
);
466 CPrinterSetupWizardSheet
* psheet
;
468 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
469 require_quiet( psheet
, exit
);
471 SetCursor(psheet
->GetCursor());
480 CSecondPage::OnSetActive()
482 CPrinterSetupWizardSheet
* psheet
;
484 OSStatus err
= kNoErr
;
486 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
487 require_action( psheet
, exit
, err
= kUnknownErr
);
489 if ( ( printer
= psheet
->GetSelectedPrinter() ) != NULL
)
491 psheet
->SetSelectedPrinter( NULL
);
496 // initialize the browse list...this will remove everything currently
497 // in it, and add the no rendezvous printers item
505 require_noerr( err
, exit
);
511 if ( err
== kDNSServiceErr_Firewall
)
513 CString text
, caption
;
515 text
.LoadString( IDS_FIREWALL
);
516 caption
.LoadString( IDS_FIREWALL_CAPTION
);
518 MessageBox(text
, caption
, MB_OK
|MB_ICONEXCLAMATION
);
522 CPrinterSetupWizardSheet::WizardException exc
;
524 exc
.text
.LoadString( IDS_NO_MDNSRESPONDER_SERVICE_TEXT
);
525 exc
.caption
.LoadString( IDS_ERROR_CAPTION
);
531 return CPropertyPage::OnSetActive();
536 CSecondPage::OnKillActive()
538 OSStatus err
= kNoErr
;
542 CPrinterSetupWizardSheet
* psheet
;
544 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
545 require_quiet( psheet
, exit
);
547 psheet
->SetSelectedPrinter( m_selected
);
548 m_printers
.remove( m_selected
);
553 require_noerr( err
, exit
);
557 return CPropertyPage::OnKillActive();
562 CSecondPage::OnBrowse(
564 DNSServiceFlags inFlags
,
565 uint32_t inInterfaceIndex
,
566 DNSServiceErrorType inErrorCode
,
569 const char * inDomain
,
575 bool moreComing
= (bool) (inFlags
& kDNSServiceFlagsMoreComing
);
577 require_noerr( inErrorCode
, exit
);
579 self
= reinterpret_cast <CSecondPage
*>( inContext
);
580 require_quiet( self
, exit
);
582 if ( inFlags
& kDNSServiceFlagsAdd
)
584 self
->OnAddPrinter( inInterfaceIndex
, inName
, inType
, inDomain
, moreComing
);
588 self
->OnRemovePrinter( inName
, inType
, inDomain
, moreComing
);
598 CSecondPage::OnResolve(
600 DNSServiceFlags inFlags
,
601 uint32_t inInterfaceIndex
,
602 DNSServiceErrorType inErrorCode
,
603 const char * inFullName
,
604 const char * inHostName
,
610 DEBUG_UNUSED(inFullName
);
611 DEBUG_UNUSED(inInterfaceIndex
);
612 DEBUG_UNUSED(inFlags
);
618 bool qtotalDefined
= false;
619 uint32_t qpriority
= kDefaultPriority
;
624 require_noerr( inErrorCode
, exit
);
626 service
= reinterpret_cast<Service
*>( inContext
);
627 require_quiet( service
, exit
);
629 check( service
->refs
!= 0 );
631 self
= service
->printer
->window
;
632 require_quiet( self
, exit
);
634 err
= self
->StopOperation( service
->serviceRef
);
635 require_noerr( err
, exit
);
638 // hold on to the hostname...
640 err
= UTF8StringToStringObject( inHostName
, service
->hostname
);
641 require_noerr( err
, exit
);
644 // <rdar://problem/3739200> remove the trailing dot on hostname
646 idx
= service
->hostname
.ReverseFind('.');
648 if ((idx
> 1) && ((service
->hostname
.GetLength() - 1) == idx
))
650 service
->hostname
.Delete(idx
, 1);
654 // hold on to the port
656 service
->portNumber
= ntohs(inPort
);
659 // parse the text record.
662 err
= self
->ParseTextRecord( service
, inTXTSize
, inTXT
, qtotalDefined
, qname
, qpriority
);
663 require_noerr( err
, exit
);
665 if ( service
->qtotal
== 1 )
668 // create a new queue
679 require_action( q
, exit
, err
= E_OUTOFMEMORY
);
686 q
->priority
= qpriority
;
688 service
->queues
.push_back( q
);
691 // we've completely resolved this service
694 self
->OnResolveService( service
);
699 // if qtotal is more than 1, then we need to get additional
700 // text records. if not, then this service is considered
704 err
= DNSServiceQueryRecord(&service
->serviceRef
, 0, inInterfaceIndex
, inFullName
, kDNSServiceType_TXT
, kDNSServiceClass_IN
, OnQuery
, (void*) service
);
705 require_noerr( err
, exit
);
707 err
= self
->StartOperation( service
->serviceRef
);
708 require_noerr( err
, exit
);
718 CSecondPage::OnQuery(
720 DNSServiceFlags inFlags
,
721 uint32_t inInterfaceIndex
,
722 DNSServiceErrorType inErrorCode
,
723 const char * inFullName
,
727 const void * inRData
,
731 DEBUG_UNUSED( inTTL
);
732 DEBUG_UNUSED( inRRClass
);
733 DEBUG_UNUSED( inRRType
);
734 DEBUG_UNUSED( inFullName
);
735 DEBUG_UNUSED( inInterfaceIndex
);
736 DEBUG_UNUSED( inRef
);
738 Service
* service
= NULL
;
741 bool qtotalDefined
= false;
742 bool moreComing
= (bool) (inFlags
& kDNSServiceFlagsMoreComing
);
743 OSStatus err
= kNoErr
;
745 require_noerr( inErrorCode
, exit
);
747 service
= reinterpret_cast<Service
*>( inContext
);
748 require_quiet( service
, exit
);
750 self
= service
->printer
->window
;
751 require_quiet( self
, exit
);
753 if ( ( inFlags
& kDNSServiceFlagsAdd
) && ( inRDLen
> 0 ) && ( inRData
!= NULL
) )
755 const char * inTXT
= ( const char * ) inRData
;
758 // create a new queue
769 require_action( q
, exit
, err
= E_OUTOFMEMORY
);
771 err
= service
->printer
->window
->ParseTextRecord( service
, inRDLen
, inTXT
, qtotalDefined
, q
->name
, q
->priority
);
772 require_noerr( err
, exit
);
774 if ( !qtotalDefined
)
783 service
->queues
.push_back( q
);
785 if ( service
->queues
.size() == service
->qtotal
)
788 // else if moreComing is not set, then we're going
789 // to assume that we're done
792 self
->StopOperation( service
->serviceRef
);
798 service
->queues
.sort( OrderQueueFunc
);
801 // we've completely resolved this service
804 self
->OnResolveService( service
);
810 if ( err
&& service
&& ( service
->serviceRef
!= NULL
) )
812 service
->printer
->window
->StopOperation( service
->serviceRef
);
819 BEGIN_MESSAGE_MAP(CSecondPage
, CPropertyPage
)
820 ON_MESSAGE( WM_SERVICE_EVENT
, OnServiceEvent
)
821 ON_NOTIFY(TVN_SELCHANGED
, IDC_BROWSE_LIST
, OnTvnSelchangedBrowseList
)
826 // Printer::EventHandler implementation
828 CSecondPage::OnAddPrinter(
829 uint32_t inInterfaceIndex
,
832 const char * inDomain
,
837 CPrinterSetupWizardSheet
* psheet
;
838 DWORD printerNameCount
;
839 bool newPrinter
= false;
840 OSStatus err
= kNoErr
;
842 check( IsWindow( m_hWnd
) );
844 m_browseList
.SetRedraw(FALSE
);
846 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
847 require_quiet( psheet
, exit
);
849 printer
= Lookup( inName
);
855 printer
= new Printer
;
862 require_action( printer
, exit
, err
= E_OUTOFMEMORY
);
864 printer
->window
= this;
865 printer
->name
= inName
;
867 err
= UTF8StringToStringObject(inName
, printer
->displayName
);
869 printer
->actualName
= printer
->displayName
;
870 printer
->installed
= false;
871 printer
->deflt
= false;
872 printer
->resolving
= 0;
875 // Compare this name against printers that are already installed
876 // to avoid name clashes. Rename as necessary
877 // to come up with a unique name.
879 printerNameCount
= 2;
883 PrinterNameMap::iterator it
;
885 it
= m_printerNames
.find(printer
->actualName
);
887 if (it
!= m_printerNames
.end())
889 printer
->actualName
.Format(L
"%s (%d)", printer
->displayName
, printerNameCount
);
904 service
= printer
->LookupService( inType
);
906 if ( service
!= NULL
)
914 service
= new Service
;
921 require_action( service
, exit
, err
= E_OUTOFMEMORY
);
923 service
->printer
= printer
;
924 service
->ifi
= inInterfaceIndex
;
925 service
->type
= inType
;
926 service
->domain
= inDomain
;
929 service
->serviceRef
= NULL
;
931 printer
->services
.push_back( service
);
934 // if the printer is selected, then we'll want to start a
935 // resolve on this guy
938 if ( m_selected
== printer
)
940 StartResolve( service
);
946 printer
->item
= m_browseList
.InsertItem(printer
->displayName
);
948 m_browseList
.SetItemData( printer
->item
, (DWORD_PTR
) printer
);
950 m_printers
.push_back( printer
);
952 m_browseList
.SortChildren(TVI_ROOT
);
954 if ( printer
->name
== m_selectedName
)
956 m_browseList
.SelectItem( printer
->item
);
960 // if the searching item is still in the list
963 // note that order is important here. Insert the printer
964 // item before removing the placeholder so we always have
965 // an item in the list to avoid experiencing the bug
966 // in Microsoft's implementation of CTreeCtrl
968 if (m_emptyListItem
!= NULL
)
970 m_browseList
.DeleteItem(m_emptyListItem
);
971 m_emptyListItem
= NULL
;
972 m_browseList
.EnableWindow(TRUE
);
980 m_browseList
.SetRedraw(TRUE
);
981 m_browseList
.Invalidate();
989 CSecondPage::OnRemovePrinter(
992 const char * inDomain
,
995 DEBUG_UNUSED( inDomain
);
996 DEBUG_UNUSED( inType
);
999 OSStatus err
= kNoErr
;
1001 check( IsWindow( m_hWnd
) );
1003 m_browseList
.SetRedraw(FALSE
);
1005 printer
= Lookup( inName
);
1011 service
= printer
->LookupService( inType
);
1013 if ( service
&& ( --service
->refs
== 0 ) )
1015 if ( service
->serviceRef
!= NULL
)
1017 err
= StopResolve( service
);
1018 require_noerr( err
, exit
);
1021 printer
->services
.remove( service
);
1026 if ( printer
->services
.size() == 0 )
1029 // check to make sure if we're the only item in the control...i.e.
1030 // the list size is 1.
1032 if (m_browseList
.GetCount() > 1)
1035 // if we're not the only thing in the list, then
1036 // simply remove it from the list
1038 m_browseList
.DeleteItem( printer
->item
);
1043 // if we're the only thing in the list, then redisplay
1044 // it with the no rendezvous printers message
1049 m_printers
.remove( printer
);
1051 if ( m_selected
== printer
)
1054 m_selectedName
= "";
1065 m_browseList
.SetRedraw(TRUE
);
1066 m_browseList
.Invalidate();
1074 CSecondPage::OnResolveService( Service
* service
)
1076 CPrinterSetupWizardSheet
* psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
1077 require_quiet( psheet
, exit
);
1081 if ( !--service
->printer
->resolving
)
1084 // sort the services now. we want the service that
1085 // has the highest priority queue to be first in
1089 service
->printer
->services
.sort( OrderServiceFunc
);
1092 // and set it to selected
1095 m_selected
= service
->printer
;
1096 m_selectedName
= service
->printer
->name
;
1099 // and update the printer information box
1101 SetPrinterInformationState( TRUE
);
1103 m_descriptionField
.SetWindowText( service
->description
);
1104 m_locationField
.SetWindowText( service
->location
);
1106 psheet
->SetWizardButtons( PSWIZB_BACK
|PSWIZB_NEXT
);
1112 psheet
->m_active
= psheet
->m_arrow
;
1113 SetCursor(psheet
->m_active
);
1123 CSecondPage::OnServiceEvent(WPARAM inWParam
, LPARAM inLParam
)
1125 if (WSAGETSELECTERROR(inLParam
) && !(HIWORD(inLParam
)))
1127 dlog( kDebugLevelError
, "OnServiceEvent: window error\n" );
1131 SOCKET sock
= (SOCKET
) inWParam
;
1133 // iterate thru list
1134 ServiceRefList::iterator begin
= m_serviceRefList
.begin();
1135 ServiceRefList::iterator end
= m_serviceRefList
.end();
1137 while (begin
!= end
)
1139 DNSServiceRef ref
= *begin
++;
1143 if ((SOCKET
) DNSServiceRefSockFD(ref
) == sock
)
1145 DNSServiceProcessResult(ref
);
1155 void CSecondPage::OnTvnSelchangedBrowseList(NMHDR
*pNMHDR
, LRESULT
*pResult
)
1157 LPNMTREEVIEW pNMTreeView
= reinterpret_cast<LPNMTREEVIEW
>(pNMHDR
);
1158 CPrinterSetupWizardSheet
* psheet
;
1161 HTREEITEM item
= m_browseList
.GetSelectedItem();
1162 require_quiet( item
, exit
);
1164 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
1165 require_action( psheet
, exit
, err
= kUnknownErr
);
1169 printer
= reinterpret_cast<Printer
*>(m_browseList
.GetItemData( item
) );
1170 require_quiet( printer
, exit
);
1173 // this call will trigger a resolve. When the resolve is complete,
1174 // our OnResolve will be called.
1176 err
= StartResolve( printer
);
1177 require_noerr( err
, exit
);
1180 // And clear out the printer information box
1182 SetPrinterInformationState( FALSE
);
1183 m_descriptionField
.SetWindowText(L
"");
1184 m_locationField
.SetWindowText(L
"");
1193 text
.LoadString(IDS_ERROR_SELECTING_PRINTER_TEXT
);
1194 caption
.LoadString(IDS_ERROR_SELECTING_PRINTER_CAPTION
);
1196 MessageBox(text
, caption
, MB_OK
|MB_ICONEXCLAMATION
);
1204 CSecondPage::OrderServiceFunc( const Service
* a
, const Service
* b
)
1208 q1
= (a
->queues
.size() > 0) ? a
->queues
.front() : NULL
;
1210 q2
= (b
->queues
.size() > 0) ? b
->queues
.front() : NULL
;
1216 else if ( q1
&& !q2
)
1220 else if ( !q1
&& q2
)
1224 else if ( q1
->priority
< q2
->priority
)
1228 else if ( q1
->priority
> q2
->priority
)
1232 else if ( ( a
->type
== kPDLServiceType
) || ( ( a
->type
== kLPRServiceType
) && ( b
->type
== kIPPServiceType
) ) )
1244 CSecondPage::OrderQueueFunc( const Queue
* q1
, const Queue
* q2
)
1246 return ( q1
->priority
<= q2
->priority
) ? true : false;
1251 CSecondPage::LoadTextAndDisableWindow( CString
& text
)
1253 m_emptyListItem
= m_browseList
.InsertItem( text
, 0, 0, NULL
, TVI_FIRST
);
1254 m_browseList
.SelectItem( NULL
);
1257 // this will remove everything else in the list...we might be navigating
1258 // back to this window, and the browse list might have changed since
1259 // we last displayed it.
1261 if ( m_emptyListItem
)
1263 HTREEITEM item
= m_browseList
.GetNextVisibleItem( m_emptyListItem
);
1267 m_browseList
.DeleteItem( item
);
1268 item
= m_browseList
.GetNextVisibleItem( m_emptyListItem
);
1272 m_browseList
.EnableWindow( FALSE
);
1277 CSecondPage::SetPrinterInformationState( BOOL state
)
1279 m_printerInformation
.EnableWindow( state
);
1280 m_descriptionLabel
.EnableWindow( state
);
1281 m_descriptionField
.EnableWindow( state
);
1282 m_locationLabel
.EnableWindow( state
);
1283 m_locationField
.EnableWindow( state
);
1288 CSecondPage::ParseTextRecord( Service
* service
, uint16_t inTXTSize
, const char * inTXT
, bool & qtotalDefined
, CString
& qname
, uint32_t & qpriority
)
1291 OSStatus err
= kNoErr
;
1297 unsigned char num
= *inTXT
;
1298 check( (int) num
< inTXTSize
);
1302 memset(buf
, 0, sizeof(buf
));
1303 memcpy(buf
, inTXT
+ 1, num
);
1307 err
= UTF8StringToStringObject( buf
, elem
);
1308 require_noerr( err
, exit
);
1312 CString key
= elem
.Tokenize(L
"=", curPos
);
1313 CString val
= elem
.Tokenize(L
"=", curPos
);
1325 if ((key
== L
"usb_mfg") || (key
== L
"usb_manufacturer"))
1327 service
->usb_MFG
= val
;
1329 else if ((key
== L
"usb_mdl") || (key
== L
"usb_model"))
1331 service
->usb_MDL
= val
;
1333 else if (key
== L
"ty")
1335 service
->description
= val
;
1337 else if (key
== L
"product")
1339 service
->product
= val
;
1341 else if (key
== L
"note")
1343 service
->location
= val
;
1345 else if (key
== L
"qtotal")
1347 service
->qtotal
= (unsigned short) _ttoi((LPCTSTR
) val
);
1348 qtotalDefined
= true;
1350 else if (key
== L
"priority")
1352 qpriority
= _ttoi((LPCTSTR
) val
);
1357 inTXTSize
-= (num
+ 1);
1365 qtotalDefined
= true;