268 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			268 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // **************************************************************************
 | |
| // Copyright (c) 1997-1999 Microsoft Corporation.
 | |
| //
 | |
| // File:  CmdLineConsumer.cpp
 | |
| //
 | |
| // Description:
 | |
| //	This file defines the class behaviors for the command-line
 | |
| //	event consumer application.
 | |
| // 
 | |
| // History:
 | |
| //
 | |
| // **************************************************************************
 | |
| 
 | |
| #include "stdafx.h"
 | |
| #include "CmdLineConsumer.h"
 | |
| #include "CmdLineConsumerDlg.h"
 | |
| #include <objbase.h>
 | |
| 
 | |
| #ifdef _DEBUG
 | |
| #define new DEBUG_NEW
 | |
| #undef THIS_FILE
 | |
| static char THIS_FILE[] = __FILE__;
 | |
| #endif
 | |
| 
 | |
| /////////////////////////////////////////////////////////////////////////////
 | |
| // CCmdLineConsumerApp
 | |
| 
 | |
| BEGIN_MESSAGE_MAP(CCmdLineConsumerApp, CWinApp)
 | |
| 	//{{AFX_MSG_MAP(CCmdLineConsumerApp)
 | |
| 		// NOTE - the ClassWizard will add and remove mapping macros here.
 | |
| 		//    DO NOT EDIT what you see in these blocks of generated code!
 | |
| 	//}}AFX_MSG
 | |
| 	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
 | |
| END_MESSAGE_MAP()
 | |
| 
 | |
| /////////////////////////////////////////////////////////////////////////////
 | |
| // CCmdLineConsumerApp construction
 | |
| 
 | |
| CCmdLineConsumerApp::CCmdLineConsumerApp()
 | |
| {
 | |
| 	// TODO: add construction code here,
 | |
| 	// Place all significant initialization in InitInstance
 | |
| 	m_clsReg = 0;
 | |
| }
 | |
| 
 | |
| /////////////////////////////////////////////////////////////////////////////
 | |
| // The one and only CCmdLineConsumerApp object
 | |
| 
 | |
| CCmdLineConsumerApp theApp;
 | |
| 
 | |
| // {892C6A1B-266C-4699-96FA-2FF67D647FC8}
 | |
| static const GUID CLSID_BVTBVTPermConsumer = 
 | |
| { 0x892c6a1b, 0x266c, 0x4699, { 0x96, 0xfa, 0x2f, 0xf6, 0x7d, 0x64, 0x7f, 0xc8 } };
 | |
| 
 | |
| /////////////////////////////////////////////////////////////////////////////
 | |
| // CCmdLineConsumerApp initialization
 | |
| 
 | |
| BOOL CCmdLineConsumerApp::InitInstance()
 | |
| {
 | |
| 	HRESULT hRes;
 | |
| 	BOOL regEmpty = FALSE; // did a self-unregister happen?
 | |
| 
 | |
| 	// OLE initialization. This is 'lighter' than OleInitialize()
 | |
| 	//  which also setups DnD, etc.
 | |
| 	if(SUCCEEDED(CoInitialize(NULL))) 
 | |
| 	{
 | |
| 		// NOTE: This is needed to work around a security problem
 | |
| 		// when using IWBEMObjectSink. The sink wont normally accept
 | |
| 		// calls when the caller wont identify themselves. This
 | |
| 		// waives that process.
 | |
| 		hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, 
 | |
| 								RPC_C_AUTHN_LEVEL_CONNECT, 
 | |
| 								RPC_C_IMP_LEVEL_IDENTIFY, 
 | |
| 								NULL, 0, 0);
 | |
| 	}
 | |
| 	else // didnt CoInitialize()
 | |
| 	{
 | |
| 		AfxMessageBox(_T("CoInitialize Failed"));
 | |
| 		return FALSE;
 | |
| 	} // endif OleInitialize()
 | |
| 
 | |
| 	// NOTE: To advertise that we can self-register, put 'OLESelfRegister'
 | |
| 	// in the version resource.
 | |
| 
 | |
| 	// see if this is a self-Unregister call.
 | |
| 	TCHAR temp[128];
 | |
| 	TCHAR seps[] = _T(" ");
 | |
| 	TCHAR *token = NULL;
 | |
| 
 | |
| 	_tcscpy(temp, (LPCTSTR)m_lpCmdLine);
 | |
| 	token = _tcstok( temp, seps );
 | |
| 	while( token != NULL )
 | |
