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.

995 lines
30 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000.
  5. //
  6. // File: lgplist.cxx
  7. //
  8. // Contents: Index server wide local/global property list class.
  9. //
  10. // History: 05 May 1997 Alanw Created
  11. // 27 Aug 1997 KrishnaN Moved from ixsso to querylib
  12. //
  13. //----------------------------------------------------------------------------
  14. #include <pch.cxx>
  15. #pragma hdrstop
  16. //-----------------------------------------------------------------------------
  17. // Include Files
  18. //-----------------------------------------------------------------------------
  19. #include <cidebug.hxx>
  20. #include <dynstack.hxx>
  21. #include <funypath.hxx>
  22. #include <dblink.hxx>
  23. #include <imprsnat.hxx>
  24. // class declaration
  25. CStaticPropertyList GlobalStaticList;
  26. CPropListFile * CLocalGlobalPropertyList::_pGlobalPropListFile = 0;
  27. CStaticMutexSem g_mtxFilePropList; // regulates access to the global file prop list.
  28. CRegChangeEvent CGlobalPropFileRefresher::_regChangeEvent( wcsRegCommonAdminTree, TRUE );
  29. WCHAR CGlobalPropFileRefresher::_wcsFileName[];
  30. FILETIME CGlobalPropFileRefresher::_ftFile;
  31. DWORD CGlobalPropFileRefresher::_dwLastCheckMoment;
  32. BOOL CGlobalPropFileRefresher::_fInited = FALSE;
  33. HKEY CGlobalPropFileRefresher::_hKey;
  34. LONG CGlobalPropFileRefresher::_lRegReturn;
  35. CGlobalPropFileRefresher gRefresher;
  36. //+-------------------------------------------------------------------------
  37. //
  38. // Member: CDefColumnRegEntry::CDefColumnRegEntry, public
  39. //
  40. // Synopsis: Constructor for registry param object
  41. //
  42. // Arguments: [pwcName] - 0 or name of the catalog from the registry
  43. //
  44. // History: 12-Oct-96 dlee Created
  45. //
  46. //--------------------------------------------------------------------------
  47. CDefColumnRegEntry::CDefColumnRegEntry()
  48. {
  49. // set default
  50. wcscpy( _awcDefaultColumnFile, L"" );
  51. } //CDefColumnRegEntry
  52. //+-------------------------------------------------------------------------
  53. //
  54. // Member: CDefColumnRegEntry::Refresh, public
  55. //
  56. // Synopsis: Reads the values from the registry
  57. //
  58. // History: 12-Oct-96 dlee Added header, reorganized
  59. //
  60. //--------------------------------------------------------------------------
  61. void CDefColumnRegEntry::Refresh( BOOL fUseDefaultsOnFailure )
  62. {
  63. TRY
  64. {
  65. // Query the registry.
  66. CRegAccess regAdmin( RTL_REGISTRY_CONTROL, wcsRegCommonAdmin );
  67. XPtrST<WCHAR> xRegValue(regAdmin.Read(wcsDefaultColumnFile, L""));
  68. wcsncpy( _awcDefaultColumnFile, xRegValue.GetPointer(), MAX_PATH );
  69. }
  70. CATCH (CException, e)
  71. {
  72. // Only store defaults when told to do so -- the params
  73. // are still in good shape at this point and are more
  74. // accurate than the default settings.
  75. if ( fUseDefaultsOnFailure )
  76. wcscpy( _awcDefaultColumnFile, L"" );
  77. }
  78. END_CATCH
  79. } //Refresh
  80. //-----------------------------------------------------------------------------
  81. //
  82. // Member: CPropListFile::CPropListFile
  83. //
  84. // Synopsis: Constructor of a property list from a file
  85. //
  86. // Arguments: [pDefaultList] -- The default property list
  87. // [fDynamicRefresh] -- True, if list should be dynamically
  88. // refreshed when file changes.
  89. // [pwcPropFile] -- The property file. If this is null,
  90. // use the registry.
  91. // [ulCodePage] -- Codepage to interpret the property list.
  92. //
  93. // Notes:
  94. //
  95. // History: 08 Sep 1997 KrishnaN Created
  96. //
  97. //-----------------------------------------------------------------------------
  98. CPropListFile::CPropListFile( CEmptyPropertyList *pDefaultList,
  99. BOOL fDynamicRefresh,
  100. WCHAR const * pwcPropFile,
  101. ULONG ulCodePage ) :
  102. CCombinedPropertyList(pDefaultList, ulCodePage),
  103. _scError( S_OK ),
  104. _iErrorLine( 0 ),
  105. _xErrorFile( 0 ),
  106. _ulCodePage( ulCodePage ),
  107. _fDynamicRefresh( fDynamicRefresh ),
  108. _dwLastCheckMoment( GetTickCount() )
  109. {
  110. if (pwcPropFile)
  111. Load(pwcPropFile);
  112. else
  113. {
  114. WCHAR wszFile[MAX_PATH+1];
  115. _RegParams.GetDefaultColumnFile( wszFile, MAX_PATH );
  116. Load(wszFile);
  117. }
  118. }
  119. CPropListFile::~CPropListFile()
  120. {
  121. ClearList();
  122. }
  123. //+---------------------------------------------------------------------------
  124. //
  125. // Member: CPropListFile::Load - public
  126. //
  127. // Synopsis: Loads the file into the property list.
  128. //
  129. // Arguments: [pwszFile] -- File name for property definitions
  130. //
  131. // History: 06 May 1997 AlanW Created
  132. //
  133. //----------------------------------------------------------------------------
  134. void CPropListFile::Load(WCHAR const * const pwszFile )
  135. {
  136. if (0 == pwszFile || 0 == *pwszFile)
  137. return;
  138. CImpersonateSystem impersonateSystem;
  139. // prevent multiple loads at the same time
  140. CLock lock(_mtx);
  141. // Erase any previous error settings.
  142. _scError = S_OK;
  143. _iErrorLine = 0;
  144. _xErrorFile.Free();
  145. SCODE sc = GetLastWriteTime(pwszFile, _ftFile);
  146. if (S_OK == sc)
  147. {
  148. // ParseNameFile should not throw exceptions.
  149. sc = ParseNameFile( pwszFile );
  150. }
  151. else
  152. sc = QPLIST_E_CANT_OPEN_FILE;
  153. if (FAILED(sc))
  154. {
  155. qutilDebugOut(( DEB_WARN, "Can't open column file named %ws\n", pwszFile ));
  156. _scError = sc;
  157. _iErrorLine = 0;
  158. if (0 == _xErrorFile.GetPointer())
  159. {
  160. WCHAR * pwcErrorFile = new WCHAR[wcslen(pwszFile)+1];
  161. wcscpy(pwcErrorFile, pwszFile);
  162. _xErrorFile.Set( pwcErrorFile );
  163. }
  164. }
  165. }
  166. //+---------------------------------------------------------------------------
  167. //
  168. // Member: CPropListFile::IsMapUpToDate - public
  169. //
  170. // Synopsis: Determines if the file is still vaid, or if it has
  171. // changed since it was last read.
  172. //
  173. // History: 06 May 1997 AlanW Created
  174. //
  175. //----------------------------------------------------------------------------
  176. SCODE CPropListFile::IsMapUpToDate()
  177. {
  178. //
  179. // Has the file been modified since last loaded?
  180. //
  181. FILETIME ft;
  182. SCODE sc = GetLastWriteTime(_xFileName.GetPointer(), ft);
  183. if (FAILED(sc))
  184. return E_HANDLE;
  185. if ( (_ftFile.dwLowDateTime == ft.dwLowDateTime) &&
  186. (_ftFile.dwHighDateTime == ft.dwHighDateTime) )
  187. return S_OK;
  188. return S_FALSE;
  189. }
  190. //+---------------------------------------------------------------------------
  191. //
  192. // Method: CPropListFile::GetLastWriteTime, static
  193. //
  194. // Purpose: Gets the last change time of the file specified
  195. //
  196. // Arguments: [wcsFileName] - name of file to get last write time of
  197. // [ftLastWrite] - on return, last mod. time of file
  198. //
  199. // Returns: SCODE - S_OK if successful.
  200. //
  201. // History: 96/Jan/23 DwightKr Created
  202. // 96/Mar/13 DwightKr Changed to use GetFileAttributesEx()
  203. //
  204. //----------------------------------------------------------------------------
  205. SCODE CPropListFile::GetLastWriteTime( WCHAR const * wcsFileName,
  206. FILETIME & ftLastWrite )
  207. {
  208. if ( 0 == wcsFileName )
  209. return E_INVALIDARG;
  210. WIN32_FIND_DATA ffData;
  211. if ( !GetFileAttributesEx( wcsFileName, GetFileExInfoStandard, &ffData ) )
  212. {
  213. ULONG error = GetLastError();
  214. qutilDebugOut(( DEB_IERROR,
  215. "Unable to GetFileAttributesEx(%ws) GetLastError=0x%x\n",
  216. wcsFileName,
  217. error ));
  218. return HRESULT_FROM_WIN32(error);
  219. }
  220. ftLastWrite = ffData.ftLastWriteTime;
  221. return S_OK;
  222. }
  223. //+---------------------------------------------------------------------------
  224. //
  225. // Member: CPropListfile::ParseNameFile, public
  226. //
  227. // Synopsis: Parses the given file name and creates a list of 'friendly
  228. // name' to CDbColId equivalences.
  229. //
  230. // Arguments: szFileName -- name of the file to parse
  231. //
  232. // History: 17-May-94 t-jeffc Created.
  233. //
  234. //----------------------------------------------------------------------------
  235. SCODE CPropListFile::ParseNameFile( WCHAR const * wcsFileName )
  236. {
  237. int iLength;
  238. BOOL fRememberFileName = FALSE;
  239. if( wcsFileName == 0 )
  240. {
  241. // use the last specified property file
  242. if( !_xFileName.IsNull() )
  243. {
  244. wcsFileName = _xFileName.GetPointer();
  245. iLength = wcslen( wcsFileName ) + 1;
  246. }
  247. else
  248. return QPLIST_E_CANT_OPEN_FILE;
  249. }
  250. else
  251. {
  252. // make a copy of the file name
  253. _xFileName.Free();
  254. iLength = wcslen( wcsFileName ) + 1;
  255. _xFileName.Set( new WCHAR[ iLength ] );
  256. memcpy( _xFileName.GetPointer(), wcsFileName, iLength * sizeof WCHAR );
  257. }
  258. CSFile pfile( OpenFileFromPath( wcsFileName ) );
  259. if( pfile == 0 )
  260. return QPLIST_E_CANT_OPEN_FILE;
  261. //
  262. // Process a line at a time, skip ahead until we find the [Names]
  263. // or [Query] section and process lines within that section only.
  264. //
  265. BOOL fNameSection = FALSE;
  266. SCODE sc = S_OK;
  267. int iLine = 0;
  268. for( ;; )
  269. {
  270. TRY
  271. {
  272. iLine++;
  273. // line buffers
  274. char szLine[ MAX_LINE_LENGTH ];
  275. WCHAR wcsLine[ MAX_LINE_LENGTH ];
  276. if( !fgets( szLine, MAX_LINE_LENGTH, pfile ) )
  277. {
  278. if( feof( pfile ) )
  279. break;
  280. THROW( CPListException( QPLIST_E_READ_ERROR, iLine ) );
  281. }
  282. //
  283. // Skip ahead until we find a [Names] section
  284. //
  285. if ( *szLine == '[' )
  286. {
  287. if ( _strnicmp(szLine, "[Names]", 7) == 0 )
  288. {
  289. fNameSection = TRUE;
  290. continue;
  291. }
  292. else
  293. {
  294. fNameSection = FALSE;
  295. continue;
  296. }
  297. }
  298. else if ( *szLine == '#' )
  299. {
  300. continue;
  301. }
  302. if ( fNameSection )
  303. {
  304. if( MultiByteToWideChar( _ulCodePage,
  305. MB_COMPOSITE,
  306. szLine,
  307. -1,
  308. wcsLine,
  309. MAX_LINE_LENGTH )
  310. == 0 )
  311. {
  312. THROW( CException() );
  313. }
  314. CQueryScanner scanner( wcsLine, FALSE );
  315. XPtr<CPropEntry> propentry;
  316. CPropertyList::ParseOneLine( scanner, iLine, propentry );
  317. if (propentry.GetPointer())
  318. {
  319. AddEntry( propentry.GetPointer(), iLine );
  320. propentry.Acquire();
  321. }
  322. }
  323. }
  324. CATCH( CPListException, e )
  325. {
  326. qutilDebugOut(( DEB_WARN,
  327. "Plist exception %08x caught parsing default column file at line %d. Line ignored.\n",
  328. e.GetErrorCode(), e.GetLine() ));
  329. sc = _scError = e.GetErrorCode();
  330. _iErrorLine = e.GetLine();
  331. fRememberFileName = TRUE;
  332. }
  333. AND_CATCH ( CException, e )
  334. {
  335. qutilDebugOut(( DEB_WARN,
  336. "Exception caught parsing default column file %08x\n",
  337. e.GetErrorCode() ));
  338. sc = _scError = e.GetErrorCode();
  339. fRememberFileName = TRUE;
  340. }
  341. END_CATCH
  342. if (fRememberFileName && 0 == _xErrorFile.GetPointer())
  343. {
  344. fRememberFileName = FALSE;
  345. WCHAR * pwcErrorFile = new WCHAR[wcslen(wcsFileName)+1];
  346. wcscpy(pwcErrorFile, wcsFileName);
  347. _xErrorFile.Set( pwcErrorFile );
  348. }
  349. }
  350. return sc;
  351. }
  352. //+---------------------------------------------------------------------------
  353. //
  354. // Member: CPropListfile::CheckError, public
  355. //
  356. // Synopsis: Checks if there was an error in the parsing of the file.
  357. //
  358. // Arguments: iLine -- error line number returned here.
  359. // ppFile -- file name returned here. can be 0 if not needed.
  360. //
  361. // History: 17-Sep-97 KrishnaN Created.
  362. //
  363. //----------------------------------------------------------------------------
  364. SCODE CPropListFile::CheckError( ULONG & iLine, WCHAR ** ppFile )
  365. {
  366. iLine = _iErrorLine;
  367. if (ppFile)
  368. *ppFile = _xErrorFile.GetPointer();
  369. return _scError;
  370. }
  371. //+---------------------------------------------------------------------------
  372. //
  373. // Member: CPropListfile::Refresh, private
  374. //
  375. // Synopsis: Reloads the property list if prop. file has been modified.
  376. //
  377. // History: 15-Sep-97 KrishnaN Created.
  378. //
  379. //----------------------------------------------------------------------------
  380. void CPropListFile::Refresh()
  381. {
  382. if (!_fDynamicRefresh)
  383. return;
  384. // Don't check more than once in a few seconds
  385. if (abs(GetTickCount() - _dwLastCheckMoment) < REFRESH_INTERVAL)
  386. return;
  387. _dwLastCheckMoment = GetTickCount();
  388. if (S_OK != IsMapUpToDate())
  389. {
  390. //
  391. // Reload.
  392. //
  393. ClearList();
  394. Load(_xFileName.GetPointer());
  395. }
  396. }
  397. //+---------------------------------------------------------------------------
  398. //
  399. // Member: CCombinedPropertyList::Find, public
  400. //
  401. // Synopsis: Attempt to find an entry in the list.
  402. //
  403. // Arguments: wcsName -- friendly property name to find
  404. //
  405. // Returns a pointer to the CPropEntry if found, 0 otherwise.
  406. //
  407. // History: 17-May-94 t-jeffc Created.
  408. // 28-Aug-97 KrishnaN modified.
  409. //
  410. //----------------------------------------------------------------------------
  411. CPropEntry const * CCombinedPropertyList::Find( WCHAR const * wcsName )
  412. {
  413. if( 0 == wcsName )
  414. return 0;
  415. //
  416. // First look in the default list, and if not found, look
  417. // in the overrides.
  418. //
  419. CPropEntry const * ppentry = _xDefaultList->Find(wcsName);
  420. if (ppentry)
  421. return ppentry;
  422. return (_xOverrideList.GetPointer() ? _xOverrideList->Find(wcsName) : 0);
  423. }
  424. //+---------------------------------------------------------------------------
  425. //
  426. // Member: CCombinedPropertyList::Next, public
  427. //
  428. // Synopsis: Gets the next property during an enumeration
  429. //
  430. // Returns: The next property entry or 0 for end of enumeration
  431. //
  432. // History: 21-Jul-97 dlee Moved from .hxx and added header
  433. //
  434. //----------------------------------------------------------------------------
  435. CPropEntry const * CCombinedPropertyList::Next()
  436. {
  437. //
  438. // First look in the static list, and if not found, look in the overrides.
  439. //
  440. CPropEntry const *pEntry = 0;
  441. if (!_fOverrides)
  442. pEntry = _xDefaultList->Next();
  443. if (pEntry)
  444. return pEntry;
  445. _fOverrides = TRUE;
  446. return (_xOverrideList.GetPointer() ? _xOverrideList->Next() : 0);
  447. } //Next
  448. //+---------------------------------------------------------------------------
  449. //
  450. // Member: CCombinedPropertyList::InitIterator, public
  451. //
  452. // Synopsis: Initialize the iterator
  453. //
  454. // History: 29-Aug-97 KrishnaN Created
  455. //
  456. //----------------------------------------------------------------------------
  457. void CCombinedPropertyList::InitIterator()
  458. {
  459. // causes the default list to be iterated before the overrides
  460. _fOverrides = FALSE;
  461. // Initialize the iterators of the two lists
  462. _xDefaultList->InitIterator();
  463. if (_xOverrideList.GetPointer())
  464. _xOverrideList->InitIterator();
  465. } //InitIterator
  466. //+---------------------------------------------------------------------------
  467. //
  468. // Member: CCombinedPropertyList::AddEntry, private
  469. //
  470. // Synopsis: Adds a CPropEntry to the overriding list. Verifies that the name
  471. // isn't already in the default list or the overriding list.
  472. //
  473. // Arguments: ppentryNew -- pointer to the CPropEntry to add
  474. // iLine -- line number we're parsing
  475. //
  476. // History: 11-Sep-97 KrishnaN Created.
  477. //
  478. //----------------------------------------------------------------------------
  479. void CCombinedPropertyList::AddEntry( CPropEntry * ppentryNew, int iLine )
  480. {
  481. // protect _xOverrideList
  482. CLock lock(_mtxAdd);
  483. if (0 == _xOverrideList.GetPointer())
  484. {
  485. _xOverrideList.Set(new CPropertyList(_ulCodePage));
  486. }
  487. //
  488. // We do not allow entries in the override list that have the same name
  489. // as the default list.
  490. //
  491. if( _xDefaultList->Find( ppentryNew->GetName() ) ||
  492. _xOverrideList->Find( ppentryNew->GetName() ) )
  493. THROW( CPListException( QPLIST_E_DUPLICATE, iLine ) );
  494. _xOverrideList->AddEntry(ppentryNew, iLine);
  495. }
  496. //+---------------------------------------------------------------------------
  497. //
  498. // Member: CCombinedPropertyList::ClearList, public
  499. //
  500. // Synopsis: Frees the memory used by the list.
  501. //
  502. // History: 11-Sep-97 KrishnaN Created.
  503. //
  504. //----------------------------------------------------------------------------
  505. void CCombinedPropertyList::ClearList()
  506. {
  507. // protect _xOverrideList
  508. CLock lock(_mtxAdd);
  509. //
  510. // Just free it now. It will be created, if necessary,
  511. // on AddEntry().
  512. //
  513. _xOverrideList.Free();
  514. }
  515. //+---------------------------------------------------------------------------
  516. //
  517. // Member: CCombinedPropertyList::SetDefaultList, public
  518. //
  519. // Synopsis: Sets the default list.
  520. //
  521. // Arguments: pDefaultList -- The list to set as default list.
  522. //
  523. // History: 11-Sep-97 KrishnaN Created.
  524. //
  525. //----------------------------------------------------------------------------
  526. void CCombinedPropertyList::SetDefaultList(CEmptyPropertyList *pDefaultList)
  527. {
  528. Win4Assert(pDefaultList);
  529. // Jettison any existing property list
  530. _xDefaultList.Free();
  531. _xDefaultList.Set(pDefaultList);
  532. pDefaultList->AddRef();
  533. }
  534. //+---------------------------------------------------------------------------
  535. //
  536. // Member: CCombinedPropertyList::GetCount, public
  537. //
  538. // Synopsis: Returns cardinality of list.
  539. //
  540. // History: 11-Sep-97 KrishnaN Created.
  541. //
  542. //----------------------------------------------------------------------------
  543. ULONG CCombinedPropertyList::GetCount()
  544. {
  545. ULONG ulTotal = _xDefaultList->GetCount();
  546. if (_xOverrideList.GetPointer())
  547. {
  548. ulTotal += _xOverrideList->GetCount();
  549. }
  550. return ulTotal;
  551. }
  552. //+---------------------------------------------------------------------------
  553. //
  554. // Member: CCombinedPropertyList::GetAllEntries, public
  555. //
  556. // Synopsis: Returns cardinality of list.
  557. //
  558. // History: 11-Sep-97 KrishnaN Created.
  559. //
  560. //----------------------------------------------------------------------------
  561. SCODE CCombinedPropertyList::GetAllEntries(CPropEntry **ppPropEntries,
  562. ULONG ulMaxCount)
  563. {
  564. ULONG ulSize = _xDefaultList->GetCount();
  565. // get the first set of entries from the default list
  566. SCODE sc = _xDefaultList->GetAllEntries(ppPropEntries, min(ulSize, ulMaxCount));
  567. // get the remaining entries from the override list
  568. if (S_OK == sc && ulMaxCount > ulSize && _xOverrideList.GetPointer())
  569. {
  570. sc = _xOverrideList->GetAllEntries(ppPropEntries+ulSize, ulMaxCount-ulSize);
  571. }
  572. return sc;
  573. }
  574. //-----------------------------------------------------------------------------
  575. //
  576. // Member: CLocalGlobalPropertyList::CLocalGlobalPropertyList
  577. //
  578. // Synopsis: Constructor of a overridable file based property list.
  579. // The file name will always be obtained through the registry.
  580. //
  581. // Arguments: [ulCodePage] -- Codepage to interpret the property list.
  582. //
  583. // Notes:
  584. //
  585. // History: 08 Sep 1997 KrishnaN Created
  586. //
  587. //-----------------------------------------------------------------------------
  588. CLocalGlobalPropertyList::CLocalGlobalPropertyList( ULONG ulCodePage ) :
  589. CCombinedPropertyList(ulCodePage),
  590. _ulCodePage( ulCodePage ),
  591. _dwLastCheckMoment( GetTickCount() ),
  592. _mtx()
  593. {
  594. XInterface<CPropListFile> xPropListFile(GetGlobalPropListFile());
  595. SetDefaultList(xPropListFile.GetPointer());
  596. }
  597. //-----------------------------------------------------------------------------
  598. //
  599. // Member: CLocalGlobalPropertyList::CLocalGlobalPropertyList
  600. //
  601. // Synopsis: Constructor of a overridable file based property list.
  602. // The file name will always be obtained through the registry.
  603. //
  604. // Arguments: [pDefaultList] -- The default property list
  605. // [fDynamicRefresh] -- True, if list should be dynamically
  606. // refreshed when file changes.
  607. // [pwcPropFile] -- The property file. If this is null,
  608. // use the registry.
  609. // [ulCodePage] -- Codepage to interpret the property list.
  610. //
  611. // Notes: This constructor is used by clients who use their own file based
  612. // list instead of using the registry based file.
  613. //
  614. // History: 08 Sep 1997 KrishnaN Created
  615. //
  616. //-----------------------------------------------------------------------------
  617. CLocalGlobalPropertyList::CLocalGlobalPropertyList
  618. (CEmptyPropertyList *pDefaultList,
  619. BOOL fDynamicRefresh,
  620. WCHAR const * pwcsPropFile,
  621. ULONG ulCodePage) :
  622. CCombinedPropertyList(ulCodePage),
  623. _ulCodePage( ulCodePage ),
  624. _dwLastCheckMoment( GetTickCount() ),
  625. _mtx()
  626. {
  627. XInterface<CPropListFile> xPropListFile(
  628. new CPropListFile(pDefaultList,
  629. fDynamicRefresh,
  630. pwcsPropFile,
  631. ulCodePage));
  632. SetDefaultList(xPropListFile.GetPointer());
  633. }
  634. //+---------------------------------------------------------------------------
  635. //
  636. // Member: CLocalGlobalPropertyList::IsMapUpToDate - public
  637. //
  638. // Synopsis: Determines if the file is still valid, or if it has
  639. // changed since it was last read.
  640. //
  641. // History: 06 May 1997 AlanW Created
  642. //
  643. //----------------------------------------------------------------------------
  644. SCODE CLocalGlobalPropertyList::IsMapUpToDate()
  645. {
  646. ULONG cchRequired = _RegParams.GetDefaultColumnFile( 0, 0 );
  647. WCHAR wszFile[MAX_PATH + 1];
  648. wszFile[0] = 0;
  649. if ( 0 != cchRequired )
  650. {
  651. _RegParams.GetDefaultColumnFile( wszFile, MAX_PATH );
  652. }
  653. //
  654. // If the current file and the one in the registry are not the same,
  655. // we are outdated.
  656. //
  657. if (0 != _wcsicmp(_xFileName.GetPointer(), wszFile))
  658. return S_FALSE;
  659. //
  660. // The filelist takes care of file modifications, so ask it
  661. // directly if it is up to date.
  662. //
  663. return GetDefaultList().IsMapUpToDate();
  664. }
  665. //+---------------------------------------------------------------------------
  666. //
  667. // Member: CLocalGlobalPropertyList::CheckError, public
  668. //
  669. // Synopsis: Checks if there was an error in the parsing of the file.
  670. //
  671. // Arguments: iLine -- error line number returned here.
  672. // ppFile -- file name returned here. can be 0 if not needed.
  673. //
  674. // History: 17-Sep-97 KrishnaN Created.
  675. //
  676. //----------------------------------------------------------------------------
  677. SCODE CLocalGlobalPropertyList::CheckError( ULONG & iLine, WCHAR ** ppFile )
  678. {
  679. return ((CPropListFile &)GetDefaultList()).CheckError(iLine, ppFile);
  680. }
  681. //+---------------------------------------------------------------------------
  682. //
  683. // Member: CLocalGlobalPropertyList::Load - public
  684. //
  685. // Synopsis: Loads the file into the property list.
  686. //
  687. // Arguments: [pwszFile] -- File name for property definitions
  688. //
  689. // History: 19 Sep 1997 KrishnaN Created
  690. //
  691. //----------------------------------------------------------------------------
  692. void CLocalGlobalPropertyList::Load(WCHAR const * const pwszFile )
  693. {
  694. ((CPropListFile &)GetDefaultList()).Load(pwszFile);
  695. }
  696. // Miscellaneous
  697. CStaticPropertyList * GetGlobalStaticPropertyList()
  698. {
  699. GlobalStaticList.AddRef();
  700. return &GlobalStaticList;
  701. }
  702. //
  703. // Return an AddRef'd global prop file list. The caller will release
  704. // when done using the global prop file list.
  705. //
  706. CPropListFile * GetGlobalPropListFile()
  707. {
  708. CImpersonateSystem impersonateSystem;
  709. CLock lock(g_mtxFilePropList);
  710. if (!CLocalGlobalPropertyList::_pGlobalPropListFile)
  711. {
  712. // The global property list will be controlled by CLocalGlobalPropertyList, so
  713. // we disable its ability to refresh dynamically.
  714. CLocalGlobalPropertyList::_pGlobalPropListFile =
  715. new CPropListFile(GetGlobalStaticPropertyList(), FALSE);
  716. }
  717. else
  718. {
  719. //
  720. // If the refresher replaces the global property list, that would
  721. // AddRef the newly created global proplist, so we should not AddREf
  722. // again. If DoIt fails, no need to AddRef.
  723. //
  724. if (!gRefresher.DoIt())
  725. CLocalGlobalPropertyList::_pGlobalPropListFile->AddRef();
  726. }
  727. Win4Assert(CLocalGlobalPropertyList::_pGlobalPropListFile);
  728. return CLocalGlobalPropertyList::_pGlobalPropListFile;
  729. }
  730. //+---------------------------------------------------------------------------
  731. //
  732. // Member: CreateNewGlobalPropFileList - public
  733. //
  734. // Synopsis: Creates a new global file based property list.
  735. //
  736. // History: 15-Sep-1997 KrishnaN Created
  737. //
  738. // Notes: This function replaces the global property file list so that newer
  739. // clients asking for the list will get an updated list (if the file has
  740. // been modified or replaced.)
  741. //
  742. //----------------------------------------------------------------------------
  743. void CreateNewGlobalPropFileList(WCHAR CONST *wcsFileName)
  744. {
  745. CLock lock(g_mtxFilePropList);
  746. Win4Assert(CLocalGlobalPropertyList::_pGlobalPropListFile);
  747. // The global property list will be controlled by CLocalGlobalPropertyList, so
  748. // we disable its ability to refresh dynamically.
  749. CLocalGlobalPropertyList::_pGlobalPropListFile =
  750. new CPropListFile(GetGlobalStaticPropertyList(),
  751. FALSE,
  752. wcsFileName);
  753. }
  754. //+---------------------------------------------------------------------------
  755. //
  756. // Member: CGlobalPropFileRefresher::DoIt - public
  757. //
  758. // Synopsis: Creates a new global file based property list if necessary.
  759. //
  760. // Returns: True if refresh happened. False otherwise.
  761. //
  762. // History: 15-Sep-1997 KrishnaN Created
  763. //
  764. // Notes: This function monitors the registry and the file so the list
  765. // can be updated if the underlying property file changes.
  766. //
  767. //----------------------------------------------------------------------------
  768. BOOL CGlobalPropFileRefresher::DoIt()
  769. {
  770. //
  771. // We don't need to lock this because currently it is only
  772. // being called after obtaining a lock elsewhere. If that
  773. // changes, then a lock may be needed here.
  774. //
  775. // Don't check more than once in a few seconds
  776. if (abs(GetTickCount() - _dwLastCheckMoment) < REFRESH_INTERVAL)
  777. return FALSE;
  778. CImpersonateSystem impersonateSystem;
  779. if (!_fInited)
  780. Init();
  781. BOOL fRefresh = FALSE;
  782. _dwLastCheckMoment = GetTickCount();
  783. // First check the registry, then check the file itself
  784. ULONG res = WaitForSingleObject( _regChangeEvent.GetEventHandle(), 0 );
  785. if (WAIT_OBJECT_0 == res)
  786. {
  787. _regChangeEvent.Reset();
  788. // the registry changed, but the value may not have. check that.
  789. WCHAR wszFile[MAX_PATH];
  790. GetDefaultColumnFile(wszFile);
  791. // Are the file names the same?
  792. if (0 != _wcsicmp(wszFile, _wcsFileName))
  793. {
  794. wcscpy(_wcsFileName, wszFile);
  795. fRefresh = TRUE;
  796. GetLastWriteTime(_ftFile);
  797. }
  798. }
  799. if (! fRefresh)
  800. {
  801. FILETIME ft;
  802. GetLastWriteTime(ft);
  803. if ((_ftFile.dwLowDateTime != ft.dwLowDateTime) ||
  804. (_ftFile.dwHighDateTime != ft.dwHighDateTime) )
  805. {
  806. _ftFile = ft;
  807. fRefresh = TRUE;
  808. }
  809. }
  810. if (fRefresh)
  811. {
  812. // refresh
  813. CreateNewGlobalPropFileList(_wcsFileName);
  814. }
  815. return fRefresh;
  816. }
  817. //+---------------------------------------------------------------------------
  818. //
  819. // Member: CGlobalPropFileRefresher::Init - public
  820. //
  821. // Synopsis: Initializes this class.
  822. //
  823. // Returns: Nothing. Can throw.
  824. //
  825. // History: 15-Sep-1997 KrishnaN Created
  826. //
  827. //----------------------------------------------------------------------------
  828. void CGlobalPropFileRefresher::Init()
  829. {
  830. _regChangeEvent.Init();
  831. _lRegReturn = RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Root
  832. wcsRegCommonAdminSubKey,
  833. 0, // Reserved
  834. KEY_READ, // Access
  835. &_hKey); // Handle
  836. GetDefaultColumnFile(_wcsFileName);
  837. GetLastWriteTime(_ftFile);
  838. _fInited = TRUE;
  839. }