Software Security and the DirectPlay API
by Andrew Wilson

Listing One
BOOL CALLBACK CNetLicense::EnumNetSup(LPGUID lpGuid, LPSTR lpDesc, 
                       DWORD dwMajorVersion, DWORD dwMinorVersion, LPVOID lpv)
{            
        CNetLicense *MyNet = (CNetLicense *)lpv;
        LONG iIndex = MyNet->m_LB_Nets.AddString(lpDesc);
        
        if(iIndex == LB_ERR)
        {
            #ifdef _DEBUG
            afxDump << "Listbox error in CNetLicense\n";
            #endif
            return FALSE;
        }
        MyNet->m_LB_Nets.SetItemData(iIndex,(LPARAM) lpGuid);
       #ifdef _DEBUG
            afxDump << lpDesc << " " << lpGuid << "\n";
        #endif
        if(strstr(lpDesc,"TCP") != NULL)
            MyNet->m_lpGuidTCP = lpGuid;
        else if (strstr(lpDesc, "IPX") != NULL)
            MyNet->m_lpGuidIPX = lpGuid;
return TRUE;
}
BOOL CNetLicense::EnumNetProviders(void)
{
        #ifdef _DEBUG
            afxDump << "Network Providers:\n";
        #endif
        if(DirectPlayEnumerate(EnumNetSup,(void *) this) != DP_OK)
        {
            #ifdef _DEBUG
              afxDump << "Enumeration of Net Providers: Failed\n";
            #else
            MessageBox("Network Enumeration Failed","Fatel Error",
                    MB_OK | MB_ICONSTOP);
            #endif
            return FALSE;
        }
        #ifdef _DEBUG
            afxDump << "Enumeration of Net Providers: Successful\n";
        #endif  
return TRUE;    
}

Listing Two
BOOL CNetLicense::CreateUser(void)
{
HRESULT hr;
char    chPlayerName[255];
char    chComputerName[255];
static  int iNumber = 1;
        DWORD iBufferSize = 252;
    srand( (unsigned)time( NULL ) );
    if(!GetUserName(chPlayerName,(LPDWORD) &iBufferSize) )
    {
        #ifdef _DEBUG
            afxDump << "No user name\n";
        #endif
        return FALSE;
    }
    #ifdef _DEBUG
    afxDump << "User name: " << chPlayerName << "\n";
    #endif
    if(!GetUserName(chComputerName,(LPDWORD) &iBufferSize))
        strcpy(chComputerName,chPlayerName);
    #ifdef _DEBUG
       afxDump << "Computer name: " << chComputerName << "\n";
    #endif
    if((hr = m_lpIDC->CreatePlayer(&m_dwPlayer, chPlayerName, 
        chComputerName, &hPlayerEvent)  != DP_OK))
    {
    int wCount = 32;
    while(wCount)
        {
            m_dwPlayer = rand();
            if(m_lpIDC->CreatePlayer(&m_dwPlayer, chPlayerName, 
                chComputerName, &hPlayerEvent) == DP_OK)
            {
                wCount = 0;
                #ifdef _DEBUG
                afxDump << "New user generated successfully\n";
                #endif
                return TRUE;
            }
            wCount--;
        }
    #ifdef _DEBUG
        afxDump << "Failed to create user\n";
    #endif
    return FALSE;
    }
    #ifdef _DEBUG
        afxDump << "New user generated successfully\n";
    #endif
    return TRUE;
}

Listing Three
void CNetLicense::OnPaint() 
{
        CPaintDC dc(this); 
        if(m_bEnumNets)
        {
            m_lSessions = FALSE;
            if(EnumNetProviders())
            {
                if(EnumTCPSessions())
                    {
                    if(EnumUsers())
                        if(CreateUser())
                            _beginthread(MessageSpin,0,this);
                    }
            }
            m_bEnumNets = FALSE;
        }
}
void CNetLicense::OnClose() 
{
        #ifdef _DEBUG
            afxDump << "Closing user connection\n";
        #endif
// deletes the player, terminates the session 

        m_lpIDC->DestroyPlayer(m_dwPlayer);
        m_lpIDC->Close();   
        CDialog::OnClose();
}
void CNetLicense::MessageSpin(void * lpvThreadParam)
{
    DWORD dwFlags;
    CNetLicense *MyNet = (CNetLicense *) lpvThreadParam;
    #ifdef _DEBUG
    afxDump << "Net Message Proc Started\n";
    #endif
    while(TRUE)
    if(WaitForSingleObject(MyNet->hPlayerEvent,INFINITE) != WAIT_TIMEOUT)
    {
        #ifdef _DEBUG
        afxDump << "Got some Message!\n";
        #endif
        if(GetHandleInformation(MyNet->hPlayerEvent,&dwFlags))
            ProcessMessage(MyNet);
        else
        {
            #ifdef _DEBUG
            afxDump << "hPlayerEvent Handle is invalid, terminating thread\n";
            #endif
            _endthread();
        }
    }
// This should run forever or until someone terminates the application
}
void CNetLicense::ProcessMessage(CNetLicense *MyNet)
{
    DPID dpIncoming;
    DPID dpOutgoing;
    struct TrapPacket
    {
        DWORD dwType;
        char szBigBuffer[1024];
    } tp; // something to cast an incoming message to.

    DWORD dwLength = sizeof(TrapPacket);

    switch(MyNet->m_lpIDC->Receive(&dpIncoming, &dpOutgoing, 
            DPRECEIVE_ALL,(char *) &tp,&dwLength))
    {
    case DP_OK:
        #ifdef _DEBUG
        afxDump << "Received and processed a message!\n"  << "\n";
        #endif

        switch(tp.dwType)
            {
           case DPSYS_DELETEPLAYER:
                DPMSG_DELETEPLAYER *sDeletePlayer =(DPMSG_DELETEPLAYER *) &tp;
                if(MyNet->m_lpIDC->DestroyPlayer(sDeletePlayer->dpId) != DP_OK)
                {
                    #ifdef _DEBUG
                    afxDump << "Could not delete user\n";
                    #endif
                }
                else
                {
                    #ifdef _DEBUG
                    afxDump << "Deleted User!\n";
                    #endif
                }
            break;
            }
        break;
        case DPERR_BUFFERTOOSMALL:
            #ifdef _DEBUG
                afxDump << "DPERR_BUFFERTOOSMALL: " << dwLength << "\n";
            #endif
            break;
        case  DPERR_NOMESSAGES:
            break;
        case  DPERR_INVALIDPARAMS:
            #ifdef _DEBUG
                afxDump << "DPERR_BUFFERTOOSMALL: " << dwLength << "\n";
            #endif
            break;
        }
}




4


