//+--------------------------------------------------------------------------- // // 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 // 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(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(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), (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; }