|
|
#include "stdafx.h"
#include "util.h"
#include "upnp.h"
#include "stdio.h"
#include "resource.h"
HRESULT GetStringStateVariable(IUPnPService* pService, LPWSTR pszVariableName, BSTR* pString) { HRESULT hr = S_OK; VARIANT Variant; VariantInit(&Variant);
BSTR VariableName; VariableName = SysAllocString(pszVariableName); if(NULL != VariableName) { hr = pService->QueryStateVariable(VariableName, &Variant); if(SUCCEEDED(hr)) { if(V_VT(&Variant) == VT_BSTR) { *pString = V_BSTR(&Variant); } else { hr = E_UNEXPECTED; } } if(FAILED(hr)) { VariantClear(&Variant); } SysFreeString(VariableName); } else { hr = E_OUTOFMEMORY; }
return hr;
}
HRESULT InvokeVoidAction(IUPnPService * pService, LPWSTR pszCommand, VARIANT* pOutParams) { HRESULT hr; BSTR bstrActionName;
bstrActionName = SysAllocString(pszCommand); if (NULL != bstrActionName) { SAFEARRAYBOUND rgsaBound[1]; SAFEARRAY * psa = NULL;
rgsaBound[0].lLbound = 0; rgsaBound[0].cElements = 0;
psa = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
if (psa) { LONG lStatus; VARIANT varInArgs; VARIANT varReturnVal;
VariantInit(&varInArgs); VariantInit(pOutParams); VariantInit(&varReturnVal);
varInArgs.vt = VT_VARIANT | VT_ARRAY;
V_ARRAY(&varInArgs) = psa;
hr = pService->InvokeAction(bstrActionName, varInArgs, pOutParams, &varReturnVal); if(SUCCEEDED(hr)) { VariantClear(&varReturnVal); }
SafeArrayDestroy(psa); } else { hr = E_OUTOFMEMORY; }
SysFreeString(bstrActionName); } else { hr = E_OUTOFMEMORY; } return hr; }
HRESULT GetConnectionName(IInternetGateway* pInternetGateway, LPTSTR* ppszConnectionName) // use LocalFree to free ppszConnectionName
{ HRESULT hr = S_OK;
*ppszConnectionName = NULL;
IUPnPService* pWANConnectionService; hr = GetWANConnectionService(pInternetGateway, &pWANConnectionService); if(SUCCEEDED(hr)) { BSTR ConnectionName; hr = GetStringStateVariable(pWANConnectionService, L"X_Name", &ConnectionName); if(SUCCEEDED(hr)) { LPSTR pszConnectionName; hr = UnicodeToAnsi(ConnectionName, SysStringLen(ConnectionName), &pszConnectionName); { IUPnPService* pOSInfoService; hr = pInternetGateway->GetService(SAHOST_SERVICE_OSINFO, &pOSInfoService); if(SUCCEEDED(hr)) { BSTR MachineName; hr = GetStringStateVariable(pOSInfoService, L"OSMachineName", &MachineName); if(SUCCEEDED(hr)) { LPSTR pszMachineName; hr = UnicodeToAnsi(MachineName, SysStringLen(MachineName), &pszMachineName); if(SUCCEEDED(hr)) { TCHAR szFormat[16]; if(0 != LoadString(_Module.GetResourceInstance(), IDS_NAME_FORMAT, szFormat, sizeof(szFormat) / sizeof(TCHAR))) { LPTSTR pszArguments[] = {pszConnectionName, pszMachineName}; LPTSTR pszFormattedName; if(0 != FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, szFormat, 0, 0, reinterpret_cast<LPTSTR>(&pszFormattedName), 0, pszArguments)) { *ppszConnectionName = pszFormattedName; } else { hr = E_FAIL; } } else { hr = E_FAIL; } CoTaskMemFree(pszMachineName); } SysFreeString(MachineName); } pOSInfoService->Release(); } CoTaskMemFree(pszConnectionName); } SysFreeString(ConnectionName); } pWANConnectionService->Release(); }
if(FAILED(hr)) { hr = S_OK; LPTSTR pszDefaultName = reinterpret_cast<LPTSTR>(LocalAlloc(0, 128 * sizeof(TCHAR))); if(NULL != pszDefaultName) { if(0 != LoadString(_Module.GetResourceInstance(), IDS_DEFAULTADAPTERNAME, pszDefaultName, 128)) { *ppszConnectionName = pszDefaultName; } else { LocalFree(pszDefaultName); hr = E_FAIL; } } else { hr = E_OUTOFMEMORY; } }
return hr; }
HRESULT GetWANConnectionService(IInternetGateway* pInternetGateway, IUPnPService** ppWANConnectionService) { HRESULT hr = S_OK;
*ppWANConnectionService = NULL;
if(NULL != pInternetGateway) { NETCON_MEDIATYPE MediaType; hr = pInternetGateway->GetMediaType(&MediaType); if(SUCCEEDED(hr)) { if(NCM_SHAREDACCESSHOST_LAN == MediaType) { hr = pInternetGateway->GetService(SAHOST_SERVICE_WANIPCONNECTION, ppWANConnectionService); } else if(NCM_SHAREDACCESSHOST_RAS == MediaType) { hr = pInternetGateway->GetService(SAHOST_SERVICE_WANPPPCONNECTION, ppWANConnectionService); } else { hr = E_UNEXPECTED; } } } else { return E_INVALIDARG; }
return hr; }
HRESULT UnicodeToAnsi(LPWSTR pszUnicodeString, ULONG ulUnicodeStringLength, LPSTR* ppszAnsiString) { HRESULT hr = S_OK;
int nSizeNeeded = WideCharToMultiByte(CP_ACP, 0, pszUnicodeString, ulUnicodeStringLength + 1, NULL, 0, NULL, NULL); if(nSizeNeeded != 0) { LPSTR pszAnsiString = reinterpret_cast<LPSTR>(CoTaskMemAlloc(nSizeNeeded)); if(NULL != pszAnsiString) { if(0 != WideCharToMultiByte(CP_ACP, 0, pszUnicodeString, ulUnicodeStringLength + 1, pszAnsiString, nSizeNeeded, NULL, NULL)) { *ppszAnsiString = pszAnsiString; } else { hr = E_FAIL; } } else { hr = E_OUTOFMEMORY; } } else { hr = E_FAIL; } return hr; }
HRESULT FormatTimeDuration(UINT uSeconds, LPTSTR pszTimeDuration, SIZE_T uTimeDurationLength) { HRESULT hr = S_OK;
TCHAR szTimeSeperator[5]; // 4 is the maximum length for szTimeSeperator
if(0 != GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIME, szTimeSeperator, sizeof(szTimeSeperator) / sizeof(TCHAR))) { UINT uMinutes = uSeconds / 60;
uSeconds = uSeconds % 60; UINT uHours = uMinutes / 60;
uMinutes = uMinutes % 60;
UINT uDays = uHours / 24;
uHours = uHours % 24;
TCHAR szFormat[64]; if(0 == uDays) { if(0 != LoadString(_Module.GetResourceInstance(), IDS_UPTIME_ZERODAYS, szFormat, sizeof(szFormat) / sizeof(TCHAR))) { _sntprintf(pszTimeDuration, uTimeDurationLength, szFormat, uHours, szTimeSeperator, uMinutes, szTimeSeperator, uSeconds); } else { hr = E_UNEXPECTED; } } else if (1 == uDays) { if(0 != LoadString(_Module.GetResourceInstance(), IDS_UPTIME_ONEDAY, szFormat, sizeof(szFormat) / sizeof(TCHAR))) { _sntprintf(pszTimeDuration, uTimeDurationLength, szFormat, uHours, szTimeSeperator, uMinutes, szTimeSeperator, uSeconds); } else { hr = E_UNEXPECTED; } } else { if(0 != LoadString(_Module.GetResourceInstance(), IDS_UPTIME_MANYDAYS, szFormat, sizeof(szFormat) / sizeof(TCHAR))) { _sntprintf(pszTimeDuration, uTimeDurationLength, szFormat, uDays, uHours, szTimeSeperator, uMinutes, szTimeSeperator, uSeconds); } else { hr = E_UNEXPECTED; } }
pszTimeDuration[uTimeDurationLength - 1] = TEXT('\0');
} else { hr = E_FAIL; } return S_OK; }
HRESULT FormatBytesPerSecond(UINT uBytesPerSecond, LPTSTR pszBytesPerSecond, SIZE_T uBytesPerSecondLength) { HRESULT hr = S_OK; enum {eZero = 0, eKilo, eMega, eGiga, eTera, eMax}; INT iOffset = 0; UINT uiDecimal = 0; const UINT c_uiKilo = 1000;
for (iOffset = eZero; iOffset < eMax; iOffset++) {
// If we still have data, increment the counter
//
if (c_uiKilo > uBytesPerSecond) { break; }
// Divide up the string
//
uiDecimal = (uBytesPerSecond % c_uiKilo); uBytesPerSecond /= c_uiKilo; }
// We only want one digit for the decimal
//
uiDecimal /= (c_uiKilo/10);
// Get the string used to display
//
TCHAR szFormat[64]; if(0 != LoadString(_Module.GetResourceInstance(), IDS_METRIC_ZERO + iOffset, szFormat, sizeof(szFormat) / sizeof(TCHAR))) { _sntprintf(pszBytesPerSecond, uBytesPerSecondLength, szFormat, uBytesPerSecond, uiDecimal); pszBytesPerSecond[uBytesPerSecondLength - 1] = TEXT('\0'); } else { hr = E_UNEXPECTED; } return hr; }
HRESULT GetConnectionStatus(IUPnPService* pWANConnection, NETCON_STATUS* pStatus) { HRESULT hr = S_OK; BSTR ConnectionStatus; hr = GetStringStateVariable(pWANConnection, L"ConnectionStatus", &ConnectionStatus); if(SUCCEEDED(hr)) { if(0 == wcscmp(ConnectionStatus, L"Connected")) { *pStatus = NCS_CONNECTED; } else if(0 == wcscmp(ConnectionStatus, L"Connecting")) { *pStatus = NCS_CONNECTING; } else if(0 == wcscmp(ConnectionStatus, L"Disconnected")) { *pStatus = NCS_DISCONNECTED; } else if(0 == wcscmp(ConnectionStatus, L"Disconnecting")) { *pStatus = NCS_DISCONNECTING; } else { *pStatus = NCS_HARDWARE_DISABLED; } SysFreeString(ConnectionStatus); }
return hr; }
HRESULT ConnectionStatusToString(NETCON_STATUS Status, LPTSTR szBuffer, int nBufferSize) { HRESULT hr = S_OK; UINT uStringID = 0; switch(Status) { case NCS_CONNECTED: uStringID = IDS_CONNECTED; break; case NCS_CONNECTING: uStringID = IDS_CONNECTING; break; case NCS_DISCONNECTED: uStringID = IDS_DISCONNECTED; break; case NCS_DISCONNECTING: uStringID = IDS_DISCONNECTING; break; default: uStringID = IDS_UNCONFIGURED; break; }
if(0 == LoadString(_Module.GetResourceInstance(), uStringID, szBuffer, nBufferSize)) { hr = E_FAIL; }
return hr; }
LRESULT ShowErrorDialog(HWND hParentWindow, UINT uiErrorString) { TCHAR szTitle[128]; TCHAR szText[1024]; if(NULL != LoadString(_Module.GetResourceInstance(), IDS_APPTITLE, szTitle, sizeof(szTitle) / sizeof(TCHAR))) { if(NULL != LoadString(_Module.GetResourceInstance(), uiErrorString, szText, sizeof(szText) / sizeof(TCHAR))) { MessageBox(hParentWindow, szText, szTitle, MB_OK); } }
return 0; }
UINT64 MakeQword2(DWORD a, DWORD b) { UINT64 qw = a; qw = qw << 32; qw |= b; return qw; }
UINT64 MakeQword4(WORD a, WORD b, WORD c, WORD d) { UINT64 qw = a; qw = qw << 16; qw |= b; qw = qw << 16; qw |= c; qw = qw << 16; qw |= d; return qw; }
HRESULT EnsureFileVersion(LPTSTR pszModule, UINT64 qwDesiredVersion) { HRESULT hr = S_OK;
DWORD dwDummy; DWORD dwVersionSize = GetFileVersionInfoSize(pszModule, &dwDummy); if(0!= dwVersionSize) { void* pVersionInfo = CoTaskMemAlloc(dwVersionSize); if(NULL != pVersionInfo) { if(0 != GetFileVersionInfo(pszModule, 0, dwVersionSize, pVersionInfo)) { void* pSubInfo; UINT uiSubInfoSize; if(0 != VerQueryValue(pVersionInfo, TEXT("\\"), &pSubInfo, &uiSubInfoSize)) { VS_FIXEDFILEINFO* pFixedFileInfo = reinterpret_cast<VS_FIXEDFILEINFO*>(pSubInfo); UINT64 qwFileVersion = MakeQword2(pFixedFileInfo->dwProductVersionMS, pFixedFileInfo->dwProductVersionLS); if(qwFileVersion < qwDesiredVersion) { hr = E_FAIL; } } else { hr = E_FAIL; } } else { hr = E_UNEXPECTED; }
CoTaskMemFree(pVersionInfo); } else { hr = E_OUTOFMEMORY; } } else { hr = E_UNEXPECTED; }
return hr; }
|