DirectPlay 6.1a Supports Ripple Launch TechnologyID: Q236614
|
The primary enhancement of DirectPlay (DPlay) 6.1a over earlier versions of DPlay is that it supports Ripple Launch technology. By definition, ripple launch uses one program to start another program. For example, the ripple launcher program masks itself as a program to start another requested program, thus becoming a third-party negotiator.
More specifically, a ripple launcher program is a security program used to start games and prevent their piracy. A game that requires a ripple launcher program to install and run cannot be pirated because the ripple launcher program is encrypted into each program and cannot be duplicated. For this reason, Ripple Launch technology is gaining popularity among software developers and vendors.
If you use a versions of DPlay earlier than 6.1a (released 4/99) to run a game created with Ripple Raunch capability, you may be unable to connect to the game online or lose connections that you did make because the ripple launcher program's encryption scheme breaks DPlay's handshaking protocol. DPlay 6.1a (or later) is updated to allow your game (or the program you are developing) to use this encryption technology with DPlay. The original functionality of DPlay remains the same and is backwards compatible with earlier versions.
The most significant change to DPlay 6.1a for Ripple Launch support involves the processing of Interprocess Communication (IPC) facilities with connections in the DirectPlayLobby. Before DPlay 6.1a, an IPC connection was established by including the process ID of the program being started in the shared IPC object name. Each program has a static Globally Unique Identifier (GUID) embedded and installed with the program and a dynamic process ID automatically issued with each running instance of the program. With DPlay 6.1a, the IPC connection is established when the ripple launcher program uses its own process identifier to send a command-line switch to the program to inform it of the identify of the IPC objects. In a ripple launch scenario, each program can also be issued a dynamic GUID along with the dynamic process identifier.
To implement a ripple launch scenario for those games relying on Setup to create the Lobby registry entries, changes must be made to the DirectPlayLobby registry keys "Launcher" and "File." The Launcher registry key must be the name of the path of the executable file being started and File is the name of the original executable file for the game with an .icd extension instead of an .exe extension (for example, <gameexename.icd>).
These registry changes put numerous requirements on the ripple launching program and the registration of the game for lobbying. These details are as follows:
HRESULT RegisterApplication(
DWORD dwFlags,
LPVOID lpAppDesc
);
You may notice that the DPAPPLICATIONDESC2 structure has an additional field for specifying lpszAppLauncherName. This is the name of the binary file to be started, instead of the program. The ripple launcher program should reside in the same directory as the actual binary file. The program name still needs to be provided and is used in the case of WaitForConnectionSettings in order to find the running program on the system.
typedef struct {
DWORD dwSize;
DWORD dwFlags;
union {
LPSTR lpszApplicationNameA;
LPWSTR lpszApplicationName;
}
GUID guidApplication;
union {
LPSTR lpszFilenameA;
LPWSTR lpszFilename;
}
union {
LPSTR lpszCommandLineA;
LPWSTR lpszCommandLine;
}
union {
LPSTR lpszPathA;
LPWSTR lpszPath;
}
union {
LPSTR lpszCurrentDirectoryA;
LPWSTR lpszCurrentDirectory;
}
LPSTR lpszDescriptionA;
LPWSTR lpszDescriptionW;
} DPAPPLICATIONDESC, FAR *LPDPAPPLICATIONDESC;
type def struct DPAPPLICATIONDESC2
{
DWORD dwSize;
DWORD dwFlags;
union
{
LPSTR lpszApplicationNameA;
LPWSTR lpszApplicationName;
};
GUID guidApplication;
union
{
LPSTR lpszFilenameA;
LPWSTR lpszFilename;
};
union
{
LPSTR lpszCommandLineA;
LPWSTR lpszCommandLine;
};
union
{
LPSTR lpszPathA;
LPWSTR lpszPath;
};
union
{
LPSTR lpszCurrentDirectoryA;
LPWSTR lpszCurrentDirectory;
};
LPSTR lpszDescriptionA;
LPWSTR lpszDescriptionW;
union
{
LPSTR lpszAppLauncherNameA;
LPWSTR lpszAppLauncherName;
};
} DPAPPLICATIONDESC2, *LPDPAPPLICATIONDESC2;
DPAPPLICATIONDESC dpad;
...
dpad.dwSize = sizeof (DPAPPLICATIONDESC);
dpad.dwFlags = 0;
dpad.lpszApplicationNameA= "MyApp";
dpad.guidApplication = {12345678-...};
dpad.lpszFilenameA= "myapp.exe";
dpad.lpszCommandLineA= "/lobbied";
dpad.lpszPathA= "C:\\games";
dpad.lpszCurrentDirectoryA= "C:\\games";
dpad.lpszDescriptionA= "My Application";
dpad.lpszDescriptionW= L"My Application";
hr = lpDPLobby3A->RegisterApplication(0, &dpad);
...
"C:\games\myapp.exe /lobbied" is executed when RunApplication is called with the {12345678-...} GUID.
DPAPPLICATIONDESC2 dpad2;
...
dpad2.dwSize = sizeof (DPAPPLICATIONDESC2);
dpad2.dwFlags = 0;
dpad2.lpszApplicationNameA= "MyApp";
dpad2.guidApplication = {12345678-...};
dpad2.lpszFilenameA= "myapp.exe";
dpad2.lpszCommandLineA= "/lobbied";
dpad2.lpszPathA= "C:\\games";
dpad2.lpszCurrentDirectoryA= "C:\\games";
dpad2.lpszDescriptionA= "My Application";
dpad2.lpszDescriptionW= L"My Application";
dpad2.lpszAppLauncherNameA= "launcher.exe";
hr = lpDPLobby3A->RegisterApplication(0, &dpad2);
...
"C:\games\launcher.exe /dplay_ipc_guid:{12345678-...} /lobbied" is run when RunApplication is called with the {12345678-...} GUID. The ripple launch program must pass all command-line parameters to <Myapp.exe>.
//
// ripple.c : example ripple launcher. Win32 Console Application
//
#include <windows.h>
#include "stdio.h"
int main(int argc, char* argv[])
{
PROCESS_INFORMATION ProcInfo;
STARTUPINFO StartupInfo;
BOOL bCreated;
LPTSTR lpCommandLine;
printf("Launcher application\n");
lpCommandLine = GetCommandLineA();
// Strip EXE name from command line, pass rest to ripple launched app.
while(*lpCommandLine && *lpCommandLine!= ' ') lpCommandLine++;
printf("passing command line: %s\n",lpCommandLine);
memset(&StartupInfo,0,sizeof(StartupInfo));
StartupInfo.cb = sizeof(StartupInfo);
bCreated=CreateProcessA(
"duel.exe", // the program we are ripple launching.
lpCommandLine,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&StartupInfo,
&ProcInfo);
if(bCreated){
printf("Waiting for application to exit\n");
WaitForSingleObject(ProcInfo.hThread, INFINITE);
} else {
printf("Failed to create process\n");
}
printf("launcher application has left the building...\n");
return 0;
}
For more information on DirectPlay 6.1a's role in client-server games, please refer to the following article in the Microsoft Knowledge Base:
Q236610 DPlay 6.1a Launches Stable Client-Server Game ConnectionsYou can also visit Microsoft's DirectX and DirectPlay Web site at:
http://www.microsoft.com/directx/developer/downloads/dplay.asp
Additional query words:
Keywords : kb3rdparty kbinterop kbprg ntsp kbbug4.00 kbfix4.00 NT4SP6Fix
Version : winnt:4.0,4.0 SP4
Platform : winnt
Issue type : kbinfo
Last Reviewed: August 2, 1999