home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NEXT Generation 27
/
NEXT27.iso
/
pc
/
demos
/
emperor
/
dx3.exe
/
SDK
/
SAMPLES
/
DPLAUNCH
/
DPLAUNCH.C
next >
Wrap
C/C++ Source or Header
|
1996-08-30
|
26KB
|
583 lines
/*==========================================================================
*
* Copyright (C) 1996 Microsoft Corporation. All Rights Reserved.
*
* File: dplaunch.c
* Content: Implementation of a DirectPlay launching utility
*
***************************************************************************/
#define INITGUID
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <objbase.h>
#include <cguid.h>
#include "dplay.h"
#include "dplobby.h"
#include "resource.h"
// maximum size of a string name
#define NAMEMAX 200
// service provider information
typedef struct {
GUID guidServiceProvider; // guid of service provider
GUID guidAddressType; // address type required by service provider
} SPINFO, *LPSPINFO;
typedef struct {
HWND hWnd;
LPDIRECTPLAYLOBBYA lpDPLobbyA;
} ENUMINFO, *LPENUMINFO;
// GUID for sessions this application creates
// {D559FC00-DC12-11cf-9C4E-00A0C905425E}
DEFINE_GUID(MY_SESSION_GUID,
0xd559fc00, 0xdc12, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
// prototypes
BOOL CALLBACK LauncherWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HRESULT InitializeLauncherWindow(HWND hWnd, LPDIRECTPLAYLOBBYA *lplpDPlayLobby);
void DestroyLauncherWindow(HWND hWnd, LPDIRECTPLAYLOBBYA lpDPlayLobby);
void LaunchDirectPlayApplication(HWND hWnd, LPDIRECTPLAYLOBBYA lpDPlayLobby);
// ---------------------------------------------------------------------------
// WinMain
// ---------------------------------------------------------------------------
// Description: Main windows entry point.
// Arguments:
// HINSTANCE [in] Standard windows stuff
// HINSTANCE [in]
// LPSTR [in]
// int [in]
// Returns:
// int
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
return DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_LAUNCHERDIALOG), NULL, LauncherWndProc, (LPARAM) hInstance);
}
// ---------------------------------------------------------------------------
// LauncherWndProc
// ---------------------------------------------------------------------------
// Description: Message callback function for Launcher dialog.
// Arguments:
// HWND [in] Dialog window handle.
// UINT [in] Window message identifier.
// WPARAM [in] Depends on message.
// LPARAM [in] Depends on message.
// Returns:
// BOOL TRUE if message was processed internally.
BOOL CALLBACK LauncherWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HINSTANCE hInst;
static LPDIRECTPLAYLOBBYA lpDPlayLobby;
HRESULT hr;
switch(uMsg)
{
case WM_INITDIALOG:
// Save the instance handle
hInst = (HINSTANCE)lParam;
// Initialize dialog with launcher information
lpDPlayLobby = NULL;
hr = InitializeLauncherWindow(hWnd, &lpDPlayLobby);
break;
case WM_DESTROY:
// Destroy launcher information in dialog
DestroyLauncherWindow(hWnd, lpDPlayLobby);
// Return failure
EndDialog(hWnd, FALSE);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_RUNAPPBUTTON:
// get settings and launch application
LaunchDirectPlayApplication(hWnd, lpDPlayLobby);
break;
case IDCANCEL:
// Return failure
EndDialog(hWnd, TRUE);
break;
}
break;
}
// Allow for default processing
return FALSE;
}
// ---------------------------------------------------------------------------
// EnumApp
// ---------------------------------------------------------------------------
// Description: Enumeration callback called by DirectPlay.
// Enumerates the applications registered with DirectPlay.
// Arguments:
// LPDPLAPPINFO [in] information about the application
// LPVOID [in] user-defined context
// DWORD [in] flags
// Returns:
// BOOL TRUE to continue enumerating
BOOL FAR PASCAL EnumApp(LPCDPLAPPINFO lpAppInfo, LPVOID lpContext, DWORD dwFlags)
{
HWND hWnd = lpContext;
LRESULT iIndex;
LPGUID lpGuid;
// store application name in combo box
iIndex = SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_ADDSTRING, 0, (LPARAM) lpAppInfo->lpszAppNameA);
if (iIndex == LB_ERR)
goto Failure;
// make space for application GUID
lpGuid = (LPGUID) GlobalAllocPtr(GHND, sizeof(GUID));
if (lpGuid == NULL)
goto Failure;
// store pointer to GUID in combo box
*lpGuid = lpAppInfo->guidApplication;
SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_SETITEMDATA, (WPARAM) iIndex, (LPARAM) lpGuid);
Failure:
return (TRUE);
}
// ---------------------------------------------------------------------------
// EnumAddressType
// ---------------------------------------------------------------------------
// Description: Enumeration callback called by DirectPlayLobby.
// Enumerates the address types supported by the
// given Service Provider.
// Arguments:
// REFGUID [in] GUID of the address type
// LPVOID [in] user-defined context
// DWORD [in] flags
// Returns:
// BOOL FALSE to stop enumerating after the first callback
BOOL FAR PASCAL EnumAddressType(REFGUID guidAddressType, LPVOID lpContext,
DWORD dwFlags)
{
LPGUID lpguidAddr = (LPGUID)lpContext;
// Save the address type guid in the pointer
*lpguidAddr = *guidAddressType;
// Note: It is possible that some Service Providers will contain more
// than one address type. We are only using the first address type
// returned in this sample. A good application should save all
// address types.
return FALSE;
}
// ---------------------------------------------------------------------------
// EnumSP
// ---------------------------------------------------------------------------
// Description: Enumeration callback called by DirectPlay.
// Enumerates service providers registered with DirectPlay.
// Arguments:
// LPGUID [in] GUID of service provider
// LPTSTR [in] name of service provider
// DWORD [in] major version of DirectPlay
// DWORD [in] minor version of DirectPlay
// LPVOID [in] user-defined context
// Returns:
// BOOL TRUE to continue enumerating
BOOL FAR PASCAL EnumSP(LPGUID lpGuid, LPTSTR lptszDesc, DWORD dwMajorVersion,
DWORD dwMinorVersion, LPVOID lpContext)
{
LPENUMINFO lpEnumInfo = (LPENUMINFO)lpContext;
LPDIRECTPLAYLOBBYA lpDPLobbyA = lpEnumInfo->lpDPLobbyA;
HWND hWnd = lpEnumInfo->hWnd;
HRESULT hr;
LRESULT iIndex;
LPSPINFO lpSPInfo;
// store service provider name in combo box
iIndex = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_ADDSTRING, 0, (LPARAM) lptszDesc);
if (iIndex == LB_ERR)
goto Failure;
// make space for service provider info
lpSPInfo = (LPSPINFO) GlobalAllocPtr(GHND, sizeof(SPINFO));
if (lpSPInfo == NULL)
goto Failure;
// Initialize the guid to GUID_NULL in case it has no address types
memset(lpSPInfo, 0, sizeof(SPINFO));
// store service provider GUID and address type in combo box
lpSPInfo->guidServiceProvider = *lpGuid;
// Get the address type for the Service Provider
hr = lpDPLobbyA->lpVtbl->EnumAddressTypes(lpDPLobbyA,
(LPDPLENUMADDRESSTYPESCALLBACK)EnumAddressType,
lpGuid, &lpSPInfo->guidAddressType, 0L);
SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_SETITEMDATA, (WPARAM) iIndex, (LPARAM) lpSPInfo);
Failure:
return (TRUE);
}
// ---------------------------------------------------------------------------
// InitializeLauncherWindow
// ---------------------------------------------------------------------------
// Description: Initializes the window for the Launcher.
// Arguments:
// HWND [in] Window handle.
// LPDIRECTPLAYLOBBYA [out] IDirectPlayLobby interface.
// Returns:
// HRESULT any errors initializing the window
HRESULT InitializeLauncherWindow(HWND hWnd, LPDIRECTPLAYLOBBYA *lplpDPlayLobby)
{
LPDIRECTPLAYLOBBYA lpDPlayLobbyA = NULL;
ENUMINFO EnumInfo;
HRESULT hr;
// get a ANSI DirectPlay lobby interface
hr = DirectPlayLobbyCreate(NULL, &lpDPlayLobbyA, NULL, NULL, 0);
if FAILED(hr)
goto Failure;
// put all the DirectPlay applications in a combo box
lpDPlayLobbyA->lpVtbl->EnumLocalApplications(lpDPlayLobbyA, EnumApp, hWnd, 0);
// setup the EnumInfo structure
EnumInfo.hWnd = hWnd;
EnumInfo.lpDPLobbyA = lpDPlayLobbyA;
// put all the service providers in a combo box
DirectPlayEnumerate(EnumSP, &EnumInfo);
// initialize the controls
SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_SETCURSEL, (WPARAM) 0, 0);
SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_SETCURSEL, (WPARAM) 0, 0);
SendDlgItemMessage(hWnd, IDC_HOSTRADIO, BM_SETCHECK, (WPARAM) BST_CHECKED, 0);
// return the ANSI lobby interface
*lplpDPlayLobby = lpDPlayLobbyA;
return (DP_OK);
Failure:
return (hr);
}
// ---------------------------------------------------------------------------
// DestroyLauncherWindow
// ---------------------------------------------------------------------------
// Description: Destroys the launcher window.
// Arguments:
// HWND [in] Window handle.
// LPDIRECTPLAYLOBBYA [in] DirectPlay Lobby interface to destroy
// Returns:
// Nothing
void DestroyLauncherWindow(HWND hWnd, LPDIRECTPLAYLOBBYA lpDPlayLobby)
{
WPARAM index;
LRESULT lpData;
// destroy the GUID's stored with each app name
index = 0;
while (TRUE)
{
lpData = SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_GETITEMDATA, (WPARAM) index, 0);
if ((lpData == CB_ERR) || (lpData == 0))
break;
GlobalFreePtr((LPVOID) lpData);
index += 1;
}
// destroy the GUID's stored with each service provider name
index = 0;
while (TRUE)
{
lpData = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETITEMDATA, (WPARAM) index, 0);
if ((lpData == CB_ERR) || (lpData == 0))
break;
GlobalFreePtr((LPVOID) lpData);
index += 1;
}
// release the lobby interface
if (lpDPlayLobby)
lpDPlayLobby->lpVtbl->Release(lpDPlayLobby);
}
// ---------------------------------------------------------------------------
// CreateAddress
// ---------------------------------------------------------------------------
// Description: Wrapper for the IDirectPlayLobby::CreateAddress() method.
// Arguments:
// LPDIRECTPLAYLOBBYA [in] DirectPlay Lobby interface to use
// LPGUID [in] GUID of servicer provider to create address for
// LPGUID [in] GUID of address data type
// LPSTR [in] string to use as address data
// LPVOID* [out] pointer to return address in
// LPDWORD [out] pointer to return address size in
// Returns:
// HRESULT any error creating the address
HRESULT CreateAddress(LPDIRECTPLAYLOBBYA lpDPlayLobby,
LPGUID lpguidServiceProvider,
LPGUID lpguidAddressType, LPSTR lpszAddressText,
LPVOID *lplpAddress, LPDWORD lpdwAddressSize)
{
LPVOID lpAddress = NULL;
DWORD dwAddressSize = 0;
HRESULT hr;
// check for invalid address types
if (IsEqualGUID(lpguidAddressType, &GUID_NULL))
return (DPERR_INVALIDPARAM);
// see how much room is needed to store this address
hr = lpDPlayLobby->lpVtbl->CreateAddress(lpDPlayLobby, lpguidServiceProvider,
lpguidAddressType, lpszAddressText, strlen(lpszAddressText) + 1,
NULL, &dwAddressSize);
if (hr != DPERR_BUFFERTOOSMALL)
goto Failure;
// allocate space
lpAddress = GlobalAllocPtr(GHND, dwAddressSize);
if (lpAddress == NULL)
{
hr = DPERR_NOMEMORY;
goto Failure;
}
// create the address
hr = lpDPlayLobby->lpVtbl->CreateAddress(lpDPlayLobby, lpguidServiceProvider,
lpguidAddressType, lpszAddressText, strlen(lpszAddressText) + 1,
lpAddress, &dwAddressSize);
if FAILED(hr)
goto Failure;
// return the address info
*lplpAddress = lpAddress;
*lpdwAddressSize = dwAddressSize;
return (DP_OK);
Failure:
if (lpAddress)
GlobalFreePtr(lpAddress);
return (hr);
}
// ---------------------------------------------------------------------------
// RunApplication
// ---------------------------------------------------------------------------
// Description: Wrapper for the IDirectPlayLobby::RunApplication() method.
// Arguments:
// LPDIRECTPLAYLOBBYA [in] DirectPlay Lobby interface to use
// LPGUID [in] GUID of application to launch
// LPGUID [in] GUID of session to host with
// LPSTR [in] GUID of service provider to connect with
// LPVOID [in] service-provider address to connect to
// DWORD [in] length of address
// LPSTR [in] name of session to host
// LPSTR [in] name of our player
// BOOL [in] TRUE to host session, FALSE to join
// Returns:
// HRESULT any error running the application
HRESULT RunApplication(LPDIRECTPLAYLOBBYA lpDPlayLobby,
LPGUID lpguidApplication,
LPGUID lpguidInstance,
LPGUID lpguidServiceProvider,
LPVOID lpAddress,
DWORD dwAddressSize,
LPSTR lpszSessionName,
LPSTR lpszPlayerName,
BOOL bHostSession)
{
DWORD appID;
DPSESSIONDESC2 sessionInfo;
DPNAME playerName;
DPLCONNECTION connectInfo;
HRESULT hr;
if (lpDPlayLobby == NULL)
return (DPERR_NOINTERFACE);
// fill out session description
ZeroMemory(&sessionInfo, sizeof(DPSESSIONDESC2));
sessionInfo.dwSize = sizeof(DPSESSIONDESC2); // Size of structure
sessionInfo.dwFlags = 0; // DPSESSION_xxx flags
sessionInfo.guidInstance = *lpguidInstance; // ID for the session instance
sessionInfo.guidApplication = *lpguidApplication;// GUID of the DirectPlay application.
sessionInfo.dwMaxPlayers = 0; // Maximum # players allowed in session
sessionInfo.dwCurrentPlayers = 0; // Current # players in session (read only)
sessionInfo.lpszSessionNameA = lpszSessionName; // ANSI name of the session
sessionInfo.lpszPasswordA = NULL; // ANSI password of the session (optional)
sessionInfo.dwReserved1 = 0; // Reserved for future MS use.
sessionInfo.dwReserved2 = 0;
sessionInfo.dwUser1 = 0; // For use by the application
sessionInfo.dwUser2 = 0;
sessionInfo.dwUser3 = 0;
sessionInfo.dwUser4 = 0;
// fill out player name
ZeroMemory(&playerName, sizeof(DPNAME));
playerName.dwSize = sizeof(DPNAME); // Size of structure
playerName.dwFlags = 0; // Not used. Must be zero.
playerName.lpszShortNameA = lpszPlayerName; // ANSI short or friendly name
playerName.lpszLongNameA = lpszPlayerName; // ANSI long or formal name
// fill out connection description
ZeroMemory(&connectInfo, sizeof(DPLCONNECTION));
connectInfo.dwSize = sizeof(DPLCONNECTION); // Size of this structure
if (bHostSession)
connectInfo.dwFlags = DPLCONNECTION_CREATESESSION; // Create a new session
else
connectInfo.dwFlags = DPLCONNECTION_JOINSESSION; // Join existing session
connectInfo.lpSessionDesc = &sessionInfo; // Pointer to session desc to use on connect
connectInfo.lpPlayerName = &playerName; // Pointer to Player name structure
connectInfo.guidSP = *lpguidServiceProvider; // GUID of the DPlay SP to use
connectInfo.lpAddress = lpAddress; // Address for service provider
connectInfo.dwAddressSize = dwAddressSize; // Size of address data
// launch and connect the game
hr = lpDPlayLobby->lpVtbl->RunApplication(lpDPlayLobby,
0, // Flags
&appID, // App ID
&connectInfo, // Connection data
NULL); // Connect event
return (hr);
}
// ---------------------------------------------------------------------------
// LaunchDirectPlayApplication
// ---------------------------------------------------------------------------
// Description: Gathers information from the dialog and runs the application.
// Arguments:
// HWND [in] Window handle.
// LPDIRECTPLAYLOBBYA [in] DirectPlay Lobby interface to use
// Returns:
// Nothing
void LaunchDirectPlayApplication(HWND hWnd, LPDIRECTPLAYLOBBYA lpDPlayLobby)
{
GUID guidApplication, guidSession, guidServiceProvider, guidAddressType;
LPSTR lpPlayerName, lpSessionName;
LPVOID lpAddress = NULL;
DWORD dwAddressSize;
LPSPINFO lpSPInfo;
char strPlayerName[NAMEMAX], strSessionName[NAMEMAX], strAddressText[NAMEMAX];
LRESULT iApp, iSP, iHost;
HRESULT hr;
SetDlgItemText(hWnd, IDC_STATUSEDIT, "Launching...");
// get guid of application to launch
iApp = SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_GETCURSEL, (WPARAM) 0, 0);
if (iApp == CB_ERR)
goto Failure;
iApp = SendDlgItemMessage(hWnd, IDC_APPCOMBO, CB_GETITEMDATA, (WPARAM) iApp, 0);
if ((iApp == CB_ERR) || (iApp == 0))
goto Failure;
guidApplication = *((LPGUID) iApp);
// get info for service provider to use for the connection
iSP = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETCURSEL, (WPARAM) 0, 0);
if (iSP == CB_ERR)
goto Failure;
iSP = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETITEMDATA, (WPARAM) iSP, 0);
if ((iSP == CB_ERR) || (iSP == 0))
goto Failure;
lpSPInfo = (LPSPINFO) iSP;
guidServiceProvider = lpSPInfo->guidServiceProvider; // GUID of service provider
guidAddressType = lpSPInfo->guidAddressType; // address type required by service provider
// get guid of session to create.
guidSession = MY_SESSION_GUID;
// get name of our player
GetDlgItemText(hWnd, IDC_PLAYEREDIT, strPlayerName, NAMEMAX);
lpPlayerName = strPlayerName;
// get host vs. join flag
iHost = SendDlgItemMessage(hWnd, IDC_HOSTRADIO, BM_GETCHECK, (WPARAM) 0, 0);
if (iHost == BST_CHECKED)
{
iHost = TRUE; // we are hosting a session
lpAddress = NULL; // don't need an address to host
dwAddressSize = 0;
// get name of session
GetDlgItemText(hWnd, IDC_SESSIONEDIT, strSessionName, NAMEMAX);
lpSessionName = strSessionName;
}
else
{
iHost = FALSE; // we are joining an existing session
lpSessionName = NULL; // don't need a session name if we are joining
lpAddress = NULL; // assume we don't need address data
dwAddressSize = 0;
// the service provider supports address data
if (!IsEqualGUID(&guidAddressType, &GUID_NULL))
{
// get service-provider specific address data as a string
GetDlgItemText(hWnd, IDC_ADDRESSEDIT, strAddressText, NAMEMAX);
// convert string to a DirectPlay address
hr = CreateAddress(lpDPlayLobby, &guidServiceProvider,
&guidAddressType, strAddressText,
&lpAddress, &dwAddressSize);
}
}
// launch the application
hr = RunApplication(lpDPlayLobby,
&guidApplication,
&guidSession,
&guidServiceProvider,
lpAddress, dwAddressSize,
lpSessionName, lpPlayerName,
iHost);
if FAILED(hr)
goto Failure;
SetDlgItemText(hWnd, IDC_STATUSEDIT, "Launch successful");
if (lpAddress)
GlobalFreePtr(lpAddress);
return;
Failure:
if (lpAddress)
GlobalFreePtr(lpAddress);
SetDlgItemText(hWnd, IDC_STATUSEDIT, "Launch failed");
return;
}