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.

377 lines
11 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // SYSTEM: Windows Update AutoUpdate Client
  4. //
  5. // CLASS: N/A
  6. // MODULE:
  7. // FILE: helpers.CPP
  8. // DESC: This file contains utility functions
  9. //
  10. //////////////////////////////////////////////////////////////////////////////
  11. #include "pch.h"
  12. #pragma hdrstop
  13. const LPTSTR HIDDEN_ITEMS_FILE = _T("hidden.xml");
  14. const LPCTSTR AU_ENV_VARS::s_AUENVVARNAMES[] = {_T("AUCLTEXITEVT"),_T("EnableNo"), _T("EnableYes"), _T("RebootWarningMode")};
  15. BOOL AU_ENV_VARS::ReadIn(void)
  16. {
  17. BOOL fRet = TRUE;
  18. if (!GetBOOLEnvironmentVar(s_AUENVVARNAMES[3], &m_fRebootWarningMode))
  19. { // if not set, implies regular mode
  20. m_fRebootWarningMode = FALSE;
  21. }
  22. if (m_fRebootWarningMode)
  23. {
  24. if (!GetBOOLEnvironmentVar(s_AUENVVARNAMES[1], &m_fEnableNo)
  25. ||!GetBOOLEnvironmentVar(s_AUENVVARNAMES[2], &m_fEnableYes)
  26. ||!GetStringEnvironmentVar(s_AUENVVARNAMES[0], m_szClientExitEvtName, ARRAYSIZE(m_szClientExitEvtName)))
  27. {
  28. return FALSE;
  29. }
  30. }
  31. return TRUE;
  32. }
  33. BOOL AU_ENV_VARS::WriteOut(LPTSTR szEnvBuf,
  34. size_t IN cchEnvBuf,
  35. BOOL IN fRebootWarningMode,
  36. BOOL IN fEnableYes,
  37. BOOL IN fEnableNo,
  38. LPCTSTR IN szClientExitEvtName)
  39. {
  40. TCHAR buf2[s_AUENVVARBUFSIZE];
  41. m_fEnableNo = fEnableNo;
  42. m_fEnableYes = fEnableYes;
  43. m_fRebootWarningMode = fRebootWarningMode;
  44. if (FAILED(StringCchCopyEx(
  45. m_szClientExitEvtName,
  46. ARRAYSIZE(m_szClientExitEvtName),
  47. szClientExitEvtName,
  48. NULL,
  49. NULL,
  50. MISTSAFE_STRING_FLAGS)))
  51. {
  52. return FALSE;
  53. }
  54. *szEnvBuf = _T('\0');
  55. for (int i = 0 ; i < ARRAYSIZE(s_AUENVVARNAMES); i++)
  56. {
  57. if (FAILED(GetStringValue(i, buf2, ARRAYSIZE(buf2))) ||
  58. FAILED(StringCchCatEx(szEnvBuf, cchEnvBuf, s_AUENVVARNAMES[i], NULL, NULL, MISTSAFE_STRING_FLAGS)) ||
  59. FAILED(StringCchCatEx(szEnvBuf, cchEnvBuf, _T("="), NULL, NULL, MISTSAFE_STRING_FLAGS)) ||
  60. FAILED(StringCchCatEx(szEnvBuf, cchEnvBuf, buf2, NULL, NULL, MISTSAFE_STRING_FLAGS)) ||
  61. FAILED(StringCchCatEx(szEnvBuf, cchEnvBuf, _T("&"), NULL, NULL, MISTSAFE_STRING_FLAGS)))
  62. {
  63. return FALSE;
  64. }
  65. }
  66. return TRUE;
  67. }
  68. HRESULT AU_ENV_VARS::GetStringValue(int index, LPTSTR buf, DWORD dwCchSize)
  69. {
  70. HRESULT hr = E_INVALIDARG;
  71. switch (index)
  72. {
  73. case 0: hr = StringCchCopyEx(buf, dwCchSize, m_szClientExitEvtName, NULL, NULL, MISTSAFE_STRING_FLAGS);
  74. break;
  75. case 1: hr = StringCchCopyEx(buf, dwCchSize, m_fEnableNo? _T("true") : _T("false"), NULL, NULL, MISTSAFE_STRING_FLAGS);
  76. break;
  77. case 2: hr = StringCchCopyEx(buf, dwCchSize, m_fEnableYes? _T("true") : _T("false"), NULL, NULL, MISTSAFE_STRING_FLAGS);
  78. break;
  79. case 3: hr = StringCchCopyEx(buf, dwCchSize, m_fRebootWarningMode ? _T("true") : _T("false"), NULL, NULL, MISTSAFE_STRING_FLAGS);
  80. break;
  81. }
  82. return hr;
  83. }
  84. BOOL AU_ENV_VARS::GetBOOLEnvironmentVar(LPCTSTR szEnvVar, BOOL *pfVal)
  85. {
  86. TCHAR szBuf[20];
  87. if (GetStringEnvironmentVar(szEnvVar, szBuf, ARRAYSIZE(szBuf)))
  88. {
  89. // DEBUGMSG("WUAUCLT got environment variable %S = %S ", szEnvVar, szBuf);
  90. *pfVal =(0 == lstrcmpi(szBuf, _T("true")));
  91. return TRUE;
  92. }
  93. return FALSE;
  94. }
  95. /////////////////////////////////////////////////////////////////////////////////////////////
  96. // dwSize: size of szBuf in number of characters
  97. ////////////////////////////////////////////////////////////////////////////////////////////
  98. BOOL AU_ENV_VARS::GetStringEnvironmentVar(LPCTSTR szEnvVar, LPTSTR szBuf, DWORD dwSize)
  99. {
  100. // Assume szEnvVar is not a proper substring in for any parameters in szCmdLine.
  101. LPTSTR szCmdLine = GetCommandLine();
  102. LPTSTR pTmp;
  103. DWORD index = 0;
  104. // DEBUGMSG("WUAUCLT read in command line %S", szCmdLine);
  105. if (NULL == szCmdLine || 0 == dwSize || (NULL == (pTmp = StrStr(szCmdLine, szEnvVar))))
  106. {
  107. return FALSE;
  108. }
  109. pTmp += lstrlen(szEnvVar) + 1; //skip '='
  110. while (_T('\0') != *pTmp && _T('&') != *pTmp)
  111. {
  112. if (index + 1 >= dwSize)
  113. {
  114. // insufficent buffer
  115. return FALSE;
  116. }
  117. szBuf[index++] = *pTmp++;
  118. }
  119. szBuf[index] = _T('\0');
  120. // DEBUGMSG(" read in %S = %S", szEnvVar, szBuf);
  121. return TRUE;
  122. }
  123. #if 0
  124. #ifdef DBG
  125. void DBGCheckEventState(LPSTR szName, HANDLE hEvt)
  126. {
  127. DWORD dwRet = WaitForSingleObject(hEvt, 0);
  128. DEBUGMSG("WUAU Event %s is %s signalled", szName,( WAIT_OBJECT_0 == dwRet) ? "" : "NOT");
  129. return;
  130. }
  131. #endif
  132. #endif
  133. ////////////////////////////////////////////////////////////////////////////////////////
  134. // check whether it is win2k for the current system
  135. ////////////////////////////////////////////////////////////////////////////////////////
  136. BOOL IsWin2K(void)
  137. {
  138. static int iIsWin2K = -1; // force first time path
  139. if (iIsWin2K == -1)
  140. {
  141. OSVERSIONINFOEX osvi;
  142. DWORDLONG dwlConditionMask = 0;
  143. ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  144. // This is information that identifies win2K
  145. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  146. osvi.dwMajorVersion = 5;
  147. osvi.dwMinorVersion = 0;
  148. // Initialize the condition mask.
  149. VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, VER_EQUAL );
  150. VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, VER_EQUAL );
  151. // Perform the test.
  152. iIsWin2K = (VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask)? 1 : 0);
  153. }
  154. return iIsWin2K;
  155. }
  156. /////////////////////////////////////////////////////////////////////////////////////
  157. // check whether a policy is set to deny current user access to AU
  158. /////////////////////////////////////////////////////////////////////////////////////
  159. BOOL fAccessibleToAU(void)
  160. {
  161. BOOL fAccessible = TRUE;
  162. DWORD dwType;
  163. DWORD dwValue;
  164. DWORD dwSize = sizeof(dwValue);
  165. DWORD dwResult = SHGetValue(HKEY_CURRENT_USER,
  166. AUREGKEY_HKCU_USER_POLICY,
  167. AUREGVALUE_DISABLE_WINDOWS_UPDATE_ACCESS,
  168. &dwType,
  169. &dwValue,
  170. &dwSize);
  171. if (ERROR_SUCCESS == dwResult && REG_DWORD == dwType && 1 == dwValue)
  172. {
  173. fAccessible = FALSE;
  174. }
  175. return fAccessible;
  176. }
  177. /*
  178. BOOL IsAdministrator()
  179. {
  180. SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
  181. PSID pSID = NULL;
  182. BOOL bResult = FALSE;
  183. if (!AllocateAndInitializeSid(&SIDAuth, 2,
  184. SECURITY_BUILTIN_DOMAIN_RID,
  185. DOMAIN_ALIAS_RID_ADMINS,
  186. 0, 0, 0, 0, 0, 0,
  187. &pSID) ||
  188. !CheckTokenMembership(NULL, pSID, &bResult))
  189. {
  190. bResult = FALSE;
  191. }
  192. if(pSID)
  193. {
  194. FreeSid(pSID);
  195. }
  196. return bResult;
  197. }
  198. */
  199. // following are hidden item related functions
  200. BOOL FHiddenItemsExist(void)
  201. {
  202. //USES_CONVERSION;
  203. DEBUGMSG("FHiddenItemsExist()");
  204. TCHAR szFile[MAX_PATH];
  205. //Initialize the global path to WU Dir
  206. if(!CreateWUDirectory(TRUE))
  207. {
  208. return FALSE;
  209. }
  210. return
  211. SUCCEEDED(StringCchCopyEx(szFile, ARRAYSIZE(szFile), g_szWUDir, NULL, NULL, MISTSAFE_STRING_FLAGS)) &&
  212. SUCCEEDED(StringCchCatEx(szFile, ARRAYSIZE(szFile), HIDDEN_ITEMS_FILE, NULL, NULL, MISTSAFE_STRING_FLAGS)) &&
  213. fFileExists(szFile);
  214. }
  215. BOOL RemoveHiddenItems(void)
  216. {
  217. //USES_CONVERSION
  218. DEBUGMSG("RemoveHiddenItems()");
  219. TCHAR szFile[MAX_PATH];
  220. AUASSERT(_T('\0') != g_szWUDir[0]);
  221. return
  222. SUCCEEDED(StringCchCopyEx(szFile, ARRAYSIZE(szFile), g_szWUDir, NULL, NULL, MISTSAFE_STRING_FLAGS)) &&
  223. SUCCEEDED(StringCchCatEx(szFile, ARRAYSIZE(szFile), HIDDEN_ITEMS_FILE, NULL, NULL, MISTSAFE_STRING_FLAGS)) &&
  224. AUDelFileOrDir(szFile);
  225. }
  226. /////////////////////////////////////////////////////////////////////////////////
  227. // bstrRTFPath is URL for the RTF file on internet
  228. // langid is the language id for the process who download this RTF
  229. ////////////////////////////////////////////////////////////////////////////////
  230. BOOL IsRTFDownloaded(BSTR bstrRTFPath, LANGID langid)
  231. {
  232. TCHAR tszLocalFullFileName[MAX_PATH];
  233. if (NULL == bstrRTFPath)
  234. {
  235. return FALSE;
  236. }
  237. if (FAILED(GetRTFDownloadPath(tszLocalFullFileName, ARRAYSIZE(tszLocalFullFileName), langid)) ||
  238. FAILED(PathCchAppend(tszLocalFullFileName, ARRAYSIZE(tszLocalFullFileName), W2T(PathFindFileNameW(bstrRTFPath)))))
  239. {
  240. return FALSE;
  241. }
  242. // DEBUGMSG("Checking existence of local RTF file %S", T2W(tszLocalFullFileName));
  243. BOOL fIsDir = TRUE;
  244. BOOL fExists = fFileExists(tszLocalFullFileName, &fIsDir);
  245. return fExists && !fIsDir;
  246. }
  247. void DisableUserInput(HWND hwnd)
  248. {
  249. int ControlIDs[] = { IDC_CHK_KEEPUPTODATE, IDC_OPTION1, IDC_OPTION2,
  250. IDC_OPTION3, IDC_CMB_DAYS, IDC_CMB_HOURS,IDC_RESTOREHIDDEN };
  251. for (int i = 0; i < ARRAYSIZE(ControlIDs); i++)
  252. {
  253. EnableWindow(GetDlgItem(hwnd, ControlIDs[i]), FALSE);
  254. }
  255. }
  256. ////////////////////////////////////////////////////////////////////////////
  257. //
  258. // Helper Function Hours2LocalizedString()
  259. // helper function to standardized the way AU formats time string
  260. // for a given time. For example "3:00 AM"
  261. //
  262. // Parameters:
  263. // pst - ptr to SYSTEMTIME for localizing the time component
  264. // ptszBuffer - buffer to hold the resulting localized string
  265. // cbSize - size of buffer in TCHARs
  266. // Return: TRUE if successful; FALSE otherwise
  267. //
  268. ////////////////////////////////////////////////////////////////////////////
  269. BOOL Hours2LocalizedString(SYSTEMTIME *pst, LPTSTR ptszBuffer, DWORD cbSize)
  270. {
  271. return (0 != GetTimeFormat(
  272. LOCALE_SYSTEM_DEFAULT,
  273. LOCALE_NOUSEROVERRIDE | TIME_NOSECONDS,
  274. pst,
  275. NULL,
  276. ptszBuffer,
  277. cbSize));
  278. }
  279. ////////////////////////////////////////////////////////////////////////////
  280. //
  281. // Helper Function FillHrsCombo()
  282. // helper function to standardized the way AU sets up the list
  283. // of hour values in a combo box.
  284. //
  285. // Parameters:
  286. // hwnd - handle to obtain the handle to the combobox
  287. // dwSchedInstallTime - hour value to default the combobox selection to
  288. // 3:00 AM will be used if this value is not valid.
  289. // Return: TRUE if successful; FALSE otherwise
  290. //
  291. ////////////////////////////////////////////////////////////////////////////
  292. BOOL FillHrsCombo(HWND hwnd, DWORD dwSchedInstallTime)
  293. {
  294. HWND hComboHrs = GetDlgItem(hwnd,IDC_CMB_HOURS);
  295. DWORD dwCurrentIndex = 3;
  296. SYSTEMTIME st = {2000, 1, 5, 1, 0, 0, 0, 0}; // 01/01/2000 00:00:00 can be any valid date/time
  297. for (WORD i = 0; i < 24; i++)
  298. {
  299. TCHAR tszHrs[30];
  300. st.wHour = i;
  301. if (!Hours2LocalizedString(&st, tszHrs, ARRAYSIZE(tszHrs)))
  302. {
  303. return FALSE;
  304. }
  305. LRESULT nIndex = SendMessage(hComboHrs,CB_ADDSTRING,0,(LPARAM)tszHrs);
  306. SendMessage(hComboHrs,CB_SETITEMDATA,nIndex,i);
  307. if( dwSchedInstallTime == i )
  308. {
  309. dwCurrentIndex = (DWORD)nIndex;
  310. }
  311. }
  312. SendMessage(hComboHrs,CB_SETCURSEL,dwCurrentIndex,(LPARAM)0);
  313. return TRUE;
  314. }
  315. BOOL FillDaysCombo(HINSTANCE hInstance, HWND hwnd, DWORD dwSchedInstallDay, UINT uMinResId, UINT uMaxResId)
  316. {
  317. HWND hComboDays = GetDlgItem(hwnd,IDC_CMB_DAYS);
  318. DWORD dwCurrentIndex = 0;
  319. for (UINT i = uMinResId, j = 0; i <= uMaxResId; i ++, j++)
  320. {
  321. WCHAR szDay[40];
  322. LoadStringW(hInstance,i,szDay,ARRAYSIZE(szDay));
  323. LRESULT nIndex = SendMessage(hComboDays,CB_ADDSTRING,0,(LPARAM)szDay);
  324. SendMessage(hComboDays,CB_SETITEMDATA,nIndex,j);
  325. if( dwSchedInstallDay == j )
  326. {
  327. dwCurrentIndex = (DWORD) nIndex;
  328. }
  329. }
  330. SendMessage(hComboDays,CB_SETCURSEL,dwCurrentIndex,(LPARAM)0);
  331. return TRUE;
  332. }