Click here to Skip to main content
15,868,016 members
Articles / Desktop Programming / ATL
Article

Client/Server connection using DCOM, with anonymous access

Rate me:
Please Sign up or sign in to vote.
4.17/5 (11 votes)
8 Feb 20052 min read 108.6K   3K   30   19
Quick implementation of client/server connection using DCOM.

Introduction

This article will explain implementing a quick client/server connection using DCOM.

Using the code

This article consists of two parts:

  • Server side implementation
  • Client side implementation

Let's start with server side implementation:

  1. Start 'New ATL COM Wizard project' with Visual Studio.
  2. Name it as TestServer.
  3. Select server type: Service.
  4. Insert new ATL object: Category-Objects, Objects-Simple Objects.
  5. Name the interface as IHello.
  6. Add method Beep().

Now, we need to turn off the authentication of DCOM server. Open TestServer.rgs from Workspace window and add the following lines just before 'TestServer.EXE':

{
    val AccessPermission = b '01000480300000004c000000000000001
            400000002001c000100000000021400010000000101000000000001000000000
            105000000000005150000007ceb240dfa4f0c2ff89fb474f2030000010500000
            0000005150000007ceb240dfa4f0c2ff89fb47401020000'
    val LaunchPermission = b '01000480300000004c000000000000001
            400000002001c000100000000021400010000000101000000000001000000000
            105000000000005150000007ceb240dfa4f0c2ff89fb474f2030000010500000
            0000005150000007ceb240dfa4f0c2ff89fb47401020000'
}

Open testMonitor.cpp, locate Run() function, and make it look like this:

void CServiceModule::Run()
{
    _Module.dwThreadID = GetCurrentThreadId();

    //This means that calls come in on a random RPC thread
    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

    // This provides a NULL DACL which will allow access to everyone.
    hr = CoInitializeSecurity( 0, -1, 0, 0, 
         RPC_C_AUTHN_LEVEL_NONE, 
         RPC_C_IMP_LEVEL_IDENTIFY, 0, 0, 0 );
    hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | 
         CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE);
    ..............

Finally, add the following line to Beep() method and the server side is ready!!!

MessageBeep(MB_ICONEXCLAMATION);

Now, let's implement the client:

  1. Start 'New MFC App Wizard, dialog based, name it TestClient.
  2. Insert Resource, Custom, and name it exactly TYPELIB.
  3. ID of TYPELIB resource must be 1.
  4. Open property page for TYPELIB resource and specify path to file as TestServer.tlb.
  5. Add #import "..//TestServer/testserver.tlb" no_namespace line to stdafx.h.
  6. Add includes for Afxctl.h, objbase.h and initguid.h to stdafx.h.
  7. Add _WIN32_DCOM to preprocessor definitions.

Now, we need to add the actual connection code. Add the following Connect() function to your app class:

IIHello* CTestClientApp::Connect(CString& strIPAddress, CString& strError)
{
    // register type library
    CLSID libid;

    CLSIDFromString (L"{55259785-1985-4DCB-B4BA-FCB7F968DFA4}", &libid);

    if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), libid))
    {
        AfxMessageBox("Failed to register server's type library");
        return NULL;
    }

    CLSID clsid;
    const IID IID_IHELLO = {0xFB57F08C,0x0F91,0x4046, 
              {0x8E,0xF1,0x05,0xD8,0x90,0x4C,0x66,0xF0}};
    MULTI_QI mqi = { &IID_IHELLO, 0, 0 };

    CLSIDFromString (L"{C7B7C24F-5B72-49D0-962B-FFD650BFFA2B}", &clsid);
    CoInitialize(0);
    COAUTHINFO cai = {  RPC_C_AUTHN_NONE,
                        RPC_C_AUTHZ_NONE,
                        0,
                        RPC_C_AUTHN_LEVEL_NONE,
                        RPC_C_IMP_LEVEL_IMPERSONATE,
                        0,
                        EOAC_NONE};

    COSERVERINFO csi = { 0, strIPAddress.AllocSysString(), &cai, 0 };

    HRESULT hr = CoCreateInstanceEx(clsid, NULL, 
                 CLSCTX_REMOTE_SERVER, &csi, 1, &mqi);

    if (FAILED(hr))
    {

        TCHAR szError[1024];
        FormatMessage(  FORMAT_MESSAGE_FROM_SYSTEM,
                        NULL,
                        hr,
                        MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
                        szError,
                        1024,
                        NULL);
        strError = szError;
        return FALSE;
    }

    return (IIHello*)(mqi.pItf);
}

