You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1523 lines
42 KiB
1523 lines
42 KiB
/*==========================================================================
|
|
*
|
|
* Copyright (C) 1996-1997 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: dplpack.c
|
|
* Content: Methods for packing/unpacking structures
|
|
*
|
|
* History:
|
|
* Date By Reason
|
|
* ======= ======= ======
|
|
* 5/31/96 myronth Created it
|
|
* 6/26/96 kipo added support for DPADDRESS.
|
|
* 7/13/96 kipo Bug fix - added (LPBYTE) cast to lpConnPack (address calc)
|
|
* in PRV_UnpackageDPLCONNECTIONAnsi()
|
|
* 11/20/96 myronth Removed packing for DPTRANSPORT
|
|
* 12/12/96 myronth Added DPLCONNECTION structure validation
|
|
* 2/12/97 myronth Mass DX5 changes
|
|
* 4/3/97 myronth Changed STRLEN's to WSTRLEN's from dplaypr.h
|
|
* 5/8/97 myronth Changed most packing functions to use the packed
|
|
* conn header, added pointer fixup function, Moved
|
|
* PRV_ConvertDPLCONNECTIONToUnicode from convert.c
|
|
* 9/29/97 myronth Fixed DPLCONNECTION package size bug (#12475)
|
|
* 12/2/97 myronth Made SessionDesc mandatory in DPLCONNECTION (#15529)
|
|
* 7/08/98 a-peterz Allow for MBCS for ANSI string sizes. ManBug 16299
|
|
* 2/10/99 aarono add support for application launcher
|
|
* 10/22/99 aarono added support for application flags
|
|
* 01/21/00 aarono added support for DPSESSION_ALLOWVOICERETRO flag
|
|
***************************************************************************/
|
|
#include "dplobpr.h"
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// Functions
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "PRV_GetDPLCONNECTIONPackageSize"
|
|
void PRV_GetDPLCONNECTIONPackageSize(LPDPLCONNECTION lpConn,
|
|
LPDWORD lpdwUnicode, LPDWORD lpdwAnsi)
|
|
{
|
|
DWORD dwSize;
|
|
DWORD dwStringSize = 0;
|
|
DWORD dwStringSizeA = 0;
|
|
LPDPSESSIONDESC2 lpsd = NULL;
|
|
LPDPNAME lpn = NULL;
|
|
|
|
|
|
DPF(7, "Entering PRV_GetDPLCONNECTIONPackageSize");
|
|
DPF(9, "Parameters: 0x%08x, 0x%08x, 0x%08x",
|
|
lpConn, lpdwUnicode, lpdwAnsi);
|
|
|
|
ASSERT(lpConn);
|
|
|
|
// First calculate the size of the structures
|
|
dwSize = sizeof(DPLCONNECTION);
|
|
|
|
// Add the size of the SessionDesc and Name structs
|
|
if(lpConn->lpSessionDesc)
|
|
{
|
|
dwSize += sizeof(DPSESSIONDESC2);
|
|
lpsd = lpConn->lpSessionDesc;
|
|
|
|
if(lpsd->lpszSessionName)
|
|
dwStringSize += WSTRLEN(lpsd->lpszSessionName);
|
|
if(lpsd->lpszPassword)
|
|
dwStringSize += WSTRLEN(lpsd->lpszPassword);
|
|
// only compute ANSI size if needed. Macro handles NULLS; includes terminator
|
|
if(lpdwAnsi)
|
|
{
|
|
dwStringSizeA += WSTR_ANSILENGTH(lpsd->lpszSessionName);
|
|
dwStringSizeA += WSTR_ANSILENGTH(lpsd->lpszPassword);
|
|
}
|
|
}
|
|
|
|
|
|
if(lpConn->lpPlayerName)
|
|
{
|
|
dwSize += sizeof(DPNAME);
|
|
lpn = lpConn->lpPlayerName;
|
|
|
|
if(lpn->lpszShortName)
|
|
dwStringSize += WSTRLEN(lpn->lpszShortName);
|
|
if(lpn->lpszLongName)
|
|
dwStringSize += WSTRLEN(lpn->lpszLongName);
|
|
// only compute ANSI size if needed. Macro handles NULLS; includes terminator
|
|
if(lpdwAnsi)
|
|
{
|
|
dwStringSizeA += WSTR_ANSILENGTH(lpn->lpszShortName);
|
|
dwStringSizeA += WSTR_ANSILENGTH(lpn->lpszLongName);
|
|
}
|
|
}
|
|
|
|
// Add the size of the SP-specific data
|
|
if(lpConn->lpAddress)
|
|
dwSize += lpConn->dwAddressSize;
|
|
|
|
// Now add in the size of the packed structure header
|
|
dwSize += sizeof(DPLOBBYI_PACKEDCONNHEADER);
|
|
|
|
// Fill in the output variables
|
|
if(lpdwAnsi)
|
|
*lpdwAnsi = dwSize + dwStringSizeA;
|
|
if(lpdwUnicode)
|
|
*lpdwUnicode = dwSize + (dwStringSize * sizeof(WCHAR));
|
|
|
|
} // PRV_GetDPLCONNECTIONPackageSize
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "PRV_PackageDPLCONNECTION"
|
|
HRESULT PRV_PackageDPLCONNECTION(LPDPLCONNECTION lpConn, LPVOID lpBuffer,
|
|
BOOL bHeader)
|
|
{
|
|
LPDPLOBBYI_PACKEDCONNHEADER lpHeader = NULL;
|
|
LPDPLCONNECTION lpConnPacked = NULL;
|
|
LPDPSESSIONDESC2 lpsd = NULL,
|
|
lpsdPacked = NULL;
|
|
LPDPNAME lpn = NULL,
|
|
lpnPacked = NULL;
|
|
LPBYTE lpStart, lpCurrent;
|
|
DWORD dwSizeAnsi,
|
|
dwSizeUnicode,
|
|
dwTemp;
|
|
|
|
|
|
DPF(7, "Entering PRV_PackageDPLCONNECTION");
|
|
DPF(9, "Parameters: 0x%08x, 0x%08x, %lu", lpConn, lpBuffer, bHeader);
|
|
|
|
ASSERT(lpConn);
|
|
|
|
// If the bHeader flag is set, we want to copy the packed header into the
|
|
// buffer first. If it is not, we only want the packed DPLCONNECTION struct
|
|
if(bHeader)
|
|
{
|
|
PRV_GetDPLCONNECTIONPackageSize(lpConn, &dwSizeUnicode, &dwSizeAnsi);
|
|
lpHeader = (LPDPLOBBYI_PACKEDCONNHEADER)lpBuffer;
|
|
lpHeader->dwUnicodeSize = dwSizeUnicode;
|
|
lpHeader->dwAnsiSize = dwSizeAnsi;
|
|
lpStart = (LPBYTE)lpBuffer + sizeof(DPLOBBYI_PACKEDCONNHEADER);
|
|
}
|
|
else
|
|
{
|
|
lpStart = lpBuffer;
|
|
}
|
|
|
|
// Copy in the structures & store the offsets
|
|
memcpy(lpStart, lpConn, sizeof(DPLCONNECTION));
|
|
lpConnPacked = (LPDPLCONNECTION)lpStart;
|
|
lpCurrent = lpStart + sizeof(DPLCONNECTION);
|
|
|
|
if(lpConn->lpSessionDesc)
|
|
{
|
|
lpsd = lpConn->lpSessionDesc;
|
|
lpsdPacked = (LPDPSESSIONDESC2)lpCurrent;
|
|
if(lpsdPacked->dwSize==sizeof(DPSESSIONDESC2)){
|
|
// we are over-riding and existing session descriptor, don't let
|
|
// the session flag for the retrofit get over-riden
|
|
lpsd->dwFlags |= (lpsdPacked->dwFlags & DPSESSION_ALLOWVOICERETRO);
|
|
}
|
|
memcpy(lpCurrent, lpsd, sizeof(DPSESSIONDESC2));
|
|
(DWORD_PTR)lpConnPacked->lpSessionDesc = (DWORD_PTR)(lpCurrent - lpStart);
|
|
lpCurrent += sizeof(DPSESSIONDESC2);
|
|
}
|
|
|
|
if(lpConn->lpPlayerName)
|
|
{
|
|
lpn = lpConn->lpPlayerName;
|
|
memcpy(lpCurrent, lpn, sizeof(DPNAME));
|
|
lpnPacked = (LPDPNAME)lpCurrent;
|
|
(DWORD_PTR)lpConnPacked->lpPlayerName = (DWORD_PTR)(lpCurrent - lpStart);
|
|
lpCurrent += sizeof(DPNAME);
|
|
}
|
|
|
|
// Copy in the strings in the SessionDesc and store the offset of the
|
|
// string from lpStart (relative offset in our package) in the pointer
|
|
// for the string in the SessionDesc structure. We will use this
|
|
// value to unpack and fix up the pointers during GetConnectionSettings
|
|
if(lpsd)
|
|
{
|
|
if(lpsd->lpszSessionName)
|
|
{
|
|
// Copy the string
|
|
dwTemp = WSTRLEN(lpsd->lpszSessionName) * sizeof(WCHAR);
|
|
memcpy(lpCurrent, lpsd->lpszSessionName, dwTemp);
|
|
|
|
// Store the offset
|
|
lpsdPacked->lpszSessionName = (LPWSTR)(DWORD_PTR)(lpCurrent - lpStart);
|
|
|
|
lpCurrent += dwTemp;
|
|
}
|
|
|
|
if(lpsd->lpszPassword)
|
|
{
|
|
// Copy the string
|
|
dwTemp = WSTRLEN(lpsd->lpszPassword) * sizeof(WCHAR);
|
|
memcpy(lpCurrent, lpsd->lpszPassword, dwTemp);
|
|
|
|
// Store the offset
|
|
lpsdPacked->lpszPassword = (LPWSTR)(DWORD_PTR)(lpCurrent - lpStart);
|
|
|
|
lpCurrent += dwTemp;
|
|
}
|
|
|
|
}
|
|
|
|
// Copy in the strings in the DPName struct and store the offset of the
|
|
// string from lpStart (relative offset in our package) in the pointer
|
|
// for the string in the SessionDesc structure. We will use this
|
|
// value to unpack and fix up the pointers during GetConnectionSettings
|
|
if(lpn)
|
|
{
|
|
if(lpn->lpszShortName)
|
|
{
|
|
// Copy the string
|
|
dwTemp = WSTRLEN(lpn->lpszShortName) * sizeof(WCHAR);
|
|
memcpy(lpCurrent, lpn->lpszShortName, dwTemp);
|
|
|
|
// Store the offset
|
|
lpnPacked->lpszShortName = (LPWSTR)(DWORD_PTR)(lpCurrent - lpStart);
|
|
|
|
lpCurrent += dwTemp;
|
|
}
|
|
|
|
if(lpn->lpszLongName)
|
|
{
|
|
// Copy the string
|
|
dwTemp = WSTRLEN(lpn->lpszLongName) * sizeof(WCHAR);
|
|
memcpy(lpCurrent, lpn->lpszLongName, dwTemp);
|
|
|
|
// Store the offset
|
|
lpnPacked->lpszLongName = (LPWSTR)(DWORD_PTR)(lpCurrent - lpStart);
|
|
|
|
lpCurrent += dwTemp;
|
|
}
|
|
|
|
}
|
|
|
|
// Copy in the SP-specific data
|
|
if(lpConn->lpAddress)
|
|
{
|
|
// Copy the data
|
|
memcpy(lpCurrent, lpConn->lpAddress, lpConn->dwAddressSize);
|
|
|
|
// Store the offset
|
|
((LPDPLCONNECTION)lpStart)->lpAddress = (LPVOID)(DWORD_PTR)(lpCurrent - lpStart);
|
|
}
|
|
|
|
return DP_OK;
|
|
|
|
} // PRV_PackageDPLCONNECTION
|
|
|
|
|
|
|
|
#define MAX_DPLCONNECTIONBUFFERSIZE (MAX_APPDATABUFFERSIZE -sizeof(DPLOBBYI_CONNCONTROL))
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "PRV_UnpackageDPLCONNECTIONUnicode"
|
|
// NOTE : really need to define a WIRE LPDPLCONNECTION so that
|
|
// we can crack it that way. This will allow compile, until
|
|
// we can test on Win64, there is no way to verify cracking
|
|
// the packet, so I've deffered this work until then AO 11/10/98
|
|
// not bringing DP4 to Win64 AO 04/03/2001
|
|
HRESULT PRV_UnpackageDPLCONNECTIONUnicode(LPVOID lpData, LPVOID lpPackage)
|
|
{
|
|
LPDPLOBBYI_PACKEDCONNHEADER lpHeader = NULL;
|
|
LPDPLCONNECTION lpConn = NULL;
|
|
LPDPSESSIONDESC2 lpsd = NULL;
|
|
LPDPNAME lpn = NULL;
|
|
LPBYTE lpPackCur, lpDataStart;
|
|
DWORD_PTR dwSize;
|
|
|
|
PCHAR pBufStart=(PCHAR)lpPackage;
|
|
PCHAR pBufEnd=(PCHAR)lpPackage+MAX_DPLCONNECTIONBUFFERSIZE-3;
|
|
|
|
HRESULT hr=DP_OK;
|
|
|
|
// SECURITY: ensure NULL termination for string scanning.
|
|
((LPBYTE)lpPackage)[MAX_DPLCONNECTIONBUFFERSIZE-1]=0;
|
|
((LPBYTE)lpPackage)[MAX_DPLCONNECTIONBUFFERSIZE-2]=0;
|
|
|
|
DPF(7, "Entering PRV_UnpackageDPLCONNECTIONUnicode");
|
|
DPF(9, "Parameters: 0x%08x, 0x%08x", lpData, lpPackage);
|
|
|
|
// If we're Unicode, all we need to do is copy the entire package
|
|
// and fix up the pointers
|
|
lpHeader = (LPDPLOBBYI_PACKEDCONNHEADER)lpPackage;
|
|
dwSize = lpHeader->dwUnicodeSize;
|
|
lpPackCur = ((LPBYTE)lpPackage) + sizeof(DPLOBBYI_PACKEDCONNHEADER);
|
|
lpDataStart = lpData;
|
|
|
|
// Copy the data
|
|
memcpy(lpData, lpPackCur, (DWORD)dwSize);
|
|
|
|
// Fix up the pointers -- the offset of every element relative to
|
|
// the start of lpConn is stored in the pointer for the element.
|
|
// So all we have to do to fix up the pointers is calculate it from
|
|
// the given offset + the value of lpConn.
|
|
lpConn = (LPDPLCONNECTION)lpData;
|
|
|
|
if(lpConn->lpSessionDesc)
|
|
{
|
|
if((UINT)lpConn->lpSessionDesc > MAX_DPLCONNECTIONBUFFERSIZE-(sizeof(DPSESSIONDESC2)))
|
|
{
|
|
DPF(4,"SECURITY WARN: Invalid offset in shared memory");
|
|
hr=DPERR_GENERIC;
|
|
goto err_exit;
|
|
}
|
|
dwSize = (DWORD_PTR)lpConn->lpSessionDesc;
|
|
lpsd = lpConn->lpSessionDesc = (LPDPSESSIONDESC2)(lpDataStart + dwSize);
|
|
|
|
// Now do the same for the strings
|
|
if(lpsd->lpszSessionName)
|
|
{
|
|
if((UINT)lpsd->lpszSessionName > MAX_DPLCONNECTIONBUFFERSIZE-3){
|
|
DPF(4,"SECURITY WARN: Invalid offset in shared memory");
|
|
hr=DPERR_GENERIC;
|
|
goto err_exit;
|
|
}
|
|
lpsd->lpszSessionName = (LPWSTR)(lpDataStart +
|
|
((DWORD_PTR)lpsd->lpszSessionName));
|
|
}
|
|
|
|
if(lpsd->lpszPassword)
|
|
{
|
|
if((UINT)lpsd->lpszPassword > MAX_DPLCONNECTIONBUFFERSIZE-3){
|
|
DPF(4,"SECURITY WARN: Invalid offset in shared memory");
|
|
hr=DPERR_GENERIC;
|
|
goto err_exit;
|
|
}
|
|
lpsd->lpszPassword = (LPWSTR)(lpDataStart +
|
|
((DWORD_PTR)lpsd->lpszPassword));
|
|
}
|
|
}
|
|
|
|
if(lpConn->lpPlayerName)
|
|
{
|
|
if((UINT)lpConn->lpPlayerName > MAX_DPLCONNECTIONBUFFERSIZE-(sizeof(DPNAME)))
|
|
{
|
|
DPF(4,"SECURITY WARN: Invalid offset in shared memory");
|
|
hr=DPERR_GENERIC;
|
|
goto err_exit;
|
|
}
|
|
dwSize = (DWORD_PTR)lpConn->lpPlayerName;
|
|
lpn = lpConn->lpPlayerName = (LPDPNAME)(lpDataStart + dwSize);
|
|
|
|
// Now do the same for the strings
|
|
if(lpn->lpszShortName)
|
|
{
|
|
if((UINT)lpn->lpszShortName > MAX_DPLCONNECTIONBUFFERSIZE-3){
|
|
DPF(4,"SECURITY WARN: Invalid offset in shared memory");
|
|
hr=DPERR_GENERIC;
|
|
goto err_exit;
|
|
}
|
|
lpn->lpszShortName = (LPWSTR)(lpDataStart +
|
|
((DWORD_PTR)lpn->lpszShortName));
|
|
}
|
|
|
|
if(lpn->lpszLongName)
|
|
{
|
|
if((UINT)lpn->lpszLongName > MAX_DPLCONNECTIONBUFFERSIZE-3){
|
|
DPF(4,"SECURITY WARN: Invalid offset in shared memory");
|
|
hr=DPERR_GENERIC;
|
|
goto err_exit;
|
|
}
|
|
lpn->lpszLongName = (LPWSTR)(lpDataStart +
|
|
((DWORD_PTR)lpn->lpszLongName));
|
|
}
|
|
|
|
}
|
|
|
|
// Fix the SPData pointer
|
|
if(lpConn->lpAddress)
|
|
{
|
|
if((UINT)lpConn->lpAddress > MAX_DPLCONNECTIONBUFFERSIZE-(sizeof(DPADDRESS)) ||
|
|
(UINT)lpConn->lpAddress+lpConn->dwAddressSize > MAX_DPLCONNECTIONBUFFERSIZE-3)
|
|
{
|
|
DPF(4,"SECURITY WARN: Invalid offset in shared memory");
|
|
hr=DPERR_GENERIC;
|
|
goto err_exit;
|
|
}
|
|
lpConn->lpAddress = lpDataStart + ((DWORD_PTR)lpConn->lpAddress);
|
|
}
|
|
|
|
return DP_OK;
|
|
|
|
err_exit:
|
|
return hr;
|
|
|
|
} // PRV_UnpackageDPLCONNECTIONUnicode
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "PRV_UnpackageDPLCONNECTIONAnsi"
|
|
HRESULT PRV_UnpackageDPLCONNECTIONAnsi(LPVOID lpData, LPVOID lpPackage)
|
|
{
|
|
LPDPLOBBYI_PACKEDCONNHEADER lpHeader = NULL;
|
|
LPDPLCONNECTION lpConnData, lpConnPack;
|
|
LPDPSESSIONDESC2 lpsdData = NULL,
|
|
lpsdPack = NULL;
|
|
LPDPNAME lpnData = NULL,
|
|
lpnPack = NULL;
|
|
LPBYTE lpDataCur, lpPackCur;
|
|
DWORD dwTemp;
|
|
LPWSTR lpszTemp;
|
|
|
|
HRESULT hr=DP_OK;
|
|
|
|
|
|
// SECURITY: ensure NULL termination for string scanning.
|
|
((LPBYTE)lpPackage)[MAX_DPLCONNECTIONBUFFERSIZE -1]=0;
|
|
((LPBYTE)lpPackage)[MAX_DPLCONNECTIONBUFFERSIZE -2]=0;
|
|
|
|
DPF(7, "Entering PRV_UnpackageDPLCONNECTIONAnsi");
|
|
DPF(9, "Parameters: 0x%08x, 0x%08x", lpData, lpPackage);
|
|
|
|
// If we're Ansi, we need to do is copy the structures, convert
|
|
// and copy the strings, and fix up all the pointers
|
|
lpPackCur = ((LPBYTE)lpPackage) + sizeof(DPLOBBYI_PACKEDCONNHEADER);
|
|
lpDataCur = lpData;
|
|
|
|
// First copy the main structures
|
|
dwTemp = sizeof(DPLCONNECTION);
|
|
memcpy(lpDataCur, lpPackCur, dwTemp);
|
|
lpConnData = (LPDPLCONNECTION)lpDataCur;
|
|
lpConnPack = (LPDPLCONNECTION)lpPackCur;
|
|
|
|
lpDataCur += dwTemp;
|
|
lpPackCur += dwTemp;
|
|
|
|
if(lpConnData->lpSessionDesc)
|
|
{
|
|
dwTemp = sizeof(DPSESSIONDESC2);
|
|
memcpySecureS(lpDataCur, lpPackCur, sizeof(DPSESSIONDESC2),lpPackage,MAX_DPLCONNECTIONBUFFERSIZE,"SECURITY WARN: Invalid Session Description in shared memory",hr=DPERR_GENERIC,err_exit);
|
|
lpsdData = lpConnData->lpSessionDesc = (LPDPSESSIONDESC2)lpDataCur;
|
|
lpsdPack = (LPDPSESSIONDESC2)lpPackCur;
|
|
lpDataCur += dwTemp;
|
|
lpPackCur += dwTemp;
|
|
}
|
|
|
|
if(lpConnData->lpPlayerName)
|
|
{
|
|
dwTemp = sizeof(DPNAME);
|
|
memcpySecureS(lpDataCur, lpPackCur, sizeof(DPNAME),lpPackage,MAX_DPLCONNECTIONBUFFERSIZE,"SECURITY WARN: Invalid DPNAME in shared memory",hr=DPERR_GENERIC,err_exit);
|
|
lpnData = lpConnData->lpPlayerName = (LPDPNAME)lpDataCur;
|
|
lpnPack = (LPDPNAME)lpPackCur;
|
|
lpDataCur += dwTemp;
|
|
lpPackCur += dwTemp;
|
|
}
|
|
|
|
// Copy the strings & fix up the pointers
|
|
if(lpsdData)
|
|
{
|
|
if(lpsdData->lpszSessionName)
|
|
{
|
|
if((UINT)lpsdData->lpszSessionName > MAX_DPLCONNECTIONBUFFERSIZE-3){
|
|
DPF(4,"SECURITY WARN: Invalid Session Name in shared memory");
|
|
hr=DPERR_GENERIC;
|
|
goto err_exit;
|
|
}
|
|
lpszTemp = (LPWSTR)((LPBYTE)lpConnPack + (DWORD_PTR)lpsdPack->lpszSessionName);
|
|
dwTemp = WideToAnsi(NULL, lpszTemp, 0); // size includes terminator
|
|
WideToAnsi((LPSTR)lpDataCur, lpszTemp, dwTemp);
|
|
lpsdData->lpszSessionNameA = (LPSTR)lpDataCur;
|
|
lpDataCur += dwTemp;
|
|
}
|
|
|
|
if(lpsdData->lpszPassword)
|
|
{
|
|
if((UINT)lpsdData->lpszPassword > MAX_DPLCONNECTIONBUFFERSIZE-3){
|
|
DPF(4,"SECURITY WARN: Invalid Password in shared memory");
|
|
hr=DPERR_GENERIC;
|
|
goto err_exit;
|
|
}
|
|
lpszTemp = (LPWSTR)((LPBYTE)lpConnPack + (DWORD_PTR)lpsdPack->lpszPassword);
|
|
dwTemp = WideToAnsi(NULL, lpszTemp, 0); // size includes terminator
|
|
WideToAnsi((LPSTR)lpDataCur, lpszTemp, dwTemp);
|
|
lpsdData->lpszPasswordA = (LPSTR)lpDataCur;
|
|
lpDataCur += dwTemp;
|
|
}
|
|
}
|
|
|
|
if(lpnData)
|
|
{
|
|
if(lpnData->lpszShortName)
|
|
{
|
|
if((UINT)lpnData->lpszShortName > MAX_DPLCONNECTIONBUFFERSIZE-3){
|
|
DPF(4,"SECURITY WARN: Invalid Short Name in shared memory");
|
|
hr=DPERR_GENERIC;
|
|
goto err_exit;
|
|
}
|
|
lpszTemp = (LPWSTR)((LPBYTE)lpConnPack + (DWORD_PTR)lpnPack->lpszShortName);
|
|
dwTemp = WideToAnsi(NULL, lpszTemp, 0); // size includes terminator
|
|
WideToAnsi((LPSTR)lpDataCur, lpszTemp, dwTemp);
|
|
lpnData->lpszShortNameA = (LPSTR)lpDataCur;
|
|
lpDataCur += dwTemp;
|
|
}
|
|
|
|
if(lpnData->lpszLongName)
|
|
{
|
|
if((UINT)lpnData->lpszLongName > MAX_DPLCONNECTIONBUFFERSIZE-3){
|
|
DPF(4,"SECURITY WARN: Invalid Long Name in shared memory");
|
|
hr=DPERR_GENERIC;
|
|
goto err_exit;
|
|
}
|
|
lpszTemp = (LPWSTR)((LPBYTE)lpConnPack + (DWORD_PTR)lpnPack->lpszLongName);
|
|
dwTemp = WideToAnsi(NULL, lpszTemp, 0); // size includes terminator
|
|
WideToAnsi((LPSTR)lpDataCur, lpszTemp, dwTemp);
|
|
lpnData->lpszLongNameA = (LPSTR)lpDataCur;
|
|
lpDataCur += dwTemp;
|
|
}
|
|
|
|
}
|
|
|
|
// Copy in the SPData & fix up the pointer
|
|
if(lpConnData->lpAddress)
|
|
{
|
|
lpPackCur = ((LPBYTE)lpConnPack) + (DWORD_PTR)lpConnPack->lpAddress;
|
|
memcpySecureS(lpDataCur, lpPackCur, lpConnPack->dwAddressSize,lpPackage,MAX_DPLCONNECTIONBUFFERSIZE,"SECURITY WARN: Invalid ADDRESS in shared memory",hr=DPERR_GENERIC,err_exit);
|
|
lpConnData->lpAddress = lpDataCur;
|
|
}
|
|
|
|
return DP_OK;
|
|
|
|
err_exit:
|
|
return hr;
|
|
|
|
} // PRV_UnpackageDPLCONNECTIONAnsi
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "PRV_ValidateDPLCONNECTION"
|
|
HRESULT PRV_ValidateDPLCONNECTION(LPDPLCONNECTION lpConn, BOOL bAnsi)
|
|
{
|
|
LPDPSESSIONDESC2 lpsd = NULL;
|
|
LPDPNAME lpn = NULL;
|
|
|
|
|
|
DPF(7, "Entering PRV_ValidateDPLCONNECTION");
|
|
DPF(9, "Parameters: 0x%08x, %lu", lpConn, bAnsi);
|
|
|
|
|
|
TRY
|
|
{
|
|
// Validate the connection structure itself
|
|
if(!VALID_DPLOBBY_CONNECTION(lpConn))
|
|
{
|
|
DPF_ERR("Invalid DPLCONNECTION structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
|
|
// Validate the flags
|
|
if(lpConn->dwFlags & ~(DPLCONNECTION_CREATESESSION | DPLCONNECTION_JOINSESSION))
|
|
{
|
|
DPF_ERR("Invalid flags exist in the dwFlags member of the DPLCONNECTION structure");
|
|
return DPERR_INVALIDFLAGS;
|
|
}
|
|
|
|
// Validate the SessionDesc structure
|
|
if(lpConn->lpSessionDesc)
|
|
{
|
|
lpsd = lpConn->lpSessionDesc;
|
|
// Validate the structure itself
|
|
if(!VALID_READ_DPSESSIONDESC2(lpsd))
|
|
{
|
|
DPF_ERR("Invalid DPSESSIONDESC2 structure in DPLCONNECTION structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
|
|
// Validate the SessionName string
|
|
if(lpsd->lpszSessionName)
|
|
{
|
|
if(!VALID_READ_PTR(lpsd->lpszSessionName, (bAnsi ?
|
|
strlen(lpsd->lpszSessionNameA) : WSTRLEN_BYTES(lpsd->lpszSessionName))))
|
|
{
|
|
DPF_ERR("Invalid SessionName string in DPLCONNECTION structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
|
|
// Validate the Password string
|
|
if(lpsd->lpszPassword)
|
|
{
|
|
if(!VALID_READ_PTR(lpsd->lpszPassword, (bAnsi ?
|
|
strlen(lpsd->lpszPasswordA) : WSTRLEN_BYTES(lpsd->lpszPassword))))
|
|
{
|
|
DPF_ERR("Invalid Password string in DPLCONNECTION structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPF_ERR("Invalid SessionDesc pointer in DPLCONNECTION structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
|
|
// Validate the Name structure
|
|
if(lpConn->lpPlayerName)
|
|
{
|
|
lpn = lpConn->lpPlayerName;
|
|
if(!VALID_READ_DPNAME_PTR(lpn))
|
|
{
|
|
DPF_ERR("Invalid DPNAME structure in DPLCONNECTION structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
|
|
// Validate the ShortName string
|
|
if(lpn->lpszShortName)
|
|
{
|
|
if(!VALID_READ_PTR(lpn->lpszShortName, (bAnsi ?
|
|
strlen(lpn->lpszShortNameA) : WSTRLEN_BYTES(lpn->lpszShortName))))
|
|
{
|
|
DPF_ERR("Invalid ShortName string in DPLCONNECTION structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
|
|
// Validate the LongName string
|
|
if(lpn->lpszLongName)
|
|
{
|
|
if(!VALID_READ_PTR(lpn->lpszLongName, (bAnsi ?
|
|
strlen(lpn->lpszLongNameA) : WSTRLEN_BYTES(lpn->lpszLongName))))
|
|
{
|
|
DPF_ERR("Invalid LongName string in DPLCONNECTION structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Validate the DPADDRESS structure
|
|
if(lpConn->lpAddress)
|
|
{
|
|
if(!VALID_READ_PTR(lpConn->lpAddress, lpConn->dwAddressSize))
|
|
{
|
|
DPF_ERR("Invalid lpAddress in DPLCONNECTION structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
}
|
|
|
|
EXCEPT( EXCEPTION_EXECUTE_HANDLER )
|
|
{
|
|
DPF_ERR( "Exception encountered validating parameters" );
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
|
|
return DP_OK;
|
|
|
|
} // PRV_ValidateDPLCONNECTION
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "PRV_ConvertDPLCONNECTIONToUnicode"
|
|
HRESULT PRV_ConvertDPLCONNECTIONToUnicode(LPDPLCONNECTION lpConnA,
|
|
LPDPLCONNECTION * lplpConnW)
|
|
{
|
|
LPDPLCONNECTION lpConnW = NULL;
|
|
LPDPSESSIONDESC2 lpsdW = NULL, lpsdA;
|
|
LPDPNAME lpnW = NULL, lpnA;
|
|
LPWSTR lpwszSessionName = NULL;
|
|
LPWSTR lpwszPassword = NULL;
|
|
LPWSTR lpwszLongName = NULL;
|
|
LPWSTR lpwszShortName = NULL;
|
|
HRESULT hr = DP_OK;
|
|
|
|
|
|
DPF(7, "Entering PRV_ConvertDPLCONNECTIONToUnicode");
|
|
DPF(9, "Parameters: 0x%08x, 0x%08x", lpConnA, lplpConnW);
|
|
|
|
ASSERT(lpConnA);
|
|
ASSERT(lplpConnW);
|
|
|
|
|
|
// Allocate memory for the DPLCONNECTION structure
|
|
lpConnW = DPMEM_ALLOC(sizeof(DPLCONNECTION));
|
|
if(!lpConnW)
|
|
{
|
|
DPF_ERR("Unable to allocate memory for temporary Unicode DPLCONNECTION struct");
|
|
hr = DPERR_OUTOFMEMORY;
|
|
goto ERROR_CONVERT_DPLCONNECTION;
|
|
}
|
|
|
|
// If we need a SessionDesc struct, allocate one
|
|
if(lpConnA->lpSessionDesc)
|
|
{
|
|
lpsdW = DPMEM_ALLOC(sizeof(DPSESSIONDESC2));
|
|
if(!lpsdW)
|
|
{
|
|
DPF_ERR("Unable to allocate memory for temporary Unicode DPSESSIONDESC struct");
|
|
hr = DPERR_OUTOFMEMORY;
|
|
goto ERROR_CONVERT_DPLCONNECTION;
|
|
}
|
|
}
|
|
|
|
// If we need a DPName struct, allocate one
|
|
if(lpConnA->lpPlayerName)
|
|
{
|
|
lpnW = DPMEM_ALLOC(sizeof(DPNAME));
|
|
if(!lpnW)
|
|
{
|
|
DPF_ERR("Unable to allocate memory for temporary Unicode DPNAME struct");
|
|
hr = DPERR_OUTOFMEMORY;
|
|
goto ERROR_CONVERT_DPLCONNECTION;
|
|
}
|
|
}
|
|
|
|
// Copy the fixed size members of the structures
|
|
memcpy(lpConnW, lpConnA, sizeof(DPLCONNECTION));
|
|
if(lpsdW)
|
|
memcpy(lpsdW, lpConnA->lpSessionDesc, sizeof(DPSESSIONDESC2));
|
|
if(lpnW)
|
|
memcpy(lpnW, lpConnA->lpPlayerName, sizeof(DPNAME));
|
|
|
|
|
|
// Get Unicode copies of all the strings
|
|
if(lpConnA->lpSessionDesc)
|
|
{
|
|
lpsdA = lpConnA->lpSessionDesc;
|
|
if(lpsdA->lpszSessionNameA)
|
|
{
|
|
hr = GetWideStringFromAnsi((LPWSTR *)&(lpwszSessionName),
|
|
(LPSTR)lpsdA->lpszSessionNameA);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to allocate temporary Unicode Session Name string");
|
|
goto ERROR_CONVERT_DPLCONNECTION;
|
|
}
|
|
}
|
|
|
|
if(lpsdA->lpszPasswordA)
|
|
{
|
|
hr = GetWideStringFromAnsi((LPWSTR *)&(lpwszPassword),
|
|
(LPSTR)lpsdA->lpszPasswordA);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to allocate temporary Unicode Password string");
|
|
goto ERROR_CONVERT_DPLCONNECTION;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(lpConnA->lpPlayerName)
|
|
{
|
|
lpnA = lpConnA->lpPlayerName;
|
|
if(lpnA->lpszShortNameA)
|
|
{
|
|
hr = GetWideStringFromAnsi((LPWSTR *)&(lpwszShortName),
|
|
(LPSTR)lpnA->lpszShortNameA);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to allocate temporary Unicode Short Name string");
|
|
goto ERROR_CONVERT_DPLCONNECTION;
|
|
}
|
|
}
|
|
|
|
if(lpnA->lpszLongNameA)
|
|
{
|
|
hr = GetWideStringFromAnsi((LPWSTR *)&(lpwszLongName),
|
|
(LPSTR)lpnA->lpszLongNameA);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to allocate temporary Unicode Long Name string");
|
|
goto ERROR_CONVERT_DPLCONNECTION;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now we've got everything so just fix up the pointers
|
|
lpConnW->lpSessionDesc = lpsdW;
|
|
lpConnW->lpPlayerName = lpnW;
|
|
|
|
if(lpsdW)
|
|
{
|
|
lpsdW->lpszSessionName = lpwszSessionName;
|
|
lpsdW->lpszPassword = lpwszPassword;
|
|
}
|
|
|
|
if(lpnW)
|
|
{
|
|
lpnW->lpszShortName = lpwszShortName;
|
|
lpnW->lpszLongName = lpwszLongName;
|
|
}
|
|
|
|
*lplpConnW = lpConnW;
|
|
|
|
return DP_OK;
|
|
|
|
|
|
ERROR_CONVERT_DPLCONNECTION:
|
|
|
|
if(lpConnW)
|
|
DPMEM_FREE(lpConnW);
|
|
if(lpsdW)
|
|
DPMEM_FREE(lpsdW);
|
|
if(lpnW)
|
|
DPMEM_FREE(lpnW);
|
|
if(lpwszSessionName)
|
|
DPMEM_FREE(lpwszSessionName);
|
|
if(lpwszPassword)
|
|
DPMEM_FREE(lpwszPassword);
|
|
if(lpwszShortName)
|
|
DPMEM_FREE(lpwszShortName);
|
|
if(lpwszLongName)
|
|
DPMEM_FREE(lpwszLongName);
|
|
|
|
return hr;
|
|
|
|
} // PRV_ConvertDPLCONNECTIONToUnicode
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "PRV_FixupDPLCONNECTIONPointers"
|
|
void PRV_FixupDPLCONNECTIONPointers(LPDPLCONNECTION lpConn)
|
|
{
|
|
LPDPSESSIONDESC2 lpsd = NULL;
|
|
LPDPNAME lpn = NULL;
|
|
|
|
|
|
DPF(7, "Entering PRV_FixupDPLCONNECTIONPointers");
|
|
DPF(9, "Parameters: 0x%08x", lpConn);
|
|
|
|
// Make sure we have a valid DPLCONNECTION pointer
|
|
if(!lpConn)
|
|
{
|
|
DPF_ERR("Invalid DPLCONNECTION pointer");
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
// Fixup the DPSESSIONDESC2 pointer
|
|
if(lpConn->lpSessionDesc)
|
|
{
|
|
lpsd = (LPDPSESSIONDESC2)((LPBYTE)lpConn + (DWORD_PTR)lpConn->lpSessionDesc);
|
|
lpConn->lpSessionDesc = lpsd;
|
|
}
|
|
|
|
// Fixup the name strings in the SessionDesc struct
|
|
if(lpsd)
|
|
{
|
|
// Fixup the session name
|
|
if(lpsd->lpszSessionName)
|
|
{
|
|
lpsd->lpszSessionName = (LPWSTR)((LPBYTE)lpConn +
|
|
(DWORD_PTR)lpsd->lpszSessionName);
|
|
}
|
|
|
|
// Fixup the password
|
|
if(lpsd->lpszPassword)
|
|
{
|
|
lpsd->lpszPassword = (LPWSTR)((LPBYTE)lpConn +
|
|
(DWORD_PTR)lpsd->lpszPassword);
|
|
}
|
|
}
|
|
|
|
// Fixup the DPNAME pointer
|
|
if(lpConn->lpPlayerName)
|
|
{
|
|
lpn = (LPDPNAME)((LPBYTE)lpConn + (DWORD_PTR)lpConn->lpPlayerName);
|
|
lpConn->lpPlayerName = lpn;
|
|
}
|
|
|
|
// Fixup the name strings
|
|
if(lpn)
|
|
{
|
|
// Fixup the short name
|
|
if(lpn->lpszShortName)
|
|
{
|
|
lpn->lpszShortName = (LPWSTR)((LPBYTE)lpConn +
|
|
(DWORD_PTR)lpn->lpszShortName);
|
|
}
|
|
|
|
// Fixup the long name
|
|
if(lpn->lpszLongName)
|
|
{
|
|
lpn->lpszLongName = (LPWSTR)((LPBYTE)lpConn +
|
|
(DWORD_PTR)lpn->lpszLongName);
|
|
}
|
|
}
|
|
|
|
// Fixup the address pointer
|
|
if(lpConn->lpAddress)
|
|
{
|
|
lpConn->lpAddress = (LPBYTE)lpConn + (DWORD_PTR)lpConn->lpAddress;
|
|
}
|
|
|
|
} // PRV_FixupDPLCONNECTIONPointers
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "PRV_ConvertDPLCONNECTIONToAnsiInPlace"
|
|
HRESULT PRV_ConvertDPLCONNECTIONToAnsiInPlace(LPDPLCONNECTION lpConn,
|
|
LPDWORD lpdwSize, DWORD dwHeaderSize)
|
|
{
|
|
DWORD dwSessionNameSize = 0, dwPasswordSize = 0;
|
|
DWORD dwShortNameSize = 0, dwLongNameSize = 0;
|
|
DWORD dwSessionDescSize = 0, dwNameSize = 0;
|
|
DWORD dwAnsiSize = 0;
|
|
LPSTR lpszSession = NULL, lpszPassword = 0;
|
|
LPSTR lpszShort = NULL, lpszLong = 0;
|
|
LPBYTE lpByte = NULL;
|
|
|
|
|
|
DPF(7, "Entering PRV_ConvertDPLCONNECTIONToAnsiInPlace");
|
|
DPF(9, "Parameters: 0x%08x, 0x%08x, %lu",
|
|
lpConn, lpdwSize, dwHeaderSize);
|
|
|
|
// If we don't have a DPLCONNECTION struct, something's wrong
|
|
ASSERT(lpConn);
|
|
ASSERT(lpdwSize);
|
|
|
|
// Start with the DPSESSIONDESC2 strings
|
|
if(lpConn->lpSessionDesc)
|
|
{
|
|
if(lpConn->lpSessionDesc->lpszSessionName)
|
|
{
|
|
GetAnsiString(&lpszSession, lpConn->lpSessionDesc->lpszSessionName);
|
|
dwSessionNameSize = STRLEN(lpszSession);
|
|
}
|
|
|
|
if(lpConn->lpSessionDesc->lpszPassword)
|
|
{
|
|
GetAnsiString(&lpszPassword, lpConn->lpSessionDesc->lpszPassword);
|
|
dwPasswordSize = STRLEN(lpszPassword);
|
|
}
|
|
dwSessionDescSize = sizeof(DPSESSIONDESC2) + dwSessionNameSize +
|
|
dwPasswordSize;
|
|
}
|
|
|
|
// Next the DPNAME strings
|
|
if(lpConn->lpPlayerName)
|
|
{
|
|
if(lpConn->lpPlayerName->lpszShortName)
|
|
{
|
|
GetAnsiString(&lpszShort, lpConn->lpPlayerName->lpszShortName);
|
|
dwShortNameSize = STRLEN(lpszShort);
|
|
}
|
|
|
|
if(lpConn->lpPlayerName->lpszLongName)
|
|
{
|
|
GetAnsiString(&lpszLong, lpConn->lpPlayerName->lpszLongName);
|
|
dwLongNameSize = STRLEN(lpszLong);
|
|
}
|
|
dwNameSize = sizeof(DPNAME) + dwShortNameSize + dwLongNameSize;
|
|
}
|
|
|
|
dwAnsiSize = dwHeaderSize + sizeof(DPLCONNECTION) +
|
|
dwSessionDescSize + dwNameSize + lpConn->dwAddressSize;
|
|
|
|
if (dwAnsiSize > *lpdwSize)
|
|
{
|
|
if(lpszSession)
|
|
DPMEM_FREE(lpszSession);
|
|
if(lpszPassword)
|
|
DPMEM_FREE(lpszPassword);
|
|
if(lpszShort)
|
|
DPMEM_FREE(lpszShort);
|
|
if(lpszLong)
|
|
DPMEM_FREE(lpszLong);
|
|
*lpdwSize = dwAnsiSize;
|
|
return DPERR_BUFFERTOOSMALL;
|
|
}
|
|
|
|
// store return size
|
|
*lpdwSize = dwAnsiSize;
|
|
|
|
// figure out where to start repacking strings
|
|
lpByte = (LPBYTE)lpConn + sizeof(DPLCONNECTION);
|
|
if(lpConn->lpSessionDesc)
|
|
lpByte += sizeof(DPSESSIONDESC2);
|
|
if(lpConn->lpPlayerName)
|
|
lpByte += sizeof(DPNAME);
|
|
|
|
// repack 'em
|
|
if(lpszSession)
|
|
{
|
|
memcpy(lpByte, lpszSession, dwSessionNameSize);
|
|
lpConn->lpSessionDesc->lpszSessionNameA = (LPSTR)lpByte;
|
|
DPMEM_FREE(lpszSession);
|
|
lpByte += dwSessionNameSize;
|
|
}
|
|
if(lpszPassword)
|
|
{
|
|
memcpy(lpByte, lpszPassword, dwPasswordSize);
|
|
lpConn->lpSessionDesc->lpszPasswordA = (LPSTR)lpByte;
|
|
DPMEM_FREE(lpszPassword);
|
|
lpByte += dwPasswordSize;
|
|
}
|
|
if(lpszShort)
|
|
{
|
|
memcpy(lpByte, lpszShort, dwShortNameSize);
|
|
lpConn->lpPlayerName->lpszShortNameA = (LPSTR)lpByte;
|
|
DPMEM_FREE(lpszShort);
|
|
lpByte += dwShortNameSize;
|
|
}
|
|
if(lpszLong)
|
|
{
|
|
memcpy(lpByte, lpszLong, dwLongNameSize);
|
|
lpConn->lpPlayerName->lpszLongNameA = (LPSTR)lpByte;
|
|
DPMEM_FREE(lpszLong);
|
|
lpByte += dwLongNameSize;
|
|
}
|
|
|
|
if(lpConn->lpAddress)
|
|
{
|
|
// recopy the address, and account for the fact that we could
|
|
// be doing an overlapping memory copy (So use MoveMemory instead
|
|
// of CopyMemory or memcpy)
|
|
MoveMemory(lpByte, lpConn->lpAddress, lpConn->dwAddressSize);
|
|
lpConn->lpAddress = lpByte;
|
|
}
|
|
|
|
return DP_OK;
|
|
} // PRV_ConvertDPLCONNECTIONToAnsiInPlace
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "PRV_ValidateDPAPPLICATIONDESC"
|
|
HRESULT PRV_ValidateDPAPPLICATIONDESC(LPDPAPPLICATIONDESC lpDesc, BOOL bAnsi)
|
|
{
|
|
DWORD LobbyDescVer;
|
|
LPDPAPPLICATIONDESC2 lpDesc2=(LPDPAPPLICATIONDESC2) lpDesc;
|
|
|
|
DPF(7, "Entering PRV_ValidateDPAPPLICATIONDESC");
|
|
DPF(9, "Parameters: 0x%08x, %lu", lpDesc, bAnsi);
|
|
|
|
|
|
TRY
|
|
{
|
|
// Validate the connection structure itself
|
|
if(VALID_DPLOBBY_APPLICATIONDESC(lpDesc)){
|
|
LobbyDescVer=1;
|
|
} else if (VALID_DPLOBBY_APPLICATIONDESC2(lpDesc)){
|
|
LobbyDescVer=2;
|
|
} else {
|
|
DPF_ERR("Invalid structure pointer or invalid size");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
|
|
// Validate the flags
|
|
if(!VALID_REGISTERAPP_FLAGS(lpDesc->dwFlags))
|
|
{
|
|
DPF_ERR("Invalid flags exist in the dwFlags member of the DPAPPLICATIONDESC structure");
|
|
return DPERR_INVALIDFLAGS;
|
|
}
|
|
if((lpDesc->dwFlags & (DPLAPP_AUTOVOICE|DPLAPP_SELFVOICE))==(DPLAPP_AUTOVOICE|DPLAPP_SELFVOICE))
|
|
{
|
|
return DPERR_INVALIDFLAGS;
|
|
}
|
|
|
|
// Validate the ApplicationName string (required)
|
|
if(lpDesc->lpszApplicationName)
|
|
{
|
|
if(!VALID_READ_PTR(lpDesc->lpszApplicationName, (bAnsi ?
|
|
strlen(lpDesc->lpszApplicationNameA) :
|
|
WSTRLEN_BYTES(lpDesc->lpszApplicationName))))
|
|
{
|
|
DPF_ERR("Invalid lpszApplicationName string in DPAPPLICTIONDESC structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPF_ERR("The lpszApplicationName member of the DPAPPLICTIONDESC structure is required");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
|
|
// Validate the GUID (required)
|
|
// We can really only check this against GUID_NULL since it will
|
|
// always be a valid guid structure inside the APPDESC struct
|
|
if(IsEqualGUID(&lpDesc->guidApplication, &GUID_NULL))
|
|
{
|
|
DPF_ERR("The guidApplication member of the DPAPPLICTIONDESC structure is required");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
|
|
// Validate the Filename string (required)
|
|
if(lpDesc->lpszFilename)
|
|
{
|
|
if(!VALID_READ_PTR(lpDesc->lpszFilename, (bAnsi ?
|
|
strlen(lpDesc->lpszFilenameA) :
|
|
WSTRLEN_BYTES(lpDesc->lpszFilename))))
|
|
{
|
|
DPF_ERR("Invalid lpszFilename string in DPAPPLICTIONDESC structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPF_ERR("The lpszFilename member of the DPAPPLICTIONDESC structure is required");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
|
|
// Validate the CommandLine string (optional)
|
|
if(lpDesc->lpszCommandLine)
|
|
{
|
|
if(!VALID_READ_PTR(lpDesc->lpszCommandLine, (bAnsi ?
|
|
strlen(lpDesc->lpszCommandLineA) :
|
|
WSTRLEN_BYTES(lpDesc->lpszCommandLine))))
|
|
{
|
|
DPF_ERR("Invalid lpszCommandLine string in DPAPPLICTIONDESC structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
|
|
// Validate the Path string (required)
|
|
if(lpDesc->lpszPath)
|
|
{
|
|
if(!VALID_READ_PTR(lpDesc->lpszPath, (bAnsi ?
|
|
strlen(lpDesc->lpszPathA) :
|
|
WSTRLEN_BYTES(lpDesc->lpszPath))))
|
|
{
|
|
DPF_ERR("Invalid lpszPath string in DPAPPLICTIONDESC structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPF_ERR("The lpszPath member of the DPAPPLICTIONDESC structure is required");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
|
|
// Validate the CurrentDirectory string (optional)
|
|
if(lpDesc->lpszCurrentDirectory)
|
|
{
|
|
if(!VALID_READ_PTR(lpDesc->lpszCurrentDirectory, (bAnsi ?
|
|
strlen(lpDesc->lpszCurrentDirectoryA) :
|
|
WSTRLEN_BYTES(lpDesc->lpszCurrentDirectory))))
|
|
{
|
|
DPF_ERR("Invalid lpszCurrentDirectory string in DPAPPLICTIONDESC structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
|
|
// Validate the DescriptionA string (optional)
|
|
if(lpDesc->lpszDescriptionA)
|
|
{
|
|
if(!VALID_READ_PTR(lpDesc->lpszDescriptionA,
|
|
strlen(lpDesc->lpszDescriptionA)))
|
|
{
|
|
DPF_ERR("Invalid lpszDescriptionA string in DPAPPLICTIONDESC structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
|
|
// Validate the DescriptionW string (optional)
|
|
if(lpDesc->lpszDescriptionW)
|
|
{
|
|
if(!VALID_READ_PTR(lpDesc->lpszDescriptionW,
|
|
WSTRLEN_BYTES(lpDesc->lpszDescriptionW)))
|
|
{
|
|
DPF_ERR("Invalid lpszDescriptionW string in DPAPPLICTIONDESC structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
|
|
// if the DPAPPLICATIONDESC2 is being used, validate the launcher name if present
|
|
if(LobbyDescVer==2)
|
|
{
|
|
// Validate AppLauncherName Name
|
|
if(lpDesc2->lpszAppLauncherNameA){
|
|
if(!VALID_READ_PTR(lpDesc2->lpszAppLauncherNameA, (bAnsi ?
|
|
strlen(lpDesc2->lpszAppLauncherNameA) :
|
|
WSTRLEN_BYTES(lpDesc2->lpszAppLauncherName))))
|
|
{
|
|
DPF_ERR("Invalid lpszAppLauncherName string in DPAPPLICATIONDESC2 structure");
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
EXCEPT( EXCEPTION_EXECUTE_HANDLER )
|
|
{
|
|
DPF_ERR( "Exception encountered validating parameters" );
|
|
return DPERR_INVALIDPARAMS;
|
|
}
|
|
|
|
return DP_OK;
|
|
|
|
} // PRV_ValidateDPAPPLICATIONDESC
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "PRV_ConvertDPAPPLICATIONDESCToUnicode"
|
|
HRESULT PRV_ConvertDPAPPLICATIONDESCToUnicode(LPDPAPPLICATIONDESC lpDescA,
|
|
LPDPAPPLICATIONDESC * lplpDescW)
|
|
{
|
|
#define lpDesc2A ((LPDPAPPLICATIONDESC2) lpDescA)
|
|
#define lpDesc2W ((LPDPAPPLICATIONDESC2) lpDescW)
|
|
|
|
LPDPAPPLICATIONDESC lpDescW = NULL;
|
|
LPWSTR lpwszApplicationName = NULL;
|
|
LPWSTR lpwszFilename = NULL;
|
|
LPWSTR lpwszCommandLine = NULL;
|
|
LPWSTR lpwszPath = NULL;
|
|
LPWSTR lpwszCurrentDirectory = NULL;
|
|
LPWSTR lpwszAppLauncherName = NULL;
|
|
HRESULT hr;
|
|
|
|
|
|
DPF(7, "Entering PRV_ValidateDPAPPLICATIONDESC");
|
|
DPF(9, "Parameters: 0x%08x, 0x%08x", lpDescA, lplpDescW);
|
|
|
|
ASSERT(lpDescA);
|
|
ASSERT(lplpDescW);
|
|
|
|
|
|
// Allocate memory for the DPAPPLICATIONDESC structure
|
|
lpDescW = DPMEM_ALLOC(lpDescA->dwSize);
|
|
if(!lpDescW)
|
|
{
|
|
DPF_ERR("Unable to allocate memory for temporary Unicode DPAPPLICATIONDESC struct");
|
|
hr = DPERR_OUTOFMEMORY;
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
|
|
}
|
|
|
|
// Copy the structure itself
|
|
memcpy(lpDescW, lpDescA, lpDescA->dwSize);
|
|
|
|
// Convert the ApplicationName
|
|
if(lpDescA->lpszApplicationNameA)
|
|
{
|
|
hr = GetWideStringFromAnsi(&lpwszApplicationName,
|
|
lpDescA->lpszApplicationNameA);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to convert ApplicationName string to Unicode");
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
|
|
}
|
|
}
|
|
|
|
// Convert the Filename
|
|
if(lpDescA->lpszFilenameA)
|
|
{
|
|
hr = GetWideStringFromAnsi(&lpwszFilename,
|
|
lpDescA->lpszFilenameA);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to convert Filename string to Unicode");
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
|
|
}
|
|
}
|
|
|
|
// Convert the CommandLine
|
|
if(lpDescA->lpszCommandLineA)
|
|
{
|
|
hr = GetWideStringFromAnsi(&lpwszCommandLine,
|
|
lpDescA->lpszCommandLineA);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to convert CommandLine string to Unicode");
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
|
|
}
|
|
}
|
|
|
|
// Convert the Path
|
|
if(lpDescA->lpszPathA)
|
|
{
|
|
hr = GetWideStringFromAnsi(&lpwszPath,
|
|
lpDescA->lpszPathA);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to convert Path string to Unicode");
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
|
|
}
|
|
}
|
|
|
|
// Convert the CurrentDirectory
|
|
if(lpDescA->lpszCurrentDirectoryA)
|
|
{
|
|
hr = GetWideStringFromAnsi(&lpwszCurrentDirectory,
|
|
lpDescA->lpszCurrentDirectoryA);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to convert CurrentDirectory string to Unicode");
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
|
|
}
|
|
}
|
|
|
|
// Convert the AppLauncher string if presend on an APPLICATIONDESC2
|
|
if(IS_DPLOBBY_APPLICATIONDESC2(lpDescA)){
|
|
if(lpDesc2A->lpszAppLauncherNameA){
|
|
hr = GetWideStringFromAnsi(&lpwszAppLauncherName,
|
|
lpDesc2A->lpszAppLauncherNameA);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to convert CurrentDirectory string to Unicode");
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
|
|
}
|
|
}
|
|
lpDesc2W->lpszAppLauncherName=lpwszAppLauncherName;
|
|
}
|
|
|
|
// We won't convert the description strings because they will
|
|
// get put in the registry as-is.
|
|
|
|
// So now that we have all the strings, setup the structure
|
|
lpDescW->lpszApplicationName = lpwszApplicationName;
|
|
lpDescW->lpszFilename = lpwszFilename;
|
|
lpDescW->lpszCommandLine = lpwszCommandLine;
|
|
lpDescW->lpszPath = lpwszPath;
|
|
lpDescW->lpszCurrentDirectory = lpwszCurrentDirectory;
|
|
|
|
lpDescW->lpszDescriptionA = lpDescA->lpszDescriptionA;
|
|
lpDescW->lpszDescriptionW = lpDescA->lpszDescriptionW;
|
|
|
|
// Set the output pointer
|
|
*lplpDescW = lpDescW;
|
|
|
|
return DP_OK;
|
|
|
|
ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE:
|
|
|
|
if(lpwszApplicationName)
|
|
DPMEM_FREE(lpwszApplicationName);
|
|
if(lpwszFilename)
|
|
DPMEM_FREE(lpwszFilename);
|
|
if(lpwszCommandLine)
|
|
DPMEM_FREE(lpwszCommandLine);
|
|
if(lpwszPath)
|
|
DPMEM_FREE(lpwszPath);
|
|
if(lpwszCurrentDirectory)
|
|
DPMEM_FREE(lpwszCurrentDirectory);
|
|
if(lpDescW)
|
|
DPMEM_FREE(lpDescW);
|
|
if(lpwszAppLauncherName){
|
|
DPMEM_FREE(lpwszAppLauncherName);
|
|
}
|
|
|
|
return hr;
|
|
|
|
#undef lpDesc2A
|
|
#undef lpDesc2W
|
|
|
|
} // PRV_ConvertDPAPPLICATIONDESCToUnicode
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "PRV_ConvertDPAPPLICATIONDESCToAnsi"
|
|
HRESULT PRV_ConvertDPAPPLICATIONDESCToAnsi(LPDPAPPLICATIONDESC lpDescW,
|
|
LPDPAPPLICATIONDESC * lplpDescA)
|
|
{
|
|
#define lpDesc2W ((LPDPAPPLICATIONDESC2)(lpDescW))
|
|
#define lpDesc2A ((LPDPAPPLICATIONDESC2)(lpDescA))
|
|
|
|
LPDPAPPLICATIONDESC lpDescA = NULL;
|
|
LPSTR lpszApplicationName = NULL;
|
|
LPSTR lpszFilename = NULL;
|
|
LPSTR lpszCommandLine = NULL;
|
|
LPSTR lpszPath = NULL;
|
|
LPSTR lpszCurrentDirectory = NULL;
|
|
LPSTR lpszAppLauncherName=NULL;
|
|
HRESULT hr;
|
|
|
|
DPF(7, "Entering PRV_ValidateDPAPPLICATIONDESC");
|
|
DPF(9, "Parameters: 0x%08x, 0x%08x", lpDescW, lplpDescA);
|
|
|
|
ASSERT(lpDescW);
|
|
ASSERT(lplpDescA);
|
|
|
|
// Allocate memory for the DPAPPLICATIONDESC structure
|
|
lpDescA = DPMEM_ALLOC(lpDescW->dwSize);
|
|
if(!lpDescA)
|
|
{
|
|
DPF_ERR("Unable to allocate memory for temporary Ansi DPAPPLICATIONDESC struct");
|
|
hr = DPERR_OUTOFMEMORY;
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
|
|
}
|
|
|
|
// Copy the structure itself
|
|
memcpy(lpDescA, lpDescW, lpDescW->dwSize);
|
|
|
|
// Convert the ApplicationName
|
|
if(lpDescW->lpszApplicationName)
|
|
{
|
|
hr = GetAnsiString(&lpszApplicationName, lpDescW->lpszApplicationName);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to convert ApplicationName string to Ansi");
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
|
|
}
|
|
}
|
|
|
|
// Convert the Filename
|
|
if(lpDescW->lpszFilename)
|
|
{
|
|
hr = GetAnsiString(&lpszFilename, lpDescW->lpszFilename);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to convert Filename string to Ansi");
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
|
|
}
|
|
}
|
|
|
|
// Convert the CommandLine
|
|
if(lpDescW->lpszCommandLine)
|
|
{
|
|
hr = GetAnsiString(&lpszCommandLine, lpDescW->lpszCommandLine);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to convert CommandLine string to Ansi");
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
|
|
}
|
|
}
|
|
|
|
// Convert the Path
|
|
if(lpDescW->lpszPath)
|
|
{
|
|
hr = GetAnsiString(&lpszPath, lpDescW->lpszPath);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to convert Path string to Ansi");
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
|
|
}
|
|
}
|
|
|
|
// Convert the CurrentDirectory
|
|
if(lpDescW->lpszCurrentDirectory)
|
|
{
|
|
hr = GetAnsiString(&lpszCurrentDirectory, lpDescW->lpszCurrentDirectory);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to convert CurrentDirectory string to Ansi");
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
|
|
}
|
|
}
|
|
|
|
// Convers the app launcher string if present.
|
|
if(IS_DPLOBBY_APPLICATIONDESC2(lpDesc2W)){
|
|
if(lpDesc2W->lpszAppLauncherName){
|
|
hr = GetAnsiString(&lpszAppLauncherName, lpDesc2W->lpszAppLauncherName);
|
|
if(FAILED(hr))
|
|
{
|
|
DPF_ERR("Unable to convert AppLauncherName string to Ansi");
|
|
goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
|
|
}
|
|
}
|
|
lpDesc2A->lpszAppLauncherNameA = lpszAppLauncherName;
|
|
}
|
|
|
|
// We won't convert the description strings because they will
|
|
// get put in the registry as-is.
|
|
|
|
// So now that we have all the strings, setup the structure
|
|
lpDescA->lpszApplicationNameA = lpszApplicationName;
|
|
lpDescA->lpszFilenameA = lpszFilename;
|
|
lpDescA->lpszCommandLineA = lpszCommandLine;
|
|
lpDescA->lpszPathA = lpszPath;
|
|
lpDescA->lpszCurrentDirectoryA = lpszCurrentDirectory;
|
|
|
|
lpDescA->lpszDescriptionA = lpDescW->lpszDescriptionA;
|
|
lpDescA->lpszDescriptionW = lpDescW->lpszDescriptionW;
|
|
|
|
// Set the output pointer
|
|
*lplpDescA = lpDescA;
|
|
|
|
return DP_OK;
|
|
|
|
ERROR_CONVERT_DPAPPLICATIONDESC_ANSI:
|
|
|
|
if(lpszApplicationName)
|
|
DPMEM_FREE(lpszApplicationName);
|
|
if(lpszFilename)
|
|
DPMEM_FREE(lpszFilename);
|
|
if(lpszCommandLine)
|
|
DPMEM_FREE(lpszCommandLine);
|
|
if(lpszPath)
|
|
DPMEM_FREE(lpszPath);
|
|
if(lpszCurrentDirectory)
|
|
DPMEM_FREE(lpszCurrentDirectory);
|
|
if(lpDescA)
|
|
DPMEM_FREE(lpDescA);
|
|
if(lpszAppLauncherName)
|
|
DPMEM_FREE(lpszAppLauncherName);
|
|
|
|
return hr;
|
|
|
|
#undef lpDesc2A
|
|
#undef lpDesc2W
|
|
} // PRV_ConvertDPAPPLICATIONDESCToAnsi
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "PRV_FreeLocalDPAPPLICATIONDESC"
|
|
void PRV_FreeLocalDPAPPLICATIONDESC(LPDPAPPLICATIONDESC lpDesc)
|
|
{
|
|
LPDPAPPLICATIONDESC2 lpDesc2 = (LPDPAPPLICATIONDESC2)lpDesc;
|
|
DPF(7, "Entering PRV_ValidateDPAPPLICATIONDESC");
|
|
DPF(9, "Parameters: 0x%08x", lpDesc);
|
|
|
|
if(lpDesc)
|
|
{
|
|
if(lpDesc->lpszApplicationName)
|
|
DPMEM_FREE(lpDesc->lpszApplicationName);
|
|
if(lpDesc->lpszFilename)
|
|
DPMEM_FREE(lpDesc->lpszFilename);
|
|
if(lpDesc->lpszCommandLine)
|
|
DPMEM_FREE(lpDesc->lpszCommandLine);
|
|
if(lpDesc->lpszPath)
|
|
DPMEM_FREE(lpDesc->lpszPath);
|
|
if(lpDesc->lpszCurrentDirectory)
|
|
DPMEM_FREE(lpDesc->lpszCurrentDirectory);
|
|
if(IS_DPLOBBY_APPLICATIONDESC2(lpDesc) && lpDesc2->lpszAppLauncherName)
|
|
DPMEM_FREE(lpDesc2->lpszAppLauncherName);
|
|
|
|
// Note: We don't need to free the Description strings because they
|
|
// were never allocated in either of the above routines, the pointers
|
|
// were just copied.
|
|
|
|
DPMEM_FREE(lpDesc);
|
|
}
|
|
|
|
} // PRV_FreeLocalDPAPPLICATIONDESC
|