| 	{
 | |
| 		/* While there are tokens in "string" */
 | |
| 		if(_tcscmp(token, _T("/UNREGSERVER")) == 0)
 | |
| 		{
 | |
| 			UnregisterServer();
 | |
| 			return FALSE;		// no use doing any more.
 | |
| 		}
 | |
| 		/* Get next token: */
 | |
| 		token = _tcstok( NULL, seps );
 | |
| 	}
 | |
| 
 | |
| 	// if we got here, the unregister didn't return out and we should
 | |
| 	// make sure we're registered now.
 | |
| 	RegisterServer();
 | |
| 
 | |
| 	// creating the dlg earlier than usual so the class factory 
 | |
| 	//	can pass m_outputList.
 | |
| 	CCmdLineConsumerDlg dlg;
 | |
| 
 | |
| 	m_factory = new CProviderFactory(&(dlg.m_output));
 | |
| 
 | |
| 	if((hRes = CoRegisterClassObject(CLSID_BVTBVTPermConsumer,
 | |
| 							(IUnknown *)m_factory,
 | |
| 							CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
 | |
| 							REGCLS_MULTIPLEUSE,
 | |
| 							&m_clsReg)) == S_OK)
 | |
| 	{
 | |
| 		TRACE(_T("registered\n"));
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		TRACE(_T("not registered\n"));
 | |
| 	}
 | |
| 
 | |
| #ifdef _AFXDLL
 | |
| 	Enable3dControls();			// Call this when using MFC in a shared DLL
 | |
| #else
 | |
| 	Enable3dControlsStatic();	// Call this when linking to MFC statically
 | |
| #endif
 | |
| 
 | |
| 	m_pMainWnd = &dlg;
 | |
| 	int nResponse = dlg.DoModal();
 | |
| 	if (nResponse == IDOK)
 | |
| 	{
 | |
| 		// TODO: Place code here to handle when the dialog is
 | |
| 		//  dismissed with OK
 | |
| 	}
 | |
| 	else if (nResponse == IDCANCEL)
 | |
| 	{
 | |
| 		// TODO: Place code here to handle when the dialog is
 | |
| 		//  dismissed with Cancel
 | |
| 	}
 | |
| 
 | |
| 	// Since the dialog has been closed, return FALSE so that we exit the
 | |
| 	//  application, rather than start the application's message pump.
 | |
| 	return FALSE;
 | |
| }
 | |
| 
 | |
| //-----------------------------------------------------------
 | |
| int CCmdLineConsumerApp::ExitInstance()
 | |
| {
 | |
| 	if(m_clsReg)
 | |
| 	{
 | |
| 		HRESULT hres = CoRevokeClassObject(m_clsReg);
 | |
| 
 | |
| 		CoUninitialize();
 | |
| 	}
 | |
| 
 | |
| 	return CWinApp::ExitInstance();
 | |
| }
 | |
| 
 | |
| #define TCHAR_LEN_IN_BYTES(str)	 _tcslen(str)*sizeof(TCHAR)+sizeof(TCHAR)
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| // DllRegisterServer
 | |
| //
 | |
| // Purpose: Called during setup or by regsvr32.
 | |
| //
 | |
| // Return:  NOERROR if registration successful, error otherwise.
 | |
| // Note: Key setups are:
 | |
| //		HKCR\CLSID\[guid]= friendly name
 | |
| //		HKCR\CLSID\[guid]\LocalServer32 = exe's path.
 | |
| //		HKCR\CLSID\AppID = [guid]
 | |
| //		HKCR\AppID\[guid] = friendly name
 | |
| //		HKCR\AppID\[guid] = 'RunAs' = "Interactive User"
 | |
| //			'RunAs' is a value name; not a subkey.
 | |
| //***************************************************************************
 | |
| void CCmdLineConsumerApp::RegisterServer(void)
 | |
