windows-nt/Source/XPSP1/NT/net/upnp/host/upnphost/registrar/uhutil.cpp
2020-09-26 16:20:57 +08:00

447 lines
11 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000.
//
// File: U H U T I L . C P P
//
// Contents: Common routines and constants for UPnP Device Host
//
// Notes:
//
// Author: mbend 6 Sep 2000
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include <shlobj.h> // For SHGetFolderPath()
#include "uhbase.h"
#include "uhutil.h"
#include "ncreg.h"
#include "ComUtility.h"
#include "RegDef.h"
#include "httpcomn.h"
// Registry locations
const wchar_t c_szRegistryMicrosoft[] = L"SOFTWARE\\Microsoft\\UPnP Device Host";
const wchar_t c_szUPnPDeviceHost[] = L"UPnP Device Host";
const wchar_t c_szMicrosoft[] = L"Microsoft";
const wchar_t c_szRegistryShellFolders[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
const wchar_t c_szCommonAppData[] = L"Common AppData";
const wchar_t c_szUpnphost[] = L"upnphost";
const wchar_t c_szUdhisapiDll[] = L"udhisapi.dll";
//+---------------------------------------------------------------------------
//
// Function: HrRegQueryString
//
// Purpose: Queries a string value from a registry key
//
// Arguments:
// hKey [in] Handle to key to query
// szValueName [in] Name of value to query
// str [out] String to return value in
//
// Returns: S_OK on success or COM error code on failure.
//
// Author: mbend 6 Sep 2000
//
// Notes:
//
HRESULT HrRegQueryString(HKEY hKey, const wchar_t * szValueName, CUString & str)
{
HRESULT hr = S_OK;
DWORD dwType = 0;
DWORD dwBytes = 0;
LPBYTE pData = NULL;
// Query size of buffer
hr = HrRegQueryValueEx(hKey, szValueName, &dwType, NULL, &dwBytes);
if(REG_SZ != dwType)
{
// Type mismatch
hr = E_INVALIDARG;
}
if(SUCCEEDED(hr))
{
pData = new BYTE[dwBytes];
if(pData)
{
if(SUCCEEDED(hr))
{
hr = HrRegQueryValueEx(hKey, szValueName, &dwType, pData, &dwBytes);
if(SUCCEEDED(hr))
{
hr = str.HrAssign(reinterpret_cast<wchar_t*>(pData));
}
}
delete [] pData;
}
else
{
hr = E_OUTOFMEMORY;
}
}
TraceHr(ttidError, FAL, hr, FALSE, "HrRegQueryString");
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: HrCreateOrOpenDeviceHostKey
//
// Purpose: Creates if not present or opens the device host root key in the registry.
//
// Arguments:
// phKeyDeviceHost [out] Pointer to Registry key handle on return.
//
// Returns: S_OK on success or COM error code on failure.
//
// Author: mbend 6 Sep 2000
//
// Notes:
//
HRESULT HrCreateOrOpenDeviceHostKey(HKEY * phKeyDeviceHost)
{
CHECK_POINTER(phKeyDeviceHost);
HRESULT hr = S_OK;
HKEY hKeyDeviceHost;
// Open HKLM\SOFTWARE\Microsoft\UPnP Device Host
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegistryMicrosoft, KEY_ALL_ACCESS, &hKeyDeviceHost);
if(SUCCEEDED(hr))
{
*phKeyDeviceHost = hKeyDeviceHost;
}
TraceHr(ttidError, FAL, hr, FALSE, "HrCreateOrOpenDeviceHostKey");
return hr;
}
HRESULT HrCreateAndReferenceContainedObject(
const wchar_t * szContainer,
REFCLSID clsid,
REFIID riid,
void ** ppv)
{
HRESULT hr = S_OK;
// For no container, just use CoCreateInstance
if(!szContainer)
{
hr = HrCoCreateInstanceInprocBase(clsid, riid, ppv);
}
else
{
// Create the container manager and use him to create object
IUPnPContainerManagerPtr pContainerManager;
hr = pContainerManager.HrCreateInstanceInproc(CLSID_UPnPContainerManager);
if(SUCCEEDED(hr))
{
hr = pContainerManager->ReferenceContainer(szContainer);
if(SUCCEEDED(hr))
{
hr = pContainerManager->CreateInstance(szContainer, clsid, riid, ppv);
if(FAILED(hr))
{
pContainerManager->UnreferenceContainer(szContainer);
}
}
}
}
TraceHr(ttidError, FAL, hr, FALSE, "HrCreateAndReferenceContainedObject");
return hr;
}
HRESULT HrCreateAndReferenceContainedObjectByProgId(
const wchar_t * szContainer,
const wchar_t * szProgId,
REFIID riid,
void ** ppv)
{
HRESULT hr = S_OK;
// Create the container manager and use him to create object
IUPnPContainerManagerPtr pContainerManager;
hr = pContainerManager.HrCreateInstanceInproc(CLSID_UPnPContainerManager);
if(SUCCEEDED(hr))
{
hr = pContainerManager->ReferenceContainer(szContainer);
if(SUCCEEDED(hr))
{
hr = pContainerManager->CreateInstanceWithProgId(szContainer, szProgId, riid, ppv);
if(FAILED(hr))
{
pContainerManager->UnreferenceContainer(szContainer);
}
}
}
TraceHr(ttidError, FAL, hr, FALSE, "HrCreateAndReferenceContainedObjectByProgId");
return hr;
}
HRESULT HrDereferenceContainer(
const wchar_t * szContainer)
{
HRESULT hr = S_OK;
// Create the container manager and unreference
IUPnPContainerManagerPtr pContainerManager;
hr = pContainerManager.HrCreateInstanceInproc(CLSID_UPnPContainerManager);
if(SUCCEEDED(hr))
{
hr = pContainerManager->UnreferenceContainer(szContainer);
}
TraceHr(ttidError, FAL, hr, FALSE, "HrDereferenceContainer");
return hr;
}
HRESULT HrPhysicalDeviceIdentifierToString(const GUID & pdi, CUString & str)
{
HRESULT hr = S_OK;
hr = str.HrInitFromGUID(pdi);
TraceHr(ttidError, FAL, hr, FALSE, "HrPhysicalDeviceIdentifierToString");
return hr;
}
HRESULT HrStringToPhysicalDeviceIdentifier(const wchar_t * szStrPdi, GUID & pdi)
{
HRESULT hr = S_OK;
hr = CLSIDFromString(const_cast<wchar_t *>(szStrPdi), &pdi);
TraceHr(ttidError, FAL, hr, FALSE, "HrStringToPhysicalDeviceIdentifier");
return hr;
}
HRESULT HrGUIDToUDNString(const UUID & uuid, CUString & strUUID)
{
HRESULT hr = S_OK;
hr = strUUID.HrAssign(L"uuid:");
if(SUCCEEDED(hr))
{
wchar_t * szUUID = NULL;
RPC_STATUS status;
status = UuidToString(const_cast<UUID*>(&uuid), (unsigned short **)&szUUID);
if(RPC_S_OUT_OF_MEMORY == status)
{
hr = E_OUTOFMEMORY;
}
if(SUCCEEDED(hr))
{
hr = strUUID.HrAppend(szUUID);
RpcStringFree((unsigned short **)&szUUID);
}
}
TraceHr(ttidError, FAL, hr, FALSE, "HrGUIDToUDNString");
return hr;
}
HRESULT HrMakeFullPath(
const wchar_t * szPath,
const wchar_t * szFile,
CUString & strFullPath)
{
HRESULT hr = S_OK;
hr = strFullPath.HrAssign(szPath);
if(SUCCEEDED(hr))
{
hr = HrEnsurePathBackslash(strFullPath);
if(SUCCEEDED(hr))
{
hr = strFullPath.HrAppend(szFile);
}
}
TraceHr(ttidError, FAL, hr, FALSE, "HrMakeFullPath");
return hr;
}
HRESULT HrEnsurePathBackslash(CUString & strPath)
{
HRESULT hr = S_OK;
long nLength = strPath.GetLength();
if(nLength)
{
if(L'\\' != strPath[nLength - 1])
{
hr = strPath.HrAppend(L"\\");
}
}
TraceHr(ttidError, FAL, hr, FALSE, "HrEnsurePathBackslash");
return hr;
}
HRESULT HrAddDirectoryToPath(CUString & strPath, const wchar_t * szDir)
{
HRESULT hr = S_OK;
CUString strTemp;
hr = strTemp.HrAssign(strPath);
if(SUCCEEDED(hr))
{
hr = HrEnsurePathBackslash(strTemp);
if(SUCCEEDED(hr))
{
hr = strTemp.HrAppend(szDir);
if(SUCCEEDED(hr))
{
if(!CreateDirectory(strTemp, NULL))
{
// Who cares if it already exists?
hr = HrFromLastWin32Error();
if(HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) == hr)
{
hr = S_OK;
}
}
}
}
}
if(SUCCEEDED(hr))
{
hr = HrEnsurePathBackslash(strTemp);
if(SUCCEEDED(hr))
{
strPath.Transfer(strTemp);
}
}
TraceHr(ttidError, FAL, hr, FALSE, "HrAddDirectoryToPath");
return hr;
}
HRESULT HrGetUPnPHostPath(CUString & strPath)
{
HRESULT hr = S_OK;
HANDLE hToken = NULL;
WCHAR szPath[MAX_PATH + 1];
CUString strCommonAppData;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
hr = SHGetFolderPath(NULL, CSIDL_APPDATA, hToken, SHGFP_TYPE_CURRENT,
szPath);
if (SUCCEEDED(hr))
{
hr = strCommonAppData.HrAssign(szPath);
if(SUCCEEDED(hr))
{
// Create the directories
hr = HrAddDirectoryToPath(strCommonAppData, c_szMicrosoft);
if(SUCCEEDED(hr))
{
hr = HrAddDirectoryToPath(strCommonAppData, c_szUPnPDeviceHost);
if(SUCCEEDED(hr))
{
strPath.Transfer(strCommonAppData);
}
}
}
}
CloseHandle(hToken);
}
TraceHr(ttidError, FAL, hr, FALSE, "HrGetUPnPHostPath");
return hr;
}
static const WCHAR c_szUrl[] = L"/upnphost";
HRESULT HrMakeIsapiExtensionDirectory()
{
HRESULT hr = S_OK;
WCHAR szSysDir[MAX_PATH];
// Create ISAPI extension directory and copy DLL there
CUString strPath;
CUString strSrcPath;
if (GetSystemDirectory(szSysDir, MAX_PATH))
{
hr = strSrcPath.HrAssign(szSysDir);
if (SUCCEEDED(hr))
{
hr = strSrcPath.HrAppend(L"\\");
if (SUCCEEDED(hr))
{
hr = strSrcPath.HrAppend(c_szUdhisapiDll);
}
}
}
else
{
hr = HrFromLastWin32Error();
}
if(SUCCEEDED(hr))
{
CUString strFile;
hr = HrGetUPnPHostPath(strPath);
if(SUCCEEDED(hr))
{
hr = HrAddDirectoryToPath(strPath, c_szUpnphost);
if(SUCCEEDED(hr))
{
hr = strFile.HrAssign(strPath);
if(SUCCEEDED(hr))
{
hr = strFile.HrAppend(c_szUdhisapiDll);
if(SUCCEEDED(hr))
{
if(!CopyFile(strSrcPath, strFile, FALSE))
{
hr = HrFromLastWin32Error();
}
}
}
}
}
}
if(SUCCEEDED(hr))
{
HKEY hkeyVroot;
HKEY hkeyNew;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_HTTPDVROOTS, KEY_ALL_ACCESS,
&hkeyVroot);
if (SUCCEEDED(hr))
{
hr = HrRegCreateKeyEx(hkeyVroot, c_szUrl, 0, KEY_ALL_ACCESS, NULL,
&hkeyNew, NULL);
if (SUCCEEDED(hr))
{
// Pass NULL to set default value
//
hr = HrRegSetSz(hkeyNew, NULL, strPath.GetBuffer());
RegCloseKey(hkeyNew);
}
RegCloseKey(hkeyVroot);
}
}
TraceHr(ttidError, FAL, hr, FALSE, "HrMakeIsapiExtensionDirectory");
return hr;
}