I am implementing a custom port monitor based off of the LocalMon sample, but when I return from my implementation of LcmEnumPorts
, I receive the error "The data is invalid", and the list of ports installed on my machine is empty. Removing the monitor eliminates the error, and all ports reappear.
Why? I've checked that the structure I am returning is coherent and fits within the buffer allocated.
Example implementation of LcmEnumPorts
:
_Success_(return != FALSE)
BOOL WINAPI LcmEnumPorts(
_In_ HANDLE hMonitor,
_In_opt_ LPWSTR pName,
DWORD Level,
_Out_writes_bytes_opt_(cbBuf)
LPBYTE pPorts,
DWORD cbBuf,
_Out_ LPDWORD pcbNeeded,
_Out_ LPDWORD pcReturned
)
{
UNREFERENCED_PARAMETER(pName);
UNREFERENCED_PARAMETER(hMonitor);
if (!pcbNeeded || !pcReturned || (!pPorts && (cbBuf > 0)))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
else if ((1 != Level) && (2 != Level))
{
SetLastError(ERROR_INVALID_LEVEL);
return FALSE;
}
const wchar_t szMonitorName[] = L"WDK Sample Port";
const wchar_t szPortName[] = L"NUL:";
size_t cbPortName = wcslen(szPortName) * sizeof(wchar_t) + sizeof(wchar_t);
size_t cbPortDesc = wcslen(szMonitorName) * sizeof(wchar_t) + sizeof(wchar_t);
size_t cbText = cbPortName + cbPortDesc;
size_t cbStruct = Level == 1 ? sizeof(PORT_INFO_1) : sizeof(PORT_INFO_2);
*pcbNeeded = (DWORD)(cbText + cbStruct);
*pcReturned = 0;
if (*pcbNeeded > cbBuf)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
if (Level == 1)
{
PPORT_INFO_1 pPort1 = (PPORT_INFO_1)pPorts;
LPWSTR pPortName = (LPWSTR)(pPorts + cbStruct);
StringCbCopy(pPortName, cbPortName, szPortName);
pPort1->pName = pPortName;
}
else if (Level == 2)
{
PPORT_INFO_2 pPort2 = (PPORT_INFO_2)pPorts;
LPWSTR pPortName = (LPWSTR)(pPorts + cbStruct);
StringCbCopy(pPortName, cbPortName, szPortName);
pPort2->pPortName = pPortName;
LPWSTR pPortDesc = (LPWSTR)(pPorts + cbStruct + cbPortName);
StringCbCopy(pPortDesc, cbPortDesc, szMonitorName);
pPort2->pMonitorName = pPortDesc;
pPort2->pDescription = pPortDesc;
pPort2->fPortType = PORT_TYPE_READ | PORT_TYPE_WRITE;
pPort2->Reserved = 0;
}
*pcReturned = 1;
return TRUE;
}