| {   
 | |
| 	HKEY hKey1, hKey2;
 | |
| 
 | |
| 	TCHAR       wcConsID[] = _T("{892C6A1B-266C-4699-96FA-2FF67D647FC8}");
 | |
|     TCHAR       wcCLSID[] = _T("CLSID\\{892C6A1B-266C-4699-96FA-2FF67D647FC8}");
 | |
|     TCHAR       wcAppID[] = _T("AppID\\{892C6A1B-266C-4699-96FA-2FF67D647FC8}");
 | |
|     TCHAR      wcModule[128];	// this will hold the exe's path.
 | |
| 	TCHAR ConsumerTextForm[] = _T("Microsoft Cmd Line Consumer");
 | |
| 
 | |
| 	// this will allow the server to display its windows on the active desktop instead
 | |
| 	// of the hidden desktop where services run.
 | |
| 	TCHAR Interactive[] = _T("Interactive User");
 | |
| 
 | |
| 
 | |
| 	GetModuleFileName(NULL, wcModule,  128);
 | |
| 
 | |
| 	//Set the "default" text under CLSID
 | |
| 	//==========================
 | |
| 	RegCreateKey(HKEY_CLASSES_ROOT, wcCLSID, &hKey1);
 | |
| 	RegSetValueEx(hKey1, NULL, 0, REG_SZ, 
 | |
| 					(LPBYTE)ConsumerTextForm, 
 | |
| 					TCHAR_LEN_IN_BYTES(ConsumerTextForm));
 | |
| 
 | |
| 	// create the LocalServer32 key so the server can be found.
 | |
| 	RegCreateKey(hKey1, _T("LocalServer32"), &hKey2);
 | |
| 	RegSetValueEx(hKey2, NULL, 0, REG_SZ, (LPBYTE)wcModule, TCHAR_LEN_IN_BYTES(wcModule));
 | |
| 	RegSetValueEx(hKey1, _T("AppID"), 0, REG_SZ, (LPBYTE)wcConsID, TCHAR_LEN_IN_BYTES(wcConsID));
 | |
| 
 | |
| 	CloseHandle(hKey2);
 | |
| 	CloseHandle(hKey1);
 | |
| 
 | |
| 	// now do the AppID keys.
 | |
| 	RegCreateKey(HKEY_CLASSES_ROOT, wcAppID, &hKey1);
 | |
| 	RegSetValueEx(hKey1, NULL, 0, REG_SZ, 
 | |
| 					(LPBYTE)ConsumerTextForm, 
 | |
| 					TCHAR_LEN_IN_BYTES(ConsumerTextForm));
 | |
| 
 | |
| 	// this makes the local server run on the active desktop (the one you're seeing) 
 | |
| 	// instead of the hidden desktop that services run on (which doesn't have UI)
 | |
| 	RegSetValueEx(hKey1, _T("RunAs"), 0, REG_SZ, (LPBYTE)Interactive, TCHAR_LEN_IN_BYTES(Interactive));
 | |
| 	CloseHandle(hKey1);
 | |
| }
 | |
| 
 | |
| //***************************************************************************
 | |
| //
 | |
| // DllUnregisterServer
 | |
| //
 | |
| // Purpose: Called when it is time to remove the registry entries.
 | |
| //
 | |
| // Return:  NOERROR if registration successful, error otherwise.
 | |
| //***************************************************************************
 | |
| void CCmdLineConsumerApp::UnregisterServer(void)
 | |
| {
 | |
|  
 | |
| 	TCHAR       wcConsID[] = _T("{892C6A1B-266C-4699-96FA-2FF67D647FC8}");
 | |
|     TCHAR       wcCLSID[] = _T("CLSID\\{892C6A1B-266C-4699-96FA-2FF67D647FC8}");
 | |
|     TCHAR       wcAppID[] = _T("AppID\\{892C6A1B-266C-4699-96FA-2FF67D647FC8}");
 | |
|     HKEY hKey1;
 | |
| 	DWORD dwRet;
 | |
| 
 | |
| 	// delete the keys under CLSID\[guid]
 | |
|     dwRet = RegOpenKey(HKEY_CLASSES_ROOT, wcCLSID, &hKey1);
 | |
|     if(dwRet == NOERROR)
 | |
|     {
 | |
|         RegDeleteKey(hKey1, _T("LocalServer32"));
 | |
|         CloseHandle(hKey1);
 | |
|     }
 | |
| 
 | |
| 	// delete CLSID\[guid] <default>
 | |
|     dwRet = RegOpenKey(HKEY_CLASSES_ROOT, _T("CLSID"), &hKey1);
 | |
|     if(dwRet == NOERROR)
 | |
|     {
 | |
|         RegDeleteKey(hKey1,wcConsID);
 | |
|         CloseHandle(hKey1);
 | |
|     }
 | |
| 
 | |
| 	// delete AppID\[guid] <default>
 | |
|     dwRet = RegOpenKey(HKEY_CLASSES_ROOT, _T("AppID"), &hKey1);
 | |
|     if(dwRet == NOERROR)
 | |
|     {
 | |
|         RegDeleteKey(hKey1, wcConsID);
 | |
|         CloseHandle(hKey1);
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 |