463 lines
11 KiB
C++

//----------------------------------------------------------------------------
//
// Copyright (C) 2004 Intel Corporation
//
// File: PTHIcommand.cpp
//
//----------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include "StatusCodeDefinitions.h"
#include "HECIWin.h"
#include "StatusStrings.h"
#include "HECI_if.h"
#include "PTHIcommand.h"
PTHICommand::PTHICommand( bool verbose): PTHIClient(HECI_PTHI_GUID,verbose)
{
}
PTHICommand::~PTHICommand(void)
{
}
/*
* Confirms the correctness of the response message header
* and the response message size
* Arguments:
* command - appropriate Host interface command
* response_header - pointer to the response message header
* response_size - value that holds the actual size of the
* response message
* expected_size - value that holds the expected size of the
* response message
* Return values:
* AMT_STATUS_SUCCESS - on success
* PTSDK_STATUS_INTERNAL_ERROR - on failure
*/
AMT_STATUS PTHICommand::VerifyResponseHeader(const UINT32 command,
const PTHI_MESSAGE_HEADER *response_header,
UINT32 response_size)
{
UINT32 status = AMT_STATUS_SUCCESS;
if (response_size != (response_header->Length + sizeof(PTHI_MESSAGE_HEADER)))
{
status = AMT_STATUS_INTERNAL_ERROR;
}
else if(response_header->Command.cmd.val != command )
{
status = AMT_STATUS_INTERNAL_ERROR;
}
else if(response_header->Reserved != 0 )
{
status = AMT_STATUS_INTERNAL_ERROR;
}
return status;
}
/*
* Checks if the given buffer is null terminated
* Arguments:
* buffer - the buffer to check for null termination
* length - length of the buffer
* Return values:
* true - on null termination
* false - otherwise
*/
bool IsNullTerminated(const CHAR* buffer, UINT32 length)
{
if(buffer == NULL)
{
return false;
}
bool isNullTerminated = false;
for(UINT32 i=0; i<length; i++)
{
if(buffer[i] == '\0')
isNullTerminated = true;
}
return isNullTerminated;
}
/*
* Confirms the correctness of the LocalSystemAccount response message
* Arguments:
* response - pointer to the response message
* Return values:
* AMT_STATUS_SUCCESS - on success
* PTSDK_STATUS_INTERNAL_ERROR - on failure
*/
UINT32 PTHICommand::VerifyLocalSystemAccount(const CFG_GET_LOCAL_SYSTEM_ACCOUNT_RESPONSE *response)
{
UINT32 status = AMT_STATUS_SUCCESS;
UINT32 localAccountLen;
localAccountLen = response->Header.Length - sizeof(AMT_STATUS);
do
{
if(!IsNullTerminated(&(response->Account.username[0]), CFG_MAX_ACL_USER_LENGTH))
{
status = AMT_STATUS_INTERNAL_ERROR;
break;
}
if(!IsNullTerminated(&(response->Account.password[0]), CFG_MAX_ACL_PWD_LENGTH))
{
status = AMT_STATUS_INTERNAL_ERROR;
break;
}
}while(0);
return status;
}
/*
* Confirms the correctness of the Unprovision response message
* Arguments:
* response - pointer to the response message
* Return values:
* PT_STATUS_SUCCESS - on success
* PTSDK_STATUS_INTERNAL_ERROR - on failure
*/
AMT_STATUS PTHICommand::VerifyUnprovision(const CFG_UNPROVISION_RESPONSE *response)
{
ULONG ByteCount;
ByteCount = response->Header.Length;
if (ByteCount !=
(sizeof(CFG_UNPROVISION_RESPONSE) - sizeof(PTHI_MESSAGE_HEADER)))
{
return PTSDK_STATUS_INTERNAL_ERROR;
}
return AMT_STATUS_SUCCESS;
}
/*
* Confirms the correctness of the provision state response message
* Arguments:
* response - pointer to the response message
* Return values:
* PT_STATUS_SUCCESS - on success
* PTSDK_STATUS_INTERNAL_ERROR - on failure
*/
AMT_STATUS PTHICommand::VerifyProvisionState(const CFG_GET_PROVISIONING_STATE_RESPONSE *response)
{
ULONG ByteCount;
ByteCount = response->Header.Length;
if (ByteCount !=
(sizeof(CFG_GET_PROVISIONING_STATE_RESPONSE) - sizeof(PTHI_MESSAGE_HEADER)))
{
return PTSDK_STATUS_INTERNAL_ERROR;
}
return AMT_STATUS_SUCCESS;
}
/*
* Get local system account AMTHI command
* Arguments:
* localAccount - pointer to the LOCAL_SYSTEM_ACCOUNT struct
* Return values:
* AMT_LOCAL_AGENT_STATUS_SUCCESS - on success
* AMT_STATUS_INTERNAL_ERROR - on failure
* AMT_STATUS_INVALID_MESSAGE_LENGTH - Length field of header is invalid.
* AMT_STATUS_NOT_FOUND - Returned if the local system account was disabled or if its password was changed
by the Network Administrator.
(This is allowed only in AMT6.0. Later versions will not allow changing or
disabling the local system account).
*/
AMT_STATUS PTHICommand::GetLocalSystemAccount(LOCAL_SYSTEM_ACCOUNT *localAccount)
{
if (localAccount == NULL)
{
return PTSDK_STATUS_INVALID_PARAM;
}
AMT_STATUS status;
UCHAR command[sizeof(CFG_GET_LOCAL_SYSTEM_ACCOUNT_REQUEST)];
memset(command, 0, sizeof(CFG_GET_LOCAL_SYSTEM_ACCOUNT_REQUEST));
if (memcpy_s(command, ARRAYSIZE(command), &GET_LOCAL_SYSTEM_ACCOUNT_HEADER, sizeof(GET_LOCAL_SYSTEM_ACCOUNT_HEADER)))
{
return AMT_STATUS_INTERNAL_ERROR;
}
UINT8 *readBuffer;
UINT32 command_size = sizeof(CFG_GET_LOCAL_SYSTEM_ACCOUNT_REQUEST);
UINT32 inBuffSize;
UINT32 outBuffSize=0;
CFG_GET_LOCAL_SYSTEM_ACCOUNT_RESPONSE *tmp_response;
PTHI_MESSAGE_HEADER *resp_header;
int bytesWritten = 0;
bytesWritten = PTHIClient.SendMessage(command,command_size);
if(bytesWritten != command_size)
{
return AMT_STATUS_INTERNAL_ERROR;
}
inBuffSize = PTHIClient.GetBufferSize();
readBuffer = (UINT8*) malloc (sizeof(UINT8) * inBuffSize);
if (readBuffer == NULL)
{
return AMT_STATUS_INTERNAL_ERROR;
}
memset(readBuffer, 0, inBuffSize);
outBuffSize = PTHIClient.ReceiveMessage(readBuffer,inBuffSize);
do
{
if( 0 == outBuffSize)
{
status = AMT_STATUS_INTERNAL_ERROR;
break;
}
tmp_response = (CFG_GET_LOCAL_SYSTEM_ACCOUNT_RESPONSE*)readBuffer;
status = tmp_response->Status;
if( status != AMT_STATUS_SUCCESS )
{
break;
}
resp_header = &(tmp_response->Header);
status = VerifyResponseHeader(GET_LOCAL_SYSTEM_ACCOUNT_RESPONSE,
resp_header,outBuffSize);
if ( status != AMT_STATUS_SUCCESS)
{
break;
}
status = VerifyLocalSystemAccount(tmp_response);
if ( status != AMT_STATUS_SUCCESS)
{
break;
}
if (memcpy_s(localAccount, sizeof(LOCAL_SYSTEM_ACCOUNT), &(tmp_response->Account), sizeof(LOCAL_SYSTEM_ACCOUNT)))
{
status = AMT_STATUS_INTERNAL_ERROR;
break;
}
}while(0);
if (readBuffer != NULL)
{
free(readBuffer);
readBuffer = NULL;
}
return status;
}
/*
* Unprovision AMTHI command
* Arguments:
* provisionMode - indicates the provisioining mode of the device upon unprovisioining
* Return values:
* AMT_LOCAL_AGENT_STATUS_SUCCESS - on success
* AMT_STATUS_INTERNAL_ERROR - on failure
* AMT_STATUS_NOT_READY - Management controller has not progressed far enough in its
* initialization to process the command.
* AMT_STATUS_INVALID_MESSAGE_LENGTH - Length field of header is invalid.
* AMT_STATUS_BLOCKING_COMPONENT - One of the ME components is not ready for unprovisioning.
*/
AMT_STATUS PTHICommand::Unprovision(CFG_PROVISIONING_MODE provisionMode)
{
if ((PROVISIONING_MODE_NONE != provisionMode) && (PROVISIONING_MODE_ENTERPRISE != provisionMode))
{
return PTSDK_STATUS_INVALID_PARAM;
}
AMT_STATUS status;
UCHAR command[sizeof(CFG_UNPROVISION_REQUEST)];
memset(command, 0, sizeof(CFG_UNPROVISION_REQUEST));
if (memcpy_s(command, ARRAYSIZE(command), &UNPROVISION_HEADER, sizeof(UNPROVISION_HEADER)))
{
return PTSDK_STATUS_INVALID_PARAM;
}
if (memcpy_s(command + sizeof(UNPROVISION_HEADER), ARRAYSIZE(command), &(provisionMode), sizeof(provisionMode)))
{
return PTSDK_STATUS_INVALID_PARAM;
}
UINT8 *readBuffer;
UINT32 command_size = sizeof(CFG_UNPROVISION_REQUEST);
UINT32 inBuffSize;
UINT32 outBuffSize=0;
CFG_UNPROVISION_RESPONSE *tmp_response;
PTHI_MESSAGE_HEADER *resp_header;
int bytesWritten = 0;
bytesWritten = PTHIClient.SendMessage(command,command_size);
if(bytesWritten != command_size)
{
return AMT_STATUS_INTERNAL_ERROR;
}
inBuffSize = PTHIClient.GetBufferSize();
readBuffer = (UINT8*) malloc (sizeof(UINT8) * inBuffSize);
if (readBuffer == NULL)
{
return AMT_STATUS_INTERNAL_ERROR;
}
memset(readBuffer, 0, inBuffSize);
outBuffSize = PTHIClient.ReceiveMessage(readBuffer,inBuffSize);
do
{
if( 0 == outBuffSize)
{
status = AMT_STATUS_INTERNAL_ERROR;
break;
}
tmp_response = (CFG_UNPROVISION_RESPONSE*)readBuffer;
status = tmp_response->Status;
if( status != AMT_STATUS_SUCCESS )
{
break;
}
resp_header = &(tmp_response->Header);
status = VerifyResponseHeader(UNPROVISION_RESPONSE, resp_header,outBuffSize);
if ( status != AMT_STATUS_SUCCESS)
{
break;
}
status = VerifyUnprovision(tmp_response);
if ( status != AMT_STATUS_SUCCESS)
{
break;
}
}while(0);
if (readBuffer != NULL)
{
free(readBuffer);
readBuffer = NULL;
}
return status;
}
/*
* Get provision state AMTHI command
* Arguments:
* state - pointer to the state
* Return values:
* AMT_STATUS_SUCCESS - on success
* AMT_STATUS_INTERNAL_ERROR - on failure
* AMT_STATUS_NOT_READY - Management controller has not progressed far enough in its initialization to process the command
* AMT_STATUS_INVALID_MESSAGE_LENGTH - Length field of header is invalid.
*/
AMT_STATUS PTHICommand::GetProvisionState(UINT32 *state)
{
if (state == NULL)
{
return PTSDK_STATUS_INVALID_PARAM;
}
AMT_STATUS status;
UCHAR command[sizeof(CFG_GET_PROVISIONING_STATE_REQUEST)];
memset(command, 0, sizeof(CFG_GET_PROVISIONING_STATE_REQUEST));
if (memcpy_s(command, ARRAYSIZE(command), &GET_PROVISION_STATE_HEADER, sizeof(GET_PROVISION_STATE_HEADER)))
{
return AMT_STATUS_INTERNAL_ERROR;
}
UINT8 *readBuffer;
UINT32 command_size = sizeof(CFG_GET_PROVISIONING_STATE_REQUEST);
UINT32 inBuffSize;
UINT32 outBuffSize=0;
CFG_GET_PROVISIONING_STATE_RESPONSE *tmp_response;
PTHI_MESSAGE_HEADER *resp_header;
int bytesWritten = 0;
bytesWritten = PTHIClient.SendMessage(command,command_size);
if(bytesWritten != command_size)
{
return AMT_STATUS_INTERNAL_ERROR;
}
inBuffSize = PTHIClient.GetBufferSize();
readBuffer = (UINT8*) malloc (sizeof(UINT8) * inBuffSize);
if (readBuffer == NULL)
{
return AMT_STATUS_INTERNAL_ERROR;
}
memset(readBuffer,0,inBuffSize);
outBuffSize = PTHIClient.ReceiveMessage(readBuffer,inBuffSize);
do
{
if( 0 == outBuffSize)
{
status = AMT_STATUS_INTERNAL_ERROR;
break;
}
tmp_response = (CFG_GET_PROVISIONING_STATE_RESPONSE*)readBuffer;
status = tmp_response->Status;
if( status != AMT_STATUS_SUCCESS )
{
break;
}
resp_header = &(tmp_response->Header);
status = VerifyResponseHeader(GET_PROVISION_STATE_RESPONSE,
resp_header,outBuffSize);
if ( status != AMT_STATUS_SUCCESS)
{
break;
}
status = VerifyProvisionState(tmp_response);
if ( status != AMT_STATUS_SUCCESS)
{
break;
}
if (memcpy_s(state, sizeof(UINT32), &(tmp_response->ProvisioningState), sizeof(UINT32)))
{
status = AMT_STATUS_INTERNAL_ERROR;
break;
}
}while(0);
if (readBuffer != NULL)
{
free(readBuffer);
readBuffer = NULL;
}
return status;
}