2025-11-28 00:35:46 +09:00

858 lines
19 KiB
C++

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 2006 Microsoft Corporation. All Rights Reserved.
//
// Module:
// WlExtHC.cpp
//
// Abstract:
// This sample shows how to create a sample Extensible Helper Class for Wireless Diagnostics
// This sample is post-Windows 2006 only.
//
// Usage:
// WlExtHC.exe [/RegServer]
// /RegServer Register the HC
//
// Author:
// Mohammad Shabbir Alam
//
#include "precomp.h"
#pragma hdrstop
GUID gWirelessHelperExtensionRepairId = { /* cb2a064e-b691-4a63-9e7e-7d2970bbe025 */
0xcb2a064e,
0xb691,
0x4a63,
{0x9e, 0x7e, 0x7d, 0x29, 0x70, 0xbb, 0xe0, 0x25}};
__inline
HRESULT
StringCchCopyWithAlloc (
__deref_out_opt PWSTR* Dest,
size_t cchMaxLen,
__in PCWSTR Src
)
{
size_t cchSize = 0;
if (NULL == Dest || NULL == Src || cchMaxLen > USHRT_MAX)
{
return E_INVALIDARG;
}
HRESULT hr = StringCchLength (Src, cchMaxLen - 1, &cchSize);
if (FAILED(hr))
{
return hr;
}
size_t cbSize = (cchSize + 1)*sizeof(WCHAR);
*Dest = (PWSTR) CoTaskMemAlloc(cbSize);
if (NULL == *Dest)
{
return E_OUTOFMEMORY;
}
SecureZeroMemory(*Dest, cbSize);
return StringCchCopy((STRSAFE_LPWSTR)*Dest, cchSize + 1, Src);
}
HRESULT
CWirelessHelperExtension::GetAttributeInfo(
__RPC__out ULONG *pcelt,
__RPC__deref_out_ecount_full_opt(*pcelt) HelperAttributeInfo **pprgAttributeInfos
)
{
HRESULT hr = S_OK;
LogEntry (this);
do
{
if (pcelt==NULL || pprgAttributeInfos==NULL)
{
hr = E_INVALIDARG;
break;
}
HelperAttributeInfo *info = (HelperAttributeInfo *)CoTaskMemAlloc(3*sizeof(HelperAttributeInfo));
if (info==NULL)
{
hr = E_OUTOFMEMORY;
break;
}
SecureZeroMemory(info,3*sizeof(HelperAttributeInfo));
StringCchCopyWithAlloc(&info[0].pwszName, MAX_PATH, L"IfType");
info[0].type=AT_UINT32;
StringCchCopyWithAlloc(&info[1].pwszName, MAX_PATH, L"LowHealthAttributeType");
info[1].type=AT_UINT32;
StringCchCopyWithAlloc(&info[2].pwszName, MAX_PATH, L"ReturnRepair");
info[2].type=AT_BOOLEAN;
*pcelt=3;
*pprgAttributeInfos=info;
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::Initialize(
ULONG celt,
__RPC__in_ecount_full(celt) HELPER_ATTRIBUTE rgAttributes[ ]
)
{
WDIAG_IHV_WLAN_ID WDiagID = {0};
HRESULT hr = S_OK;
LogEntry (this);
do
{
if (celt == 0)
{
break;
}
if (rgAttributes == NULL)
{
hr = E_INVALIDARG;
break;
}
for (UINT i = 0; i < celt; i++)
{
switch (rgAttributes[i].type)
{
case (AT_GUID):
{
LogInfo ("\t[%d] GUID Attribute <%ws>, value=<%!guid!>\n",
i+1, rgAttributes[i].pwszName, &rgAttributes[i].Guid);
break;
}
case (AT_UINT32):
{
LogInfo ("\t[%d] UINT Attribute <%ws>, value=<%d>\n",
i+1, rgAttributes[i].pwszName, rgAttributes[i].DWord);
break;
}
case (AT_BOOLEAN):
{
LogInfo ("\t[%d] BOOLEAN Attribute <%ws>, value=<%d>\n",
i+1, rgAttributes[i].pwszName, rgAttributes[i].Boolean);
break;
}
case (AT_STRING):
{
LogInfo ("\t[%d] STRING Attribute <%ws>, value=<%ws>\n",
i+1, rgAttributes[i].pwszName, rgAttributes[i].PWStr);
break;
}
case (AT_OCTET_STRING):
{
LogInfo ("\t[%d] AT_OCTET_STRING Attribute <%ws>, Length=<%d>\n",
i+1, rgAttributes[i].pwszName, rgAttributes[i].OctetString.dwLength);
if (rgAttributes[i].OctetString.dwLength < sizeof(WDIAG_IHV_WLAN_ID))
{
LogInfo ("\t\tLength=<%d> < sizeof(WDIAG_IHV_WLAN_ID)=<%d>\n",
rgAttributes[i].OctetString.dwLength, sizeof(WDIAG_IHV_WLAN_ID));
break;
}
RtlCopyMemory (&WDiagID, rgAttributes[i].OctetString.lpValue, sizeof (WDIAG_IHV_WLAN_ID));
LogInfo ("\t\tProfileName=<%ws>\n", WDiagID.strProfileName);
LogInfo ("\t\tSsidLength=<%d>\n", WDiagID.Ssid.uSSIDLength);
LogInfo ("\t\tBssType=<%d>\n", WDiagID.BssType);
LogInfo ("\t\tReasonCode=<%d>\n", WDiagID.dwReasonCode);
LogInfo ("\t\tFlags=<0x%x>\n", WDiagID.dwFlags);
break;
}
default:
{
LogInfo ("\t[%d] Attribute <%ws>, Unknown type=<%d>\n",
i+1, rgAttributes[i].pwszName, rgAttributes[i].type);
break;
}
}
}
if (S_OK != hr)
{
break;
}
InterlockedCompareExchange(&m_initialized, 1, 0);
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::GetDiagnosticsInfo(
__RPC__deref_out_opt DiagnosticsInfo **ppInfo
)
{
HRESULT hr = S_OK;
LogEntry (this);
do
{
if (NULL == ppInfo)
{
break;
}
*ppInfo = (DiagnosticsInfo *)CoTaskMemAlloc(sizeof(DiagnosticsInfo));
if (*ppInfo == NULL)
{
hr = E_OUTOFMEMORY;
break;
}
(*ppInfo)->cost = 0;
(*ppInfo)->flags = DF_TRACELESS;
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::GetKeyAttributes(
__RPC__out ULONG *pcelt,
__RPC__deref_out_ecount_full_opt(*pcelt) HELPER_ATTRIBUTE **pprgAttributes
)
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER (pcelt);
UNREFERENCED_PARAMETER (pprgAttributes);
LogEntry (this);
do
{
hr = E_NOTIMPL;
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::LowHealth(
__RPC__in_opt LPCWSTR pwszInstanceDescription,
__RPC__deref_out_opt_string LPWSTR *ppwszDescription,
__RPC__out long *pDeferredTime,
__RPC__out DIAGNOSIS_STATUS *pStatus
)
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER (pwszInstanceDescription);
LogEntry (this);
do
{
if (m_initialized <= 0)
{
hr = E_UNEXPECTED;
break;
}
if (pDeferredTime == NULL || pStatus == NULL || ppwszDescription == NULL)
{
hr = E_INVALIDARG;
break;
}
//
// this class will always confirm. this way we know the class
// was instantiated and was called successfully
//
*pStatus = DS_CONFIRMED;
m_ReturnRepair = TRUE;
hr = StringCchCopyWithAlloc(ppwszDescription, 256, L"Helper Extension LowHealth call succeeded.");
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::HighUtilization(
__RPC__in_opt LPCWSTR pwszInstanceDescription,
__RPC__deref_out_opt_string LPWSTR *ppwszDescription,
__RPC__out long *pDeferredTime,
__RPC__out DIAGNOSIS_STATUS *pStatus
)
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER (pwszInstanceDescription);
UNREFERENCED_PARAMETER (ppwszDescription);
UNREFERENCED_PARAMETER (pDeferredTime);
UNREFERENCED_PARAMETER (pStatus);
LogEntry (this);
do
{
hr = E_NOTIMPL;
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::GetLowerHypotheses(
__RPC__out ULONG *pcelt,
__RPC__deref_out_ecount_full_opt(*pcelt) HYPOTHESIS **pprgHypotheses
)
{
HYPOTHESIS *hypothses = NULL;
HELPER_ATTRIBUTE *attributes = NULL;
size_t size = sizeof(HYPOTHESIS);
HRESULT hr = S_OK;
LogEntry (this);
do
{
if (m_initialized <= 0)
{
hr = E_UNEXPECTED;
break;
}
if (pcelt == NULL)
{
hr = E_INVALIDARG;
break;
}
//if no attribute type specified we don't perform a lower hypotheses
if(m_LowHealthAttributeType==0)
{
*pcelt = 0;
*pprgHypotheses=NULL;
hr = S_OK;
break;
}
// check to see if additional storage is needed for attributes.
hypothses = (HYPOTHESIS*)CoTaskMemAlloc(size);
if (hypothses == NULL)
{
hr = E_OUTOFMEMORY;
break;
}
SecureZeroMemory(hypothses, size);
hr = StringCchCopyWithAlloc(&(hypothses->pwszClassName), MAX_PATH, L"LowHealthHypotheses");
if (FAILED (hr))
{
break;
}
hr = StringCchCopyWithAlloc(&(hypothses->pwszDescription), MAX_PATH, L"TestHypotheses");
if (FAILED (hr))
{
break;
}
hypothses->celt = 1;
attributes = hypothses->rgAttributes = (PHELPER_ATTRIBUTE)CoTaskMemAlloc(sizeof HELPER_ATTRIBUTE);
if (attributes == NULL)
{
hr = E_OUTOFMEMORY;
break;
}
switch(m_LowHealthAttributeType)
{
case AT_BOOLEAN:
attributes->type = AT_BOOLEAN;
break;
case AT_INT8:
attributes->type = AT_INT8;
break;
case AT_UINT8:
attributes->type = AT_UINT8;
break;
case AT_INT16:
attributes->type = AT_INT16;
break;
case AT_UINT16:
attributes->type = AT_UINT16;
break;
case AT_INT32:
attributes->type = AT_INT32;
break;
case AT_UINT32:
attributes->type = AT_UINT32;
break;
case AT_INT64:
attributes->type = AT_INT64;
break;
case AT_UINT64:
attributes->type = AT_UINT64;
break;
case AT_STRING:
attributes->type = AT_STRING;
StringCchCopyWithAlloc(&(attributes->PWStr), MAX_PATH, L"String Attribute Value");
break;
case AT_GUID:
attributes->type = AT_GUID;
break;
case AT_LIFE_TIME:
attributes->type = AT_LIFE_TIME;
break;
case AT_SOCKADDR:
attributes->type = AT_SOCKADDR;
break;
case AT_OCTET_STRING:
attributes->type = AT_OCTET_STRING;
attributes->OctetString.dwLength = 32;
attributes->OctetString.lpValue = (BYTE *)CoTaskMemAlloc(32*sizeof(BYTE));
if(attributes->OctetString.lpValue==NULL)
{
hr = E_OUTOFMEMORY;
break;
}
SecureZeroMemory(attributes->OctetString.lpValue,32*sizeof(BYTE));
break;
}
if (FAILED (hr))
{
break;
}
if (hypothses->celt!=0)
{
hr = StringCchCopyWithAlloc(&(attributes->pwszName), MAX_PATH, L"TestAttribute");
if (FAILED (hr))
{
break;
}
}
*pcelt = 1;
if (pprgHypotheses)
{
*pprgHypotheses = hypothses;
}
} while (FALSE);
if ((FAILED (hr)) &&
(hypothses))
{
CoTaskMemFree(hypothses->pwszClassName);
attributes = hypothses->rgAttributes;
if (attributes)
{
for (UINT i = 0; i < hypothses->celt; i++, ++attributes)
{
CoTaskMemFree(attributes->pwszName);
switch(attributes->type)
{
case AT_STRING:
if(attributes->PWStr!=NULL) CoTaskMemFree(attributes->PWStr);
case AT_OCTET_STRING:
if(attributes->OctetString.lpValue!=NULL) CoTaskMemFree(attributes->OctetString.lpValue);
}
}
CoTaskMemFree(attributes);
}
CoTaskMemFree(hypothses);
}
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::GetDownStreamHypotheses(
__RPC__out ULONG *pcelt,
__RPC__deref_out_ecount_full_opt(*pcelt) HYPOTHESIS **pprgHypotheses
)
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER (pcelt);
UNREFERENCED_PARAMETER (pprgHypotheses);
LogEntry (this);
do
{
hr = E_NOTIMPL;
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::GetHigherHypotheses(
__RPC__out ULONG *pcelt,
__RPC__deref_out_ecount_full_opt(*pcelt) HYPOTHESIS **pprgHypotheses
)
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER (pcelt);
UNREFERENCED_PARAMETER (pprgHypotheses);
LogEntry (this);
do
{
hr = E_NOTIMPL;
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::GetUpStreamHypotheses(
__RPC__out ULONG *pcelt,
__RPC__deref_out_ecount_full_opt(*pcelt) HYPOTHESIS **pprgHypotheses
)
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER (pcelt);
UNREFERENCED_PARAMETER (pprgHypotheses);
LogEntry (this);
do
{
hr = E_NOTIMPL;
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::Repair(
__RPC__in RepairInfo *pInfo,
__RPC__out long *pDeferredTime,
__RPC__out REPAIR_STATUS *pStatus
)
{
HRESULT hr = S_OK;
LogEntry (this);
do
{
if (m_initialized <= 0)
{
hr = E_UNEXPECTED;
break;
}
if (pInfo == NULL || pDeferredTime == NULL || pStatus == NULL)
{
hr = E_INVALIDARG;
break;
}
if (!IsEqualGUID(pInfo->guid, gWirelessHelperExtensionRepairId))
{
hr = E_NOTIMPL;
break;
}
*pDeferredTime = 0;
*pStatus = RS_REPAIRED;
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::Validate(
PROBLEM_TYPE problem,
__RPC__out long *pDeferredTime,
__RPC__out REPAIR_STATUS *pStatus
)
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER (problem);
UNREFERENCED_PARAMETER (pDeferredTime);
UNREFERENCED_PARAMETER (pStatus);
LogEntry (this);
do
{
if (m_initialized <= 0)
{
hr = E_UNEXPECTED;
break;
}
hr = E_NOTIMPL;
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::GetRepairInfo(
PROBLEM_TYPE problem,
__RPC__out ULONG *pcelt,
__RPC__deref_out_ecount_full_opt(*pcelt) RepairInfo **ppInfo
)
{
RepairInfo *info = NULL;
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER (problem);
LogEntry (this);
do
{
if (m_initialized <= 0)
{
hr = E_UNEXPECTED;
break;
}
if (pcelt == NULL)
{
hr = E_INVALIDARG;
break;
}
if (ppInfo == NULL)
{
hr = S_OK;
break;
}
if(!m_ReturnRepair)
{
*pcelt=0;
*ppInfo=NULL;
hr = S_OK;
break;
}
info = (RepairInfo *)CoTaskMemAlloc(sizeof(RepairInfo));
if (info == NULL)
{
hr = E_OUTOFMEMORY;
break;
}
SecureZeroMemory(info, sizeof(RepairInfo));
info->guid = gWirelessHelperExtensionRepairId;
hr = StringCchCopyWithAlloc(&(info->pwszClassName), MAX_PATH, L"SampleWirelessHelperExtension");
if (FAILED (hr))
{
break;
}
hr = StringCchCopyWithAlloc(&(info->pwszDescription), MAX_PATH, L"Sample repair from SampleWirelessHelperExtension");
if (FAILED (hr))
{
break;
}
info->cost = 5;
info->sidType = WinBuiltinNetworkConfigurationOperatorsSid;
info->flags = RF_INFORMATION_ONLY;
info->scope = RS_SYSTEM;
info->risk = RR_NORISK;
info->UiInfo.type = UIT_NONE;
*pcelt = 1;
*ppInfo = info;
} while (FALSE);
if ((FAILED (hr)) &&
(info))
{
CoTaskMemFree(info->pwszClassName);
CoTaskMemFree(info->pwszDescription);
CoTaskMemFree(info);
}
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::GetLifeTime(
__RPC__out LIFE_TIME *pLifeTime
)
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER (pLifeTime);
LogEntry (this);
do
{
hr = E_NOTIMPL;
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::SetLifeTime(
LIFE_TIME lifeTime
)
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER (lifeTime);
LogEntry (this);
do
{
hr = E_NOTIMPL;
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::GetCacheTime(
__RPC__out FILETIME *pCacheTime
)
{
HRESULT hr = S_OK;
LogEntry (this);
do
{
SecureZeroMemory (pCacheTime, sizeof(FILETIME));
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::GetAttributes(
__RPC__out ULONG *pcelt,
__RPC__deref_out_ecount_full_opt(*pcelt) HELPER_ATTRIBUTE **pprgAttributes
)
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER (pcelt);
UNREFERENCED_PARAMETER (pprgAttributes);
LogEntry (this);
do
{
hr = E_NOTIMPL;
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::Cancel(
)
{
HRESULT hr = S_OK;
LogEntry (this);
do
{
} while (FALSE);
LogExit (hr);
return (hr);
}
HRESULT
CWirelessHelperExtension::Cleanup(
)
{
HRESULT hr = S_OK;
LogEntry (this);
do
{
} while (FALSE);
LogExit (hr);
return (hr);
}