home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / DPLAUNCH / DPLAUNCH.C next >
C/C++ Source or Header  |  1996-08-30  |  26KB  |  583 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1996 Microsoft Corporation.  All Rights Reserved.
  4.  *
  5.  *  File:       dplaunch.c
  6.  *  Content:    Implementation of a DirectPlay launching utility
  7.  *
  8.  ***************************************************************************/
  9.  
  10. #define INITGUID
  11. #define WIN32_LEAN_AND_MEAN
  12.  
  13. #include <windows.h>
  14. #include <windowsx.h>
  15. #include <objbase.h>
  16. #include <cguid.h>
  17.  
  18. #include "dplay.h"
  19. #include "dplobby.h"
  20.  
  21. #include "resource.h"
  22.  
  23. // maximum size of a string name
  24. #define NAMEMAX         200
  25.  
  26. // service provider information
  27. typedef struct {
  28.         GUID    guidServiceProvider;            // guid of service provider
  29.         GUID    guidAddressType;                        // address type required by service provider
  30. } SPINFO, *LPSPINFO;
  31.  
  32. typedef struct {
  33.         HWND                            hWnd;
  34.         LPDIRECTPLAYLOBBYA      lpDPLobbyA;
  35. } ENUMINFO, *LPENUMINFO;
  36.  
  37. // GUID for sessions this application creates
  38. // {D559FC00-DC12-11cf-9C4E-00A0C905425E}
  39. DEFINE_GUID(MY_SESSION_GUID, 
  40. 0xd559fc00, 0xdc12, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
  41.  
  42. // prototypes
  43. BOOL CALLBACK           LauncherWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  44. HRESULT                         InitializeLauncherWindow(HWND hWnd, LPDIRECTPLAYLOBBYA *lplpDPlayLobby);
  45. void                            DestroyLauncherWindow(HWND hWnd, LPDIRECTPLAYLOBBYA lpDPlayLobby);
  46. void                            LaunchDirectPlayApplication(HWND hWnd, LPDIRECTPLAYLOBBYA lpDPlayLobby);
  47.  
  48.  
  49. // ---------------------------------------------------------------------------
  50. // WinMain
  51. // ---------------------------------------------------------------------------
  52. // Description:             Main windows entry point.
  53. // Arguments:
  54. //  HINSTANCE               [in] Standard windows stuff
  55. //  HINSTANCE               [in]
  56. //  LPSTR                   [in]
  57. //  int                     [in]
  58. // Returns:
  59. //  int                                         
  60. int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  61.                                     LPSTR lpCmdLine, int nCmdShow )
  62. {
  63.     return DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_LAUNCHERDIALOG), NULL, LauncherWndProc, (LPARAM) hInstance);
  64. }
  65.  
  66.  
  67. // ---------------------------------------------------------------------------
  68. // LauncherWndProc
  69. // ---------------------------------------------------------------------------
  70. // Description:             Message callback function for Launcher dialog.
  71. // Arguments:
  72. //  HWND                    [in] Dialog window handle.
  73. //  UINT                    [in] Window message identifier.
  74. //  WPARAM                  [in] Depends on message.
  75. //  LPARAM                  [in] Depends on message.
  76. // Returns:
  77. //  BOOL                    TRUE if message was processed internally.
  78. BOOL CALLBACK LauncherWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  79. {
  80.     static HINSTANCE                    hInst;
  81.         static LPDIRECTPLAYLOBBYA       lpDPlayLobby;
  82.         HRESULT                                         hr;
  83.  
  84.     switch(uMsg)
  85.     {
  86.         case WM_INITDIALOG:
  87.             // Save the instance handle
  88.             hInst = (HINSTANCE)lParam;
  89.                         
  90.                         // Initialize dialog with launcher information
  91.                         lpDPlayLobby = NULL;
  92.                         hr = InitializeLauncherWindow(hWnd, &lpDPlayLobby);
  93.             break;
  94.  
  95.         case WM_DESTROY:
  96.                         // Destroy launcher information in dialog
  97.                         DestroyLauncherWindow(hWnd, lpDPlayLobby);
  98.  
  99.             // Return failure
  100.             EndDialog(hWnd, FALSE);
  101.  
  102.             break;
  103.  
  104.         case WM_COMMAND:
  105.             switch(LOWORD(wParam))
  106.             {
  107.                 case IDC_RUNAPPBUTTON:
  108.                                         // get settings and launch application
  109.                     LaunchDirectPlayApplication(hWnd, lpDPlayLobby);
  110.  
  111.                     break;
  112.  
  113.                 case IDCANCEL:
  114.                     // Return failure
  115.                     EndDialog(hWnd, TRUE);
  116.  
  117.                     break;
  118.             }
  119.  
  120.             break;
  121.     }
  122.  
  123.     // Allow for default processing
  124.     return FALSE;
  125. }
  126.  
  127. // ---------------------------------------------------------------------------
  128. // EnumApp
  129. // ---------------------------------------------------------------------------
  130. // Description:             Enumeration callback called by DirectPlay.
  131. //                                                      Enumerates the applications registered with DirectPlay.
  132. // Arguments:
  133. //  LPDPLAPPINFO            [in] information about the application
  134. //  LPVOID                                  [in] user-defined context
  135. //  DWORD                                       [in] flags
  136. // Returns:
  137. //  BOOL                                        TRUE to continue enumerating
  138. BOOL FAR PASCAL EnumApp(LPCDPLAPPINFO lpAppInfo, LPVOID lpContext, DWORD dwFlags)
  139. {
  140.     HWND                        hWnd = lpContext;
  141.     LRESULT                     iIndex;
  142.         LPGUID                  lpGuid;
  143.  
  144.         // store application name in combo box
  145.         iIndex = SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_ADDSTRING, 0, (LPARAM) lpAppInfo->lpszAppNameA);
  146.         if (iIndex == LB_ERR)
  147.                 goto Failure;
  148.  
  149.         // make space for application GUID
  150.         lpGuid = (LPGUID) GlobalAllocPtr(GHND, sizeof(GUID));
  151.         if (lpGuid == NULL)
  152.                 goto Failure;
  153.  
  154.         // store pointer to GUID in combo box
  155.         *lpGuid = lpAppInfo->guidApplication;
  156.         SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_SETITEMDATA, (WPARAM) iIndex, (LPARAM) lpGuid);
  157.  
  158. Failure:
  159.     return (TRUE);
  160. }
  161.  
  162. // ---------------------------------------------------------------------------
  163. // EnumAddressType
  164. // ---------------------------------------------------------------------------
  165. // Description:             Enumeration callback called by DirectPlayLobby.
  166. //                                                      Enumerates the address types supported by the
  167. //                                                      given Service Provider.
  168. // Arguments:
  169. //  REFGUID                 [in] GUID of the address type
  170. //  LPVOID                                  [in] user-defined context
  171. //  DWORD                                       [in] flags
  172. // Returns:
  173. //  BOOL                                        FALSE to stop enumerating after the first callback
  174. BOOL FAR PASCAL EnumAddressType(REFGUID guidAddressType, LPVOID lpContext,
  175.                                         DWORD dwFlags)
  176. {
  177.         LPGUID  lpguidAddr = (LPGUID)lpContext;
  178.  
  179.  
  180.         // Save the address type guid in the pointer
  181.         *lpguidAddr = *guidAddressType;
  182.  
  183.         // Note: It is possible that some Service Providers will contain more
  184.         // than one address type.  We are only using the first address type
  185.         // returned in this sample.  A good application should save all
  186.         // address types.
  187.         return FALSE;
  188. }
  189.  
  190.  
  191. // ---------------------------------------------------------------------------
  192. // EnumSP
  193. // ---------------------------------------------------------------------------
  194. // Description:             Enumeration callback called by DirectPlay.
  195. //                                                      Enumerates service providers registered with DirectPlay.
  196. // Arguments:
  197. //  LPGUID                                      [in] GUID of service provider
  198. //  LPTSTR                                      [in] name of service provider
  199. //  DWORD                                       [in] major version of DirectPlay
  200. //  DWORD                                       [in] minor version of DirectPlay
  201. //  LPVOID                                  [in] user-defined context
  202. // Returns:
  203. //  BOOL                                        TRUE to continue enumerating
  204. BOOL FAR PASCAL EnumSP(LPGUID lpGuid, LPTSTR lptszDesc, DWORD dwMajorVersion,
  205.                                DWORD dwMinorVersion, LPVOID lpContext)
  206. {
  207.         LPENUMINFO                      lpEnumInfo = (LPENUMINFO)lpContext;
  208.     LPDIRECTPLAYLOBBYA  lpDPLobbyA = lpEnumInfo->lpDPLobbyA;
  209.         HWND                            hWnd = lpEnumInfo->hWnd;
  210.         HRESULT                         hr;
  211.     LRESULT                             iIndex;
  212.         LPSPINFO                        lpSPInfo;
  213.  
  214.         // store service provider name in combo box
  215.         iIndex = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_ADDSTRING, 0, (LPARAM) lptszDesc);
  216.         if (iIndex == LB_ERR)
  217.                 goto Failure;
  218.  
  219.         // make space for service provider info
  220.         lpSPInfo = (LPSPINFO) GlobalAllocPtr(GHND, sizeof(SPINFO));
  221.         if (lpSPInfo == NULL)
  222.                 goto Failure;
  223.  
  224.         // Initialize the guid to GUID_NULL in case it has no address types
  225.         memset(lpSPInfo, 0, sizeof(SPINFO));
  226.  
  227.         // store service provider GUID and address type in combo box
  228.         lpSPInfo->guidServiceProvider = *lpGuid;
  229.  
  230.         // Get the address type for the Service Provider
  231.         hr = lpDPLobbyA->lpVtbl->EnumAddressTypes(lpDPLobbyA,
  232.                         (LPDPLENUMADDRESSTYPESCALLBACK)EnumAddressType,
  233.                         lpGuid, &lpSPInfo->guidAddressType, 0L);
  234.  
  235.         SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_SETITEMDATA, (WPARAM) iIndex, (LPARAM) lpSPInfo);
  236.  
  237. Failure:
  238.     return (TRUE);
  239. }
  240.  
  241. // ---------------------------------------------------------------------------
  242. // InitializeLauncherWindow
  243. // ---------------------------------------------------------------------------
  244. // Description:             Initializes the window for the Launcher.
  245. // Arguments:
  246. //  HWND                    [in] Window handle.
  247. //  LPDIRECTPLAYLOBBYA          [out] IDirectPlayLobby interface.
  248. // Returns:
  249. //  HRESULT                                     any errors initializing the window
  250. HRESULT InitializeLauncherWindow(HWND hWnd, LPDIRECTPLAYLOBBYA *lplpDPlayLobby)
  251. {
  252.         LPDIRECTPLAYLOBBYA      lpDPlayLobbyA = NULL;
  253.         ENUMINFO                        EnumInfo;
  254.         HRESULT                         hr;
  255.                 
  256.         // get a ANSI DirectPlay lobby interface
  257.         hr = DirectPlayLobbyCreate(NULL, &lpDPlayLobbyA, NULL, NULL, 0);
  258.         if FAILED(hr)
  259.                 goto Failure;
  260.  
  261.         // put all the DirectPlay applications in a combo box
  262.         lpDPlayLobbyA->lpVtbl->EnumLocalApplications(lpDPlayLobbyA, EnumApp, hWnd, 0);
  263.  
  264.         // setup the EnumInfo structure
  265.         EnumInfo.hWnd = hWnd;
  266.         EnumInfo.lpDPLobbyA = lpDPlayLobbyA;
  267.         
  268.         // put all the service providers in a combo box
  269.         DirectPlayEnumerate(EnumSP, &EnumInfo);
  270.  
  271.         // initialize the controls
  272.         SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_SETCURSEL, (WPARAM) 0, 0);
  273.         SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_SETCURSEL, (WPARAM) 0, 0);
  274.         SendDlgItemMessage(hWnd, IDC_HOSTRADIO, BM_SETCHECK, (WPARAM) BST_CHECKED, 0);
  275.  
  276.         // return the ANSI lobby interface
  277.         *lplpDPlayLobby = lpDPlayLobbyA;
  278.  
  279.         return (DP_OK);
  280.  
  281. Failure:
  282.  
  283.         return (hr);
  284. }
  285.  
  286. // ---------------------------------------------------------------------------
  287. // DestroyLauncherWindow
  288. // ---------------------------------------------------------------------------
  289. // Description:             Destroys the launcher window.
  290. // Arguments:
  291. //  HWND                    [in] Window handle.
  292. //  LPDIRECTPLAYLOBBYA      [in] DirectPlay Lobby interface to destroy
  293. // Returns:
  294. //  Nothing
  295. void DestroyLauncherWindow(HWND hWnd, LPDIRECTPLAYLOBBYA lpDPlayLobby)
  296. {
  297.         WPARAM  index;
  298.         LRESULT lpData;
  299.  
  300.         // destroy the GUID's stored with each app name
  301.         index = 0;
  302.         while (TRUE)
  303.         {
  304.                 lpData = SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_GETITEMDATA, (WPARAM) index, 0);
  305.                 if ((lpData == CB_ERR) || (lpData == 0))
  306.                         break;
  307.  
  308.                 GlobalFreePtr((LPVOID) lpData);
  309.                 index += 1;
  310.         }
  311.  
  312.         // destroy the GUID's stored with each service provider name
  313.         index = 0;
  314.         while (TRUE)
  315.         {
  316.                 lpData = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETITEMDATA, (WPARAM) index, 0);
  317.                 if ((lpData == CB_ERR) || (lpData == 0))
  318.                         break;
  319.  
  320.                 GlobalFreePtr((LPVOID) lpData);
  321.                 index += 1;
  322.         }
  323.  
  324.         // release the lobby interface
  325.         if (lpDPlayLobby)
  326.                 lpDPlayLobby->lpVtbl->Release(lpDPlayLobby);
  327. }
  328.  
  329. // ---------------------------------------------------------------------------
  330. // CreateAddress
  331. // ---------------------------------------------------------------------------
  332. // Description:             Wrapper for the IDirectPlayLobby::CreateAddress() method.
  333. // Arguments:
  334. //  LPDIRECTPLAYLOBBYA      [in] DirectPlay Lobby interface to use
  335. //  LPGUID                                      [in] GUID of servicer provider to create address for
  336. //  LPGUID                                      [in] GUID of address data type
  337. //  LPSTR                                       [in] string to use as address data
  338. //  LPVOID*                                     [out] pointer to return address in
  339. //  LPDWORD                                     [out] pointer to return address size in
  340. // Returns:
  341. //  HRESULT                                     any error creating the address
  342. HRESULT CreateAddress(LPDIRECTPLAYLOBBYA lpDPlayLobby,
  343.                                           LPGUID lpguidServiceProvider,
  344.                                           LPGUID lpguidAddressType, LPSTR lpszAddressText,
  345.                                           LPVOID *lplpAddress, LPDWORD lpdwAddressSize)
  346. {
  347.         LPVOID          lpAddress = NULL;
  348.         DWORD           dwAddressSize = 0;
  349.         HRESULT         hr;
  350.  
  351.         // check for invalid address types
  352.         if (IsEqualGUID(lpguidAddressType, &GUID_NULL))
  353.                 return (DPERR_INVALIDPARAM);
  354.         
  355.         // see how much room is needed to store this address
  356.         hr = lpDPlayLobby->lpVtbl->CreateAddress(lpDPlayLobby, lpguidServiceProvider,
  357.                                         lpguidAddressType, lpszAddressText, strlen(lpszAddressText) + 1,
  358.                                         NULL, &dwAddressSize);
  359.         if (hr != DPERR_BUFFERTOOSMALL)
  360.                 goto Failure;
  361.  
  362.         // allocate space
  363.         lpAddress = GlobalAllocPtr(GHND, dwAddressSize);
  364.         if (lpAddress == NULL)
  365.         {
  366.                 hr = DPERR_NOMEMORY;
  367.                 goto Failure;
  368.         }
  369.  
  370.         // create the address
  371.         hr = lpDPlayLobby->lpVtbl->CreateAddress(lpDPlayLobby, lpguidServiceProvider,
  372.                                         lpguidAddressType, lpszAddressText, strlen(lpszAddressText) + 1,
  373.                                         lpAddress, &dwAddressSize);
  374.         if FAILED(hr)
  375.                 goto Failure;
  376.  
  377.         // return the address info
  378.         *lplpAddress = lpAddress;
  379.         *lpdwAddressSize = dwAddressSize;
  380.  
  381.         return (DP_OK);
  382.  
  383. Failure:
  384.         if (lpAddress)
  385.                 GlobalFreePtr(lpAddress);
  386.  
  387.         return (hr);
  388. }
  389.  
  390. // ---------------------------------------------------------------------------
  391. // RunApplication
  392. // ---------------------------------------------------------------------------
  393. // Description:             Wrapper for the IDirectPlayLobby::RunApplication() method.
  394. // Arguments:
  395. //  LPDIRECTPLAYLOBBYA          [in] DirectPlay Lobby interface to use
  396. //  LPGUID                                      [in] GUID of application to launch
  397. //  LPGUID                                      [in] GUID of session to host with
  398. //  LPSTR                                       [in] GUID of service provider to connect with
  399. //  LPVOID                                      [in] service-provider address to connect to
  400. //  DWORD                                       [in] length of address
  401. //  LPSTR                                       [in] name of session to host
  402. //  LPSTR                                       [in] name of our player
  403. //  BOOL                                        [in] TRUE to host session, FALSE to join
  404. // Returns:
  405. //  HRESULT                                     any error running the application
  406. HRESULT RunApplication(LPDIRECTPLAYLOBBYA lpDPlayLobby,
  407.                                            LPGUID lpguidApplication,
  408.                                            LPGUID lpguidInstance,
  409.                                            LPGUID lpguidServiceProvider,
  410.                                            LPVOID lpAddress,
  411.                                            DWORD  dwAddressSize,
  412.                                            LPSTR  lpszSessionName,
  413.                                            LPSTR  lpszPlayerName,
  414.                                            BOOL   bHostSession)
  415. {
  416.         DWORD                           appID;
  417.         DPSESSIONDESC2          sessionInfo;
  418.         DPNAME                          playerName;
  419.         DPLCONNECTION           connectInfo;
  420.         HRESULT                         hr;
  421.  
  422.         if (lpDPlayLobby == NULL)
  423.                 return (DPERR_NOINTERFACE);
  424.  
  425.         // fill out session description
  426.         ZeroMemory(&sessionInfo, sizeof(DPSESSIONDESC2));
  427.     sessionInfo.dwSize = sizeof(DPSESSIONDESC2);        // Size of structure
  428.         sessionInfo.dwFlags = 0;                                                // DPSESSION_xxx flags
  429.     sessionInfo.guidInstance = *lpguidInstance;         // ID for the session instance
  430.     sessionInfo.guidApplication = *lpguidApplication;// GUID of the DirectPlay application.
  431.     sessionInfo.dwMaxPlayers = 0;                                       // Maximum # players allowed in session
  432.     sessionInfo.dwCurrentPlayers = 0;                           // Current # players in session (read only)
  433.         sessionInfo.lpszSessionNameA = lpszSessionName; // ANSI name of the session
  434.         sessionInfo.lpszPasswordA = NULL;                               // ANSI password of the session (optional)
  435.         sessionInfo.dwReserved1 = 0;                                    // Reserved for future MS use.
  436.     sessionInfo.dwReserved2 = 0;
  437.     sessionInfo.dwUser1 = 0;                                            // For use by the application
  438.     sessionInfo.dwUser2 = 0;
  439.     sessionInfo.dwUser3 = 0;
  440.     sessionInfo.dwUser4 = 0;
  441.  
  442.         // fill out player name
  443.         ZeroMemory(&playerName, sizeof(DPNAME));
  444.         playerName.dwSize = sizeof(DPNAME);                             // Size of structure
  445.     playerName.dwFlags = 0;                                                     // Not used. Must be zero.
  446.         playerName.lpszShortNameA = lpszPlayerName;             // ANSI short or friendly name
  447.         playerName.lpszLongNameA = lpszPlayerName;              // ANSI long or formal name
  448.         
  449.         // fill out connection description
  450.         ZeroMemory(&connectInfo, sizeof(DPLCONNECTION));
  451.         connectInfo.dwSize = sizeof(DPLCONNECTION);             // Size of this structure
  452.         if (bHostSession)
  453.                 connectInfo.dwFlags = DPLCONNECTION_CREATESESSION; // Create a new session
  454.         else
  455.                 connectInfo.dwFlags = DPLCONNECTION_JOINSESSION; // Join existing session
  456.         connectInfo.lpSessionDesc = &sessionInfo;               // Pointer to session desc to use on connect
  457.         connectInfo.lpPlayerName = &playerName;                 // Pointer to Player name structure
  458.         connectInfo.guidSP = *lpguidServiceProvider;    // GUID of the DPlay SP to use
  459.         connectInfo.lpAddress = lpAddress;                              // Address for service provider
  460.         connectInfo.dwAddressSize = dwAddressSize;              // Size of address data
  461.  
  462.         // launch and connect the game
  463.         hr = lpDPlayLobby->lpVtbl->RunApplication(lpDPlayLobby,
  464.                                                                                 0,                      // Flags
  465.                                                                                 &appID,         // App ID
  466.                                                                                 &connectInfo,   // Connection data
  467.                                                                                 NULL);          // Connect event
  468.         return (hr);
  469. }
  470.  
  471. // ---------------------------------------------------------------------------
  472. // LaunchDirectPlayApplication
  473. // ---------------------------------------------------------------------------
  474. // Description:             Gathers information from the dialog and runs the application.
  475. // Arguments:
  476. //  HWND                    [in] Window handle.
  477. //  LPDIRECTPLAYLOBBYA      [in] DirectPlay Lobby interface to use
  478. // Returns:
  479. //  Nothing
  480. void LaunchDirectPlayApplication(HWND hWnd, LPDIRECTPLAYLOBBYA lpDPlayLobby)
  481. {
  482.         GUID                            guidApplication, guidSession, guidServiceProvider, guidAddressType;
  483.         LPSTR                           lpPlayerName, lpSessionName;
  484.         LPVOID                          lpAddress = NULL;
  485.         DWORD                           dwAddressSize;
  486.         LPSPINFO                        lpSPInfo;
  487.         char                            strPlayerName[NAMEMAX], strSessionName[NAMEMAX], strAddressText[NAMEMAX];
  488.         LRESULT                         iApp, iSP, iHost;
  489.         HRESULT                         hr;
  490.  
  491.         SetDlgItemText(hWnd, IDC_STATUSEDIT, "Launching...");
  492.  
  493.         // get guid of application to launch
  494.         iApp = SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_GETCURSEL, (WPARAM) 0, 0);
  495.         if (iApp == CB_ERR)
  496.                 goto Failure;
  497.  
  498.         iApp = SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_GETITEMDATA, (WPARAM) iApp, 0);
  499.         if ((iApp == CB_ERR) || (iApp == 0))
  500.                 goto Failure;
  501.  
  502.         guidApplication = *((LPGUID) iApp);
  503.  
  504.         // get info for service provider to use for the connection
  505.         iSP = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETCURSEL, (WPARAM) 0, 0);
  506.         if (iSP == CB_ERR)
  507.                 goto Failure;
  508.  
  509.         iSP = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETITEMDATA, (WPARAM) iSP, 0);
  510.         if ((iSP == CB_ERR) || (iSP == 0))
  511.                 goto Failure;
  512.  
  513.         lpSPInfo = (LPSPINFO) iSP;
  514.         guidServiceProvider = lpSPInfo->guidServiceProvider;    // GUID of service provider
  515.         guidAddressType = lpSPInfo->guidAddressType;                    // address type required by service provider
  516.  
  517.         // get guid of session to create.
  518.         guidSession = MY_SESSION_GUID;
  519.         
  520.         // get name of our player
  521.         GetDlgItemText(hWnd, IDC_PLAYEREDIT, strPlayerName, NAMEMAX);
  522.         lpPlayerName = strPlayerName;
  523.  
  524.         // get host vs. join flag
  525.         iHost = SendDlgItemMessage(hWnd, IDC_HOSTRADIO, BM_GETCHECK, (WPARAM) 0, 0);
  526.         if (iHost == BST_CHECKED)
  527.         {
  528.                 iHost = TRUE;                   // we are hosting a session
  529.                 lpAddress = NULL;               // don't need an address to host
  530.                 dwAddressSize = 0;
  531.  
  532.                 // get name of session
  533.                 GetDlgItemText(hWnd, IDC_SESSIONEDIT, strSessionName, NAMEMAX);
  534.                 lpSessionName = strSessionName;
  535.         }
  536.         else
  537.         {
  538.                 iHost = FALSE;                  // we are joining an existing session
  539.                 lpSessionName = NULL;   // don't need a session name if we are joining
  540.  
  541.                 lpAddress = NULL;               // assume we don't need address data
  542.                 dwAddressSize = 0;
  543.  
  544.                 // the service provider supports address data
  545.                 if (!IsEqualGUID(&guidAddressType, &GUID_NULL))
  546.                 {
  547.                         // get service-provider specific address data as a string
  548.                         GetDlgItemText(hWnd, IDC_ADDRESSEDIT, strAddressText, NAMEMAX);
  549.  
  550.                         // convert string to a DirectPlay address
  551.                         hr = CreateAddress(lpDPlayLobby, &guidServiceProvider,
  552.                                                            &guidAddressType, strAddressText,
  553.                                                            &lpAddress, &dwAddressSize);
  554.                 }
  555.         }
  556.  
  557.         // launch the application
  558.         hr = RunApplication(lpDPlayLobby,
  559.                                                 &guidApplication,
  560.                                                 &guidSession,
  561.                                                 &guidServiceProvider,
  562.                                                 lpAddress, dwAddressSize,
  563.                                                 lpSessionName, lpPlayerName,
  564.                                                 iHost);
  565.         if FAILED(hr)
  566.                 goto Failure;
  567.  
  568.         SetDlgItemText(hWnd, IDC_STATUSEDIT, "Launch successful");
  569.  
  570.         if (lpAddress)
  571.                 GlobalFreePtr(lpAddress);
  572.         return;
  573.  
  574. Failure:
  575.         if (lpAddress)
  576.                 GlobalFreePtr(lpAddress);
  577.  
  578.         SetDlgItemText(hWnd, IDC_STATUSEDIT, "Launch failed");
  579.  
  580.         return;
  581. }
  582.  
  583.