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