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.

864 lines
26 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1999 **
  4. //*********************************************************************
  5. //
  6. // PID.CPP - Header for the implementation of CSystemClock
  7. //
  8. // HISTORY:
  9. //
  10. // 1/27/99 a-jaswed Created.
  11. //
  12. #include "sysclock.h"
  13. #include "appdefs.h"
  14. #include "dispids.h"
  15. #include "msobmain.h"
  16. #include "resource.h"
  17. #include <stdlib.h>
  18. int WINAPI StrToWideStr(LPWSTR pwsz, LPCSTR psz)
  19. {
  20. return MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, MAX_PATH);
  21. }
  22. DISPATCHLIST SystemClockExternalInterface[] =
  23. {
  24. { L"set_TimeZone", DISPID_SYSTEMCLOCK_SETTIMEZONE },
  25. { L"set_Time", DISPID_SYSTEMCLOCK_SETTIME },
  26. { L"set_Date", DISPID_SYSTEMCLOCK_SETDATE },
  27. // new oobe2 methods below, others are currently unused
  28. { L"Init", DISPID_SYSTEMCLOCK_INIT },
  29. { L"get_AllTimeZones", DISPID_SYSTEMCLOCK_GETALLTIMEZONES },
  30. { L"get_TimeZoneIdx", DISPID_SYSTEMCLOCK_GETTIMEZONEIDX },
  31. { L"set_TimeZoneIdx", DISPID_SYSTEMCLOCK_SETTIMEZONEIDX },
  32. { L"set_AutoDaylight", DISPID_SYSTEMCLOCK_SETAUTODAYLIGHT },
  33. { L"get_AutoDaylight", DISPID_SYSTEMCLOCK_GETAUTODAYLIGHT },
  34. { L"get_DaylightEnabled", DISPID_SYSTEMCLOCK_GETDAYLIGHT_ENABLED },
  35. { L"get_TimeZonewasPreset", DISPID_SYSTEMCLOCK_GETTIMEZONEWASPRESET }
  36. };
  37. /////////////////////////////////////////////////////////////
  38. // CSystemClock::CSystemClock
  39. CSystemClock::CSystemClock(HINSTANCE hInstance)
  40. {
  41. // Init member vars
  42. m_cRef = 0;
  43. m_cNumTimeZones = 0;
  44. m_pTimeZoneArr = NULL;
  45. m_szTimeZoneOptionStrs = NULL;
  46. m_uCurTimeZoneIdx = 0;
  47. m_bSetAutoDaylightMode = TRUE; // on by default
  48. m_bTimeZonePreset = FALSE;
  49. m_hInstance=hInstance;
  50. }
  51. /////////////////////////////////////////////////////////////
  52. // CSystemClock::~CSystemClock
  53. CSystemClock::~CSystemClock()
  54. {
  55. MYASSERT(m_cRef == 0);
  56. if ( m_pTimeZoneArr )
  57. HeapFree(GetProcessHeap(), 0x0, (LPVOID) m_pTimeZoneArr );
  58. if(m_szTimeZoneOptionStrs)
  59. HeapFree(GetProcessHeap(), 0x0,(LPVOID) m_szTimeZoneOptionStrs);
  60. m_cNumTimeZones = 0;
  61. m_pTimeZoneArr = NULL;
  62. m_szTimeZoneOptionStrs = NULL;
  63. }
  64. int CSystemClock::GetTimeZoneValStr() {
  65. LPCWSTR szINIFileName = INI_SETTINGS_FILENAME;
  66. UINT uiSectionName = IDS_SECTION_OPTIONS;
  67. UINT uiKeyName = IDS_KEY_TIMEZONEVAL;
  68. int Result = -1;
  69. WCHAR szSectionName[1024], szKeyName[1024];
  70. if(GetString(m_hInstance, uiSectionName, szSectionName) && GetString(m_hInstance, uiKeyName, szKeyName))
  71. {
  72. WCHAR szINIPath[MAX_PATH];
  73. if(GetCanonicalizedPath(szINIPath, szINIFileName))
  74. Result = GetPrivateProfileInt(szSectionName, szKeyName, -1, szINIPath);
  75. }
  76. return Result;
  77. }
  78. int
  79. __cdecl
  80. TimeZoneCompare(
  81. const void *arg1,
  82. const void *arg2
  83. )
  84. {
  85. int BiasDiff = ((PTZINFO)arg2)->Bias - ((PTZINFO)arg1)->Bias;
  86. if (BiasDiff) {
  87. return BiasDiff;
  88. } else {
  89. return lstrcmp(
  90. ((PTZINFO)arg1)->szDisplayName,
  91. ((PTZINFO)arg2)->szDisplayName
  92. );
  93. }
  94. }
  95. HRESULT CSystemClock::InitSystemClock()
  96. {
  97. // constructor cant return failure, so make separate init fn
  98. DWORD cDefltZoneNameLen, cTotalDispNameSize;
  99. HRESULT hr;
  100. HKEY hRootZoneKey = NULL;
  101. HKEY hTimeZoneInfoKey = NULL;
  102. hr = RegOpenKey(HKEY_LOCAL_MACHINE, TIME_ZONE_REGKEY, &hRootZoneKey);
  103. if(hr != ERROR_SUCCESS)
  104. return hr;
  105. // find number of keys, length of default keystr
  106. hr= RegQueryInfoKey(hRootZoneKey, NULL,NULL,NULL,
  107. &m_cNumTimeZones,
  108. NULL, // longest subkey name length
  109. NULL, // longest class string length
  110. NULL, // number of value entries
  111. &cDefltZoneNameLen, // longest value name length
  112. NULL, // longest value data length
  113. NULL, // security descriptor length
  114. NULL); // last write time
  115. if(hr != ERROR_SUCCESS)
  116. return hr;
  117. MYASSERT(cDefltZoneNameLen<TZNAME_SIZE);
  118. MYASSERT(m_cNumTimeZones>0 && m_cNumTimeZones<1000); // ensure reasonable value
  119. cTotalDispNameSize=0;
  120. if(m_pTimeZoneArr!=NULL)
  121. HeapFree(GetProcessHeap(), 0x0,m_pTimeZoneArr);
  122. m_pTimeZoneArr = (PTZINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (m_cNumTimeZones+2) * sizeof(TZINFO) );
  123. if( m_pTimeZoneArr == NULL)
  124. return ERROR_OUTOFMEMORY;
  125. DWORD i;
  126. WCHAR CurZoneKeyName[MAXKEYNAMELEN];
  127. DWORD CurZoneKeyNameLen;
  128. HKEY hCurZoneKey = NULL;
  129. HRESULT hrEnumRes = ERROR_SUCCESS;
  130. for(i=0;hrEnumRes==ERROR_SUCCESS; i++) {
  131. CurZoneKeyNameLen=sizeof(CurZoneKeyName);
  132. hr = hrEnumRes = RegEnumKeyEx(hRootZoneKey, i,CurZoneKeyName,&CurZoneKeyNameLen,NULL,NULL,NULL,NULL);
  133. if(!((hr == ERROR_NO_MORE_ITEMS) || (hr ==ERROR_SUCCESS)))
  134. return hr;
  135. #ifdef DBG
  136. if(hr!=ERROR_NO_MORE_ITEMS)
  137. MYASSERT(CurZoneKeyNameLen<MAXKEYNAMELEN); // for some reason CurZoneKeyNameLen is reset to the orig value at the end of the enumeration
  138. #endif
  139. // call ReadZoneData for each KeyName
  140. hr=RegOpenKey(hRootZoneKey, CurZoneKeyName, &hCurZoneKey);
  141. if(hr != ERROR_SUCCESS)
  142. return hr;
  143. hr = ReadZoneData(&m_pTimeZoneArr[i], hCurZoneKey, CurZoneKeyName);
  144. if(hr != S_OK)
  145. return hr;
  146. cTotalDispNameSize+= BYTES_REQUIRED_BY_SZ(m_pTimeZoneArr[i].szDisplayName) + sizeof(WCHAR); //+1 for safety
  147. RegCloseKey(hCurZoneKey);
  148. }
  149. MYASSERT((i-1)==m_cNumTimeZones);
  150. DWORD uType, uLen = sizeof(DefltZoneKeyValue);
  151. MYASSERT(uLen>cDefltZoneNameLen);
  152. //
  153. // Get the current timezone name.
  154. //
  155. hr = RegOpenKey( HKEY_LOCAL_MACHINE,
  156. TIME_ZONE_INFO_REGKEY,
  157. &hTimeZoneInfoKey
  158. );
  159. if ( hr != ERROR_SUCCESS )
  160. return hr;
  161. hr = RegQueryValueEx( hTimeZoneInfoKey,
  162. TIMEZONE_STANDARD_NAME,
  163. NULL,
  164. &uType,
  165. (LPBYTE)DefltZoneKeyValue,
  166. &uLen
  167. );
  168. if(hr != ERROR_SUCCESS)
  169. return hr;
  170. RegCloseKey( hTimeZoneInfoKey );
  171. hTimeZoneInfoKey = NULL;
  172. //
  173. // Sort our array of timezones.
  174. //
  175. qsort(
  176. m_pTimeZoneArr,
  177. m_cNumTimeZones,
  178. sizeof(TZINFO),
  179. TimeZoneCompare
  180. );
  181. // Set the timezone by the value in oobeinfo.ini, if specified
  182. int iINIidx=GetTimeZoneValStr();
  183. if ( iINIidx != -1 ) {
  184. // Search for the specified Index
  185. for(i=0;i<m_cNumTimeZones; i++) {
  186. if ( m_pTimeZoneArr[i].Index == iINIidx ) {
  187. m_uCurTimeZoneIdx = i;
  188. break;
  189. }
  190. }
  191. // need to tell script to skip tz page if we do the preset
  192. // set timezone to preset value
  193. if(i<m_cNumTimeZones) {
  194. m_bTimeZonePreset=TRUE;
  195. }
  196. }
  197. // find index of default std name
  198. if ( !m_bTimeZonePreset ) {
  199. for(i=0;i<m_cNumTimeZones; i++) {
  200. if(CSTR_EQUAL==CompareString(LOCALE_USER_DEFAULT, 0,
  201. DefltZoneKeyValue, -1,
  202. m_pTimeZoneArr[i].szStandardName, -1))
  203. break;
  204. }
  205. if(i>=m_cNumTimeZones) {
  206. // search failed, the default stdname value of the timezone root key does not
  207. // exist in the subkeys's stdnames, use default of 0
  208. i = 0;
  209. }
  210. m_uCurTimeZoneIdx = i;
  211. }
  212. // Create the SELECT tag OPTIONS for the html so it can get all the country names in one shot.
  213. if(m_szTimeZoneOptionStrs)
  214. HeapFree(GetProcessHeap(), 0x0,m_szTimeZoneOptionStrs);
  215. cTotalDispNameSize += m_cNumTimeZones * sizeof(szOptionTag) + 1;
  216. m_szTimeZoneOptionStrs = (WCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cTotalDispNameSize);
  217. if(m_szTimeZoneOptionStrs == NULL)
  218. return ERROR_OUTOFMEMORY;
  219. WCHAR szTempBuf[MAX_PATH];
  220. for (i=0; i < m_cNumTimeZones; i++)
  221. {
  222. wsprintf(szTempBuf, szOptionTag, m_pTimeZoneArr[i].szDisplayName);
  223. lstrcat(m_szTimeZoneOptionStrs, szTempBuf);
  224. }
  225. return hr;
  226. }
  227. ////////////////////////////////////////////////
  228. ////////////////////////////////////////////////
  229. //// GET / SET :: System clock stuff
  230. ////
  231. HRESULT CSystemClock::set_Time(WORD wHour, WORD wMinute, WORD wSec)
  232. {
  233. SYSTEMTIME SystemTime;
  234. GetSystemTime(&SystemTime);
  235. SystemTime.wHour = wHour;
  236. SystemTime.wMinute = wMinute;
  237. SystemTime.wSecond = wSec;
  238. SystemTime.wMilliseconds = 0;
  239. SetLocalTime (&SystemTime);
  240. SendMessage((HWND)-1, WM_TIMECHANGE, 0, 0);
  241. return S_OK;
  242. }
  243. HRESULT CSystemClock::set_Date(WORD wMonth, WORD wDay, WORD wYear)
  244. {
  245. SYSTEMTIME SystemTime;
  246. GetSystemTime(&SystemTime);
  247. SystemTime.wMonth = wMonth;
  248. SystemTime.wDay = wDay;
  249. SystemTime.wYear = wYear;
  250. SetLocalTime (&SystemTime);
  251. SendMessage((HWND)-1, WM_TIMECHANGE, 0, 0);
  252. return S_OK;
  253. }
  254. HRESULT CSystemClock::set_TimeZone(BSTR bstrTimeZone)
  255. {
  256. TZINFO tZone;
  257. ZeroMemory((void*)&tZone, sizeof(TZINFO));
  258. BOOL bRet = FALSE;
  259. HKEY hKey = NULL;
  260. HKEY hSubKey = NULL;
  261. if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, TIME_ZONE_REGKEY, &hKey))
  262. {
  263. // user can pass key name
  264. if(RegOpenKey(hKey, bstrTimeZone, &hSubKey) == ERROR_SUCCESS)
  265. {
  266. if(ReadZoneData(&tZone, hSubKey, bstrTimeZone))
  267. bRet = TRUE;
  268. }
  269. RegCloseKey(hKey);
  270. if(bRet)
  271. SetTheTimezone(m_bSetAutoDaylightMode, &tZone);
  272. }
  273. SendMessage((HWND)-1, WM_TIMECHANGE, 0, 0);
  274. return S_OK;
  275. }
  276. HRESULT CSystemClock::ReadZoneData(PTZINFO ptZone, HKEY hKey, LPCWSTR szKeyName)
  277. {
  278. DWORD dwLen = 0;
  279. HRESULT hr;
  280. dwLen = sizeof(ptZone->szDisplayName);
  281. if(ERROR_SUCCESS != (hr = RegQueryValueEx(hKey,
  282. TIME_ZONE_DISPLAYNAME_REGVAL,
  283. 0,
  284. NULL,
  285. (LPBYTE)ptZone->szDisplayName,
  286. &dwLen)))
  287. {
  288. if(hr == ERROR_MORE_DATA) {
  289. // registry strings from timezone.inf are too long (timezone.inf author error)
  290. // truncate them
  291. ptZone->szDisplayName[sizeof(ptZone->szDisplayName)-1]=L'\0';
  292. } else
  293. return hr;
  294. }
  295. dwLen = sizeof(ptZone->szStandardName);
  296. if(ERROR_SUCCESS != (hr = RegQueryValueEx(hKey,
  297. TIME_ZONE_STANDARDNAME_REGVAL,
  298. 0,
  299. NULL,
  300. (LPBYTE)ptZone->szStandardName,
  301. &dwLen)))
  302. {
  303. if(hr == ERROR_MORE_DATA) {
  304. // registry strings from timezone.inf are too long (timezone.inf author error)
  305. // truncate them
  306. ptZone->szStandardName[sizeof(ptZone->szStandardName)-1]=L'\0';
  307. } else {
  308. // use keyname if cant get StandardName value
  309. lstrcpyn(ptZone->szStandardName, szKeyName, MAX_CHARS_IN_BUFFER(ptZone->szStandardName));
  310. }
  311. }
  312. dwLen = sizeof(ptZone->szDaylightName);
  313. if(ERROR_SUCCESS != (hr = RegQueryValueEx(hKey,
  314. TIME_ZONE_DAYLIGHTNAME_REGVAL,
  315. 0,
  316. NULL,
  317. (LPBYTE)ptZone->szDaylightName,
  318. &dwLen)))
  319. {
  320. if(hr == ERROR_MORE_DATA) {
  321. // registry strings from timezone.inf are too long (timezone.inf author error)
  322. // truncate them
  323. ptZone->szDaylightName[sizeof(ptZone->szDaylightName)-1]=L'\0';
  324. } else
  325. return hr;
  326. }
  327. // get the Index
  328. dwLen = sizeof(ptZone->Index);
  329. if(ERROR_SUCCESS != (hr = RegQueryValueEx(hKey,
  330. TIME_ZONE_INDEX_REGVAL,
  331. NULL,
  332. NULL,
  333. (LPBYTE) &(ptZone->Index),
  334. &dwLen)))
  335. {
  336. return hr;
  337. }
  338. // read all these fields in at once, the way they are stored in registry
  339. dwLen = sizeof(ptZone->Bias) +
  340. sizeof(ptZone->StandardBias) +
  341. sizeof(ptZone->DaylightBias) +
  342. sizeof(ptZone->StandardDate) +
  343. sizeof(ptZone->DaylightDate);
  344. if(ERROR_SUCCESS != (hr = RegQueryValueEx(hKey,
  345. TIME_ZONE_TZI_REGVAL,
  346. NULL,
  347. NULL,
  348. (LPBYTE) &(ptZone->Bias),
  349. &dwLen)))
  350. {
  351. // registry data from timezone.inf is too long (timezone.inf author error)
  352. // no good fallback behavior for binary data, so fail it so people notice the problem
  353. return hr;
  354. }
  355. return S_OK;
  356. }
  357. BOOL CSystemClock::SetTheTimezone(BOOL fAutoDaylightSavings, PTZINFO ptZone)
  358. {
  359. TIME_ZONE_INFORMATION tzi;
  360. ZeroMemory((void*)&tzi, sizeof(TIME_ZONE_INFORMATION));
  361. if (ptZone==NULL)
  362. return FALSE;
  363. lstrcpyn(tzi.StandardName, ptZone->szStandardName,
  364. MAX_CHARS_IN_BUFFER(tzi.StandardName));
  365. lstrcpyn(tzi.DaylightName, ptZone->szStandardName,
  366. MAX_CHARS_IN_BUFFER(tzi.DaylightName));
  367. tzi.Bias = ptZone->Bias;
  368. tzi.StandardBias = ptZone->StandardBias;
  369. tzi.DaylightBias = ptZone->DaylightBias;
  370. tzi.StandardDate = ptZone->StandardDate;
  371. tzi.DaylightDate = ptZone->DaylightDate;
  372. SetAllowLocalTimeChange(fAutoDaylightSavings);
  373. return SetTimeZoneInformation(&tzi);
  374. }
  375. void CSystemClock::GetTimeZoneInfo(BOOL fAutoDaylightSavings, PTZINFO ptZone)
  376. {
  377. TIME_ZONE_INFORMATION tzi;
  378. ZeroMemory((void*)&tzi, sizeof(TIME_ZONE_INFORMATION));
  379. if (!ptZone)
  380. return;
  381. lstrcpyn(tzi.StandardName, ptZone->szStandardName,
  382. MAX_CHARS_IN_BUFFER(tzi.StandardName));
  383. lstrcpyn(tzi.DaylightName, ptZone->szStandardName,
  384. MAX_CHARS_IN_BUFFER(tzi.DaylightName));
  385. tzi.Bias = ptZone->Bias;
  386. tzi.StandardBias = ptZone->StandardBias;
  387. tzi.DaylightBias = ptZone->DaylightBias;
  388. tzi.StandardDate = ptZone->StandardDate;
  389. tzi.DaylightDate = ptZone->DaylightDate;
  390. SetAllowLocalTimeChange(fAutoDaylightSavings);
  391. SetTimeZoneInformation(&tzi);
  392. }
  393. void CSystemClock::SetAllowLocalTimeChange(BOOL fAutoDaylightSavings)
  394. {
  395. HKEY hKey = NULL;
  396. DWORD dwVal = 1;
  397. if(fAutoDaylightSavings)
  398. {
  399. // remove the disallow flag from the registry if it exists
  400. if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE,
  401. REGSTR_PATH_TIMEZONE,
  402. &hKey))
  403. {
  404. RegDeleteValue(hKey, REGSTR_VAL_TZNOAUTOTIME);
  405. }
  406. }
  407. else
  408. {
  409. // add/set the nonzero disallow flag
  410. if(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE,
  411. REGSTR_PATH_TIMEZONE,
  412. &hKey))
  413. {
  414. RegSetValueEx(hKey,
  415. (LPCWSTR)REGSTR_VAL_TZNOAUTOTIME,
  416. 0UL,
  417. REG_DWORD,
  418. (LPBYTE)&dwVal,
  419. sizeof(dwVal));
  420. }
  421. }
  422. if(hKey)
  423. RegCloseKey(hKey);
  424. }
  425. /////////////////////////////////////////////////////////////
  426. /////////////////////////////////////////////////////////////
  427. /////////////////////////////////////////////////////////////
  428. /////// IUnknown implementation
  429. ///////
  430. ///////
  431. /////////////////////////////////////////////////////////////
  432. // CSystemClock::QueryInterface
  433. STDMETHODIMP CSystemClock::QueryInterface(REFIID riid, LPVOID* ppvObj)
  434. {
  435. // must set out pointer parameters to NULL
  436. *ppvObj = NULL;
  437. if ( riid == IID_IUnknown)
  438. {
  439. AddRef();
  440. *ppvObj = (IUnknown*)this;
  441. return ResultFromScode(S_OK);
  442. }
  443. if (riid == IID_IDispatch)
  444. {
  445. AddRef();
  446. *ppvObj = (IDispatch*)this;
  447. return ResultFromScode(S_OK);
  448. }
  449. // Not a supported interface
  450. return ResultFromScode(E_NOINTERFACE);
  451. }
  452. /////////////////////////////////////////////////////////////
  453. // CSystemClock::AddRef
  454. STDMETHODIMP_(ULONG) CSystemClock::AddRef()
  455. {
  456. return ++m_cRef;
  457. }
  458. /////////////////////////////////////////////////////////////
  459. // CSystemClock::Release
  460. STDMETHODIMP_(ULONG) CSystemClock::Release()
  461. {
  462. return --m_cRef;
  463. }
  464. /////////////////////////////////////////////////////////////
  465. /////////////////////////////////////////////////////////////
  466. /////////////////////////////////////////////////////////////
  467. /////// IDispatch implementation
  468. ///////
  469. ///////
  470. /////////////////////////////////////////////////////////////
  471. // CSystemClock::GetTypeInfo
  472. STDMETHODIMP CSystemClock::GetTypeInfo(UINT, LCID, ITypeInfo**)
  473. {
  474. return E_NOTIMPL;
  475. }
  476. /////////////////////////////////////////////////////////////
  477. // CSystemClock::GetTypeInfoCount
  478. STDMETHODIMP CSystemClock::GetTypeInfoCount(UINT* pcInfo)
  479. {
  480. return E_NOTIMPL;
  481. }
  482. /////////////////////////////////////////////////////////////
  483. // CSystemClock::GetIDsOfNames
  484. STDMETHODIMP CSystemClock::GetIDsOfNames(REFIID riid,
  485. OLECHAR** rgszNames,
  486. UINT cNames,
  487. LCID lcid,
  488. DISPID* rgDispId)
  489. {
  490. HRESULT hr = DISP_E_UNKNOWNNAME;
  491. rgDispId[0] = DISPID_UNKNOWN;
  492. for (int iX = 0; iX < sizeof(SystemClockExternalInterface)/sizeof(DISPATCHLIST); iX ++)
  493. {
  494. if(lstrcmp(SystemClockExternalInterface[iX].szName, rgszNames[0]) == 0)
  495. {
  496. rgDispId[0] = SystemClockExternalInterface[iX].dwDispID;
  497. hr = NOERROR;
  498. break;
  499. }
  500. }
  501. // Set the disid's for the parameters
  502. if (cNames > 1)
  503. {
  504. // Set a DISPID for function parameters
  505. for (UINT i = 1; i < cNames ; i++)
  506. rgDispId[i] = DISPID_UNKNOWN;
  507. }
  508. return hr;
  509. }
  510. /////////////////////////////////////////////////////////////
  511. // CSystemClock::Invoke
  512. HRESULT CSystemClock::Invoke
  513. (
  514. DISPID dispidMember,
  515. REFIID riid,
  516. LCID lcid,
  517. WORD wFlags,
  518. DISPPARAMS* pdispparams,
  519. VARIANT* pvarResult,
  520. EXCEPINFO* pexcepinfo,
  521. UINT* puArgErr
  522. )
  523. {
  524. HRESULT hr = S_OK;
  525. switch(dispidMember)
  526. {
  527. case DISPID_SYSTEMCLOCK_INIT:
  528. {
  529. TRACE(L"DISPID_SYSTEMCLOCK_INIT\n");
  530. InitSystemClock();
  531. break;
  532. }
  533. case DISPID_SYSTEMCLOCK_GETALLTIMEZONES:
  534. {
  535. TRACE(L"DISPID_SYSTEMCLOCK_GETALLTIMEZONES\n");
  536. if (m_cNumTimeZones && m_szTimeZoneOptionStrs && pvarResult) {
  537. VariantInit(pvarResult);
  538. V_VT(pvarResult) = VT_BSTR;
  539. pvarResult->bstrVal = SysAllocString(m_szTimeZoneOptionStrs);
  540. }
  541. break;
  542. }
  543. case DISPID_SYSTEMCLOCK_GETTIMEZONEIDX:
  544. {
  545. TRACE(L"DISPID_SYSTEMCLOCK_GETTIMEZONEIDX\n");
  546. if(pvarResult==NULL)
  547. break;
  548. VariantInit(pvarResult);
  549. V_VT(pvarResult) = VT_I4;
  550. V_I4(pvarResult) = m_uCurTimeZoneIdx;
  551. break;
  552. }
  553. case DISPID_SYSTEMCLOCK_SETTIMEZONEIDX:
  554. {
  555. TRACE(L"DISPID_SYSTEMCLOCK_SETTIMEZONEIDX\n");
  556. if(pdispparams && (&pdispparams[0].rgvarg[0]))
  557. {
  558. BOOL bReboot;
  559. m_uCurTimeZoneIdx = pdispparams[0].rgvarg[0].iVal;
  560. SetTheTimezone(m_bSetAutoDaylightMode,
  561. &m_pTimeZoneArr[m_uCurTimeZoneIdx]
  562. );
  563. if (pvarResult != NULL)
  564. {
  565. WCHAR szWindowsRoot[MAX_PATH];
  566. BOOL bCheckTimezone = TRUE;
  567. VariantInit(pvarResult);
  568. V_VT(pvarResult) = VT_BOOL;
  569. V_BOOL(pvarResult) = Bool2VarBool(FALSE);
  570. if (GetWindowsDirectory(szWindowsRoot, MAX_PATH))
  571. {
  572. // If Windows is installed on an NTFS volume,
  573. // no need to check the timezones and evtl reboot
  574. // The problem we are working around only exists on FAT
  575. bCheckTimezone = !(IsDriveNTFS(szWindowsRoot[0]));
  576. }
  577. if (bCheckTimezone)
  578. {
  579. // If the name of the default time zone the now selected one is different, we need a reboot.
  580. // Problem with fonts, if the time zone changes.
  581. V_BOOL(pvarResult) = Bool2VarBool(CSTR_EQUAL!=CompareString(LOCALE_USER_DEFAULT, 0,
  582. DefltZoneKeyValue, -1,
  583. m_pTimeZoneArr[m_uCurTimeZoneIdx].szStandardName, -1));
  584. }
  585. }
  586. }
  587. break;
  588. }
  589. case DISPID_SYSTEMCLOCK_GETAUTODAYLIGHT:
  590. {
  591. TRACE(L"DISPID_SYSTEMCLOCK_GETAUTODAYLIGHT\n");
  592. if(pvarResult==NULL)
  593. break;
  594. VariantInit(pvarResult);
  595. V_VT(pvarResult) = VT_BOOL;
  596. V_BOOL(pvarResult) = Bool2VarBool(m_bSetAutoDaylightMode);
  597. break;
  598. }
  599. case DISPID_SYSTEMCLOCK_GETDAYLIGHT_ENABLED:
  600. {
  601. TRACE(L"DISPID_SYSTEMCLOCK_GETDAYLIGHT_ENABLED\n");
  602. if(pvarResult==NULL)
  603. break;
  604. if(!(pdispparams && (&pdispparams[0].rgvarg[0])))
  605. {
  606. break;
  607. }
  608. DWORD iTzIdx = pdispparams[0].rgvarg[0].iVal;
  609. if(iTzIdx >= m_cNumTimeZones)
  610. {
  611. break;
  612. }
  613. // if either daylight change date is invalid (0), no daylight savings time for that zone
  614. BOOL bEnabled = !((m_pTimeZoneArr[iTzIdx].StandardDate.wMonth == 0) ||
  615. (m_pTimeZoneArr[iTzIdx].DaylightDate.wMonth == 0));
  616. VariantInit(pvarResult);
  617. V_VT(pvarResult) = VT_BOOL;
  618. V_BOOL(pvarResult) = Bool2VarBool(bEnabled);
  619. break;
  620. }
  621. case DISPID_SYSTEMCLOCK_GETTIMEZONEWASPRESET:
  622. {
  623. TRACE(L"DISPID_SYSTEMCLOCK_GETTIMEZONEWASPRESET\n");
  624. if(pvarResult==NULL)
  625. break;
  626. VariantInit(pvarResult);
  627. V_VT(pvarResult) = VT_BOOL;
  628. V_BOOL(pvarResult) = Bool2VarBool(m_bTimeZonePreset);
  629. break;
  630. }
  631. case DISPID_SYSTEMCLOCK_SETAUTODAYLIGHT:
  632. {
  633. TRACE(L"DISPID_SYSTEMCLOCK_SETAUTODAYLIGHT\n");
  634. if(!(pdispparams && (&pdispparams[0].rgvarg[0])))
  635. {
  636. break;
  637. }
  638. m_bSetAutoDaylightMode = pdispparams[0].rgvarg[0].boolVal;
  639. break;
  640. }
  641. case DISPID_SYSTEMCLOCK_SETTIMEZONE:
  642. {
  643. TRACE(L"DISPID_SYSTEMCLOCK_SETTIMEZONE\n");
  644. if(pdispparams && &pdispparams[0].rgvarg[0])
  645. set_TimeZone(pdispparams[0].rgvarg[0].bstrVal);
  646. break;
  647. }
  648. case DISPID_SYSTEMCLOCK_SETTIME:
  649. {
  650. TRACE(L"DISPID_SYSTEMCLOCK_SETTIME\n");
  651. if(pdispparams &&
  652. &pdispparams[0].rgvarg[0] &&
  653. &pdispparams[0].rgvarg[1] &&
  654. &pdispparams[0].rgvarg[2]
  655. )
  656. {
  657. set_Time(pdispparams[0].rgvarg[2].iVal,
  658. pdispparams[0].rgvarg[1].iVal,
  659. pdispparams[0].rgvarg[0].iVal);
  660. }
  661. break;
  662. }
  663. case DISPID_SYSTEMCLOCK_SETDATE:
  664. {
  665. TRACE(L"DISPID_SYSTEMCLOCK_SETDATE\n");
  666. if(pdispparams &&
  667. &pdispparams[0].rgvarg[0] &&
  668. &pdispparams[0].rgvarg[1] &&
  669. &pdispparams[0].rgvarg[2]
  670. )
  671. {
  672. set_Date(pdispparams[0].rgvarg[2].iVal,
  673. pdispparams[0].rgvarg[1].iVal,
  674. pdispparams[0].rgvarg[0].iVal);
  675. }
  676. break;
  677. }
  678. default:
  679. {
  680. hr = DISP_E_MEMBERNOTFOUND;
  681. break;
  682. }
  683. }
  684. return hr;
  685. }