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
))