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.

517 lines
14 KiB

  1. #include "stdafx.h"
  2. #include "util.h"
  3. #include "upnp.h"
  4. #include "stdio.h"
  5. #include "resource.h"
  6. HRESULT GetStringStateVariable(IUPnPService* pService, LPWSTR pszVariableName, BSTR* pString)
  7. {
  8. HRESULT hr = S_OK;
  9. VARIANT Variant;
  10. VariantInit(&Variant);
  11. BSTR VariableName;
  12. VariableName = SysAllocString(pszVariableName);
  13. if(NULL != VariableName)
  14. {
  15. hr = pService->QueryStateVariable(VariableName, &Variant);
  16. if(SUCCEEDED(hr))
  17. {
  18. if(V_VT(&Variant) == VT_BSTR)
  19. {
  20. *pString = V_BSTR(&Variant);
  21. }
  22. else
  23. {
  24. hr = E_UNEXPECTED;
  25. }
  26. }
  27. if(FAILED(hr))
  28. {
  29. VariantClear(&Variant);
  30. }
  31. SysFreeString(VariableName);
  32. }
  33. else
  34. {
  35. hr = E_OUTOFMEMORY;
  36. }
  37. return hr;
  38. }
  39. HRESULT InvokeVoidAction(IUPnPService * pService, LPWSTR pszCommand, VARIANT* pOutParams)
  40. {
  41. HRESULT hr;
  42. BSTR bstrActionName;
  43. bstrActionName = SysAllocString(pszCommand);
  44. if (NULL != bstrActionName)
  45. {
  46. SAFEARRAYBOUND rgsaBound[1];
  47. SAFEARRAY * psa = NULL;
  48. rgsaBound[0].lLbound = 0;
  49. rgsaBound[0].cElements = 0;
  50. psa = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
  51. if (psa)
  52. {
  53. LONG lStatus;
  54. VARIANT varInArgs;
  55. VARIANT varReturnVal;
  56. VariantInit(&varInArgs);
  57. VariantInit(pOutParams);
  58. VariantInit(&varReturnVal);
  59. varInArgs.vt = VT_VARIANT | VT_ARRAY;
  60. V_ARRAY(&varInArgs) = psa;
  61. hr = pService->InvokeAction(bstrActionName,
  62. varInArgs,
  63. pOutParams,
  64. &varReturnVal);
  65. if(SUCCEEDED(hr))
  66. {
  67. VariantClear(&varReturnVal);
  68. }
  69. SafeArrayDestroy(psa);
  70. }
  71. else
  72. {
  73. hr = E_OUTOFMEMORY;
  74. }
  75. SysFreeString(bstrActionName);
  76. }
  77. else
  78. {
  79. hr = E_OUTOFMEMORY;
  80. }
  81. return hr;
  82. }
  83. HRESULT GetConnectionName(IInternetGateway* pInternetGateway, LPTSTR* ppszConnectionName) // use LocalFree to free ppszConnectionName
  84. {
  85. HRESULT hr = S_OK;
  86. *ppszConnectionName = NULL;
  87. IUPnPService* pWANConnectionService;
  88. hr = GetWANConnectionService(pInternetGateway, &pWANConnectionService);
  89. if(SUCCEEDED(hr))
  90. {
  91. BSTR ConnectionName;
  92. hr = GetStringStateVariable(pWANConnectionService, L"X_Name", &ConnectionName);
  93. if(SUCCEEDED(hr))
  94. {
  95. LPSTR pszConnectionName;
  96. hr = UnicodeToAnsi(ConnectionName, SysStringLen(ConnectionName), &pszConnectionName);
  97. {
  98. IUPnPService* pOSInfoService;
  99. hr = pInternetGateway->GetService(SAHOST_SERVICE_OSINFO, &pOSInfoService);
  100. if(SUCCEEDED(hr))
  101. {
  102. BSTR MachineName;
  103. hr = GetStringStateVariable(pOSInfoService, L"OSMachineName", &MachineName);
  104. if(SUCCEEDED(hr))
  105. {
  106. LPSTR pszMachineName;
  107. hr = UnicodeToAnsi(MachineName, SysStringLen(MachineName), &pszMachineName);
  108. if(SUCCEEDED(hr))
  109. {
  110. TCHAR szFormat[16];
  111. if(0 != LoadString(_Module.GetResourceInstance(), IDS_NAME_FORMAT, szFormat, sizeof(szFormat) / sizeof(TCHAR)))
  112. {
  113. LPTSTR pszArguments[] = {pszConnectionName, pszMachineName};
  114. LPTSTR pszFormattedName;
  115. if(0 != FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, szFormat, 0, 0, reinterpret_cast<LPTSTR>(&pszFormattedName), 0, pszArguments))
  116. {
  117. *ppszConnectionName = pszFormattedName;
  118. }
  119. else
  120. {
  121. hr = E_FAIL;
  122. }
  123. }
  124. else
  125. {
  126. hr = E_FAIL;
  127. }
  128. CoTaskMemFree(pszMachineName);
  129. }
  130. SysFreeString(MachineName);
  131. }
  132. pOSInfoService->Release();
  133. }
  134. CoTaskMemFree(pszConnectionName);
  135. }
  136. SysFreeString(ConnectionName);
  137. }
  138. pWANConnectionService->Release();
  139. }
  140. if(FAILED(hr))
  141. {
  142. hr = S_OK;
  143. LPTSTR pszDefaultName = reinterpret_cast<LPTSTR>(LocalAlloc(0, 128 * sizeof(TCHAR)));
  144. if(NULL != pszDefaultName)
  145. {
  146. if(0 != LoadString(_Module.GetResourceInstance(), IDS_DEFAULTADAPTERNAME, pszDefaultName, 128))
  147. {
  148. *ppszConnectionName = pszDefaultName;
  149. }
  150. else
  151. {
  152. LocalFree(pszDefaultName);
  153. hr = E_FAIL;
  154. }
  155. }
  156. else
  157. {
  158. hr = E_OUTOFMEMORY;
  159. }
  160. }
  161. return hr;
  162. }
  163. HRESULT GetWANConnectionService(IInternetGateway* pInternetGateway, IUPnPService** ppWANConnectionService)
  164. {
  165. HRESULT hr = S_OK;
  166. *ppWANConnectionService = NULL;
  167. if(NULL != pInternetGateway)
  168. {
  169. NETCON_MEDIATYPE MediaType;
  170. hr = pInternetGateway->GetMediaType(&MediaType);
  171. if(SUCCEEDED(hr))
  172. {
  173. if(NCM_SHAREDACCESSHOST_LAN == MediaType)
  174. {
  175. hr = pInternetGateway->GetService(SAHOST_SERVICE_WANIPCONNECTION, ppWANConnectionService);
  176. }
  177. else if(NCM_SHAREDACCESSHOST_RAS == MediaType)
  178. {
  179. hr = pInternetGateway->GetService(SAHOST_SERVICE_WANPPPCONNECTION, ppWANConnectionService);
  180. }
  181. else
  182. {
  183. hr = E_UNEXPECTED;
  184. }
  185. }
  186. }
  187. else
  188. {
  189. return E_INVALIDARG;
  190. }
  191. return hr;
  192. }
  193. HRESULT UnicodeToAnsi(LPWSTR pszUnicodeString, ULONG ulUnicodeStringLength, LPSTR* ppszAnsiString)
  194. {
  195. HRESULT hr = S_OK;
  196. int nSizeNeeded = WideCharToMultiByte(CP_ACP, 0, pszUnicodeString, ulUnicodeStringLength + 1, NULL, 0, NULL, NULL);
  197. if(nSizeNeeded != 0)
  198. {
  199. LPSTR pszAnsiString = reinterpret_cast<LPSTR>(CoTaskMemAlloc(nSizeNeeded));
  200. if(NULL != pszAnsiString)
  201. {
  202. if(0 != WideCharToMultiByte(CP_ACP, 0, pszUnicodeString, ulUnicodeStringLength + 1, pszAnsiString, nSizeNeeded, NULL, NULL))
  203. {
  204. *ppszAnsiString = pszAnsiString;
  205. }
  206. else
  207. {
  208. hr = E_FAIL;
  209. }
  210. }
  211. else
  212. {
  213. hr = E_OUTOFMEMORY;
  214. }
  215. }
  216. else
  217. {
  218. hr = E_FAIL;
  219. }
  220. return hr;
  221. }
  222. HRESULT FormatTimeDuration(UINT uSeconds, LPTSTR pszTimeDuration, SIZE_T uTimeDurationLength)
  223. {
  224. HRESULT hr = S_OK;
  225. TCHAR szTimeSeperator[5]; // 4 is the maximum length for szTimeSeperator
  226. if(0 != GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIME, szTimeSeperator, sizeof(szTimeSeperator) / sizeof(TCHAR)))
  227. {
  228. UINT uMinutes = uSeconds / 60;
  229. uSeconds = uSeconds % 60;
  230. UINT uHours = uMinutes / 60;
  231. uMinutes = uMinutes % 60;
  232. UINT uDays = uHours / 24;
  233. uHours = uHours % 24;
  234. TCHAR szFormat[64];
  235. if(0 == uDays)
  236. {
  237. if(0 != LoadString(_Module.GetResourceInstance(), IDS_UPTIME_ZERODAYS, szFormat, sizeof(szFormat) / sizeof(TCHAR)))
  238. {
  239. _sntprintf(pszTimeDuration, uTimeDurationLength, szFormat, uHours, szTimeSeperator, uMinutes, szTimeSeperator, uSeconds);
  240. }
  241. else
  242. {
  243. hr = E_UNEXPECTED;
  244. }
  245. }
  246. else if (1 == uDays)
  247. {
  248. if(0 != LoadString(_Module.GetResourceInstance(), IDS_UPTIME_ONEDAY, szFormat, sizeof(szFormat) / sizeof(TCHAR)))
  249. {
  250. _sntprintf(pszTimeDuration, uTimeDurationLength, szFormat, uHours, szTimeSeperator, uMinutes, szTimeSeperator, uSeconds);
  251. }
  252. else
  253. {
  254. hr = E_UNEXPECTED;
  255. }
  256. }
  257. else
  258. {
  259. if(0 != LoadString(_Module.GetResourceInstance(), IDS_UPTIME_MANYDAYS, szFormat, sizeof(szFormat) / sizeof(TCHAR)))
  260. {
  261. _sntprintf(pszTimeDuration, uTimeDurationLength, szFormat, uDays, uHours, szTimeSeperator, uMinutes, szTimeSeperator, uSeconds);
  262. }
  263. else
  264. {
  265. hr = E_UNEXPECTED;
  266. }
  267. }
  268. pszTimeDuration[uTimeDurationLength - 1] = TEXT('\0');
  269. }
  270. else
  271. {
  272. hr = E_FAIL;
  273. }
  274. return S_OK;
  275. }
  276. HRESULT FormatBytesPerSecond(UINT uBytesPerSecond, LPTSTR pszBytesPerSecond, SIZE_T uBytesPerSecondLength)
  277. {
  278. HRESULT hr = S_OK;
  279. enum {eZero = 0, eKilo, eMega, eGiga, eTera, eMax};
  280. INT iOffset = 0;
  281. UINT uiDecimal = 0;
  282. const UINT c_uiKilo = 1000;
  283. for (iOffset = eZero; iOffset < eMax; iOffset++)
  284. {
  285. // If we still have data, increment the counter
  286. //
  287. if (c_uiKilo > uBytesPerSecond)
  288. {
  289. break;
  290. }
  291. // Divide up the string
  292. //
  293. uiDecimal = (uBytesPerSecond % c_uiKilo);
  294. uBytesPerSecond /= c_uiKilo;
  295. }
  296. // We only want one digit for the decimal
  297. //
  298. uiDecimal /= (c_uiKilo/10);
  299. // Get the string used to display
  300. //
  301. TCHAR szFormat[64];
  302. if(0 != LoadString(_Module.GetResourceInstance(), IDS_METRIC_ZERO + iOffset, szFormat, sizeof(szFormat) / sizeof(TCHAR)))
  303. {
  304. _sntprintf(pszBytesPerSecond, uBytesPerSecondLength, szFormat, uBytesPerSecond, uiDecimal);
  305. pszBytesPerSecond[uBytesPerSecondLength - 1] = TEXT('\0');
  306. }
  307. else
  308. {
  309. hr = E_UNEXPECTED;
  310. }
  311. return hr;
  312. }
  313. HRESULT GetConnectionStatus(IUPnPService* pWANConnection, NETCON_STATUS* pStatus)
  314. {
  315. HRESULT hr = S_OK;
  316. BSTR ConnectionStatus;
  317. hr = GetStringStateVariable(pWANConnection, L"ConnectionStatus", &ConnectionStatus);
  318. if(SUCCEEDED(hr))
  319. {
  320. if(0 == wcscmp(ConnectionStatus, L"Connected"))
  321. {
  322. *pStatus = NCS_CONNECTED;
  323. }
  324. else if(0 == wcscmp(ConnectionStatus, L"Connecting"))
  325. {
  326. *pStatus = NCS_CONNECTING;
  327. }
  328. else if(0 == wcscmp(ConnectionStatus, L"Disconnected"))
  329. {
  330. *pStatus = NCS_DISCONNECTED;
  331. }
  332. else if(0 == wcscmp(ConnectionStatus, L"Disconnecting"))
  333. {
  334. *pStatus = NCS_DISCONNECTING;
  335. }
  336. else
  337. {
  338. *pStatus = NCS_HARDWARE_DISABLED;
  339. }
  340. SysFreeString(ConnectionStatus);
  341. }
  342. return hr;
  343. }
  344. HRESULT ConnectionStatusToString(NETCON_STATUS Status, LPTSTR szBuffer, int nBufferSize)
  345. {
  346. HRESULT hr = S_OK;
  347. UINT uStringID = 0;
  348. switch(Status)
  349. {
  350. case NCS_CONNECTED:
  351. uStringID = IDS_CONNECTED;
  352. break;
  353. case NCS_CONNECTING:
  354. uStringID = IDS_CONNECTING;
  355. break;
  356. case NCS_DISCONNECTED:
  357. uStringID = IDS_DISCONNECTED;
  358. break;
  359. case NCS_DISCONNECTING:
  360. uStringID = IDS_DISCONNECTING;
  361. break;
  362. default:
  363. uStringID = IDS_UNCONFIGURED;
  364. break;
  365. }
  366. if(0 == LoadString(_Module.GetResourceInstance(), uStringID, szBuffer, nBufferSize))
  367. {
  368. hr = E_FAIL;
  369. }
  370. return hr;
  371. }
  372. LRESULT ShowErrorDialog(HWND hParentWindow, UINT uiErrorString)
  373. {
  374. TCHAR szTitle[128];
  375. TCHAR szText[1024];
  376. if(NULL != LoadString(_Module.GetResourceInstance(), IDS_APPTITLE, szTitle, sizeof(szTitle) / sizeof(TCHAR)))
  377. {
  378. if(NULL != LoadString(_Module.GetResourceInstance(), uiErrorString, szText, sizeof(szText) / sizeof(TCHAR)))
  379. {
  380. MessageBox(hParentWindow, szText, szTitle, MB_OK);
  381. }
  382. }
  383. return 0;
  384. }
  385. UINT64 MakeQword2(DWORD a, DWORD b)
  386. {
  387. UINT64 qw = a;
  388. qw = qw << 32;
  389. qw |= b;
  390. return qw;
  391. }
  392. UINT64 MakeQword4(WORD a, WORD b, WORD c, WORD d)
  393. {
  394. UINT64 qw = a;
  395. qw = qw << 16;
  396. qw |= b;
  397. qw = qw << 16;
  398. qw |= c;
  399. qw = qw << 16;
  400. qw |= d;
  401. return qw;
  402. }
  403. HRESULT EnsureFileVersion(LPTSTR pszModule, UINT64 qwDesiredVersion)
  404. {
  405. HRESULT hr = S_OK;
  406. DWORD dwDummy;
  407. DWORD dwVersionSize = GetFileVersionInfoSize(pszModule, &dwDummy);
  408. if(0!= dwVersionSize)
  409. {
  410. void* pVersionInfo = CoTaskMemAlloc(dwVersionSize);
  411. if(NULL != pVersionInfo)
  412. {
  413. if(0 != GetFileVersionInfo(pszModule, 0, dwVersionSize, pVersionInfo))
  414. {
  415. void* pSubInfo;
  416. UINT uiSubInfoSize;
  417. if(0 != VerQueryValue(pVersionInfo, TEXT("\\"), &pSubInfo, &uiSubInfoSize))
  418. {
  419. VS_FIXEDFILEINFO* pFixedFileInfo = reinterpret_cast<VS_FIXEDFILEINFO*>(pSubInfo);
  420. UINT64 qwFileVersion = MakeQword2(pFixedFileInfo->dwProductVersionMS, pFixedFileInfo->dwProductVersionLS);
  421. if(qwFileVersion < qwDesiredVersion)
  422. {
  423. hr = E_FAIL;
  424. }
  425. }
  426. else
  427. {
  428. hr = E_FAIL;
  429. }
  430. }
  431. else
  432. {
  433. hr = E_UNEXPECTED;
  434. }
  435. CoTaskMemFree(pVersionInfo);
  436. }
  437. else
  438. {
  439. hr = E_OUTOFMEMORY;
  440. }
  441. }
  442. else
  443. {
  444. hr = E_UNEXPECTED;
  445. }
  446. return hr;
  447. }