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.
908 lines
26 KiB
908 lines
26 KiB
|
|
/*************************************************************************
|
|
*
|
|
* rpcwire.c
|
|
*
|
|
* Common functions for converting internal WinStation API structures
|
|
* to/from a wire format which enables interoperability between various
|
|
* releases of icasrv and winsta.dll.
|
|
*
|
|
* Copyright Microsoft Corporation. 1998
|
|
*
|
|
*************************************************************************/
|
|
|
|
/*
|
|
* Includes
|
|
*/
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <ntddkbd.h>
|
|
#include <ntddmou.h>
|
|
#include <windows.h>
|
|
#include <winbase.h>
|
|
#include <winerror.h>
|
|
#include <wincrypt.h>
|
|
#include <winsta.h>
|
|
|
|
#include "rpcwire.h"
|
|
|
|
//
|
|
// Allocation routines as defined by the client/server.
|
|
//
|
|
extern void * MIDL_user_allocate(size_t);
|
|
extern void MIDL_user_free( void * );
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* InitVarData
|
|
*
|
|
* Initialize a generic structure which describes variable length data
|
|
* within a wire buffer.
|
|
*
|
|
* ENTRY:
|
|
* pVarData (input)
|
|
* The structure to initialize.
|
|
* Size (input)
|
|
* The size of the variable length data.
|
|
* Offset (input)
|
|
* The offset to the start of the data in the wire buffer.
|
|
*
|
|
****************************************************************************/
|
|
|
|
VOID InitVarData(PVARDATA_WIRE pVarData,
|
|
ULONG Size,
|
|
ULONG Offset)
|
|
{
|
|
pVarData->Size = (USHORT) Size;
|
|
pVarData->Offset = (USHORT) Offset;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* NextOffset
|
|
*
|
|
* Returns the offset to the next variable length data area.
|
|
*
|
|
* ENTRY:
|
|
* PrevData (input)
|
|
* The current last variable length data area.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
ULONG NextOffset(PVARDATA_WIRE PrevData)
|
|
{
|
|
return(PrevData->Offset + PrevData->Size);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* SdClassSize
|
|
*
|
|
* Returns the actual size of the data associated with a given SdClass.
|
|
*
|
|
* ENTRY:
|
|
* SdClass (input)
|
|
* The type of Sd.
|
|
*
|
|
* EXIT
|
|
* Returns the data size if known otherwise 0.
|
|
*****************************************************************************/
|
|
|
|
ULONG SdClassSize(SDCLASS SdClass)
|
|
{
|
|
switch (SdClass) {
|
|
case SdNetwork: return(sizeof(NETWORKCONFIGW));
|
|
case SdAsync: return(sizeof(ASYNCCONFIGW));
|
|
case SdNasi: return(sizeof(NASICONFIGW));
|
|
case SdOemFilter: return(sizeof(OEMTDCONFIGW));
|
|
#ifdef notdef
|
|
// These cases are valid in 1.7
|
|
case SdConsole: return(sizeof(CONSOLECONFIGW));
|
|
case SdFrame: return(sizeof(FRAMECONFIG));
|
|
case SdReliable: return(sizeof(RELIABLECONFIG));
|
|
case SdCompress: return(sizeof(COMPRESSCONFIG));
|
|
case SdModem: return(sizeof(MODEMCONFIGW));
|
|
#endif
|
|
default:
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CopySourceToDest
|
|
*
|
|
* Copies variable length data to/from local/wire buffers. If the source
|
|
* buffer is smaller than the destination buffer, the destination buffer
|
|
* is zero filled after SourceSize, upto DestSize. (e.g. client queries
|
|
* down-level icasrv). If the source buffer is larger than the
|
|
* destination buffer, the data is truncated at DestSize (e.g. down-level
|
|
* client queries newer icasrv).
|
|
*
|
|
* ENTRY:
|
|
* SourceBuf (input)
|
|
* Source buffer
|
|
* SourceSize (input)
|
|
* Source buffer size
|
|
* DestBuf (input)
|
|
* Destination buffer
|
|
* DestSize (input)
|
|
* Destiantion buffer size
|
|
*
|
|
* EXIT
|
|
* Returns the amount of data copied.
|
|
*****************************************************************************/
|
|
|
|
ULONG CopySourceToDest(PCHAR SourceBuf, ULONG SourceSize,
|
|
PCHAR DestBuf, ULONG DestSize)
|
|
{
|
|
ULONG DataSize;
|
|
|
|
if (SourceSize >= DestSize ) {
|
|
memcpy(DestBuf, SourceBuf, DestSize);
|
|
DataSize = DestSize;
|
|
}
|
|
else {
|
|
// Down-level server/client (zero fill)
|
|
memcpy(DestBuf, SourceBuf, SourceSize);
|
|
memset(DestBuf+SourceSize, 0, DestSize - SourceSize);
|
|
DataSize = SourceSize;
|
|
}
|
|
return(DataSize);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CopyPdParamsToWire
|
|
*
|
|
* Copies a PDPARAMSW structure to a wire buffer.
|
|
*
|
|
* ENTRY:
|
|
* PdParamsWire (input)
|
|
* Destination wire buffer
|
|
* PdParams (input)
|
|
* Source PDPARAMSW structure
|
|
*
|
|
*****************************************************************************/
|
|
|
|
VOID
|
|
CopyPdParamsToWire(PPDPARAMSWIREW PdParamsWire, PPDPARAMSW PdParams)
|
|
{
|
|
ULONG Size;
|
|
ULONG DataSize;
|
|
|
|
PdParamsWire->SdClass = PdParams->SdClass;
|
|
Size = SdClassSize(PdParams->SdClass);
|
|
DataSize = CopySourceToDest((PCHAR)&PdParams->Network,
|
|
Size,
|
|
(PCHAR)PdParamsWire +
|
|
PdParamsWire->SdClassSpecific.Offset,
|
|
PdParamsWire->SdClassSpecific.Size);
|
|
|
|
PdParamsWire->SdClassSpecific.Size = (USHORT)DataSize;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CopyPdParamsFromWire
|
|
*
|
|
* Copies a wire buffer to a PDPARAMSW structure.
|
|
*
|
|
* ENTRY:
|
|
* PdParamsWire (input)
|
|
* Source wire buffer
|
|
* PdParams (input)
|
|
* Destination PDPARAMSW structure.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
VOID
|
|
CopyPdParamsFromWire(PPDPARAMSWIREW PdParamsWire, PPDPARAMSW PdParams)
|
|
{
|
|
ULONG Size;
|
|
|
|
PdParams->SdClass = PdParamsWire->SdClass;
|
|
Size = SdClassSize(PdParams->SdClass);
|
|
CopySourceToDest((PCHAR)PdParamsWire + PdParamsWire->SdClassSpecific.Offset,
|
|
PdParamsWire->SdClassSpecific.Size,
|
|
(PCHAR)&PdParams->Network,
|
|
Size);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CopyPdConfigToWire
|
|
*
|
|
* Copies a PDCONFIGW structure to a wire buffer.
|
|
*
|
|
* ENTRY:
|
|
* PdConfigWire (input)
|
|
* Destination wire buffer
|
|
* PdConfig (input)
|
|
* Source PDCONFIGW structure
|
|
*
|
|
*****************************************************************************/
|
|
|
|
VOID CopyPdConfigToWire(PPDCONFIGWIREW PdConfigWire, PPDCONFIGW PdConfig)
|
|
{
|
|
CopySourceToDest((PCHAR) &PdConfig->Create, sizeof(PDCONFIG2W),
|
|
(PCHAR)PdConfigWire + PdConfigWire->PdConfig2W.Offset,
|
|
PdConfigWire->PdConfig2W.Size);
|
|
CopyPdParamsToWire(&PdConfigWire->PdParams,&PdConfig->Params);
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CopyPdConfigFromWire
|
|
*
|
|
* Copies a wire buffer to a PDCONFIGW structure.
|
|
*
|
|
* ENTRY:
|
|
* PdConfigWire (input)
|
|
* Destination wire buffer
|
|
* PdConfig (input)
|
|
* Source PDCONFIGW structure
|
|
*
|
|
*****************************************************************************/
|
|
|
|
VOID CopyPdConfigFromWire(PPDCONFIGWIREW PdConfigWire, PPDCONFIGW PdConfig)
|
|
{
|
|
CopySourceToDest((PCHAR)PdConfigWire + PdConfigWire->PdConfig2W.Offset,
|
|
PdConfigWire->PdConfig2W.Size,
|
|
(PCHAR) &PdConfig->Create, sizeof(PDCONFIG2W));
|
|
CopyPdParamsFromWire(&PdConfigWire->PdParams,&PdConfig->Params);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CopyWinStaConfigToWire
|
|
*
|
|
* Copies a WINSTATIONCONFIGW structure to a wire buffer.
|
|
*
|
|
* ENTRY:
|
|
* WinStaConfigWire (input)
|
|
* Destination wire buffer
|
|
* WinStaConfig (input)
|
|
* Source WINSTATIONCONFIGW structure
|
|
*
|
|
*****************************************************************************/
|
|
|
|
VOID CopyWinStaConfigToWire(PWINSTACONFIGWIREW WinStaConfigWire,
|
|
PWINSTATIONCONFIGW WinStaConfig)
|
|
{
|
|
CopySourceToDest((PCHAR) &WinStaConfig->User, sizeof(USERCONFIGW),
|
|
(PCHAR)WinStaConfigWire+WinStaConfigWire->UserConfig.Offset,
|
|
WinStaConfigWire->UserConfig.Size);
|
|
CopySourceToDest((PCHAR)&WinStaConfig->Comment,
|
|
sizeof(WinStaConfig->Comment),
|
|
(PCHAR)&WinStaConfigWire->Comment,
|
|
sizeof(WinStaConfigWire->Comment));
|
|
CopySourceToDest((PCHAR)&WinStaConfig->OEMId,
|
|
sizeof(WinStaConfig->OEMId),
|
|
(PCHAR)&WinStaConfigWire->OEMId,
|
|
sizeof(WinStaConfigWire->OEMId));
|
|
CopySourceToDest((PCHAR)&WinStaConfig + sizeof(WINSTATIONCONFIGW),
|
|
0, // Change this when new fields are added
|
|
(PCHAR)WinStaConfigWire+WinStaConfigWire->NewFields.Offset,
|
|
WinStaConfigWire->NewFields.Size);
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CopyWinStaConfigFromWire
|
|
*
|
|
* Copies a wire buffer to a WINSTATIONCONFIGW structure.
|
|
*
|
|
* ENTRY:
|
|
* WinStaConfigWire (input)
|
|
* Source wire buffer
|
|
* WinStaConfig (input)
|
|
* Destiantion WINSTATIONCONFIGW structure
|
|
*
|
|
*****************************************************************************/
|
|
|
|
VOID CopyWinStaConfigFromWire(PWINSTACONFIGWIREW WinStaConfigWire,
|
|
PWINSTATIONCONFIGW WinStaConfig)
|
|
{
|
|
CopySourceToDest((PCHAR)WinStaConfigWire+WinStaConfigWire->UserConfig.Offset,
|
|
WinStaConfigWire->UserConfig.Size,
|
|
(PCHAR) &WinStaConfig->User, sizeof(USERCONFIGW));
|
|
|
|
CopySourceToDest((PCHAR)&WinStaConfigWire->Comment,
|
|
sizeof(WinStaConfigWire->Comment),
|
|
(PCHAR)&WinStaConfig->Comment,
|
|
sizeof(WinStaConfig->Comment));
|
|
|
|
CopySourceToDest((PCHAR)&WinStaConfigWire->OEMId,
|
|
sizeof(WinStaConfigWire->OEMId),
|
|
(PCHAR)&WinStaConfig->OEMId,
|
|
sizeof(WinStaConfig->OEMId));
|
|
|
|
CopySourceToDest((PCHAR)WinStaConfigWire+WinStaConfigWire->NewFields.Offset,
|
|
WinStaConfigWire->NewFields.Size,
|
|
(PCHAR) &WinStaConfig + sizeof(WINSTATIONCONFIGW),
|
|
0); // Change this when new fields are added
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CopyGenericToWire
|
|
*
|
|
* Copies a single variable length structure to a wire buffer.
|
|
*
|
|
* ENTRY:
|
|
* WireBuf (input)
|
|
* Destination wire buffer
|
|
* LocalBuf (input)
|
|
* Source structure
|
|
* LocalBufLength (input)
|
|
* Source structure length
|
|
*****************************************************************************/
|
|
|
|
VOID CopyGenericToWire(PVARDATA_WIRE WireBuf, PVOID LocalBuf, ULONG LocalBufLen)
|
|
{
|
|
CopySourceToDest((PCHAR)LocalBuf,
|
|
LocalBufLen,
|
|
(PCHAR) WireBuf + WireBuf->Offset,
|
|
WireBuf->Size);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CopyGenericFromWire
|
|
*
|
|
* Copies a wire buffer to a single variable length structure.
|
|
*
|
|
* ENTRY:
|
|
* WireBuf (input)
|
|
* Source wire buffer
|
|
* LocalBuf (input)
|
|
* Destination structure
|
|
* LocalBufLength (input)
|
|
* Destination structure length
|
|
*****************************************************************************/
|
|
|
|
VOID CopyGenericFromWire(PVARDATA_WIRE WireBuf, PVOID LocalBuf, ULONG LocalBufLen)
|
|
{
|
|
CopySourceToDest((PCHAR) WireBuf + WireBuf->Offset,
|
|
WireBuf->Size,
|
|
(PCHAR)LocalBuf,
|
|
LocalBufLen);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CopyOutWireBuf
|
|
*
|
|
* Copies a wire buffer to a local structure.
|
|
*
|
|
* ENTRY:
|
|
* InfoClass (input)
|
|
* WinStationQuery/Set information class
|
|
* UserBuf (input)
|
|
* Destination local structure
|
|
* WireBuf
|
|
* Source wire buffer
|
|
*****************************************************************************/
|
|
|
|
BOOLEAN
|
|
CopyOutWireBuf(WINSTATIONINFOCLASS InfoClass,
|
|
PVOID UserBuf,
|
|
PVOID WireBuf)
|
|
{
|
|
ULONG BufSize;
|
|
PPDCONFIGWIREW PdConfigWire;
|
|
PPDCONFIGW PdConfig;
|
|
PPDPARAMSWIREW PdParamsWire;
|
|
PPDPARAMSW PdParam;
|
|
PWINSTACONFIGWIREW WinStaConfigWire;
|
|
PWINSTATIONCONFIGW WinStaConfig;
|
|
|
|
switch (InfoClass) {
|
|
case WinStationPd:
|
|
PdConfigWire = (PPDCONFIGWIREW)WireBuf;
|
|
PdConfig = (PPDCONFIGW)UserBuf;
|
|
CopyPdConfigFromWire(PdConfigWire, PdConfig);
|
|
break;
|
|
case WinStationPdParams:
|
|
PdParamsWire = (PPDPARAMSWIREW)WireBuf;
|
|
|
|
CopyPdParamsFromWire(PdParamsWire,
|
|
(PPDPARAMS)UserBuf);
|
|
break;
|
|
|
|
case WinStationConfiguration:
|
|
WinStaConfigWire = (PWINSTACONFIGWIREW)WireBuf;
|
|
WinStaConfig = (PWINSTATIONCONFIGW)UserBuf;
|
|
|
|
CopyWinStaConfigFromWire(WinStaConfigWire, WinStaConfig);
|
|
break;
|
|
|
|
case WinStationInformation:
|
|
CopyGenericFromWire((PVARDATA_WIRE)WireBuf,
|
|
UserBuf,
|
|
sizeof(WINSTATIONINFORMATIONW));
|
|
break;
|
|
|
|
case WinStationWd:
|
|
CopyGenericFromWire((PVARDATA_WIRE)WireBuf,
|
|
UserBuf,
|
|
sizeof(WDCONFIGW));
|
|
break;
|
|
|
|
case WinStationClient:
|
|
CopyGenericFromWire((PVARDATA_WIRE)WireBuf,
|
|
UserBuf,
|
|
sizeof(WINSTATIONCLIENTW));
|
|
break;
|
|
|
|
default:
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CopyInWireBuf
|
|
*
|
|
* Copies a local structure to a wire buffer.
|
|
*
|
|
* ENTRY:
|
|
* InfoClass (input)
|
|
* WinStationQuery/Set information class
|
|
* WireBuf (input)
|
|
* Destination wire buffer
|
|
* UserBuf (input)
|
|
* Destination local structure
|
|
*****************************************************************************/
|
|
|
|
BOOLEAN
|
|
CopyInWireBuf(WINSTATIONINFOCLASS InfoClass,
|
|
PVOID UserBuf,
|
|
PVOID WireBuf)
|
|
{
|
|
ULONG BufSize;
|
|
PPDCONFIGWIREW PdConfigWire;
|
|
PPDCONFIGW PdConfig;
|
|
PPDPARAMSWIREW PdParamsWire;
|
|
PPDPARAMSW PdParam;
|
|
PWINSTACONFIGWIREW WinStaConfigWire;
|
|
PWINSTATIONCONFIGW WinStaConfig;
|
|
|
|
switch (InfoClass) {
|
|
case WinStationPd:
|
|
PdConfigWire = (PPDCONFIGWIREW)WireBuf;
|
|
PdConfig = (PPDCONFIGW)UserBuf;
|
|
CopyPdConfigToWire(PdConfigWire, PdConfig);
|
|
break;
|
|
case WinStationPdParams:
|
|
PdParamsWire = (PPDPARAMSWIREW)WireBuf;
|
|
|
|
CopyPdParamsToWire(PdParamsWire,
|
|
(PPDPARAMS)UserBuf);
|
|
break;
|
|
|
|
case WinStationConfiguration:
|
|
WinStaConfigWire = (PWINSTACONFIGWIREW)WireBuf;
|
|
WinStaConfig = (PWINSTATIONCONFIGW)UserBuf;
|
|
|
|
CopyWinStaConfigToWire(WinStaConfigWire, WinStaConfig);
|
|
break;
|
|
|
|
case WinStationInformation:
|
|
CopyGenericToWire((PVARDATA_WIRE)WireBuf,
|
|
UserBuf,
|
|
sizeof(WINSTATIONINFORMATIONW));
|
|
break;
|
|
|
|
case WinStationWd:
|
|
CopyGenericToWire((PVARDATA_WIRE)WireBuf,
|
|
UserBuf,
|
|
sizeof(WDCONFIGW));
|
|
break;
|
|
|
|
case WinStationClient:
|
|
CopyGenericToWire((PVARDATA_WIRE)WireBuf,
|
|
UserBuf,
|
|
sizeof(WINSTATIONCLIENTW));
|
|
break;
|
|
|
|
default:
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* AllocateAndCopyCredToWire
|
|
*
|
|
* Allocates a buffer big enough for the credentials and then copies them in.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
ULONG
|
|
AllocateAndCopyCredToWire(
|
|
PWLXCLIENTCREDWIREW *ppWire,
|
|
PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCredentials
|
|
)
|
|
{
|
|
ULONG cchUserName;
|
|
ULONG cchDomain;
|
|
ULONG cchPassword;
|
|
ULONG cbWireBuf;
|
|
//Password length in characrters alligned by CRYPTPROTECTMEMORY_BLOCK_SIZE
|
|
ULONG cchPasswordEx;
|
|
|
|
cchUserName = lstrlenW(pCredentials->pszUserName) + 1;
|
|
cchDomain = lstrlenW(pCredentials->pszDomain) + 1;
|
|
cchPassword = lstrlenW(pCredentials->pszPassword) + 1;
|
|
|
|
//Make it multiple of CRYPTPROTECTMEMORY_BLOCK_SIZE (for encryption)
|
|
cchPasswordEx =cchPassword + CRYPTPROTECTMEMORY_BLOCK_SIZE -
|
|
(cchPassword%CRYPTPROTECTMEMORY_BLOCK_SIZE);
|
|
|
|
cbWireBuf = sizeof(WLXCLIENTCREDWIREW) +
|
|
(cchUserName + cchDomain + cchPasswordEx) * sizeof(WCHAR);
|
|
|
|
*ppWire = MIDL_user_allocate(cbWireBuf);
|
|
|
|
if (*ppWire != NULL)
|
|
{
|
|
ZeroMemory(*ppWire, cbWireBuf);
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
return(0);
|
|
}
|
|
|
|
(*ppWire)->dwType = pCredentials->dwType;
|
|
(*ppWire)->fDisconnectOnLogonFailure = pCredentials->fDisconnectOnLogonFailure;
|
|
(*ppWire)->fPromptForPassword = pCredentials->fPromptForPassword;
|
|
|
|
InitVarData(
|
|
&((*ppWire)->UserNameData),
|
|
cchUserName * sizeof(WCHAR),
|
|
sizeof(WLXCLIENTCREDWIREW)
|
|
);
|
|
CopyMemory(
|
|
(LPBYTE)(*ppWire) + (*ppWire)->UserNameData.Offset,
|
|
pCredentials->pszUserName,
|
|
(*ppWire)->UserNameData.Size
|
|
);
|
|
|
|
InitVarData(
|
|
&((*ppWire)->DomainData),
|
|
cchDomain * sizeof(WCHAR),
|
|
NextOffset(&((*ppWire)->UserNameData))
|
|
);
|
|
CopyMemory(
|
|
(LPBYTE)(*ppWire) + (*ppWire)->DomainData.Offset,
|
|
pCredentials->pszDomain,
|
|
(*ppWire)->DomainData.Size
|
|
);
|
|
|
|
InitVarData(
|
|
&((*ppWire)->PasswordData),
|
|
cchPasswordEx * sizeof(WCHAR),
|
|
NextOffset(&((*ppWire)->DomainData))
|
|
);
|
|
CopyMemory(
|
|
(LPBYTE)(*ppWire) + (*ppWire)->PasswordData.Offset,
|
|
pCredentials->pszPassword,
|
|
cchPassword * sizeof(WCHAR)
|
|
);
|
|
|
|
//Encrypt password, so it won't hang around in clear text in RPC internal buffers.
|
|
if(!CryptProtectMemory((LPBYTE)(*ppWire) + (*ppWire)->PasswordData.Offset,
|
|
(*ppWire)->PasswordData.Size, CRYPTPROTECTMEMORY_SAME_LOGON))
|
|
{
|
|
DWORD Err = GetLastError();
|
|
RtlSecureZeroMemory((LPBYTE)(*ppWire) + (*ppWire)->PasswordData.Offset,
|
|
(*ppWire)->PasswordData.Size);
|
|
MIDL_user_free(*ppWire);
|
|
*ppWire = NULL;
|
|
SetLastError(Err);
|
|
return 0;
|
|
}
|
|
|
|
return(cbWireBuf);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CopyCredFromWire
|
|
*
|
|
* Copies credentials from the wire buffer.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOLEAN
|
|
CopyCredFromWire(
|
|
PWLXCLIENTCREDWIREW pWire,
|
|
PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCredentials
|
|
)
|
|
{
|
|
BOOLEAN fRet;
|
|
|
|
pCredentials->pszUserName = LocalAlloc(
|
|
LMEM_FIXED,
|
|
pWire->UserNameData.Size
|
|
);
|
|
|
|
if (pCredentials->pszUserName != NULL)
|
|
{
|
|
CopyMemory(
|
|
(LPBYTE)(pCredentials->pszUserName),
|
|
(LPBYTE)pWire + pWire->UserNameData.Offset,
|
|
pWire->UserNameData.Size
|
|
);
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
fRet = FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
pCredentials->pszDomain = LocalAlloc(
|
|
LMEM_FIXED,
|
|
pWire->DomainData.Size
|
|
);
|
|
|
|
if (pCredentials->pszDomain != NULL)
|
|
{
|
|
CopyMemory(
|
|
(LPBYTE)(pCredentials->pszDomain),
|
|
(LPBYTE)pWire + pWire->DomainData.Offset,
|
|
pWire->DomainData.Size
|
|
);
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
fRet = FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
pCredentials->pszPassword = LocalAlloc(
|
|
LMEM_FIXED,
|
|
pWire->PasswordData.Size
|
|
);
|
|
|
|
if (pCredentials->pszPassword != NULL)
|
|
{
|
|
if(CryptUnprotectMemory((LPBYTE)pWire + pWire->PasswordData.Offset,
|
|
pWire->PasswordData.Size,
|
|
CRYPTPROTECTMEMORY_SAME_LOGON))
|
|
{
|
|
CopyMemory(
|
|
(LPBYTE)(pCredentials->pszPassword),
|
|
(LPBYTE)pWire + pWire->PasswordData.Offset,
|
|
pWire->PasswordData.Size
|
|
);
|
|
}
|
|
else
|
|
{
|
|
fRet = FALSE;
|
|
goto exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
fRet = FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
pCredentials->dwType = pWire->dwType;
|
|
pCredentials->fDisconnectOnLogonFailure = pWire->fDisconnectOnLogonFailure;
|
|
pCredentials->fPromptForPassword = pWire->fPromptForPassword;
|
|
|
|
fRet = TRUE;
|
|
|
|
exit:
|
|
if (!fRet)
|
|
{
|
|
if (pCredentials->pszUserName != NULL)
|
|
{
|
|
LocalFree(pCredentials->pszUserName);
|
|
pCredentials->pszUserName = NULL;
|
|
}
|
|
|
|
if (pCredentials->pszDomain != NULL)
|
|
{
|
|
LocalFree(pCredentials->pszDomain);
|
|
pCredentials->pszDomain = NULL;
|
|
}
|
|
|
|
if (pCredentials->pszPassword != NULL)
|
|
{
|
|
LocalFree(pCredentials->pszPassword);
|
|
pCredentials->pszPassword = NULL;
|
|
}
|
|
}
|
|
|
|
return(fRet);
|
|
}
|
|
|
|
/*
|
|
* Licensing Core functions
|
|
*/
|
|
|
|
ULONG
|
|
CopyPolicyInformationToWire(
|
|
LPLCPOLICYINFOGENERIC *ppWire,
|
|
LPLCPOLICYINFOGENERIC pPolicyInfo
|
|
)
|
|
{
|
|
ULONG ulReturn;
|
|
|
|
ASSERT(ppWire != NULL);
|
|
ASSERT(pPolicyInfo != NULL);
|
|
|
|
if (pPolicyInfo->ulVersion == LCPOLICYINFOTYPE_V1)
|
|
{
|
|
LPLCPOLICYINFOWIRE_V1 *ppWireV1;
|
|
LPLCPOLICYINFO_V1W pPolicyInfoV1;
|
|
ULONG cbPolicyName;
|
|
ULONG cbPolicyDescription;
|
|
|
|
ppWireV1 = (LPLCPOLICYINFOWIRE_V1*)ppWire;
|
|
pPolicyInfoV1 = (LPLCPOLICYINFO_V1W)pPolicyInfo;
|
|
cbPolicyName = (lstrlenW(pPolicyInfoV1->lpPolicyName) + 1) * sizeof(WCHAR);
|
|
cbPolicyDescription = (lstrlenW(pPolicyInfoV1->lpPolicyDescription) + 1) * sizeof(WCHAR);
|
|
|
|
ulReturn = sizeof(LCPOLICYINFOWIRE_V1);
|
|
ulReturn += cbPolicyName;
|
|
ulReturn += cbPolicyDescription;
|
|
|
|
*ppWireV1 = MIDL_user_allocate(ulReturn);
|
|
|
|
if (*ppWireV1 != NULL)
|
|
{
|
|
(*ppWireV1)->ulVersion = LCPOLICYINFOTYPE_V1;
|
|
|
|
InitVarData(
|
|
&((*ppWireV1)->PolicyNameData),
|
|
cbPolicyName,
|
|
sizeof(LCPOLICYINFOWIRE_V1)
|
|
);
|
|
CopyMemory(
|
|
(LPBYTE)(*ppWireV1) + (*ppWireV1)->PolicyNameData.Offset,
|
|
pPolicyInfoV1->lpPolicyName,
|
|
(*ppWireV1)->PolicyNameData.Size
|
|
);
|
|
|
|
InitVarData(
|
|
&((*ppWireV1)->PolicyDescriptionData),
|
|
cbPolicyDescription,
|
|
NextOffset(&((*ppWireV1)->PolicyNameData))
|
|
);
|
|
CopyMemory(
|
|
(LPBYTE)(*ppWireV1) + (*ppWireV1)->PolicyDescriptionData.Offset,
|
|
pPolicyInfoV1->lpPolicyDescription,
|
|
(*ppWireV1)->PolicyDescriptionData.Size
|
|
);
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
ulReturn = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_UNKNOWN_REVISION);
|
|
ulReturn = 0;
|
|
}
|
|
|
|
return(ulReturn);
|
|
}
|
|
|
|
BOOLEAN
|
|
CopyPolicyInformationFromWire(
|
|
LPLCPOLICYINFOGENERIC *ppPolicyInfo,
|
|
LPLCPOLICYINFOGENERIC pWire
|
|
)
|
|
{
|
|
BOOLEAN fRet;
|
|
|
|
ASSERT(ppPolicyInfo != NULL);
|
|
ASSERT(pWire != NULL);
|
|
|
|
if (pWire->ulVersion == LCPOLICYINFOTYPE_V1)
|
|
{
|
|
LPLCPOLICYINFO_V1W *ppPolicyInfoV1;
|
|
LPLCPOLICYINFOWIRE_V1 pWireV1;
|
|
|
|
ppPolicyInfoV1 = (LPLCPOLICYINFO_V1W*)ppPolicyInfo;
|
|
pWireV1 = (LPLCPOLICYINFOWIRE_V1)pWire;
|
|
|
|
*ppPolicyInfoV1 = LocalAlloc(LPTR, sizeof(LCPOLICYINFO_V1W));
|
|
|
|
if (*ppPolicyInfoV1 != NULL)
|
|
{
|
|
(*ppPolicyInfoV1)->ulVersion = LCPOLICYINFOTYPE_V1;
|
|
|
|
(*ppPolicyInfoV1)->lpPolicyName = LocalAlloc(LPTR, pWireV1->PolicyNameData.Size);
|
|
|
|
if ((*ppPolicyInfoV1)->lpPolicyName != NULL)
|
|
{
|
|
CopyMemory(
|
|
(LPBYTE)((*ppPolicyInfoV1)->lpPolicyName),
|
|
(LPBYTE)pWireV1 + pWireV1->PolicyNameData.Offset,
|
|
pWireV1->PolicyNameData.Size
|
|
);
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
fRet = FALSE;
|
|
goto V1error;
|
|
}
|
|
|
|
(*ppPolicyInfoV1)->lpPolicyDescription = LocalAlloc(LPTR, pWireV1->PolicyDescriptionData.Size);
|
|
|
|
if ((*ppPolicyInfoV1)->lpPolicyDescription != NULL)
|
|
{
|
|
CopyMemory(
|
|
(LPBYTE)((*ppPolicyInfoV1)->lpPolicyDescription),
|
|
(LPBYTE)pWireV1 + pWireV1->PolicyDescriptionData.Offset,
|
|
pWireV1->PolicyDescriptionData.Size
|
|
);
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
fRet = FALSE;
|
|
goto V1error;
|
|
}
|
|
|
|
fRet = TRUE;
|
|
goto exit;
|
|
|
|
V1error:
|
|
if ((*ppPolicyInfoV1)->lpPolicyName != NULL)
|
|
{
|
|
LocalFree((*ppPolicyInfoV1)->lpPolicyName);
|
|
(*ppPolicyInfoV1)->lpPolicyName = NULL;
|
|
}
|
|
|
|
if ((*ppPolicyInfoV1)->lpPolicyDescription != NULL)
|
|
{
|
|
LocalFree((*ppPolicyInfoV1)->lpPolicyDescription);
|
|
(*ppPolicyInfoV1)->lpPolicyDescription = NULL;
|
|
}
|
|
|
|
LocalFree(*ppPolicyInfoV1);
|
|
*ppPolicyInfoV1 = NULL;
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
fRet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_UNKNOWN_REVISION);
|
|
fRet = FALSE;
|
|
}
|
|
|
|
exit:
|
|
return(fRet);
|
|
}
|
|
|
|
|