Leaked source code of windows server 2003
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.

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