Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

446 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: U H U T I L . C P P
  7. //
  8. // Contents: Common routines and constants for UPnP Device Host
  9. //
  10. // Notes:
  11. //
  12. // Author: mbend 6 Sep 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include <shlobj.h> // For SHGetFolderPath()
  18. #include "uhbase.h"
  19. #include "uhutil.h"
  20. #include "ncreg.h"
  21. #include "ComUtility.h"
  22. #include "RegDef.h"
  23. #include "httpcomn.h"
  24. // Registry locations
  25. const wchar_t c_szRegistryMicrosoft[] = L"SOFTWARE\\Microsoft\\UPnP Device Host";
  26. const wchar_t c_szUPnPDeviceHost[] = L"UPnP Device Host";
  27. const wchar_t c_szMicrosoft[] = L"Microsoft";
  28. const wchar_t c_szRegistryShellFolders[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
  29. const wchar_t c_szCommonAppData[] = L"Common AppData";
  30. const wchar_t c_szUpnphost[] = L"upnphost";
  31. const wchar_t c_szUdhisapiDll[] = L"udhisapi.dll";
  32. //+---------------------------------------------------------------------------
  33. //
  34. // Function: HrRegQueryString
  35. //
  36. // Purpose: Queries a string value from a registry key
  37. //
  38. // Arguments:
  39. // hKey [in] Handle to key to query
  40. // szValueName [in] Name of value to query
  41. // str [out] String to return value in
  42. //
  43. // Returns: S_OK on success or COM error code on failure.
  44. //
  45. // Author: mbend 6 Sep 2000
  46. //
  47. // Notes:
  48. //
  49. HRESULT HrRegQueryString(HKEY hKey, const wchar_t * szValueName, CUString & str)
  50. {
  51. HRESULT hr = S_OK;
  52. DWORD dwType = 0;
  53. DWORD dwBytes = 0;
  54. LPBYTE pData = NULL;
  55. // Query size of buffer
  56. hr = HrRegQueryValueEx(hKey, szValueName, &dwType, NULL, &dwBytes);
  57. if(REG_SZ != dwType)
  58. {
  59. // Type mismatch
  60. hr = E_INVALIDARG;
  61. }
  62. if(SUCCEEDED(hr))
  63. {
  64. pData = new BYTE[dwBytes];
  65. if(pData)
  66. {
  67. if(SUCCEEDED(hr))
  68. {
  69. hr = HrRegQueryValueEx(hKey, szValueName, &dwType, pData, &dwBytes);
  70. if(SUCCEEDED(hr))
  71. {
  72. hr = str.HrAssign(reinterpret_cast<wchar_t*>(pData));
  73. }
  74. }
  75. delete [] pData;
  76. }
  77. else
  78. {
  79. hr = E_OUTOFMEMORY;
  80. }
  81. }
  82. TraceHr(ttidError, FAL, hr, FALSE, "HrRegQueryString");
  83. return hr;
  84. }
  85. //+---------------------------------------------------------------------------
  86. //
  87. // Function: HrCreateOrOpenDeviceHostKey
  88. //
  89. // Purpose: Creates if not present or opens the device host root key in the registry.
  90. //
  91. // Arguments:
  92. // phKeyDeviceHost [out] Pointer to Registry key handle on return.
  93. //
  94. // Returns: S_OK on success or COM error code on failure.
  95. //
  96. // Author: mbend 6 Sep 2000
  97. //
  98. // Notes:
  99. //
  100. HRESULT HrCreateOrOpenDeviceHostKey(HKEY * phKeyDeviceHost)
  101. {
  102. CHECK_POINTER(phKeyDeviceHost);
  103. HRESULT hr = S_OK;
  104. HKEY hKeyDeviceHost;
  105. // Open HKLM\SOFTWARE\Microsoft\UPnP Device Host
  106. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegistryMicrosoft, KEY_ALL_ACCESS, &hKeyDeviceHost);
  107. if(SUCCEEDED(hr))
  108. {
  109. *phKeyDeviceHost = hKeyDeviceHost;
  110. }
  111. TraceHr(ttidError, FAL, hr, FALSE, "HrCreateOrOpenDeviceHostKey");
  112. return hr;
  113. }
  114. HRESULT HrCreateAndReferenceContainedObject(
  115. const wchar_t * szContainer,
  116. REFCLSID clsid,
  117. REFIID riid,
  118. void ** ppv)
  119. {
  120. HRESULT hr = S_OK;
  121. // For no container, just use CoCreateInstance
  122. if(!szContainer)
  123. {
  124. hr = HrCoCreateInstanceInprocBase(clsid, riid, ppv);
  125. }
  126. else
  127. {
  128. // Create the container manager and use him to create object
  129. IUPnPContainerManagerPtr pContainerManager;
  130. hr = pContainerManager.HrCreateInstanceInproc(CLSID_UPnPContainerManager);
  131. if(SUCCEEDED(hr))
  132. {
  133. hr = pContainerManager->ReferenceContainer(szContainer);
  134. if(SUCCEEDED(hr))
  135. {
  136. hr = pContainerManager->CreateInstance(szContainer, clsid, riid, ppv);
  137. if(FAILED(hr))
  138. {
  139. pContainerManager->UnreferenceContainer(szContainer);
  140. }
  141. }
  142. }
  143. }
  144. TraceHr(ttidError, FAL, hr, FALSE, "HrCreateAndReferenceContainedObject");
  145. return hr;
  146. }
  147. HRESULT HrCreateAndReferenceContainedObjectByProgId(
  148. const wchar_t * szContainer,
  149. const wchar_t * szProgId,
  150. REFIID riid,
  151. void ** ppv)
  152. {
  153. HRESULT hr = S_OK;
  154. // Create the container manager and use him to create object
  155. IUPnPContainerManagerPtr pContainerManager;
  156. hr = pContainerManager.HrCreateInstanceInproc(CLSID_UPnPContainerManager);
  157. if(SUCCEEDED(hr))
  158. {
  159. hr = pContainerManager->ReferenceContainer(szContainer);
  160. if(SUCCEEDED(hr))
  161. {
  162. hr = pContainerManager->CreateInstanceWithProgId(szContainer, szProgId, riid, ppv);
  163. if(FAILED(hr))
  164. {
  165. pContainerManager->UnreferenceContainer(szContainer);
  166. }
  167. }
  168. }
  169. TraceHr(ttidError, FAL, hr, FALSE, "HrCreateAndReferenceContainedObjectByProgId");
  170. return hr;
  171. }
  172. HRESULT HrDereferenceContainer(
  173. const wchar_t * szContainer)
  174. {
  175. HRESULT hr = S_OK;
  176. // Create the container manager and unreference
  177. IUPnPContainerManagerPtr pContainerManager;
  178. hr = pContainerManager.HrCreateInstanceInproc(CLSID_UPnPContainerManager);
  179. if(SUCCEEDED(hr))
  180. {
  181. hr = pContainerManager->UnreferenceContainer(szContainer);
  182. }
  183. TraceHr(ttidError, FAL, hr, FALSE, "HrDereferenceContainer");
  184. return hr;
  185. }
  186. HRESULT HrPhysicalDeviceIdentifierToString(const GUID & pdi, CUString & str)
  187. {
  188. HRESULT hr = S_OK;
  189. hr = str.HrInitFromGUID(pdi);
  190. TraceHr(ttidError, FAL, hr, FALSE, "HrPhysicalDeviceIdentifierToString");
  191. return hr;
  192. }
  193. HRESULT HrStringToPhysicalDeviceIdentifier(const wchar_t * szStrPdi, GUID & pdi)
  194. {
  195. HRESULT hr = S_OK;
  196. hr = CLSIDFromString(const_cast<wchar_t *>(szStrPdi), &pdi);
  197. TraceHr(ttidError, FAL, hr, FALSE, "HrStringToPhysicalDeviceIdentifier");
  198. return hr;
  199. }
  200. HRESULT HrGUIDToUDNString(const UUID & uuid, CUString & strUUID)
  201. {
  202. HRESULT hr = S_OK;
  203. hr = strUUID.HrAssign(L"uuid:");
  204. if(SUCCEEDED(hr))
  205. {
  206. wchar_t * szUUID = NULL;
  207. RPC_STATUS status;
  208. status = UuidToString(const_cast<UUID*>(&uuid), (unsigned short **)&szUUID);
  209. if(RPC_S_OUT_OF_MEMORY == status)
  210. {
  211. hr = E_OUTOFMEMORY;
  212. }
  213. if(SUCCEEDED(hr))
  214. {
  215. hr = strUUID.HrAppend(szUUID);
  216. RpcStringFree((unsigned short **)&szUUID);
  217. }
  218. }
  219. TraceHr(ttidError, FAL, hr, FALSE, "HrGUIDToUDNString");
  220. return hr;
  221. }
  222. HRESULT HrMakeFullPath(
  223. const wchar_t * szPath,
  224. const wchar_t * szFile,
  225. CUString & strFullPath)
  226. {
  227. HRESULT hr = S_OK;
  228. hr = strFullPath.HrAssign(szPath);
  229. if(SUCCEEDED(hr))
  230. {
  231. hr = HrEnsurePathBackslash(strFullPath);
  232. if(SUCCEEDED(hr))
  233. {
  234. hr = strFullPath.HrAppend(szFile);
  235. }
  236. }
  237. TraceHr(ttidError, FAL, hr, FALSE, "HrMakeFullPath");
  238. return hr;
  239. }
  240. HRESULT HrEnsurePathBackslash(CUString & strPath)
  241. {
  242. HRESULT hr = S_OK;
  243. long nLength = strPath.GetLength();
  244. if(nLength)
  245. {
  246. if(L'\\' != strPath[nLength - 1])
  247. {
  248. hr = strPath.HrAppend(L"\\");
  249. }
  250. }
  251. TraceHr(ttidError, FAL, hr, FALSE, "HrEnsurePathBackslash");
  252. return hr;
  253. }
  254. HRESULT HrAddDirectoryToPath(CUString & strPath, const wchar_t * szDir)
  255. {
  256. HRESULT hr = S_OK;
  257. CUString strTemp;
  258. hr = strTemp.HrAssign(strPath);
  259. if(SUCCEEDED(hr))
  260. {
  261. hr = HrEnsurePathBackslash(strTemp);
  262. if(SUCCEEDED(hr))
  263. {
  264. hr = strTemp.HrAppend(szDir);
  265. if(SUCCEEDED(hr))
  266. {
  267. if(!CreateDirectory(strTemp, NULL))
  268. {
  269. // Who cares if it already exists?
  270. hr = HrFromLastWin32Error();
  271. if(HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) == hr)
  272. {
  273. hr = S_OK;
  274. }
  275. }
  276. }
  277. }
  278. }
  279. if(SUCCEEDED(hr))
  280. {
  281. hr = HrEnsurePathBackslash(strTemp);
  282. if(SUCCEEDED(hr))
  283. {
  284. strPath.Transfer(strTemp);
  285. }
  286. }
  287. TraceHr(ttidError, FAL, hr, FALSE, "HrAddDirectoryToPath");
  288. return hr;
  289. }
  290. HRESULT HrGetUPnPHostPath(CUString & strPath)
  291. {
  292. HRESULT hr = S_OK;
  293. HANDLE hToken = NULL;
  294. WCHAR szPath[MAX_PATH + 1];
  295. CUString strCommonAppData;
  296. if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
  297. {
  298. hr = SHGetFolderPath(NULL, CSIDL_APPDATA, hToken, SHGFP_TYPE_CURRENT,
  299. szPath);
  300. if (SUCCEEDED(hr))
  301. {
  302. hr = strCommonAppData.HrAssign(szPath);
  303. if(SUCCEEDED(hr))
  304. {
  305. // Create the directories
  306. hr = HrAddDirectoryToPath(strCommonAppData, c_szMicrosoft);
  307. if(SUCCEEDED(hr))
  308. {
  309. hr = HrAddDirectoryToPath(strCommonAppData, c_szUPnPDeviceHost);
  310. if(SUCCEEDED(hr))
  311. {
  312. strPath.Transfer(strCommonAppData);
  313. }
  314. }
  315. }
  316. }
  317. CloseHandle(hToken);
  318. }
  319. TraceHr(ttidError, FAL, hr, FALSE, "HrGetUPnPHostPath");
  320. return hr;
  321. }
  322. static const WCHAR c_szUrl[] = L"/upnphost";
  323. HRESULT HrMakeIsapiExtensionDirectory()
  324. {
  325. HRESULT hr = S_OK;
  326. WCHAR szSysDir[MAX_PATH];
  327. // Create ISAPI extension directory and copy DLL there
  328. CUString strPath;
  329. CUString strSrcPath;
  330. if (GetSystemDirectory(szSysDir, MAX_PATH))
  331. {
  332. hr = strSrcPath.HrAssign(szSysDir);
  333. if (SUCCEEDED(hr))
  334. {
  335. hr = strSrcPath.HrAppend(L"\\");
  336. if (SUCCEEDED(hr))
  337. {
  338. hr = strSrcPath.HrAppend(c_szUdhisapiDll);
  339. }
  340. }
  341. }
  342. else
  343. {
  344. hr = HrFromLastWin32Error();
  345. }
  346. if(SUCCEEDED(hr))
  347. {
  348. CUString strFile;
  349. hr = HrGetUPnPHostPath(strPath);
  350. if(SUCCEEDED(hr))
  351. {
  352. hr = HrAddDirectoryToPath(strPath, c_szUpnphost);
  353. if(SUCCEEDED(hr))
  354. {
  355. hr = strFile.HrAssign(strPath);
  356. if(SUCCEEDED(hr))
  357. {
  358. hr = strFile.HrAppend(c_szUdhisapiDll);
  359. if(SUCCEEDED(hr))
  360. {
  361. if(!CopyFile(strSrcPath, strFile, FALSE))
  362. {
  363. hr = HrFromLastWin32Error();
  364. }
  365. }
  366. }
  367. }
  368. }
  369. }
  370. if(SUCCEEDED(hr))
  371. {
  372. HKEY hkeyVroot;
  373. HKEY hkeyNew;
  374. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_HTTPDVROOTS, KEY_ALL_ACCESS,
  375. &hkeyVroot);
  376. if (SUCCEEDED(hr))
  377. {
  378. hr = HrRegCreateKeyEx(hkeyVroot, c_szUrl, 0, KEY_ALL_ACCESS, NULL,
  379. &hkeyNew, NULL);
  380. if (SUCCEEDED(hr))
  381. {
  382. // Pass NULL to set default value
  383. //
  384. hr = HrRegSetSz(hkeyNew, NULL, strPath.GetBuffer());
  385. RegCloseKey(hkeyNew);
  386. }
  387. RegCloseKey(hkeyVroot);
  388. }
  389. }
  390. TraceHr(ttidError, FAL, hr, FALSE, "HrMakeIsapiExtensionDirectory");
  391. return hr;
  392. }