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.

371 lines
8.6 KiB

  1. //=======================================================================
  2. //
  3. // Copyright (C) Microsoft Corporation, 1998 - 1999 All Rights Reserved.
  4. //
  5. // File: SysInfo.cpp
  6. //
  7. // Description:
  8. // Gathers system information necessary to do redirect to windows update site.
  9. //
  10. //=======================================================================
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <tchar.h>
  14. #include <windows.h>
  15. #include <shellapi.h>
  16. #include <wininet.h>
  17. #include <ras.h>
  18. #include <ole2.h>
  19. #include <atlbase.h>
  20. #include <exdisp.h>
  21. #include <sysinfo.h>
  22. //
  23. // Definitions
  24. //
  25. // internationalize
  26. const TCHAR REGKEY_REMOTE_URL[] = _T("Remote URL");
  27. const TCHAR REGVAL_MACHTYPE_AT[] = _T("AT/AT COMPATIBLE");
  28. const TCHAR REGVAL_MACHTYPE_NEC[] = _T("NEC PC-98");
  29. // NEC detection based on existence of NEC keyboard
  30. #define LOOKUP_OEMID(keybdid) HIBYTE(LOWORD((keybdid)))
  31. #define PC98_KEYBOARD_ID 0x0D
  32. const TCHAR MACHTYPE_AT[] = _T("at");
  33. const TCHAR MACHTYPE_NEC[] = _T("nec");
  34. #define LANGID_LEN 20
  35. #define SafeFree(x){if(NULL != x){free(x); x = NULL;}}
  36. typedef enum
  37. {
  38. enAT,
  39. enNEC,
  40. enOther
  41. } enumMachineType;
  42. // Minimum OS versions supported by Windows Update
  43. // For NT, it is 5.0 (NT 5)
  44. // for Win9x, it is 4.1 (Win 98)
  45. const DWORD dwNT5MinMajorVer = 5;
  46. const DWORD dwNT5MinMinorVer = 0;
  47. const DWORD dwWin98MinMajorVer = 4;
  48. const DWORD dwWin98MinMinorVer = 1;
  49. /////////////////////////////////////////////////////////////////////////////
  50. // vGetWindowsDirectory
  51. // Get the path to %windir%\web.
  52. //
  53. // Parameters:
  54. //
  55. // Comments :
  56. /////////////////////////////////////////////////////////////////////////////
  57. void vGetWindowsDirectory(LPTSTR tszWinDirectory)
  58. {
  59. UINT nGetWindowsDirectory = ::GetWindowsDirectory(tszWinDirectory, MAX_PATH);
  60. if ( nGetWindowsDirectory != 0 )
  61. {
  62. if ( tszWinDirectory[lstrlen(tszWinDirectory) - 1] != _T('\\') )
  63. {
  64. lstrcat(tszWinDirectory, _T("\\"));
  65. }
  66. }
  67. else
  68. {
  69. lstrcpy(tszWinDirectory, _T("C:\\WINNT\\"));
  70. }
  71. }
  72. /////////////////////////////////////////////////////////////////////////////
  73. // HrGetMachineType
  74. // Determine whether the machine is of AT or NEC type.
  75. //
  76. /////////////////////////////////////////////////////////////////////////////
  77. HRESULT HrGetMachineType(WORD langid, enumMachineType *penMachineType)
  78. {
  79. *penMachineType = enAT;
  80. if ( langid == LANG_JAPANESE )
  81. {
  82. HKEY hKey;
  83. DWORD type;
  84. TCHAR tszMachineType[50];
  85. DWORD size = sizeof(tszMachineType);
  86. // determine if we should log transmissions
  87. if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  88. NT5_REGPATH_MACHTYPE,
  89. 0,
  90. KEY_QUERY_VALUE,
  91. &hKey) == ERROR_SUCCESS )
  92. {
  93. if ( RegQueryValueEx(hKey,
  94. NT5_REGKEY_MACHTYPE,
  95. 0,
  96. &type,
  97. (BYTE *)tszMachineType,
  98. &size) == ERROR_SUCCESS )
  99. {
  100. if ( type == REG_SZ )
  101. {
  102. if ( lstrcmpi(tszMachineType, REGVAL_MACHTYPE_NEC) == 0 )
  103. {
  104. *penMachineType = enNEC;
  105. }
  106. }
  107. }
  108. RegCloseKey(hKey);
  109. }
  110. }
  111. return S_OK;
  112. }
  113. /////////////////////////////////////////////////////////////////////////////
  114. // vAppendRedirArguments
  115. // Append redir arguments to the redir.dll URL.
  116. //
  117. // Parameters:
  118. //
  119. // Comments :
  120. /////////////////////////////////////////////////////////////////////////////
  121. void
  122. vAppendRedirArguments(LPTSTR tszURLPrefix, LPTSTR tszURL)
  123. {
  124. LANGID langidUser = GetUserDefaultLangID();
  125. LANGID langidMachine = GetSystemDefaultLangID();
  126. enumMachineType enMachineType;
  127. HrGetMachineType(PRIMARYLANGID(langidMachine), &enMachineType);
  128. wsprintf(tszURL, L"%ws?OLCID=0x%04x&CLCID=0x%04x&OS=%ws",
  129. tszURLPrefix,
  130. langidMachine,
  131. langidUser,
  132. (enMachineType == enAT) ? MACHTYPE_AT : MACHTYPE_NEC);
  133. }
  134. /////////////////////////////////////////////////////////////////////////////
  135. // FWinUpdDisabled
  136. // Determine if corporate administrator has turned off Windows Update via
  137. // policy settings.
  138. //
  139. // Parameters:
  140. //
  141. // Comments :
  142. /////////////////////////////////////////////////////////////////////////////
  143. bool FWinUpdDisabled(void)
  144. {
  145. bool fDisabled = false;
  146. HKEY hKey;
  147. DWORD dwDisabled;
  148. DWORD dwSize = sizeof(dwDisabled);
  149. DWORD dwType;
  150. if ( RegOpenKeyEx( HKEY_CURRENT_USER,
  151. REGPATH_EXPLORER,
  152. NULL,
  153. KEY_QUERY_VALUE,
  154. &hKey) == ERROR_SUCCESS )
  155. {
  156. if ( RegQueryValueEx(hKey,
  157. REGKEY_WINUPD_DISABLED,
  158. NULL,
  159. &dwType,
  160. (LPBYTE)&dwDisabled,
  161. &dwSize) == ERROR_SUCCESS )
  162. {
  163. if ( (dwType == REG_DWORD) && (dwDisabled != 0) )
  164. {
  165. fDisabled = true;
  166. }
  167. }
  168. RegCloseKey(hKey);
  169. }
  170. return fDisabled;
  171. }
  172. //
  173. // FRASConnectoidExists
  174. // Checks to see whether there is a default RAS connectoid.
  175. // If so, we know we're configured to connect to the Internet
  176. //
  177. bool FRASConnectoidExists()
  178. {
  179. DWORD cb = 0;
  180. DWORD cEntries = 0;
  181. DWORD dwRet = 0;
  182. bool fRet = false;
  183. // We have to have a valid structure with the dwSize initialized, but we pass 0 as the size
  184. // This will return us the correct count of entries (which is all we care about)
  185. LPRASENTRYNAME lpRasEntryName = (LPRASENTRYNAME) malloc( sizeof(RASENTRYNAME) );
  186. lpRasEntryName->dwSize = sizeof(RASENTRYNAME);
  187. dwRet = RasEnumEntries( NULL, NULL, lpRasEntryName, &cb, &cEntries );
  188. // Check to make sure there's at least one RAS entry
  189. if(cEntries > 0)
  190. {
  191. fRet = true;
  192. }
  193. SafeFree(lpRasEntryName );
  194. return fRet;
  195. }
  196. //
  197. // FICWConnection Exists
  198. // Checks to see whether the "Completed" flag has been set for the ICW.
  199. // as of XP build 2472, this also applies to the Network Connection Wizard
  200. //
  201. bool FICWConnectionExists()
  202. {
  203. HKEY hKey = NULL;
  204. DWORD dwCompleted = 0;
  205. DWORD dwSize = sizeof(dwCompleted);
  206. DWORD dwType = 0;
  207. bool fRet = false;
  208. if ( RegOpenKeyEx( HKEY_CURRENT_USER,
  209. REGPATH_CONNECTION_WIZARD,
  210. NULL,
  211. KEY_QUERY_VALUE,
  212. &hKey) == ERROR_SUCCESS )
  213. {
  214. if ( RegQueryValueEx(hKey,
  215. REGKEY_CONNECTION_WIZARD,
  216. NULL,
  217. &dwType,
  218. (BYTE *)&dwCompleted,
  219. &dwSize) == ERROR_SUCCESS )
  220. {
  221. if ( ((dwType != REG_DWORD) && (dwType != REG_BINARY)) ||
  222. dwCompleted )
  223. {
  224. fRet = true;
  225. }
  226. }
  227. RegCloseKey(hKey);
  228. }
  229. return fRet;
  230. }
  231. bool FIsLanConnection()
  232. {
  233. DWORD dwConnTypes = 0;
  234. // We don't care about the return value - we just care whether we get the LAN flag
  235. (void)InternetGetConnectedState( &dwConnTypes, 0 );
  236. return (dwConnTypes & INTERNET_CONNECTION_LAN) ? true : false;
  237. }
  238. /////////////////////////////////////////////////////////////////////////////
  239. // HrGetConnectionStatus
  240. // Determine whether the Internet Connection Wizard has run.
  241. //
  242. // Parameters:
  243. //
  244. // Comments :
  245. /////////////////////////////////////////////////////////////////////////////
  246. HRESULT HrGetConnectionStatus(bool *pfConnected)
  247. {
  248. // Check to see if there is a default entry in the RAS phone book.
  249. // If so, we know this computer has configured a connection to the Internet.
  250. // We can't tell whether the connection is live, but we can let IE handle prompting to connect.
  251. *pfConnected = FRASConnectoidExists() ||
  252. // If there's no default RAS entry, check to see if the user has run the ICW
  253. // As of build 2472, the Network Connection Wizard sets this same key for both RAS and persistent network connections
  254. FICWConnectionExists() ||
  255. // if the user has a LAN connection, we will trust IE's ability to get through
  256. FIsLanConnection();
  257. // if *pfConnected is still false at this point, there is no preconfigured Internet connection
  258. return S_OK;
  259. }
  260. /////////////////////////////////////////////////////////////////////////////
  261. // vLaunchIE
  262. // Launch IE on URL.
  263. //
  264. // Parameters:
  265. //
  266. // Comments :
  267. /////////////////////////////////////////////////////////////////////////////
  268. HRESULT vLaunchIE(LPTSTR tszURL)
  269. {
  270. IWebBrowser2 *pwb2;
  271. HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  272. if ( SUCCEEDED(hr) )
  273. {
  274. hr = CoCreateInstance(CLSID_InternetExplorer, NULL,
  275. CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (LPVOID*)&pwb2);
  276. if ( SUCCEEDED(hr) )
  277. {
  278. USES_CONVERSION;
  279. BSTR bstrURL = SysAllocString(T2W(tszURL));
  280. VARIANT varURL;
  281. varURL.vt = VT_BSTR;
  282. varURL.bstrVal = bstrURL;
  283. VARIANT varFlags;
  284. varFlags.vt = VT_I4;
  285. varFlags.lVal = 0;
  286. VARIANT varEmpty;
  287. VariantInit(&varEmpty);
  288. hr = pwb2->Navigate2(&varURL, &varFlags, &varEmpty, &varEmpty, &varEmpty);
  289. if ( SUCCEEDED(hr) )
  290. {
  291. // check to see if lhwnd should be type of LONG_PTR instead of long in win_64
  292. LONG_PTR lhwnd = NULL;
  293. if ( SUCCEEDED(pwb2->get_HWND((LONG_PTR*)&lhwnd)) )
  294. {
  295. SetForegroundWindow((HWND)lhwnd);
  296. }
  297. hr = pwb2->put_Visible(TRUE);
  298. }
  299. pwb2->Release();
  300. }
  301. CoUninitialize();
  302. }
  303. return hr;
  304. }