Files
rpc/MicroLMS/heci/HECIWin.c

378 lines
11 KiB
C

/* INTEL CONFIDENTIAL
* Copyright 2011 - 2019 Intel Corporation.
* This software and the related documents are Intel copyrighted materials, and your use of them is governed by the express license under which they were provided to you ("License"). Unless the License provides otherwise, you may not use, modify, copy, publish, distribute, disclose or transmit this software or the related documents without Intel's prior written permission.
* This software and the related documents are provided as is, with no express or implied warranties, other than those that are expressly stated in the License.
*/
#ifndef _MINCORE
#include <windows.h>
#include <setupapi.h>
#include <initguid.h>
#include <winioctl.h>
#include "HECIWin.h"
#include "heci_if.h"
#define false 0
#define true 1
#define HECI_MAX_LINE_LEN 300
DEFINE_GUID(GUID_DEVINTERFACE_HECI, 0xE2D1FF34, 0x3458, 0x49A9, 0x88, 0xDA, 0x8E, 0x69, 0x15, 0xCE, 0x9B, 0xE5);
DEFINE_GUID(HECI_PTHI_GUID , 0x12F80028, 0xB4B7, 0x4b2d, 0xAC, 0xA8, 0x46, 0xE0, 0xFF, 0x65, 0x81, 0x4c);
DEFINE_GUID(LMS_GUID , 0x6733a4db, 0x0476, 0x4e7b, 0xb3, 0xaf, 0xbc, 0xfc, 0x29, 0xbe, 0xe7, 0xa7);
DEFINE_GUID(MKHI_GUID , 0x8E6A6715, 0x9ABC, 0x4043, 0x88, 0xEF, 0x9E, 0x39, 0xC6, 0xF6, 0x3E, 0x0F);
//VOID _displayHECIError(UINT32 errorCode,DWORD lastError);
//VOID _displayHECIData(UINT32 messageId);
int heci_doIoctl(struct MEImodule* module, DWORD code, void *inbuf, int inlen, void *outbuf, int outlen);
struct MEImodule MEI_global;
/***************************** public functions *****************************/
unsigned int heci_GetBufferSize(struct MEImodule* module) { if (module != NULL) return module->_bufSize; else return MEI_global._bufSize; }
unsigned char heci_GetProtocolVersion(struct MEImodule* module) { if (module != NULL) return module->_protocolVersion; else return MEI_global._protocolVersion; }
bool heci_IsInitialized(struct MEImodule* module) { if (module != NULL) return module->_initialized; else return MEI_global._initialized; }
bool heci_GetHeciVersion(struct MEImodule* module, HECI_VERSION *version)
{
if (module == NULL) module = &MEI_global;
if (module->m_haveHeciVersion)
{
memcpy_s(version, sizeof(HECI_VERSION), &(module->m_heciVersion), sizeof(HECI_VERSION));
return true;
}
return false;
}
bool heci_Init(struct MEImodule* module, HECI_CLIENTS client)
{
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetail = NULL;
HDEVINFO hDeviceInfo;
DWORD bufferSize;
SP_DEVICE_INTERFACE_DATA interfaceData;
LONG ii = 0;
int result;
HECI_CLIENT properties;
GUID guid;
if (client == PTHI_CLIENT) guid = HECI_PTHI_GUID;
if (client == LMS_CLIENT) guid = LMS_GUID;
if (client == MKHI_CLIENT) guid = MKHI_GUID;
if (module == NULL) module = &MEI_global;
module->_verbose = false;
if (module->_initialized) {
heci_Deinit(module);
}
// Find all devices that have our interface
hDeviceInfo = SetupDiGetClassDevs((LPGUID)&GUID_DEVINTERFACE_HECI, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDeviceInfo == INVALID_HANDLE_VALUE) {
if (module->_verbose) {
//_displayHECIError(GET_CLASS_DEVS,GetLastError());
}
return false; //GET_CLASS_DEVS;
}
// Setup the interface data struct
interfaceData.cbSize = sizeof(interfaceData);
for (ii = 0;
SetupDiEnumDeviceInterfaces(hDeviceInfo, NULL, (LPGUID)&GUID_DEVINTERFACE_HECI, ii, &interfaceData);
++ii) {
// Found our device instance
if (!SetupDiGetDeviceInterfaceDetail(hDeviceInfo, &interfaceData, NULL, 0, &bufferSize, NULL)) {
DWORD err = GetLastError();
if (err != ERROR_INSUFFICIENT_BUFFER) {
if (module->_verbose) {
//_displayHECIError(GET_INTERFACE_DETAIL,err);
}
continue;
}
}
// Allocate a big enough buffer to get detail data
deviceDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(bufferSize);
if (deviceDetail == NULL) {
if (module->_verbose) {
//_displayHECIError(ALLOCATE_MEMORY_ERROR,0);
}
continue;
}
// Setup the device interface struct
deviceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
// Try again to get the device interface detail info
if (!SetupDiGetDeviceInterfaceDetail(hDeviceInfo, &interfaceData, deviceDetail, bufferSize, NULL, NULL))
{
/*
if (_verbose)
{
DWORD err = GetLastError();
_displayHECIError(GET_INTERFACE_DETAIL,err);
}
*/
free(deviceDetail);
deviceDetail = NULL;
continue;
}
break;
}
SetupDiDestroyDeviceInfoList(hDeviceInfo);
if (deviceDetail == NULL) {
if (module->_verbose) {
//_displayHECIError(FIND_HECI_FAILURE,0);
}
return false; //FIND_HECI_FAILURE;
}
module->_handle = CreateFile(deviceDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
free(deviceDetail);
if (module->_handle == INVALID_HANDLE_VALUE) {
if (module->_verbose) {
//_displayHECIError(CREATE_HECI_FILE_FAILURE,GetLastError());
}
return false; //CREATE_HECI_FILE_FAILURE;
}
module->_initialized = true;
result = heci_doIoctl(module, (DWORD)IOCTL_HECI_GET_VERSION, NULL, 0, &(module->m_heciVersion), sizeof(HECI_VERSION));
if (result != sizeof(HECI_VERSION)) {
if (module->_verbose) {
//_displayHECIError(GET_HECI_DRIVER_VERSION_FAILURE,0);
}
heci_Deinit(module);
return false; //GET_HECI_DRIVER_VERSION_FAILURE;
}
module->m_haveHeciVersion = true;
if (module->_verbose) {
//_displayHECIData(HECI_DRIVER_VERSION);
//_ftprintf(stdout,_T("%d.%d.%d.%d\n"), (m_heciVersion).major, (m_heciVersion).minor, (m_heciVersion).hotfix, (m_heciVersion).build);
}
memset(&properties, 0, sizeof(properties));
result = heci_doIoctl(module, (DWORD)IOCTL_HECI_CONNECT_CLIENT, (void*)(&guid), sizeof(GUID), &properties, sizeof(properties));
if (result != sizeof(properties))
{
if (module->_verbose) {
//_displayHECIError(HECI_CONNECT_TO_PTHI_CLIENT_FAILURE,0);
}
//Deinit();
return false; //HECI_CONNECT_TO_PTHI_CLIENT_FAILURE;
}
module->_bufSize = properties.MaxMessageLength;
return true;
}
void heci_Deinit(struct MEImodule* module)
{
if (module == NULL) module = &MEI_global;
if (module->_initialized == false) return;
module->_initialized = false;
module->_bufSize = 0;
if (module->_handle != INVALID_HANDLE_VALUE)
{
CloseHandle(module->_handle);
module->_handle = INVALID_HANDLE_VALUE;
}
}
int heci_ReceiveMessage(struct MEImodule* module, unsigned char *buffer, int len, unsigned long timeout) // Timeout default is 2000
{
DWORD bytesRead = 0;
int res;
HANDLE h_event = NULL;
OVERLAPPED overlapped;
DWORD error;
DWORD eventRes;
if (module == NULL) module = &MEI_global;
if ((h_event = CreateEvent(NULL, FALSE, FALSE, NULL)) == 0) goto out;
overlapped.hEvent = h_event;
overlapped.Offset = 0;
overlapped.OffsetHigh = 0;
res = ReadFile(module->_handle, buffer, len, &bytesRead, &overlapped);
error = GetLastError();
if ((0 == res) && (ERROR_IO_PENDING != error)) {
if (module->_verbose) {
//_displayHECIError(READ_FILE,GetLastError());
}
bytesRead = (DWORD)-1;
goto out;
}
eventRes = WaitForSingleObject(h_event, timeout);
if (eventRes == WAIT_TIMEOUT) {
bytesRead = 0;
goto out;
}
res = GetOverlappedResult(module->_handle, &overlapped, &bytesRead, true);
if (res == 0) {
if (module->_verbose) {
//_displayHECIError(READ_FILE,GetLastError());
}
bytesRead = (DWORD)-1;
goto out;
}
out:
if (h_event != NULL) CloseHandle(h_event);
if (bytesRead <= 0) heci_Deinit(module);
return bytesRead;
}
int heci_SendMessage(struct MEImodule* module, const unsigned char *buffer, int len, unsigned long timeout) // Timeout default is 2000
{
DWORD bytesWritten = 0;
int res;
HANDLE h_event = NULL;
OVERLAPPED overlapped;
DWORD lastError;
DWORD eventRes;
if (module == NULL) module = &MEI_global;
if ((h_event = CreateEvent(NULL, FALSE, FALSE, NULL)) == 0) goto out;
overlapped.hEvent = h_event;
overlapped.Offset = 0;
overlapped.OffsetHigh = 0;
res = WriteFile(module->_handle, buffer, len, &bytesWritten, &overlapped);
lastError = GetLastError();
if ((0 == res) && (ERROR_IO_PENDING !=lastError )) {
if (module->_verbose) {
//_displayHECIError(WRITE_FILE,GetLastError());
}
bytesWritten = (DWORD)-1;
goto out;
}
eventRes = WaitForSingleObject(h_event, timeout);
if (eventRes == WAIT_TIMEOUT) {
if (module->_verbose) {
//_displayHECIError(WRITE_FILE_TIME_OUT,0);
}
bytesWritten = 0;
goto out;
}
res = GetOverlappedResult(module->_handle, &overlapped, &bytesWritten, false);
if (res == 0) {
if (module->_verbose) {
//_displayHECIError(WRITE_FILE,GetLastError());
}
bytesWritten = (DWORD)-1;
goto out;
}
out:
if (h_event != NULL) CloseHandle(h_event);
if (bytesWritten <= 0) heci_Deinit(module);
return bytesWritten;
}
int heci_doIoctl(struct MEImodule* module, DWORD code, void *inbuf, int inlen, void *outbuf, int outlen)
{
int res;
DWORD bytesRead = 0;
HANDLE h_event = NULL;
OVERLAPPED overlapped;
if (module == NULL) module = &MEI_global;
if (!module->_initialized) return -1;
if ((h_event = CreateEvent(NULL, FALSE, FALSE, NULL)) == 0) goto out;
overlapped.hEvent = h_event;
overlapped.Offset = 0;
overlapped.OffsetHigh = 0;
res = DeviceIoControl(module->_handle, code, inbuf, inlen, outbuf, outlen, &bytesRead, &overlapped);
if ((0 == res) && (ERROR_IO_PENDING != GetLastError())) {
if (module->_verbose) {
//_displayHECIError(IOCTL_COMMAND,GetLastError());
}
bytesRead = (DWORD)-1;
goto out;
}
WaitForSingleObject(h_event, INFINITE);
res = GetOverlappedResult(module->_handle, &overlapped, &bytesRead, true);
if (res == 0) {
if (module->_verbose) {
//_displayHECIError(IOCTL_COMMAND,GetLastError());
}
bytesRead = (DWORD)-1;
goto out;
}
out:
if (h_event != NULL) CloseHandle(h_event);
if (bytesRead == (DWORD)-1) heci_Deinit(module);
return bytesRead;
}
TCHAR *_getErrMsg(DWORD err)
{
static TCHAR buffer[1024];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
err,
0,
buffer,
sizeof(buffer) - 1,
0);
return buffer;
}
/*
// Display a HECI error message
void _displayHECIError(UINT32 errorCode, DWORD lastError)
{
TCHAR str[HECI_MAX_LINE_LEN];
TCHAR *msg;
LoadString(GetModuleHandle(NULL), HECI_ERROR_MESSAGE, str, sizeof(str)/sizeof(TCHAR));
_ftprintf(stderr, _T("%s"), str);
_ftprintf(stderr, _T("%s"), L" ");
LoadString(GetModuleHandle(NULL), errorCode , str, sizeof(str)/sizeof(TCHAR));
if(0!= lastError)
{
msg = _getErrMsg(lastError);
_ftprintf(stderr, _T("%s (%d): %s\n"),str, lastError, msg);
}
else
{
_ftprintf(stderr, _T("%s\n"),str);
}
}
// Display a HECI data message
void _displayHECIData(UINT32 messageId)
{
TCHAR str[HECI_MAX_LINE_LEN];
LoadString(GetModuleHandle(NULL), messageId , str, sizeof(str)/sizeof(TCHAR));
_ftprintf(stdout,_T("%s"),str);
_ftprintf(stdout,_T("%s"),L" ");
}
*/
#endif