/********************************************************************
Copyright (c) 1999 Microsoft Corporation

Module Name:
    sfprpcs.cpp

Abstract:
    implements server rpc thread - exported in  SFPSAPI.LIB
               server shutdown - exported in  SFPSAPI.LIB
    
Revision History:

    Brijesh Krishnaswami (brijeshk) - 06/16/99 - Created

********************************************************************/

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "srrpc.h"    // header file generated by MIDL compiler
#include "srdefs.h"
#include "utils.h"
#include <dbgtrace.h>

#ifdef THIS_FILE
#undef THIS_FILE
#endif
static char __szTraceSourceFile[] = __FILE__;
#define THIS_FILE __szTraceSourceFile


#define MIN_RPC_CALLS 1
#define MAX_RPC_CALLS 5


RPC_STATUS RPC_ENTRY SecurityCallBack (RPC_IF_HANDLE hInterface,
                                       handle_t hBinding)
{
    RPC_STATUS status = RPC_S_OK;
    UINT fLocal = FALSE;
    RPC_AUTHZ_HANDLE hPrivs;
    DWORD dwAuthn;

    status = I_RpcBindingIsClientLocal (hBinding, &fLocal);
    if (status != RPC_S_OK || fLocal == FALSE)
    {
        status = ERROR_ACCESS_DENIED;
        goto done;
    }

    status = RpcBindingInqAuthClient (hBinding,
                                     &hPrivs,
                                     NULL,
                                     &dwAuthn,
                                     NULL,
                                     NULL);

    if (status != RPC_S_OK || dwAuthn < RPC_C_AUTHN_LEVEL_PKT_INTEGRITY)
    {
        status = ERROR_ACCESS_DENIED;
        goto done;
    }
    
done:
    return status;
}

// RPC Server 
// registers as an rpc server and waits for requests

extern "C" DWORD WINAPI
RpcServerStart()
{   
    RPC_STATUS  status;

    TENTER("RpcServerStart");
    
    status = RpcServerRegisterAuthInfo(L"NT AUTHORITY\\SYSTEM",
                                       RPC_C_AUTHN_WINNT, 
                                       0,
                                       0);

    if (status != RPC_S_OK)
    {
        TRACE(0, "! RpcServerRegisterAuthInfo : %ld", status);
        goto exit;
    }

    // specify to use the local rpc protocol sequence
    status = RpcServerUseProtseqEp(s_cszRPCProtocol,
                                   MAX_RPC_CALLS,
                                   s_cszRPCEndPoint,
                                   NULL);  // Security descriptor
    if (status != 0 && status != RPC_S_DUPLICATE_ENDPOINT) 
    {
        TRACE(0, "! RpcServerUseProtseqEp : %ld", status);
        goto exit;
    }

    // register the srrpc interface
    status = RpcServerRegisterIfEx(srrpc_ServerIfHandle,  // interface to register
                                   NULL,    // MgrTypeUuid
                                   NULL,    // MgrEpv; null means use default
                                   RPC_IF_AUTOLISTEN |  // auto-listen interface
                                   RPC_IF_ALLOW_SECURE_ONLY,
                                   MAX_RPC_CALLS,       // max concurrent calls
                                   SecurityCallBack);   // callback
    if (status) 
    {
        TRACE(0, "! RpcServerRegisterIfEx : %ld", status);    
        goto exit;
    }

    TRACE(0, "Started to listen to RPC calls");

exit:
    TLEAVE();
    return status;
}


// function to shut down the rpc server 

extern "C" DWORD WINAPI
RpcServerShutdown()
{
    RPC_STATUS status;

    TENTER("RpcServerShutdown");
    
    // unregister the server endpoint
    status = RpcServerUnregisterIf(srrpc_ServerIfHandle, NULL, TRUE);
    if (status)
    {
        TRACE(0, "! RpcServerUnregisterIf : %ld", status);    
        goto exit;
    }

exit:
    TLEAVE();
    return status;
}



// functions used by midl compiler to allocate and free memory
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
    return(SRMemAlloc((DWORD) len));
}

void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
    SRMemFree(ptr);
}



