1 /* -*- Mode: C; tab-width: 4 -*- 
   3  * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved. 
   5  * Licensed under the Apache License, Version 2.0 (the "License"); 
   6  * you may not use this file except in compliance with the License. 
   7  * You may obtain a copy of the License at 
   9  *     http://www.apache.org/licenses/LICENSE-2.0 
  11  * Unless required by applicable law or agreed to in writing, software 
  12  * distributed under the License is distributed on an "AS IS" BASIS, 
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  14  * See the License for the specific language governing permissions and 
  15  * limitations under the License. 
  18 // <rdar://problem/4278931> Doesn't compile correctly with latest Platform SDK 
  20 #if !defined(_WIN32_DCOM) 
  33 static const int kMaxTries                      
= 30; 
  34 static const int kRetrySleepPeriod      
= 1 * 1000; // 1 second 
  38 mDNSFirewallInitialize(OUT INetFwProfile 
** fwProfile
) 
  40         INetFwMgr               
*       fwMgr           
= NULL
; 
  41         INetFwPolicy    
*       fwPolicy        
= NULL
; 
  45         _ASSERT(fwProfile 
!= NULL
); 
  49         // Use COM to get a reference to the firewall settings manager.  This 
  50         // call will fail on anything other than XP SP2 
  52         err 
= CoCreateInstance( __uuidof(NetFwMgr
), NULL
, CLSCTX_INPROC_SERVER
, __uuidof(INetFwMgr
), (void**)&fwMgr 
); 
  53         require(SUCCEEDED(err
) && ( fwMgr 
!= NULL 
), exit
); 
  55         // Use the reference to get the local firewall policy 
  57         err 
= fwMgr
->get_LocalPolicy(&fwPolicy
); 
  58         require(SUCCEEDED(err
) && ( fwPolicy 
!= NULL 
), exit
); 
  60         // Use the reference to get the extant profile. Empirical evidence 
  61         // suggests that there is the potential for a race condition when a system 
  62         // service whose startup type is automatic calls this method. 
  63         // This is true even when the service declares itself to be dependent 
  64         // on the firewall service. Re-trying the method will succeed within 
  69         err 
= fwPolicy
->get_CurrentProfile(fwProfile
); 
  73                         Sleep(kRetrySleepPeriod
); 
  76         while (err 
&& (numRetries
++ < kMaxTries
)); 
  78         require(SUCCEEDED(err
), exit
); 
  84         // Release temporary COM objects 
 103                         IN INetFwProfile        
*       fwProfile
 
 106         // Call Release on the COM reference. 
 108     if (fwProfile 
!= NULL
) 
 110         fwProfile
->Release(); 
 116 mDNSFirewallAppIsEnabled
 
 118                         IN INetFwProfile        
*       fwProfile
, 
 119                         IN 
const wchar_t        *       fwProcessImageFileName
, 
 120                         OUT BOOL                        
*       fwAppEnabled    
 
 123         BSTR                                                    fwBstrProcessImageFileName 
= NULL
; 
 124         VARIANT_BOOL                                    fwEnabled
; 
 125         INetFwAuthorizedApplication     
*       fwApp   
= NULL
; 
 126         INetFwAuthorizedApplications
*   fwApps  
= NULL
; 
 127         OSStatus                                                err             
= kNoErr
; 
 129         _ASSERT(fwProfile 
!= NULL
); 
 130         _ASSERT(fwProcessImageFileName 
!= NULL
); 
 131         _ASSERT(fwAppEnabled 
!= NULL
); 
 133     *fwAppEnabled 
= FALSE
; 
 135         // Get the list of authorized applications 
 137         err 
= fwProfile
->get_AuthorizedApplications(&fwApps
); 
 138         require(SUCCEEDED(err
) && ( fwApps 
!= NULL 
), exit
); 
 140     fwBstrProcessImageFileName 
= SysAllocString(fwProcessImageFileName
); 
 141         require_action( ( fwProcessImageFileName 
!= NULL 
) && ( SysStringLen(fwBstrProcessImageFileName
) > 0 ), exit
, err 
= kNoMemoryErr
); 
 145     err 
= fwApps
->Item(fwBstrProcessImageFileName
, &fwApp
); 
 147     if (SUCCEEDED(err
) && ( fwApp 
!= NULL 
) ) 
 149         // It's listed, but is it enabled? 
 151                 err 
= fwApp
->get_Enabled(&fwEnabled
); 
 152                 require(SUCCEEDED(err
), exit
); 
 154         if (fwEnabled 
!= VARIANT_FALSE
) 
 158             *fwAppEnabled 
= TRUE
; 
 166         // Deallocate the BSTR 
 168         if ( fwBstrProcessImageFileName 
!= NULL 
) 
 170                 SysFreeString(fwBstrProcessImageFileName
); 
 173         // Release the COM objects 
 192             IN INetFwProfile    
*       fwProfile
, 
 193             IN 
const wchar_t    *       fwProcessImageFileName
, 
 194             IN 
const wchar_t    *       fwName
 
 198         BSTR                                                    fwBstrName 
= NULL
; 
 199         BSTR                                                    fwBstrProcessImageFileName 
= NULL
; 
 200         INetFwAuthorizedApplication     
*       fwApp 
= NULL
; 
 201         INetFwAuthorizedApplications
*   fwApps 
= NULL
; 
 204         _ASSERT(fwProfile 
!= NULL
); 
 205     _ASSERT(fwProcessImageFileName 
!= NULL
); 
 206     _ASSERT(fwName 
!= NULL
); 
 208     // First check to see if the application is already authorized. 
 209         err 
= mDNSFirewallAppIsEnabled( fwProfile
, fwProcessImageFileName
, &fwAppEnabled 
); 
 210         require_noerr(err
, exit
); 
 212         // Only add the application if it isn't enabled 
 216                 // Get the list of authorized applications 
 218         err 
= fwProfile
->get_AuthorizedApplications(&fwApps
); 
 219                 require(SUCCEEDED(err
) && ( fwApps 
!= NULL 
), exit
); 
 221         // Create an instance of an authorized application. 
 223                 err 
= CoCreateInstance( __uuidof(NetFwAuthorizedApplication
), NULL
, CLSCTX_INPROC_SERVER
, __uuidof(INetFwAuthorizedApplication
), (void**)&fwApp 
); 
 224                 require(SUCCEEDED(err
) && ( fwApp 
!= NULL 
), exit
); 
 226         fwBstrProcessImageFileName 
= SysAllocString(fwProcessImageFileName
); 
 227                 require_action(( fwProcessImageFileName 
!= NULL 
) && ( SysStringLen(fwBstrProcessImageFileName
) > 0 ), exit
, err 
= kNoMemoryErr
); 
 229                 // Set the executable file name 
 231                 err 
= fwApp
->put_ProcessImageFileName(fwBstrProcessImageFileName
); 
 232                 require(SUCCEEDED(err
), exit
); 
 234                 fwBstrName 
= SysAllocString(fwName
); 
 235                 require_action( ( fwBstrName 
!= NULL 
) && ( SysStringLen(fwBstrName
) > 0 ), exit
, err 
= kNoMemoryErr
); 
 237                 // Set the friendly name 
 239         err 
= fwApp
->put_Name(fwBstrName
); 
 240                 require(SUCCEEDED(err
), exit
); 
 242                 // Now add the application 
 244         err 
= fwApps
->Add(fwApp
); 
 245                 require(SUCCEEDED(err
), exit
); 
 252         // Deallocate the BSTR objects 
 254         if ( fwBstrName 
!= NULL 
) 
 256                 SysFreeString(fwBstrName
); 
 259         if ( fwBstrProcessImageFileName 
!= NULL 
) 
 261                 SysFreeString(fwBstrProcessImageFileName
); 
 264     // Release the COM objects 
 285 mDNSFirewallIsFileAndPrintSharingEnabled
 
 289         IN INetFwProfile        
* fwProfile
, 
 291         OUT BOOL                        
* fwServiceEnabled
 
 297     VARIANT_BOOL fwEnabled
; 
 299     INetFwService
* fwService 
= NULL
; 
 301     INetFwServices
* fwServices 
= NULL
; 
 307     _ASSERT(fwProfile 
!= NULL
); 
 309     _ASSERT(fwServiceEnabled 
!= NULL
); 
 313     *fwServiceEnabled 
= FALSE
; 
 317     // Retrieve the globally open ports collection. 
 319     err 
= fwProfile
->get_Services(&fwServices
); 
 321         require( SUCCEEDED( err 
), exit 
); 
 325     // Attempt to retrieve the globally open port. 
 327     err 
= fwServices
->Item(NET_FW_SERVICE_FILE_AND_PRINT
, &fwService
); 
 329         require( SUCCEEDED( err 
), exit 
); 
 333         // Find out if the globally open port is enabled. 
 335     err 
= fwService
->get_Enabled(&fwEnabled
); 
 337         require( SUCCEEDED( err 
), exit 
); 
 339         if (fwEnabled 
!= VARIANT_FALSE
) 
 343                 *fwServiceEnabled 
= TRUE
; 
 353     // Release the globally open port. 
 355     if (fwService 
!= NULL
) 
 359         fwService
->Release(); 
 365     // Release the globally open ports collection. 
 367     if (fwServices 
!= NULL
) 
 371         fwServices
->Release(); 
 389         INetFwProfile   
*       fwProfile       
= NULL
; 
 390         HRESULT                         comInit         
= E_FAIL
; 
 391         OSStatus                        err                     
= kNoErr
; 
 395         comInit 
= CoInitializeEx( 0, COINIT_APARTMENTTHREADED 
| COINIT_DISABLE_OLE1DDE 
); 
 397         // Ignore this case. RPC_E_CHANGED_MODE means that COM has already been 
 398         // initialized with a different mode. 
 400         if (comInit 
!= RPC_E_CHANGED_MODE
) 
 403                 require(SUCCEEDED(err
), exit
); 
 406         // Connect to the firewall 
 408         err 
= mDNSFirewallInitialize(&fwProfile
); 
 409         require( SUCCEEDED( err 
) && ( fwProfile 
!= NULL 
), exit
); 
 411         // Add us to the list of exempt programs 
 413         err 
= mDNSFirewallAddApp( fwProfile
, executable
, name 
); 
 414         require_noerr(err
, exit
); 
 418         // Disconnect from the firewall 
 420         if ( fwProfile 
!= NULL 
) 
 422                 mDNSFirewallCleanup(fwProfile
); 
 427         if (SUCCEEDED(comInit
)) 
 437 mDNSIsFileAndPrintSharingEnabled( BOOL 
* retry 
) 
 439         INetFwProfile   
*       fwProfile                                       
= NULL
; 
 440         HRESULT                         comInit                                         
= E_FAIL
; 
 441         BOOL                            enabled                                         
= FALSE
; 
 442         OSStatus                        err                                                     
= kNoErr
; 
 447         comInit 
= CoInitializeEx( 0, COINIT_APARTMENTTHREADED 
| COINIT_DISABLE_OLE1DDE 
); 
 449         // Ignore this case. RPC_E_CHANGED_MODE means that COM has already been 
 450         // initialized with a different mode. 
 452         if (comInit 
!= RPC_E_CHANGED_MODE
) 
 456                 require(SUCCEEDED(err
), exit
); 
 459         // Connect to the firewall 
 461         err 
= mDNSFirewallInitialize(&fwProfile
); 
 462         require( SUCCEEDED( err 
) && ( fwProfile 
!= NULL 
), exit
); 
 464         err 
= mDNSFirewallIsFileAndPrintSharingEnabled( fwProfile
, &enabled 
); 
 465         require_noerr( err
, exit 
); 
 469         // Disconnect from the firewall 
 471         if ( fwProfile 
!= NULL 
) 
 473                 mDNSFirewallCleanup(fwProfile
); 
 478         if (SUCCEEDED(comInit
))