forked from dolphin-emu/dolphin
		
	
		
			
	
	
		
			551 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			551 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|   | // Under MIT licence from http://www.mindcontrol.org/~hplus/http-get.html
 | ||
|  | 
 | ||
|  | #include "PortableSockets.h"
 | ||
|  | 
 | ||
|  | #if NEED_GETTIMEOFDAY
 | ||
|  | #if defined( _WIN32 )
 | ||
|  | 
 | ||
|  | #include <sys/types.h>
 | ||
|  | #include <sys/timeb.h>
 | ||
|  | #include <math.h>
 | ||
|  | #include <assert.h>
 | ||
|  | #include <mmsystem.h>
 | ||
|  | 
 | ||
|  | #pragma comment( lib, "winmm.lib" )
 | ||
|  | //#pragma comment( lib, "ws2_32.lib" )
 | ||
|  | 
 | ||
|  | 
 | ||
|  | namespace { | ||
|  | 
 | ||
|  | 	// This class could be made cheaper using RDTSC for short-term 
 | ||
|  | 	// measurement. But, whatever.
 | ||
|  | 	class init_gettimeofday | ||
|  | 	{ | ||
|  | 	public: | ||
|  | 		init_gettimeofday() | ||
|  | 		{ | ||
|  | 			timeBeginPeriod( 2 ); | ||
|  | 			__int64 rr; | ||
|  | 			QueryPerformanceFrequency( (LARGE_INTEGER *)&rr ); | ||
|  | 			ticksPerSecInv_ = 1.0 / (double)((DWORD)rr & 0xffffffff); | ||
|  | 			int watchdog = 0; | ||
|  | again: | ||
|  | 			lastTicks_ = timeGetTime(); | ||
|  | 			QueryPerformanceCounter( (LARGE_INTEGER *)&lastRead_ ); | ||
|  | 			timeb tb; | ||
|  | 			ftime( &tb ); | ||
|  | 			timeOffset_ = tb.time + tb.millitm * 0.001 - lastRead_ * ticksPerSecInv_; | ||
|  | 			lastTime_ = timeOffset_; | ||
|  | 			//  make sure it didn't take too long
 | ||
|  | 			if( watchdog++ < 10 && (timeGetTime() != lastTicks_) ) { | ||
|  | 				goto again; | ||
|  | 			} | ||
|  | 		} | ||
|  | 		~init_gettimeofday() | ||
|  | 		{ | ||
|  | 			timeEndPeriod( 2 ); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		void get( timeval * tv ) | ||
|  | 		{ | ||
|  | 			__int64 nu; | ||
|  | 			int watchdog = 0; | ||
|  | again: | ||
|  | 			DWORD m = timeGetTime(); | ||
|  | 			QueryPerformanceCounter( (LARGE_INTEGER *)&nu ); | ||
|  | 			DWORD n = timeGetTime(); | ||
|  | 			// guard against pre-emption
 | ||
|  | 			if( (watchdog++ < 10) && (n != m) ) { | ||
|  | 				goto again; | ||
|  | 			} | ||
|  | 			double nuTime = nu * ticksPerSecInv_ + timeOffset_; | ||
|  | 			if( (nu - lastRead_) & 0x7fffffff80000000ULL ) { | ||
|  | 				//  there's a chance that we're seeing a jump-ahead
 | ||
|  | 				double adjust = (nuTime - lastTime_ - (n - lastTicks_) * 0.001); | ||
|  | 				if( adjust > 0.1f ) { | ||
|  | 					timeOffset_ -= adjust; | ||
|  | 					nuTime -= adjust; | ||
|  | 					assert( nuTime >= lastTime_ ); | ||
|  | 				} | ||
|  | 			} | ||
|  | 			lastRead_ = nu; | ||
|  | 			lastTicks_ = n; | ||
|  | 			lastTime_ = nuTime; | ||
|  | 			tv->tv_sec = (ulong)floor( nuTime ); | ||
|  | 			tv->tv_usec = (ulong)(1000000 * (nuTime - tv->tv_sec)); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		double ticksPerSecInv_; | ||
|  | 		double timeOffset_; | ||
|  | 		double lastTime_; | ||
|  | 		__int64 lastRead_; | ||
|  | 		DWORD lastTicks_; | ||
|  | 	}; | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | void gettimeofday( timeval * tv, int ) | ||
|  | { | ||
|  | 	static init_gettimeofday data; | ||
|  | 	data.get( tv ); | ||
|  | } | ||
|  | 
 | ||
|  | #else
 | ||
|  | #error "don't know how to do this"
 | ||
|  | #endif
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if NEED_WINDOWS_POLL
 | ||
|  | #if defined( WIN32 )
 | ||
|  | 
 | ||
|  | #include <assert.h>
 | ||
|  | #include <winsock2.h>
 | ||
|  | #include <windows.h>
 | ||
|  | 
 | ||
|  | //  This is somewhat less than ideal -- better would be if we could 
 | ||
|  | //  abstract pollfd enough that it's non-copying on Windows.
 | ||
|  | int poll( pollfd * iofds, size_t count, int ms ) | ||
|  | { | ||
|  | 	FD_SET rd, wr, ex; | ||
|  | 	FD_ZERO( &rd ); | ||
|  | 	FD_ZERO( &wr ); | ||
|  | 	FD_ZERO( &ex ); | ||
|  | 	SOCKET m = 0; | ||
|  | 	for( size_t ix = 0; ix < count; ++ix ) { | ||
|  | 		iofds[ix].revents = 0; | ||
|  | 		if( iofds[ix].fd >= m ) { | ||
|  | 			m = iofds[ix].fd + 1; | ||
|  | 		} | ||
|  | 		if( iofds[ix].events & (POLLIN | POLLPRI) ) { | ||
|  | 			assert( rd.fd_count < FD_SETSIZE ); | ||
|  | 			rd.fd_array[ rd.fd_count++ ] = iofds[ix].fd; | ||
|  | 		} | ||
|  | 		if( iofds[ix].events & (POLLOUT) ) { | ||
|  | 			assert( wr.fd_count < FD_SETSIZE ); | ||
|  | 			wr.fd_array[ wr.fd_count++ ] = iofds[ix].fd; | ||
|  | 		} | ||
|  | 		assert( ex.fd_count < FD_SETSIZE ); | ||
|  | 		ex.fd_array[ ex.fd_count++ ] = iofds[ix].fd; | ||
|  | 	} | ||
|  | 	timeval tv; | ||
|  | 	tv.tv_sec = ms/1000; | ||
|  | 	tv.tv_usec = (ms - (tv.tv_sec * 1000)) * 1000; | ||
|  | 	int r = 0; | ||
|  | 	if( m == 0 ) { | ||
|  | 		::Sleep( ms ); | ||
|  | 	} | ||
|  | 	else { | ||
|  | 		r = ::select( (int)m, (rd.fd_count ? &rd : 0), (wr.fd_count ? &wr : 0), (ex.fd_count ? &ex : 0), &tv ); | ||
|  | 	} | ||
|  | 	if( r < 0 ) { | ||
|  | 		int err = WSAGetLastError(); | ||
|  | 		errno = err; | ||
|  | 		return r; | ||
|  | 	} | ||
|  | 	r = 0; | ||
|  | 	for( size_t ix = 0; ix < count; ++ix ) { | ||
|  | 		for( size_t iy = 0; iy < rd.fd_count; ++iy ) { | ||
|  | 			if( rd.fd_array[ iy ] == iofds[ix].fd ) { | ||
|  | 				iofds[ix].revents |= POLLIN; | ||
|  | 				++r; | ||
|  | 				break; | ||
|  | 			} | ||
|  | 		} | ||
|  | 		for( size_t iy = 0; iy < wr.fd_count; ++iy ) { | ||
|  | 			if( wr.fd_array[ iy ] == iofds[ix].fd ) { | ||
|  | 				iofds[ix].revents |= POLLOUT; | ||
|  | 				++r; | ||
|  | 				break; | ||
|  | 			} | ||
|  | 		} | ||
|  | 		for( size_t iy = 0; iy < ex.fd_count; ++iy ) { | ||
|  | 			if( ex.fd_array[ iy ] == iofds[ix].fd ) { | ||
|  | 				iofds[ix].revents |= POLLERR; | ||
|  | 				++r; | ||
|  | 				break; | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | 	return r; | ||
|  | } | ||
|  | 
 | ||
|  | #else
 | ||
|  | #error "don't know how to do this"
 | ||
|  | #endif
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #if NEED_FIREWALL_ENABLE
 | ||
|  | #if defined( WIN32 )
 | ||
|  | 
 | ||
|  | #undef _WIN32_WINNT
 | ||
|  | #define _WIN32_WINNT 0x500
 | ||
|  | 
 | ||
|  | #include <objbase.h>
 | ||
|  | #include <oleauto.h>
 | ||
|  | //#include <netfw.h>
 | ||
|  | 
 | ||
|  | /*
 | ||
|  | #define _ASSERT assert
 | ||
|  | 
 | ||
|  | namespace { | ||
|  | 
 | ||
|  | 	HRESULT WindowsFirewallInitialize(OUT INetFwProfile** fwProfile) | ||
|  | 	{ | ||
|  | 		HRESULT hr = S_OK; | ||
|  | 		INetFwMgr* fwMgr = NULL; | ||
|  | 		INetFwPolicy* fwPolicy = NULL; | ||
|  | 
 | ||
|  | 		_ASSERT(fwProfile != NULL); | ||
|  | 
 | ||
|  | 		*fwProfile = NULL; | ||
|  | 
 | ||
|  | 		// Create an instance of the firewall settings manager.
 | ||
|  | 		hr = CoCreateInstance( | ||
|  | 			__uuidof(NetFwMgr), | ||
|  | 			NULL, | ||
|  | 			CLSCTX_INPROC_SERVER, | ||
|  | 			__uuidof(INetFwMgr), | ||
|  | 			(void**)&fwMgr | ||
|  | 			); | ||
|  | 		if (FAILED(hr)) | ||
|  | 		{ | ||
|  | 			printf("CoCreateInstance failed: 0x%08lx\n", hr); | ||
|  | 			goto error; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Retrieve the local firewall policy.
 | ||
|  | 		hr = fwMgr->get_LocalPolicy(&fwPolicy); | ||
|  | 		if (FAILED(hr)) | ||
|  | 		{ | ||
|  | 			printf("get_LocalPolicy failed: 0x%08lx\n", hr); | ||
|  | 			goto error; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Retrieve the firewall profile currently in effect.
 | ||
|  | 		hr = fwPolicy->get_CurrentProfile(fwProfile); | ||
|  | 		if (FAILED(hr)) | ||
|  | 		{ | ||
|  | 			printf("get_CurrentProfile failed: 0x%08lx\n", hr); | ||
|  | 			goto error; | ||
|  | 		} | ||
|  | 
 | ||
|  | error: | ||
|  | 
 | ||
|  | 		// Release the local firewall policy.
 | ||
|  | 		if (fwPolicy != NULL) | ||
|  | 		{ | ||
|  | 			fwPolicy->Release(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Release the firewall settings manager.
 | ||
|  | 		if (fwMgr != NULL) | ||
|  | 		{ | ||
|  | 			fwMgr->Release(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return hr; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	void WindowsFirewallCleanup(IN INetFwProfile* fwProfile) | ||
|  | 	{ | ||
|  | 		// Release the firewall profile.
 | ||
|  | 		if (fwProfile != NULL) | ||
|  | 		{ | ||
|  | 			fwProfile->Release(); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	HRESULT WindowsFirewallAppIsEnabled( | ||
|  | 		IN INetFwProfile* fwProfile, | ||
|  | 		IN const wchar_t* fwProcessImageFileName, | ||
|  | 		OUT BOOL* fwAppEnabled | ||
|  | 		) | ||
|  | 	{ | ||
|  | 		HRESULT hr = S_OK; | ||
|  | 		BSTR fwBstrProcessImageFileName = NULL; | ||
|  | 		VARIANT_BOOL fwEnabled; | ||
|  | 		INetFwAuthorizedApplication* fwApp = NULL; | ||
|  | 		INetFwAuthorizedApplications* fwApps = NULL; | ||
|  | 
 | ||
|  | 		_ASSERT(fwProfile != NULL); | ||
|  | 		_ASSERT(fwProcessImageFileName != NULL); | ||
|  | 		_ASSERT(fwAppEnabled != NULL); | ||
|  | 
 | ||
|  | 		*fwAppEnabled = FALSE; | ||
|  | 
 | ||
|  | 		// Retrieve the authorized application collection.
 | ||
|  | 		hr = fwProfile->get_AuthorizedApplications(&fwApps); | ||
|  | 		if (FAILED(hr)) | ||
|  | 		{ | ||
|  | 			printf("get_AuthorizedApplications failed: 0x%08lx\n", hr); | ||
|  | 			goto error; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Allocate a BSTR for the process image file name.
 | ||
|  | 		fwBstrProcessImageFileName = SysAllocString(fwProcessImageFileName); | ||
|  | 		if (SysStringLen(fwBstrProcessImageFileName) == 0) | ||
|  | 		{ | ||
|  | 			hr = E_OUTOFMEMORY; | ||
|  | 			printf("SysAllocString failed: 0x%08lx\n", hr); | ||
|  | 			goto error; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Attempt to retrieve the authorized application.
 | ||
|  | 		hr = fwApps->Item(fwBstrProcessImageFileName, &fwApp); | ||
|  | 		if (SUCCEEDED(hr)) | ||
|  | 		{ | ||
|  | 			// Find out if the authorized application is enabled.
 | ||
|  | 			hr = fwApp->get_Enabled(&fwEnabled); | ||
|  | 			if (FAILED(hr)) | ||
|  | 			{ | ||
|  | 				printf("get_Enabled failed: 0x%08lx\n", hr); | ||
|  | 				goto error; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			if (fwEnabled != VARIANT_FALSE) | ||
|  | 			{ | ||
|  | 				// The authorized application is enabled.
 | ||
|  | 				*fwAppEnabled = TRUE; | ||
|  | 
 | ||
|  | 				printf( | ||
|  | 					"Authorized application %lS is enabled in the firewall.\n", | ||
|  | 					fwProcessImageFileName | ||
|  | 					); | ||
|  | 			} | ||
|  | 			else | ||
|  | 			{ | ||
|  | 				printf( | ||
|  | 					"Authorized application %lS is disabled in the firewall.\n", | ||
|  | 					fwProcessImageFileName | ||
|  | 					); | ||
|  | 			} | ||
|  | 		} | ||
|  | 		else | ||
|  | 		{ | ||
|  | 			// The authorized application was not in the collection.
 | ||
|  | 			hr = S_OK; | ||
|  | 
 | ||
|  | 			printf( | ||
|  | 				"Authorized application %lS is disabled in the firewall.\n", | ||
|  | 				fwProcessImageFileName | ||
|  | 				); | ||
|  | 		} | ||
|  | 
 | ||
|  | error: | ||
|  | 
 | ||
|  | 		// Free the BSTR.
 | ||
|  | 		SysFreeString(fwBstrProcessImageFileName); | ||
|  | 
 | ||
|  | 		// Release the authorized application instance.
 | ||
|  | 		if (fwApp != NULL) | ||
|  | 		{ | ||
|  | 			fwApp->Release(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Release the authorized application collection.
 | ||
|  | 		if (fwApps != NULL) | ||
|  | 		{ | ||
|  | 			fwApps->Release(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return hr; | ||
|  | 	} | ||
|  | 
 | ||
|  | 
 | ||
|  | 	HRESULT WindowsFirewallAddApp( | ||
|  | 		IN INetFwProfile* fwProfile, | ||
|  | 		IN const wchar_t* fwProcessImageFileName, | ||
|  | 		IN const wchar_t* fwName | ||
|  | 		) | ||
|  | 	{ | ||
|  | 		HRESULT hr = S_OK; | ||
|  | 		BOOL fwAppEnabled; | ||
|  | 		BSTR fwBstrName = NULL; | ||
|  | 		BSTR fwBstrProcessImageFileName = NULL; | ||
|  | 		INetFwAuthorizedApplication* fwApp = NULL; | ||
|  | 		INetFwAuthorizedApplications* fwApps = NULL; | ||
|  | 
 | ||
|  | 		_ASSERT(fwProfile != NULL); | ||
|  | 		_ASSERT(fwProcessImageFileName != NULL); | ||
|  | 		_ASSERT(fwName != NULL); | ||
|  | 
 | ||
|  | 		// First check to see if the application is already authorized.
 | ||
|  | 		hr = WindowsFirewallAppIsEnabled( | ||
|  | 			fwProfile, | ||
|  | 			fwProcessImageFileName, | ||
|  | 			&fwAppEnabled | ||
|  | 			); | ||
|  | 		if (FAILED(hr)) | ||
|  | 		{ | ||
|  | 			printf("WindowsFirewallAppIsEnabled failed: 0x%08lx\n", hr); | ||
|  | 			goto error; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Only add the application if it isn't already authorized.
 | ||
|  | 		if (!fwAppEnabled) | ||
|  | 		{ | ||
|  | 			// Retrieve the authorized application collection.
 | ||
|  | 			hr = fwProfile->get_AuthorizedApplications(&fwApps); | ||
|  | 			if (FAILED(hr)) | ||
|  | 			{ | ||
|  | 				printf("get_AuthorizedApplications failed: 0x%08lx\n", hr); | ||
|  | 				goto error; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Create an instance of an authorized application.
 | ||
|  | 			hr = CoCreateInstance( | ||
|  | 				__uuidof(NetFwAuthorizedApplication), | ||
|  | 				NULL, | ||
|  | 				CLSCTX_INPROC_SERVER, | ||
|  | 				__uuidof(INetFwAuthorizedApplication), | ||
|  | 				(void**)&fwApp | ||
|  | 				); | ||
|  | 			if (FAILED(hr)) | ||
|  | 			{ | ||
|  | 				printf("CoCreateInstance failed: 0x%08lx\n", hr); | ||
|  | 				goto error; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Allocate a BSTR for the process image file name.
 | ||
|  | 			fwBstrProcessImageFileName = SysAllocString(fwProcessImageFileName); | ||
|  | 			if (SysStringLen(fwBstrProcessImageFileName) == 0) | ||
|  | 			{ | ||
|  | 				hr = E_OUTOFMEMORY; | ||
|  | 				printf("SysAllocString failed: 0x%08lx\n", hr); | ||
|  | 				goto error; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Set the process image file name.
 | ||
|  | 			hr = fwApp->put_ProcessImageFileName(fwBstrProcessImageFileName); | ||
|  | 			if (FAILED(hr)) | ||
|  | 			{ | ||
|  | 				printf("put_ProcessImageFileName failed: 0x%08lx\n", hr); | ||
|  | 				goto error; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Allocate a BSTR for the application friendly name.
 | ||
|  | 			fwBstrName = SysAllocString(fwName); | ||
|  | 			if (SysStringLen(fwBstrName) == 0) | ||
|  | 			{ | ||
|  | 				hr = E_OUTOFMEMORY; | ||
|  | 				printf("SysAllocString failed: 0x%08lx\n", hr); | ||
|  | 				goto error; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Set the application friendly name.
 | ||
|  | 			hr = fwApp->put_Name(fwBstrName); | ||
|  | 			if (FAILED(hr)) | ||
|  | 			{ | ||
|  | 				printf("put_Name failed: 0x%08lx\n", hr); | ||
|  | 				goto error; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Add the application to the collection.
 | ||
|  | 			hr = fwApps->Add(fwApp); | ||
|  | 			if (FAILED(hr)) | ||
|  | 			{ | ||
|  | 				printf("Add failed: 0x%08lx\n", hr); | ||
|  | 				goto error; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			printf( | ||
|  | 				"Authorized application %lS is now enabled in the firewall.\n", | ||
|  | 				fwProcessImageFileName | ||
|  | 				); | ||
|  | 		} | ||
|  | 
 | ||
|  | error: | ||
|  | 
 | ||
|  | 		// Free the BSTRs.
 | ||
|  | 		SysFreeString(fwBstrName); | ||
|  | 		SysFreeString(fwBstrProcessImageFileName); | ||
|  | 
 | ||
|  | 		// Release the authorized application instance.
 | ||
|  | 		if (fwApp != NULL) | ||
|  | 		{ | ||
|  | 			fwApp->Release(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Release the authorized application collection.
 | ||
|  | 		if (fwApps != NULL) | ||
|  | 		{ | ||
|  | 			fwApps->Release(); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return hr; | ||
|  | 	} | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | bool ENABLE_FIREWALL() | ||
|  | { | ||
|  | 	BOOL couldEnable = false; | ||
|  | 	HRESULT hr = S_OK; | ||
|  | 	HRESULT comInit = E_FAIL; | ||
|  | 	INetFwProfile* fwProfile = NULL; | ||
|  | 
 | ||
|  | 	// Initialize COM.
 | ||
|  | #if 1
 | ||
|  | 	comInit = CoInitialize( 0 ); | ||
|  | #else
 | ||
|  | 	comInit = CoInitializeEx( | ||
|  | 		0, | ||
|  | 		COINIT_APARTMENTTHREADED //| COINIT_DISABLE_OLE1DDE
 | ||
|  | 		); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | 	// Ignore RPC_E_CHANGED_MODE; this just means that COM has already been
 | ||
|  | 	// initialized with a different mode. Since we don't care what the mode is,
 | ||
|  | 	// we'll just use the existing mode.
 | ||
|  | 	if (comInit != RPC_E_CHANGED_MODE) { | ||
|  | 		hr = comInit; | ||
|  | 		if (FAILED(hr)) { | ||
|  | 			fprintf( stderr, "CoInitializeEx failed: 0x%08lx\n", hr ); | ||
|  | 			goto error; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Retrieve the firewall profile currently in effect.
 | ||
|  | 	hr = WindowsFirewallInitialize(&fwProfile); | ||
|  | 	if (FAILED(hr)) { | ||
|  | 		fprintf( stderr, "WindowsFirewallInitialize failed: 0x%08lx\n", hr ); | ||
|  | 		goto error; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	HMODULE hm = GetModuleHandle( 0 ); | ||
|  | 	wchar_t path[512]; | ||
|  | 	if( !GetModuleFileNameW( hm, path, sizeof(path)/sizeof(wchar_t) ) ) { | ||
|  | 		fprintf( stderr, "GetModuleFileName() failed: 0x%lx\n", GetLastError() ); | ||
|  | 		goto error; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Add the application to the authorized application collection.
 | ||
|  | 	hr = WindowsFirewallAddApp( | ||
|  | 		fwProfile, | ||
|  | 		path, | ||
|  | 		L"Introduction Library User" | ||
|  | 		); | ||
|  | 	if (FAILED(hr)) { | ||
|  | 		fprintf( stderr, "WindowsFirewallAddApp failed: 0x%08lx\n", hr ); | ||
|  | 		goto error; | ||
|  | 	} | ||
|  | 
 | ||
|  | error: | ||
|  | 
 | ||
|  | 	WindowsFirewallCleanup(fwProfile); | ||
|  | 
 | ||
|  | 	if (SUCCEEDED(comInit)) { | ||
|  | 		CoUninitialize(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return couldEnable != FALSE; | ||
|  | } | ||
|  | */ | ||
|  | 
 | ||
|  | #else
 | ||
|  | #error "don't know how to do this"
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #endif
 |