From the code provided above, it can be seen that three GUIDs are needed: LIBID, CLASSID, and ITERFACEID. All of them must be taken from testserver.idl. Our connection code example is a bit hard-coded, but it allows to run the client on any machine without any registration. Server has to be registered before use. Since this is a DCOM server, it can be registered as a service or as a local server. To register the server as a service, type:

testserver /Service

To register the server as a local server, type:

testserver /RegServer

And finally, let's execute Beep() method on the remote server. To do that, let's just add a handler for the Beep button.

void CTestClientDlg::OnButtonBeep()
{
    ((CTestClientApp*)AfxGetApp())->m_pHello->Beep();
}

Hope this wasn't boring, but useful :-)

History

  • 06/02/2005 - Initial document creation.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 3 Pin
Michael Chourdakis22-Jul-12 0:12
mvaMichael Chourdakis22-Jul-12 0:12 
Access denied. It works only for local PC server.
GeneralAccess is denied Pin
Manik_Fulpagar9-Jun-08 23:53
Manik_Fulpagar9-Jun-08 23:53 
GeneralAccess Denied or class not register Pin
sanjayrvyas27-Sep-07 1:41
sanjayrvyas27-Sep-07 1:41 
QuestionDCOM vb Client Pin
sivakumar Ganesan 8318-Dec-06 5:10
sivakumar Ganesan 8318-Dec-06 5:10 
GeneralGenerate & Build Proxy dll for DCOM Pin
Ashwin kumar Gurujala13-Dec-05 22:34
Ashwin kumar Gurujala13-Dec-05 22:34 
GeneralRe: Generate & Build Proxy dll for DCOM Pin
Ashwin kumar Gurujala13-Dec-05 22:35
Ashwin kumar Gurujala13-Dec-05 22:35 
GeneralAccess is denied Pin
shijith nair17-May-05 23:52
shijith nair17-May-05 23:52 
GeneralRe: Access is denied Pin
Layla5522-Jun-05 4:00
Layla5522-Jun-05 4:00 
GeneralRe: Access is denied Pin
kevinlzj8-May-06 22:00
kevinlzj8-May-06 22:00 
GeneralRe: Access is denied Pin
shibu george20-Jul-06 19:18
shibu george20-Jul-06 19:18 
GeneralRPC-Server Pin
NightShark15-Feb-05 0:13
NightShark15-Feb-05 0:13 
GeneralRe: RPC-Server Pin
Vigen Dolbakyan15-Feb-05 5:43
Vigen Dolbakyan15-Feb-05 5:43 
GeneralRe: RPC-Server Pin
NightShark15-Feb-05 11:32
NightShark15-Feb-05 11:32 
GeneralRe: RPC-Server Pin
skchow14-Mar-05 16:01
skchow14-Mar-05 16:01 
GeneralRe: RPC-Server Pin
Anonymous14-Apr-05 3:58
Anonymous14-Apr-05 3:58 
GeneralRe: RPC-Server Pin
Grol214-Apr-10 3:30
Grol214-Apr-10 3:30 
GeneralVS.NET 2003 Pin
briviere29-Feb-05 5:59
briviere29-Feb-05 5:59 
GeneralRe: VS.NET 2003 Pin
briviere29-Feb-05 6:01
briviere29-Feb-05 6:01 
GeneralRe: VS.NET 2003 Pin
Vigen Dolbakyan9-Feb-05 6:02
Vigen Dolbakyan9-Feb-05 6:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.