home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / dpslots / dialog.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-15  |  23.3 KB  |  879 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1996-1997 Microsoft Corporation.  All Rights Reserved.
  4.  *
  5.  *  File:       dialog.cpp
  6.  *  Content:    Creates a dialog to query the user for connection settings
  7.  *                and establish a connection.
  8.  *
  9.  ***************************************************************************/
  10.  
  11. #define INITGUID
  12. #include <windows.h>
  13. #include <windowsx.h>
  14. #include <cguid.h>
  15.  
  16. #include "dpslots.h"
  17. #include "resource.h"
  18.  
  19. // constants
  20. const UINT    TIMERID            = 1;        // timer ID to use
  21. const UINT    TIMERINTERVAL    = 1000;        // timer interval
  22.  
  23. // structures
  24.  
  25. // server configuration information
  26. typedef struct {
  27.     CHAR        szServerName[MAXSTRLEN];
  28.     CHAR        szDatabaseFile[MAXSTRLEN];
  29.     CHAR        szSecurityProvider[MAXSTRLEN];
  30.     BOOL        bRequireSecureLogin;
  31. } SERVERCONFIG, *LPSERVERCONFIG;
  32.  
  33. // client login information
  34. typedef struct {
  35.     CHAR        szPlayerName[MAXSTRLEN];
  36.     CHAR        szUserName[MAXSTRLEN];
  37.     CHAR        szPassword[MAXSTRLEN];
  38.     CHAR        szDomain[MAXSTRLEN];
  39. } CLIENTLOGIN, *LPCLIENTLOGIN;
  40.  
  41. // prototypes
  42. BOOL CALLBACK    ConnectWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  43.  
  44. HRESULT            CreateDirectPlayInterface(LPDIRECTPLAY3A *lplpDirectPlay3A );
  45. BOOL FAR PASCAL DirectPlayEnumConnectionsCallback(LPCGUID lpguidSP,
  46.                             LPVOID lpConnection, DWORD dwConnectionSize,
  47.                             LPCDPNAME lpName, DWORD dwFlags, LPVOID lpContext);
  48. HRESULT            DestroyDirectPlayInterface(HWND hWnd, LPDIRECTPLAY3A lpDirectPlay3A);
  49. HRESULT            HostSession(LPDIRECTPLAY3A lpDirectPlay3A,
  50.                             LPSERVERCONFIG lpServerConfig,
  51.                             LPDPLAYINFO lpDPInfo);
  52. HRESULT            JoinSession(LPDIRECTPLAY3A lpDirectPlay3A,
  53.                             LPGUID lpguidSessionInstance,
  54.                             LPCLIENTLOGIN lpClientLogin,
  55.                             LPDPLAYINFO lpDPInfo);
  56. HRESULT            EnumSessions(HWND hWnd, LPDIRECTPLAY3A lpDirectPlay3A);
  57.  
  58. HRESULT            GetConnection(HWND hWnd, LPVOID *lplpConnection);
  59. void            DeleteConnectionList(HWND hWnd);
  60. HRESULT            GetSessionInstanceGuid(HWND hWnd, LPGUID lpguidSessionInstance);
  61. void            SelectSessionInstance(HWND hWnd, LPGUID lpguidSessionInstance);
  62. void            DeleteSessionInstanceList(HWND hWnd);
  63. BOOL            GetServerConfig(HWND hWnd, LPSERVERCONFIG lpServerConfig);
  64. BOOL            GetClientLogin(HWND hWnd, LPCLIENTLOGIN lpClientLogin);
  65. HRESULT            GetSessionDesc(LPDIRECTPLAY3A lpDirectPlay3A, LPDPSESSIONDESC2 *lplpSessionDesc);
  66.  
  67. HRESULT ConnectUsingDialog(HINSTANCE hInstance, LPDPLAYINFO lpDPInfo)
  68. {
  69.     // ask user for connection settings
  70.     if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CONNECTDIALOG),
  71.                        NULL, (DLGPROC) ConnectWndProc, (LPARAM) lpDPInfo))
  72.     {
  73.         return (DP_OK);
  74.     }
  75.     else
  76.     {
  77.         return (DPERR_USERCANCEL);
  78.     }
  79. }
  80.  
  81. BOOL CALLBACK ConnectWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  82. {
  83.     static LPDPLAYINFO        lpDPInfo;
  84.     static LPDIRECTPLAY3A    lpDirectPlay3A;
  85.     static UINT                idTimer;
  86.     GUID                    guidSessionInstance;
  87.     SERVERCONFIG            serverConfig;
  88.     CLIENTLOGIN                clientLogin;
  89.     LPVOID                    lpConnection = NULL;
  90.     DWORD                    dwNameSize;
  91.     HRESULT                    hr;
  92.  
  93.     switch(uMsg)
  94.     {
  95.     case WM_INITDIALOG:
  96.         // save the connection info pointer
  97.         lpDPInfo = (LPDPLAYINFO) lParam;
  98.         lpDirectPlay3A = NULL;
  99.  
  100.         // Create an IDirectPlay3 interface
  101.         hr = CreateDirectPlayInterface( &lpDirectPlay3A );
  102.  
  103.         if (FAILED(hr))
  104.             goto SETUP_FAILURE;
  105.  
  106.         // set first item in the connections combo box
  107.         SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_ADDSTRING, (WPARAM) 0, (LPARAM) "<Select a service provider>");
  108.         SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_SETITEMDATA, (WPARAM) 0, (LPARAM) 0);
  109.         SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0);
  110.  
  111.         // put all the available connections in a combo box
  112.         lpDirectPlay3A->EnumConnections(&DPSLOTS_GUID, DirectPlayEnumConnectionsCallback, hWnd, 0);
  113.  
  114.         // setup initial button state
  115.         EnableDlgButton(hWnd, IDC_HOSTBUTTON, FALSE);
  116.         EnableDlgButton(hWnd, IDC_JOINBUTTON, FALSE);
  117.         break;
  118.  
  119.     SETUP_FAILURE:
  120.         ErrorBox("Could not create DirectPlay object because of error 0x%08X", hr);
  121.         EndDialog(hWnd, FALSE);
  122.         break;
  123.  
  124.     case WM_DESTROY:
  125.         // delete information stored along with the lists
  126.         DeleteConnectionList(hWnd);
  127.         DeleteSessionInstanceList(hWnd);
  128.         break;
  129.  
  130.     case WM_TIMER:
  131.         // refresh the session list
  132.         hr = EnumSessions(hWnd, lpDirectPlay3A);
  133.         break;
  134.  
  135.     case WM_COMMAND:
  136.         switch(LOWORD(wParam))
  137.         {
  138.         case IDC_SPCOMBO:
  139.             switch (HIWORD(wParam))
  140.             {
  141.             case CBN_SELCHANGE:
  142.                 // service provider changed, so rebuild display and
  143.                 // delete any existing DirectPlay interface
  144.                 KillTimer(hWnd, idTimer ); 
  145.                 hr = DestroyDirectPlayInterface(hWnd, lpDirectPlay3A);
  146.                 lpDirectPlay3A = NULL;
  147.  
  148.                 // get pointer to the selected connection
  149.                 hr = GetConnection(hWnd, &lpConnection);
  150.                 if FAILED(hr)
  151.                     goto SP_FAILURE;
  152.  
  153.                 if (lpConnection)
  154.                 {
  155.                     hr = CreateDirectPlayInterface( &lpDirectPlay3A );
  156.  
  157.                     if ((FAILED(hr)) || (NULL == lpDirectPlay3A))
  158.                         goto SP_FAILURE;
  159.  
  160.                     // initialize the connection
  161.                     hr = lpDirectPlay3A->InitializeConnection(lpConnection, 0);
  162.                     if FAILED(hr)
  163.                         goto SP_FAILURE;
  164.  
  165.                     // OK to host now
  166.                     EnableDlgButton(hWnd, IDC_HOSTBUTTON, TRUE);
  167.  
  168.                     // start enumerating the sessions
  169.                     hr = EnumSessions(hWnd, lpDirectPlay3A);
  170.                     if FAILED(hr)
  171.                         goto SP_FAILURE;
  172.  
  173.                     // set a timer to refresh the session list
  174.                     idTimer = SetTimer(hWnd, TIMERID, TIMERINTERVAL, NULL);
  175.                 }
  176.                 else
  177.                 {
  178.                     // They've selected the generic option "<Select a service provider>"
  179.                     EnableDlgButton(hWnd, IDC_HOSTBUTTON, FALSE);
  180.                     EnableDlgButton(hWnd, IDC_JOINBUTTON, FALSE);
  181.                 }
  182.                 break;
  183.             }
  184.             break;
  185.  
  186.         SP_FAILURE:
  187.             if (hr != DPERR_USERCANCEL)
  188.                 ErrorBox("Could not select service provider because of error 0x%08X", hr);
  189.             break;
  190.  
  191.  
  192.         case IDC_HOSTBUTTON:
  193.                 // should have an interface by now
  194.             if (lpDirectPlay3A == NULL)
  195.                 break;
  196.  
  197.             // get server configuration from user
  198.             ZeroMemory(&serverConfig, sizeof(SERVERCONFIG));
  199.             if (!GetServerConfig(hWnd, &serverConfig))
  200.                 break;
  201.  
  202.             // host a new session on this service provider
  203.             hr = HostSession(lpDirectPlay3A, &serverConfig, lpDPInfo);
  204.             if FAILED(hr)
  205.                 goto HOST_FAILURE;
  206.  
  207.             // dismiss dialog if we succeeded in hosting
  208.             EndDialog(hWnd, TRUE);
  209.             break;
  210.  
  211.         HOST_FAILURE:
  212.             ErrorBox("Could not host session because of error 0x%08X", hr);
  213.             break;
  214.  
  215.         case IDC_JOINBUTTON:
  216.  
  217.             // should have an interface by now
  218.             if (lpDirectPlay3A == NULL)
  219.                 break;
  220.  
  221.             // get guid of selected session instance
  222.             hr = GetSessionInstanceGuid(hWnd, &guidSessionInstance);
  223.             if FAILED(hr)
  224.                 goto JOIN_FAILURE;
  225.  
  226.             // get server configuration from user
  227.             ZeroMemory(&clientLogin, sizeof(CLIENTLOGIN));
  228.  
  229.             // use user name for player name
  230.             dwNameSize = MAXSTRLEN;
  231.             GetUserName(clientLogin.szPlayerName, &dwNameSize);
  232.                         
  233.             // join this session
  234.             hr = JoinSession(lpDirectPlay3A, &guidSessionInstance, &clientLogin, lpDPInfo);
  235.  
  236.             // need to ask user for credentials
  237.             if (hr == DPERR_LOGONDENIED)
  238.             {
  239.                 if (!GetClientLogin(hWnd, &clientLogin))
  240.                     break;
  241.  
  242.                 // try again, this time with credentials
  243.                 hr = JoinSession(lpDirectPlay3A, &guidSessionInstance, &clientLogin, lpDPInfo);
  244.             }
  245.  
  246.             if FAILED(hr)
  247.                 goto JOIN_FAILURE;
  248.  
  249.             // dismiss dialog if we succeeded in joining
  250.             EndDialog(hWnd, TRUE);
  251.             break;
  252.  
  253.         JOIN_FAILURE:
  254.             ErrorBox("Could not join session because of error 0x%08X", hr);
  255.             break;
  256.  
  257.         case IDCANCEL:
  258.             // delete any interface created if cancelling
  259.             hr = DestroyDirectPlayInterface(hWnd, lpDirectPlay3A);
  260.             lpDirectPlay3A = NULL;
  261.  
  262.             EndDialog(hWnd, FALSE);
  263.             break;
  264.         }
  265.  
  266.         break;
  267.     }
  268.  
  269.     // Allow for default processing
  270.     return FALSE;
  271. }
  272.  
  273. BOOL FAR PASCAL DirectPlayEnumConnectionsCallback(
  274.                         LPCGUID     lpguidSP,
  275.                         LPVOID        lpConnection,
  276.                         DWORD        dwConnectionSize,
  277.                         LPCDPNAME   lpName,
  278.                         DWORD         dwFlags,
  279.                         LPVOID         lpContext)
  280. {
  281.  
  282.     HWND            hWnd = (HWND) lpContext;
  283.     LRESULT            iIndex;
  284.     LPVOID            lpConnectionBuffer;
  285.  
  286.     // store service provider name in combo box
  287.     iIndex = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_ADDSTRING, 0, 
  288.                                     (LPARAM) lpName->lpszShortNameA);
  289.     if (iIndex == CB_ERR)
  290.         goto FAILURE;
  291.  
  292.     // make space for Connection Shortcut
  293.     lpConnectionBuffer = GlobalAllocPtr(GHND, dwConnectionSize);
  294.     if (lpConnectionBuffer == NULL)
  295.         goto FAILURE;
  296.  
  297.     // store pointer to GUID in combo box
  298.     memcpy(lpConnectionBuffer, lpConnection, dwConnectionSize);
  299.     SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_SETITEMDATA, (WPARAM) iIndex, 
  300.                                     (LPARAM) lpConnectionBuffer);
  301.  
  302. FAILURE:
  303.     return (TRUE);
  304. }
  305.  
  306.  
  307. HRESULT CreateDirectPlayInterface( LPDIRECTPLAY3A *lplpDirectPlay3A )
  308. {
  309.     HRESULT                hr;
  310.     LPDIRECTPLAY3A        lpDirectPlay3A = NULL;
  311.  
  312.     // Create an IDirectPlay3 interface
  313.     hr = CoCreateInstance(    CLSID_DirectPlay, NULL, CLSCTX_INPROC_SERVER, 
  314.                             IID_IDirectPlay3A, (LPVOID*)&lpDirectPlay3A);
  315.  
  316.     // return interface created
  317.     *lplpDirectPlay3A = lpDirectPlay3A;
  318.  
  319.     return (hr);
  320. }
  321.  
  322.  
  323. HRESULT DestroyDirectPlayInterface(HWND hWnd, LPDIRECTPLAY3A lpDirectPlay3A)
  324. {
  325.     HRESULT        hr = DP_OK;
  326.  
  327.     if (lpDirectPlay3A)
  328.     {
  329.         DeleteSessionInstanceList(hWnd);
  330.         EnableDlgButton(hWnd, IDC_JOINBUTTON, FALSE);
  331.  
  332.         hr = lpDirectPlay3A->Release();
  333.     }
  334.  
  335.     return (hr);
  336. }
  337.  
  338. HRESULT HostSession(LPDIRECTPLAY3A lpDirectPlay3A,
  339.                     LPSERVERCONFIG lpServerConfig,
  340.                     LPDPLAYINFO lpDPInfo)
  341. {
  342.     DPID                dpidPlayer;
  343.     DPSESSIONDESC2        sessionDesc;
  344.     DPSECURITYDESC        securityDesc;
  345.     LPDPSECURITYDESC    lpSecurityDesc;
  346.     HRESULT                hr;
  347.  
  348.     // check for valid interface
  349.     if (lpDirectPlay3A == NULL)
  350.         return (DPERR_INVALIDOBJECT);
  351.  
  352.     // host a new session
  353.     ZeroMemory(&sessionDesc, sizeof(DPSESSIONDESC2));
  354.     sessionDesc.dwSize = sizeof(DPSESSIONDESC2);
  355.     sessionDesc.guidApplication = DPSLOTS_GUID;
  356.     sessionDesc.dwMaxPlayers = 0;
  357.     sessionDesc.lpszSessionNameA = lpServerConfig->szServerName;
  358.     sessionDesc.dwFlags = SESSIONFLAGS(lpServerConfig->bRequireSecureLogin);
  359.  
  360.     // assume no security descriptor will be needed
  361.     lpSecurityDesc = NULL;
  362.  
  363.     if (lpServerConfig->bRequireSecureLogin)
  364.     {
  365.         // a service provider string was entered, so use it
  366.         if (lstrlen(lpServerConfig->szSecurityProvider))
  367.         {
  368.             ZeroMemory(&securityDesc, sizeof(DPSECURITYDESC));
  369.             securityDesc.dwSize = sizeof(DPSECURITYDESC);
  370.             securityDesc.dwFlags = 0;
  371.             securityDesc.lpszSSPIProviderA = lpServerConfig->szSecurityProvider;
  372.             lpSecurityDesc = &securityDesc;
  373.         }
  374.     }
  375.  
  376.     // host the session
  377.     hr = lpDirectPlay3A->SecureOpen(&sessionDesc, DPOPEN_CREATE, lpSecurityDesc, NULL);
  378.     if FAILED(hr)
  379.         goto FAILURE;
  380.  
  381.     // create a server player with no name
  382.     hr = lpDirectPlay3A->CreatePlayer(&dpidPlayer, NULL, 
  383.                             lpDPInfo->hPlayerEvent, NULL, 0, SERVERPLAYERFLAGS);
  384.     if FAILED(hr)
  385.         goto FAILURE;
  386.  
  387.     // return connection info
  388.     lpDPInfo->lpDirectPlay3A = lpDirectPlay3A;
  389.     lpDPInfo->dpidPlayer = dpidPlayer;
  390.     lpDPInfo->bIsHost = TRUE;
  391.     lpDPInfo->bIsSecure = lpServerConfig->bRequireSecureLogin;
  392.  
  393.     // save database name in global
  394.     lstrcpy(gszDatabaseName, lpServerConfig->szDatabaseFile);
  395.  
  396.     return (DP_OK);
  397.  
  398. FAILURE:
  399.     lpDirectPlay3A->Close();
  400.     return (hr);
  401. }
  402.  
  403. HRESULT JoinSession(LPDIRECTPLAY3A lpDirectPlay3A,
  404.                     LPGUID lpguidSessionInstance,
  405.                     LPCLIENTLOGIN lpClientLogin,
  406.                     LPDPLAYINFO lpDPInfo)
  407. {
  408.     DPID                dpidPlayer;
  409.     DPNAME                dpName;
  410.     DPSESSIONDESC2        sessionDesc;
  411.     LPDPSESSIONDESC2    lpSessionDesc = NULL;
  412.     DPCREDENTIALS        credentials;
  413.     LPDPCREDENTIALS        lpCredentials;
  414.     HRESULT                hr;
  415.  
  416.     // check for valid interface
  417.     if (lpDirectPlay3A == NULL)
  418.         return (DPERR_INVALIDOBJECT);
  419.  
  420.     // join existing session
  421.     ZeroMemory(&sessionDesc, sizeof(DPSESSIONDESC2));
  422.     sessionDesc.dwSize = sizeof(DPSESSIONDESC2);
  423.     sessionDesc.guidInstance = *lpguidSessionInstance;
  424.  
  425.     // assume no credentials are going to be used
  426.     lpCredentials = NULL;
  427.  
  428.     // setup credentials
  429.     ZeroMemory(&credentials, sizeof(DPCREDENTIALS));
  430.     credentials.dwSize = sizeof(DPCREDENTIALS);
  431.     credentials.dwFlags = 0;
  432.  
  433.     if (lstrlen(lpClientLogin->szUserName))
  434.     {
  435.         credentials.lpszUsernameA = lpClientLogin->szUserName;
  436.         lpCredentials = &credentials;
  437.     }
  438.  
  439.     if (lstrlen(lpClientLogin->szPassword))
  440.     {
  441.         credentials.lpszPasswordA = lpClientLogin->szPassword; 
  442.         lpCredentials = &credentials;
  443.     }
  444.  
  445.     if (lstrlen(lpClientLogin->szDomain))
  446.     {
  447.         credentials.lpszDomainA = lpClientLogin->szDomain; 
  448.         lpCredentials = &credentials;
  449.     }
  450.  
  451.     // join the session 
  452.     hr = lpDirectPlay3A->SecureOpen(&sessionDesc, DPOPEN_JOIN, NULL, lpCredentials);
  453.     
  454.     if FAILED(hr)
  455.         goto FAILURE;
  456.  
  457.     // fill out name structure
  458.     ZeroMemory(&dpName, sizeof(DPNAME));
  459.     dpName.dwSize = sizeof(DPNAME);
  460.     dpName.lpszShortNameA = lpClientLogin->szPlayerName;
  461.     dpName.lpszLongNameA = NULL;
  462.  
  463.     // create a player with this name
  464.     hr = lpDirectPlay3A->CreatePlayer(&dpidPlayer, &dpName, 
  465.                             lpDPInfo->hPlayerEvent, NULL, 0, CLIENTPLAYERFLAGS);
  466.     if FAILED(hr)
  467.         goto FAILURE;
  468.  
  469.     // get the session desc
  470.     hr = GetSessionDesc(lpDirectPlay3A, &lpSessionDesc);
  471.     if FAILED(hr)
  472.         goto FAILURE;
  473.  
  474.     // return connection info
  475.     lpDPInfo->lpDirectPlay3A = lpDirectPlay3A;
  476.     lpDPInfo->dpidPlayer = dpidPlayer;
  477.     lpDPInfo->bIsHost = FALSE;
  478.  
  479.     if (lpSessionDesc->dwFlags & DPSESSION_SECURESERVER)
  480.         lpDPInfo->bIsSecure = TRUE;
  481.     else
  482.         lpDPInfo->bIsSecure = FALSE;
  483.  
  484.     GlobalFreePtr(lpSessionDesc);
  485.  
  486.     return (DP_OK);
  487.  
  488. FAILURE:
  489.     if (lpSessionDesc)
  490.         GlobalFreePtr(lpSessionDesc);
  491.  
  492.     lpDirectPlay3A->Close();
  493.     return (hr);
  494. }
  495.  
  496. BOOL FAR PASCAL EnumSessionsCallback(
  497.                         LPCDPSESSIONDESC2    lpSessionDesc,
  498.                         LPDWORD                lpdwTimeOut,
  499.                         DWORD                dwFlags,
  500.                         LPVOID                lpContext)
  501. {
  502.     HWND            hWnd = (HWND) lpContext;
  503.     LPGUID            lpGuid;
  504.     LONG            iIndex;
  505.  
  506.     // see if last session has been enumerated
  507.     if (dwFlags & DPESC_TIMEDOUT)
  508.         return (FALSE);                        
  509.  
  510.     // store session name in list
  511.     iIndex = SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_ADDSTRING, 
  512.                                 (WPARAM) 0, (LPARAM) lpSessionDesc->lpszSessionNameA);
  513.  
  514.     if (iIndex == LB_ERR)
  515.         goto FAILURE;
  516.  
  517.  
  518.     // make space for session instance guid
  519.     lpGuid = (LPGUID) GlobalAllocPtr(GHND, sizeof(GUID));
  520.     if (lpGuid == NULL)
  521.         goto FAILURE;
  522.  
  523.     // store pointer to guid in list
  524.     *lpGuid = lpSessionDesc->guidInstance;
  525.     SendDlgItemMessage( hWnd, IDC_SESSIONLIST, LB_SETITEMDATA, (WPARAM) iIndex, (LPARAM) lpGuid);
  526.  
  527. FAILURE:
  528.     return (TRUE);
  529. }
  530.  
  531. HRESULT EnumSessions(HWND hWnd, LPDIRECTPLAY3A lpDirectPlay3A)
  532. {
  533.     DPSESSIONDESC2    sessionDesc;
  534.     GUID            guidSessionInstance;
  535.     LONG            iIndex;
  536.     HRESULT            hr;
  537.  
  538.     // check for valid interface
  539.     if (lpDirectPlay3A == NULL)
  540.         return (DPERR_INVALIDOBJECT);
  541.  
  542.     // get guid of currently selected session
  543.     guidSessionInstance = GUID_NULL;
  544.     hr = GetSessionInstanceGuid(hWnd, &guidSessionInstance);
  545.  
  546.     // delete existing session list
  547.     DeleteSessionInstanceList(hWnd);
  548.  
  549.     // add sessions to session list
  550.     ZeroMemory(&sessionDesc, sizeof(DPSESSIONDESC2));
  551.     sessionDesc.dwSize = sizeof(DPSESSIONDESC2);
  552.     sessionDesc.guidApplication = DPSLOTS_GUID;
  553.  
  554.     hr = lpDirectPlay3A->EnumSessions(&sessionDesc, 0, EnumSessionsCallback,
  555.                                       hWnd, DPENUMSESSIONS_AVAILABLE | DPENUMSESSIONS_ASYNC);
  556.  
  557.     // select the session that was previously selected
  558.     SelectSessionInstance(hWnd, &guidSessionInstance);
  559.  
  560.     // hilite "Join" button only if there are sessions to join
  561.     iIndex = SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_GETCOUNT,
  562.                            (WPARAM) 0, (LPARAM) 0);
  563.  
  564.     EnableDlgButton(hWnd, IDC_JOINBUTTON, (iIndex > 0) ? TRUE : FALSE);
  565.  
  566.     return (hr);
  567. }
  568.  
  569. HRESULT GetConnection(HWND hWnd, LPVOID *lplpConnection)
  570. {
  571.     LONG    iIndex;
  572.  
  573.     // get index of the item currently selected in the combobox
  574.     iIndex = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETCURSEL,
  575.                                 (WPARAM) 0, (LPARAM) 0);
  576.     if (iIndex == CB_ERR)
  577.         return (DPERR_GENERIC);
  578.  
  579.     // get the pointer to the connection shortcut associated with
  580.     // the item
  581.     iIndex = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETITEMDATA,
  582.                                 (WPARAM) iIndex, (LPARAM) 0);
  583.     if (iIndex == CB_ERR)
  584.         return (DPERR_GENERIC);
  585.  
  586.     *lplpConnection = (LPVOID) iIndex;
  587.  
  588.     return (DP_OK);
  589. }
  590.  
  591. void DeleteConnectionList(HWND hWnd)
  592. {
  593.     WPARAM    i;
  594.     LONG    lpData;
  595.     
  596.     // destroy the GUID's stored with each service provider name
  597.     i = 0;
  598.     while (TRUE)
  599.     {
  600.         // get data pointer stored with item
  601.         lpData = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETITEMDATA,
  602.                                     (WPARAM) i, (LPARAM) 0);
  603.         if (lpData == CB_ERR)        // error getting data
  604.             break;
  605.  
  606.         if (lpData != 0)            // no data to delete
  607.             GlobalFreePtr((LPVOID) lpData);
  608.  
  609.         i += 1;
  610.     }
  611.  
  612.     // delete all items in combo box
  613.     SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_RESETCONTENT,
  614.                                 (WPARAM) 0, (LPARAM) 0);
  615. }
  616.  
  617. HRESULT GetSessionInstanceGuid(HWND hWnd, LPGUID lpguidSessionInstance)
  618. {
  619.     LONG    iIndex;
  620.  
  621.     // get guid for session
  622.     iIndex = SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_GETCURSEL,
  623.                                 (WPARAM) 0, (LPARAM) 0);
  624.     if (iIndex == LB_ERR)
  625.         return (DPERR_GENERIC);
  626.  
  627.     iIndex = SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_GETITEMDATA,
  628.                                 (WPARAM) iIndex, (LPARAM) 0);
  629.     if ((iIndex == LB_ERR) || (iIndex == 0))
  630.         return (DPERR_GENERIC);
  631.  
  632.     *lpguidSessionInstance = *((LPGUID) iIndex);
  633.  
  634.     return (DP_OK);
  635. }
  636.  
  637. void DeleteSessionInstanceList(HWND hWnd)
  638. {
  639.     WPARAM    i;
  640.     LONG    lpData;
  641.     
  642.     // destroy the GUID's stored with each session name
  643.     i = 0;
  644.     while (TRUE)
  645.     {
  646.         // get data pointer stored with item
  647.         lpData = SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_GETITEMDATA,
  648.                                     (WPARAM) i, (LPARAM) 0);
  649.         if (lpData == CB_ERR)        // error getting data
  650.             break;
  651.  
  652.         if (lpData == 0)            // no data to delete
  653.             continue;
  654.  
  655.         GlobalFreePtr((LPVOID) lpData);
  656.         i += 1;
  657.     }
  658.  
  659.     // delete all items in list
  660.     SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_RESETCONTENT,
  661.                                 (WPARAM) 0, (LPARAM) 0);
  662. }
  663.  
  664. void SelectSessionInstance(HWND hWnd, LPGUID lpguidSessionInstance)
  665. {
  666.     WPARAM    i, iIndex;
  667.     LONG    lpData;
  668.     
  669.     // loop over the GUID's stored with each session name
  670.     // to find the one that matches what was passed in
  671.     i = 0;
  672.     iIndex = 0;
  673.     while (TRUE)
  674.     {
  675.         // get data pointer stored with item
  676.         lpData = SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_GETITEMDATA,
  677.                                     (WPARAM) i, (LPARAM) 0);
  678.         if (lpData == CB_ERR)        // error getting data
  679.             break;
  680.  
  681.         if (lpData == 0)            // no data to compare to
  682.             continue;
  683.  
  684.         // guid matches
  685.         if (IsEqualGUID(*lpguidSessionInstance, *((LPGUID) lpData)))
  686.         {
  687.             iIndex = i;                // store index of this string
  688.             break;
  689.         }
  690.  
  691.         i += 1;
  692.     }
  693.  
  694.     // select this item
  695.     SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_SETCURSEL, (WPARAM) iIndex, (LPARAM) 0);
  696. }
  697.  
  698. HRESULT GetSessionDesc(LPDIRECTPLAY3A lpDirectPlay3A, LPDPSESSIONDESC2 *lplpSessionDesc)
  699. {
  700.     LPDPSESSIONDESC2    lpSessionDesc = NULL;
  701.     DWORD                dwSessionDescSize;
  702.     HRESULT                hr;
  703.  
  704.     // get size of session desc
  705.     hr = lpDirectPlay3A->GetSessionDesc(NULL, &dwSessionDescSize);
  706.     if (hr != DPERR_BUFFERTOOSMALL)
  707.         goto FAILURE;
  708.  
  709.     // make room for it
  710.     lpSessionDesc = (LPDPSESSIONDESC2) GlobalAllocPtr(GHND, dwSessionDescSize);
  711.     if (lpSessionDesc == NULL)
  712.     {
  713.         hr = DPERR_OUTOFMEMORY;
  714.         goto FAILURE;
  715.     }
  716.  
  717.     // get the session desc
  718.     hr = lpDirectPlay3A->GetSessionDesc(lpSessionDesc, &dwSessionDescSize);
  719.     if FAILED(hr)
  720.         goto FAILURE;
  721.  
  722.     // return account description
  723.     *lplpSessionDesc = lpSessionDesc;
  724.     lpSessionDesc = NULL;
  725.  
  726. FAILURE:
  727.     if (lpSessionDesc)
  728.         GlobalFreePtr(lpSessionDesc);
  729.  
  730.     return (hr);
  731. }
  732.  
  733. void InitializeServerConfigWindow(HWND hWnd)
  734. {
  735.     char        szSessionName[MAXSTRLEN];
  736.     DWORD        dwNameSize;
  737.  
  738.     // use username for default
  739.     dwNameSize = MAXSTRLEN;
  740.     if (GetComputerName(szSessionName, &dwNameSize))
  741.         SetDlgItemText(hWnd, IDC_SERVERNAMEEDIT, szSessionName);
  742.     
  743.     // use default name
  744.     SetDlgItemText(hWnd, IDC_DATABASEFILEEDIT, DEFAULTDATABASE);
  745.  
  746.     // security off by default
  747.     CheckDlgItem(hWnd, IDC_SECURECHECK, FALSE);
  748. }
  749.  
  750. void SaveServerConfig(HWND hWnd, LPSERVERCONFIG lpServerConfig)
  751. {
  752.     // get strings from dialog
  753.     GetDlgItemText(hWnd, IDC_SERVERNAMEEDIT, lpServerConfig->szServerName, MAXSTRLEN);
  754.     GetDlgItemText(hWnd, IDC_DATABASEFILEEDIT, lpServerConfig->szDatabaseFile, MAXSTRLEN);
  755.     GetDlgItemText(hWnd, IDC_SECURITYPROVIDEREDIT, lpServerConfig->szSecurityProvider, MAXSTRLEN);
  756.  
  757.     if (DlgItemIsChecked(hWnd, IDC_SECURECHECK))
  758.         lpServerConfig->bRequireSecureLogin = TRUE;
  759.     else
  760.         lpServerConfig->bRequireSecureLogin = FALSE;
  761. }
  762.  
  763. BOOL CALLBACK ServerConfigWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  764. {
  765.     static LPSERVERCONFIG    lpServerConfig;
  766.  
  767.     switch(uMsg)
  768.     {
  769.         case WM_INITDIALOG:
  770.  
  771.             // globals are passed in lParam
  772.             lpServerConfig = (LPSERVERCONFIG) lParam;
  773.  
  774.             // Initialize dialog with appropriate information
  775.             InitializeServerConfigWindow(hWnd);
  776.             break;
  777.  
  778.         case WM_DESTROY:
  779.             break;
  780.  
  781.         case WM_COMMAND:
  782.             switch(LOWORD(wParam))
  783.             {
  784.                 case IDOK:
  785.                     // save changes they made
  786.                     SaveServerConfig(hWnd, lpServerConfig);
  787.                     // Return success
  788.                     EndDialog(hWnd, TRUE);
  789.  
  790.                     break;
  791.  
  792.                 case IDCANCEL:
  793.                     // Return failure
  794.                     EndDialog(hWnd, FALSE);
  795.  
  796.                     break;
  797.             }
  798.  
  799.             break;
  800.     }
  801.  
  802.     // Allow for default processing
  803.     return FALSE;
  804. }
  805.  
  806. BOOL GetServerConfig(HWND hWnd, LPSERVERCONFIG lpServerConfig)
  807. {
  808.     // collect server config from dialog
  809.     return (DialogBoxParam(ghInstance, MAKEINTRESOURCE(IDD_SERVERCONFIGDIALOG), hWnd, (DLGPROC) ServerConfigWndProc, (LPARAM) lpServerConfig));
  810. }
  811.  
  812. void InitializeClientLoginWindow(HWND hWnd)
  813. {
  814.     char        szPlayerName[MAXSTRLEN];
  815.     DWORD        dwNameSize;
  816.  
  817.     // use user name for player name
  818.     dwNameSize = MAXSTRLEN;
  819.     if (GetUserName(szPlayerName, &dwNameSize))
  820.         SetDlgItemText(hWnd, IDC_USERNAMEEDIT, szPlayerName);
  821. }
  822.  
  823. void SaveClientLogin(HWND hWnd, LPCLIENTLOGIN lpClientLogin)
  824. {
  825.     // get strings from dialog
  826.     GetDlgItemText(hWnd, IDC_USERNAMEEDIT, lpClientLogin->szUserName, MAXSTRLEN);
  827.     GetDlgItemText(hWnd, IDC_PASSWORDEDIT, lpClientLogin->szPassword, MAXSTRLEN);
  828.     GetDlgItemText(hWnd, IDC_DOMAINEDIT, lpClientLogin->szDomain, MAXSTRLEN);
  829. }
  830.  
  831. BOOL CALLBACK ClientLoginWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  832. {
  833.     static LPCLIENTLOGIN    lpClientLogin;
  834.  
  835.     switch(uMsg)
  836.     {
  837.         case WM_INITDIALOG:
  838.  
  839.             // globals are passed in lParam
  840.             lpClientLogin = (LPCLIENTLOGIN) lParam;
  841.  
  842.             // Initialize dialog with appropriate information
  843.             InitializeClientLoginWindow(hWnd);
  844.             break;
  845.  
  846.         case WM_DESTROY:
  847.             break;
  848.  
  849.         case WM_COMMAND:
  850.             switch(LOWORD(wParam))
  851.             {
  852.                 case IDOK:
  853.                     // save changes they made
  854.                     SaveClientLogin(hWnd, lpClientLogin);
  855.                     // Return success
  856.                     EndDialog(hWnd, TRUE);
  857.  
  858.                     break;
  859.  
  860.                 case IDCANCEL:
  861.                     // Return failure
  862.                     EndDialog(hWnd, FALSE);
  863.  
  864.                     break;
  865.             }
  866.  
  867.             break;
  868.     }
  869.  
  870.     // Allow for default processing
  871.     return FALSE;
  872. }
  873.  
  874. BOOL GetClientLogin(HWND hWnd, LPCLIENTLOGIN lpClientLogin)
  875. {
  876.     // collect server config from dialog
  877.     return (DialogBoxParam(ghInstance, MAKEINTRESOURCE(IDD_CLIENTLOGINDIALOG), hWnd, (DLGPROC) ClientLoginWndProc, (LPARAM) lpClientLogin));
  878. }
  879.