CXHNDLC.C
/**************************************************************************** 
                   Microsoft RPC Version 2.0 
           Copyright Microsoft Corp. 1992, 1993, 1994- 1996 
                      cxhndl Example 
 
    FILE:       cxhndlc.c 
 
    USAGE:      cxhndlc  -n network_address 
                         -p protocol_sequence 
                         -e endpoint 
                         -o options 
                         -f filename 
 
    PURPOSE:    Client side of RPC distributed application 
 
    FUNCTIONS:  main() - binds to server and calls remote procedure 
 
    COMMENTS:   This distributed application uses a context handle. 
 
****************************************************************************/ 
 
#include <stdlib.h> 
#include <stdio.h> 
#include "cxhndl.h"    // header file generated by MIDL compiler 
 
 
#define PURPOSE \ 
"This Microsoft RPC Version 2.0 sample program demonstrates\n\ 
the use of the [context_handle] attribute. For more information\n\ 
about attributes and RPC API functions, see the RPC programming\n\ 
guide and reference.\n\n" 
 
 
void Usage(char * pszProgramName) 
{ 
    fprintf(stderr, "%s", PURPOSE); 
    fprintf(stderr, "Usage:  %s\n", pszProgramName); 
    fprintf(stderr, " -p protocol_sequence\n"); 
    fprintf(stderr, " -n network_address\n"); 
    fprintf(stderr, " -e endpoint\n"); 
    fprintf(stderr, " -o options\n"); 
    fprintf(stderr, " -f filename\n"); 
    exit(1); 
} 
 
void _CRTAPI1 main(int argc, char **argv) 
{ 
    RPC_STATUS status; 
    PCONTEXT_HANDLE_TYPE phContext = NULL; 
 
    unsigned char * pbBuf = NULL; 
    short cbRead;    // count of bytes read 
 
    unsigned char * pszUuid             = NULL; 
    unsigned char * pszProtocolSequence = "ncacn_np"; 
    unsigned char * pszNetworkAddress   = NULL; 
    unsigned char * pszEndpoint         = "\\pipe\\cxhndl"; 
    unsigned char * pszOptions          = NULL; 
    unsigned char * pszStringBinding    = NULL; 
    unsigned char * pszFileName         = "readme.txt"; 
    int i; 
 
    /* allow the user to override settings with command line switches */ 
    for (i = 1; i < argc; i++) { 
        if ((*argv[i] == '-') || (*argv[i] == '/')) { 
            switch (tolower(*(argv[i]+1))) { 
            case 'p':  // protocol sequence 
                pszProtocolSequence = argv[++i]; 
                break; 
            case 'n':  // network address 
                pszNetworkAddress = argv[++i]; 
                break; 
            case 'e': 
                pszEndpoint = argv[++i]; 
                break; 
            case 'o': 
                pszOptions = argv[++i]; 
                break; 
            case 'f': 
                pszFileName = argv[++i]; 
                break; 
            case 'h': 
            case '?': 
            default: 
                Usage(argv[0]); 
            } 
        } 
        else 
            Usage(argv[0]); 
    } 
 
    pbBuf = (unsigned char *) 
            midl_user_allocate(BUFSIZE * sizeof(unsigned char)); 
 
    /* Use a convenience function to concatenate the elements of  */ 
    /* the string binding into the proper sequence.               */ 
    status = RpcStringBindingCompose(pszUuid, 
                                     pszProtocolSequence, 
                                     pszNetworkAddress, 
                                     pszEndpoint, 
                                     pszOptions, 
                                     &pszStringBinding); 
    printf("RpcStringBindingCompose returned 0x%x\n", status); 
    printf("pszStringBinding = %s\n", pszStringBinding); 
    if (status) { 
        exit(status); 
    } 
 
    /* Set the binding handle that will be used to bind to the server. */ 
    status = RpcBindingFromStringBinding(pszStringBinding, 
                                         &hStarter); 
    printf("RpcBindingFromStringBinding returned 0x%x\n", status); 
    if (status) { 
        exit(status); 
    } 
 
    printf("Calling the remote procedure RemoteOpen\n"); 
    if (RemoteOpen(&phContext, pszFileName) < 0) { 
        printf("Unable to open %s\n", pszFileName); 
        Shutdown(); 
        exit(2); 
    } 
 
    /* Now the context handle also manages the binding. */ 
    status = RpcBindingFree(&hStarter); 
    printf("RpcBindingFree returned 0x%x\n", status); 
    if (status) { 
        exit(status); 
    } 
 
    /*  Free the string binding */ 
    status = RpcStringFree(&pszStringBinding); 
    printf("RpcStringFree returned 0x%x\n", status); 
    if (status) { 
        exit(status); 
    } 
 
    printf("Calling the remote procedure RemoteRead\n"); 
    while (RemoteRead(phContext, pbBuf, &cbRead) > 0) { 
        for (i = 0; i < cbRead; i++) 
            putchar(*(pbBuf+i)); 
    } 
 
    printf("Calling the remote procedure RemoteClose\n"); 
    if (RemoteClose(&phContext) < 0 ) { 
        printf("Close failed on %s\n", pszFileName); 
        exit(2); 
    } 
 
    exit(0); 
 
}  // end main() 
 
 
/*********************************************************************/ 
/*                 MIDL allocate and free                            */ 
/*********************************************************************/ 
 
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) 
{ 
    return(malloc(len)); 
} 
 
void __RPC_USER midl_user_free(void __RPC_FAR * ptr) 
{ 
    free(ptr); 
} 
 
/* end cxhndlc.c */