Leaked source code of windows server 2003
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

/*==========================================================================
*
* 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