/* --------------------------------------------------------------------
 
File : reg.h

Title : registry look up routine used for netbios transport

Description :

History :

19-1-95    Tony Chan        

-------------------------------------------------------------------- */
#ifndef _REGH
#define _REGH

#include "common.h"


#define MAX_LANA 255

                                /* for registry lookup */
PROTOCOL_MAP ProtoToLana[MAX_LANA] = { 0};

                                /* number of Network cards */
int NumCards;

#define ProtocolTable   ProtoToLana

#define RPC_REG_ROOT HKEY_LOCAL_MACHINE
#define REG_NETBIOS "Software\\Microsoft\\Rpc\\NetBios"



// The maximum send is the size of four user data frames on an ethernet.
#define HOSTNAME_LEN       NETBIOS_NAME_LENGTH

void
unicode_to_ascii ( RPC_CHAR * in, unsigned char * out )
{
    unsigned char *ascii_ptr;
    RPC_CHAR *unicode_ptr;

    ascii_ptr = out;
    unicode_ptr = in;

    *ascii_ptr = (unsigned char) *unicode_ptr ;

    while (1)
        {
        if (*ascii_ptr == 0) return;

        ascii_ptr++;
        unicode_ptr++;
        *ascii_ptr = (unsigned char) *unicode_ptr;
        }
}


void
InitialNtRegistry(
                  )

/*++

Routine Description:

    This information is automatically generated by NT setup and the Networks
    Control Panel applet.  Because it can change dynamically, we load it
    all at once to achieve consistent data.

Arguments:

    None

ReturnValue:

    None

--*/

{
    HKEY RegHandle;
    LONG status;
    int i;
    char protseq[64];
    DWORD protseq_len;
    DWORD lana;
    DWORD lana_len;
    DWORD data_type;
    char *  LanaString ;
    int     LanaNum;
    
    

    
    // Return immediately if the table is already initialized.
    if (ProtocolTable[0].ProtoSeq)
        {
        return;
        }

    NumCards = 0;
    
    // Open the registry key for RPC NetBIOS information
        status = RegOpenKeyExA(RPC_REG_ROOT,
                               REG_NETBIOS,
                               0,
                               KEY_READ,
                               &RegHandle);

    ASSERT(!status);

    if (status)
        {
        return;
        }
    

    for (i = 0; !status && i < MAX_LANA; i++)
        {
        protseq_len = sizeof(protseq);
        lana_len = sizeof(lana);
        
        status = RegEnumValueA(RegHandle,
                               i,
                               protseq,
                               &protseq_len,
                               NULL,
                               &data_type,
                               (LPBYTE) &lana,
                               &lana_len);
        
        if (!status && data_type == REG_DWORD && lana <= MAX_LANA)
            {
            ProtocolTable[i].ProtoSeq = I_RpcAllocate(protseq_len + 1);
            
            ASSERT(ProtocolTable[i].ProtoSeq);
            
            if (! ProtocolTable[i].ProtoSeq)
                {
                status = RPC_S_OUT_OF_RESOURCES;
                }
            else
                {
                strcpy(ProtocolTable[i].ProtoSeq, protseq);
                ProtocolTable[i].Lana = (unsigned char) lana;
    
                LanaString = protseq + strlen(protseq) -1; 
                LanaNum = atoi(LanaString);
                
#ifdef TONY
                PrintToDebugger("RPCLTSCM: the current lana examinging is %d \n"
                                , LanaNum);
#endif
                /* find out how many cards we have */
                if(NumCards < LanaNum)
                       {
                       NumCards = LanaNum;
                       }
                }
            }
        else
            {
            ASSERT(status == ERROR_NO_MORE_ITEMS);
            }
        }
    
    RegCloseKey(RegHandle);
        
    return;
}


RPC_STATUS
MapProtocol(
    IN RPC_CHAR *ProtoSeq,
    IN int DriverNumber,
    OUT PPROTOCOL_MAP *ProtocolEntry
    )

/*++

Routine Description:

    This function maps a protocol string into a protocol map entry.

Arguments:

    ProtoSeq - the protocol sequence that we want to map

    DriverNumber - the logical driver number for the protocol.

    ProtocolEntry - pointer to place to return the results.

Return Value:

    RPC_S_OK, RPC_S_OUT_OF_RESOURCES, RPC_S_INVALID_ENDPOINT_FORMAT

    The output pointer is set to the corresponding entry when found.

--*/
{
    long status;
    char Protocol[40];
    char LanaString[10];
    long BufferLength = sizeof(LanaString);
    int i;
    
    // Copy the possible unicode protocol string to ascii.

    for (i = 0; (Protocol[i] = (char) ProtoSeq[i]) && i < sizeof(Protocol);
         i++) ;

    // Add the logical driver number to the protocol string.  This
    // allows multiple drivers (net cards) to be attached to the same
    // logical protocol.

    Protocol[i] = (char) ('0' + DriverNumber);
    Protocol[i+1] = 0;

    // First look in the proto sequences that we have already mapped.

    for (i = 0; ProtocolTable[i].ProtoSeq && i < MAX_LANA; i++)
        {
        // If found, set the output pointer.

        if (strcmp(ProtocolTable[i].ProtoSeq, Protocol) == 0)
            {
            *ProtocolEntry = &ProtocolTable[i];
            return(RPC_S_OK);
            }
        }

    return(RPC_S_PROTSEQ_NOT_FOUND);
    
}

#endif