OSDN Git Service

Merge Myagi exe shell version to show overlay
[tortoisegit/TortoiseGitJp.git] / src / TortoiseShell / ShellCache.h
1 // TortoiseGit - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2003-2008 - Stefan Kueng\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #pragma once\r
20 #include "registry.h"\r
21 #include "Globals.h"\r
22 #include "GitAdminDir.h"\r
23 #include "Git.h"\r
24 \r
25 #define REGISTRYTIMEOUT 2000\r
26 #define EXCLUDELISTTIMEOUT 5000\r
27 #define ADMINDIRTIMEOUT 10000\r
28 #define DRIVETYPETIMEOUT 300000         // 5 min\r
29 #define NUMBERFMTTIMEOUT 300000\r
30 #define MENUTIMEOUT 100\r
31 \r
32 typedef CComCritSecLock<CComCriticalSection> Locker;\r
33 \r
34 /**\r
35  * \ingroup TortoiseShell\r
36  * Helper class which caches access to the registry. Also provides helper methods\r
37  * for checks against the settings stored in the registry.\r
38  */\r
39 class ShellCache\r
40 {\r
41 public:\r
42         enum CacheType\r
43         {\r
44                 none,\r
45                 exe,\r
46                 dll,\r
47                 dllFull,// same as dll except it uses commandline git tool with all status modes supported\r
48         };\r
49         ShellCache()\r
50         {\r
51                 cachetype = CRegStdWORD(_T("Software\\TortoiseGit\\CacheType"), GetSystemMetrics(SM_REMOTESESSION) ? dll : exe);\r
52                 showrecursive = CRegStdWORD(_T("Software\\TortoiseGit\\RecursiveOverlay"), TRUE);\r
53                 folderoverlay = CRegStdWORD(_T("Software\\TortoiseGit\\FolderOverlay"), TRUE);\r
54                 driveremote = CRegStdWORD(_T("Software\\TortoiseGit\\DriveMaskRemote"));\r
55                 drivefixed = CRegStdWORD(_T("Software\\TortoiseGit\\DriveMaskFixed"), TRUE);\r
56                 drivecdrom = CRegStdWORD(_T("Software\\TortoiseGit\\DriveMaskCDROM"));\r
57                 driveremove = CRegStdWORD(_T("Software\\TortoiseGit\\DriveMaskRemovable"));\r
58                 drivefloppy = CRegStdWORD(_T("Software\\TortoiseGit\\DriveMaskFloppy"));\r
59                 driveram = CRegStdWORD(_T("Software\\TortoiseGit\\DriveMaskRAM"));\r
60                 driveunknown = CRegStdWORD(_T("Software\\TortoiseGit\\DriveMaskUnknown"));\r
61                 excludelist = CRegStdString(_T("Software\\TortoiseGit\\OverlayExcludeList"));\r
62                 includelist = CRegStdString(_T("Software\\TortoiseGit\\OverlayIncludeList"));\r
63                 simplecontext = CRegStdWORD(_T("Software\\TortoiseGit\\SimpleContext"), FALSE);\r
64                 unversionedasmodified = CRegStdWORD(_T("Software\\TortoiseGit\\UnversionedAsModified"), FALSE);\r
65                 showunversionedoverlay = CRegStdWORD(_T("Software\\TortoiseGit\\ShowUnversionedOverlay"), TRUE);\r
66                 showignoredoverlay = CRegStdWORD(_T("Software\\TortoiseGit\\ShowIgnoredOverlay"), TRUE);\r
67                 getlocktop = CRegStdWORD(_T("Software\\TortoiseGit\\GetLockTop"), TRUE);\r
68                 excludedasnormal = CRegStdWORD(_T("Software\\TortoiseGit\\ShowExcludedAsNormal"), TRUE);\r
69                 cachetypeticker = GetTickCount();\r
70                 recursiveticker = cachetypeticker;\r
71                 folderoverlayticker = cachetypeticker;\r
72                 driveticker = cachetypeticker;\r
73                 drivetypeticker = cachetypeticker;\r
74                 langticker = cachetypeticker;\r
75                 columnrevformatticker = cachetypeticker;\r
76                 excludelistticker = cachetypeticker;\r
77                 includelistticker = cachetypeticker;\r
78                 simplecontextticker = cachetypeticker;\r
79                 unversionedasmodifiedticker = cachetypeticker;\r
80                 showunversionedoverlayticker = cachetypeticker;\r
81                 showignoredoverlayticker = cachetypeticker;\r
82                 admindirticker = cachetypeticker;\r
83                 columnseverywhereticker = cachetypeticker;\r
84                 getlocktopticker = cachetypeticker;\r
85                 excludedasnormalticker = cachetypeticker;\r
86                 excontextticker = cachetypeticker;\r
87                 menulayoutlow = CRegStdWORD(_T("Software\\TortoiseGit\\ContextMenuEntries"),              MENUCREATEREPOS|MENUCLONE|MENUUPDATE|MENUCOMMIT);\r
88                 menulayouthigh = CRegStdWORD(_T("Software\\TortoiseGit\\ContextMenuEntrieshigh"), (MENUCREATEREPOS|MENUCLONE|MENUUPDATE|MENUCOMMIT)>>32);\r
89                 menumasklow_lm = CRegStdWORD(_T("Software\\TortoiseGit\\ContextMenuEntriesMaskLow"), 0, FALSE, HKEY_LOCAL_MACHINE);\r
90                 menumaskhigh_lm = CRegStdWORD(_T("Software\\TortoiseGit\\ContextMenuEntriesMaskHigh"), 0, FALSE, HKEY_LOCAL_MACHINE);\r
91                 menumasklow_cu = CRegStdWORD(_T("Software\\TortoiseGit\\ContextMenuEntriesMaskLow"), 0);\r
92                 menumaskhigh_cu = CRegStdWORD(_T("Software\\TortoiseGit\\ContextMenuEntriesMaskHigh"), 0);\r
93                 langid = CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), 1033);\r
94                 blockstatus = CRegStdWORD(_T("Software\\TortoiseGit\\BlockStatus"), 0);\r
95                 columnseverywhere = CRegStdWORD(_T("Software\\TortoiseGit\\ColumnsEveryWhere"), FALSE);\r
96                 for (int i=0; i<27; i++)\r
97                 {\r
98                         drivetypecache[i] = (UINT)-1;\r
99                 }\r
100                 // A: and B: are floppy disks\r
101                 drivetypecache[0] = DRIVE_REMOVABLE;\r
102                 drivetypecache[1] = DRIVE_REMOVABLE;\r
103                 TCHAR szBuffer[5];\r
104                 columnrevformatticker = GetTickCount();\r
105                 SecureZeroMemory(&columnrevformat, sizeof(NUMBERFMT));\r
106                 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, &szDecSep[0], sizeof(szDecSep));\r
107                 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, &szThousandsSep[0], sizeof(szThousandsSep));\r
108                 columnrevformat.lpDecimalSep = szDecSep;\r
109                 columnrevformat.lpThousandSep = szThousandsSep;\r
110                 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, &szBuffer[0], sizeof(szBuffer));\r
111                 columnrevformat.Grouping = _ttoi(szBuffer);\r
112                 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_INEGNUMBER, &szBuffer[0], sizeof(szBuffer));\r
113                 columnrevformat.NegativeOrder = _ttoi(szBuffer);\r
114                 sAdminDirCacheKey.reserve(MAX_PATH);            // MAX_PATH as buffer reservation ok.\r
115                 nocontextpaths = CRegStdString(_T("Software\\TortoiseGit\\NoContextPaths"), _T(""));\r
116                 m_critSec.Init();\r
117         }\r
118         void ForceRefresh()\r
119         {\r
120                 cachetype.read();\r
121                 showrecursive.read();\r
122                 folderoverlay.read();\r
123                 driveremote.read();\r
124                 drivefixed.read();\r
125                 drivecdrom.read();\r
126                 driveremove.read();\r
127                 drivefloppy.read();\r
128                 driveram.read();\r
129                 driveunknown.read();\r
130                 excludelist.read();\r
131                 includelist.read();\r
132                 simplecontext.read();\r
133                 unversionedasmodified.read();\r
134                 showunversionedoverlay.read();\r
135                 showignoredoverlay.read();\r
136                 excludedasnormal.read();\r
137                 menulayoutlow.read();\r
138                 menulayouthigh.read();\r
139                 langid.read();\r
140                 blockstatus.read();\r
141                 columnseverywhere.read();\r
142                 getlocktop.read();\r
143                 menumasklow_lm.read();\r
144                 menumaskhigh_lm.read();\r
145                 menumasklow_cu.read();\r
146                 menumaskhigh_cu.read();\r
147                 nocontextpaths.read();\r
148         }\r
149         CacheType GetCacheType()\r
150         {\r
151                 if ((GetTickCount() - REGISTRYTIMEOUT) > cachetypeticker)\r
152                 {\r
153                         cachetypeticker = GetTickCount();\r
154                         cachetype.read();\r
155                 }\r
156                 //return CacheType(DWORD((cachetype)));\r
157                 /*TEMP: until TGitCache done*/\r
158 //              if(CGit::IsVista())\r
159 //                      return none;\r
160                 return CacheType(DWORD((cachetype))) == exe ? dll : CacheType(DWORD((cachetype)));\r
161         }\r
162         DWORD BlockStatus()\r
163         {\r
164                 if ((GetTickCount() - REGISTRYTIMEOUT) > blockstatusticker)\r
165                 {\r
166                         blockstatusticker = GetTickCount();\r
167                         blockstatus.read();\r
168                 }\r
169                 return (blockstatus);\r
170         }\r
171         unsigned __int64 GetMenuLayout()\r
172         {\r
173                 if ((GetTickCount() - REGISTRYTIMEOUT) > layoutticker)\r
174                 {\r
175                         layoutticker = GetTickCount();\r
176                         menulayoutlow.read();\r
177                         menulayouthigh.read();\r
178                 }\r
179                 unsigned __int64 temp = unsigned __int64(DWORD(menulayouthigh))<<32;\r
180                 temp |= unsigned __int64(DWORD(menulayoutlow));\r
181                 return temp;\r
182         }\r
183         unsigned __int64 GetMenuMask()\r
184         {\r
185                 if ((GetTickCount() - REGISTRYTIMEOUT) > menumaskticker)\r
186                 {\r
187                         menumaskticker = GetTickCount();\r
188                         menumasklow_lm.read();\r
189                         menumaskhigh_lm.read();\r
190                         menumasklow_cu.read();\r
191                         menumaskhigh_cu.read();\r
192                 }\r
193                 DWORD low = (DWORD)menumasklow_lm | (DWORD)menumasklow_cu;\r
194                 DWORD high = (DWORD)menumaskhigh_lm | (DWORD)menumaskhigh_cu;\r
195                 unsigned __int64 temp = unsigned __int64(high)<<32;\r
196                 temp |= unsigned __int64(low);\r
197                 return temp;\r
198         }\r
199         BOOL IsRecursive()\r
200         {\r
201                 if ((GetTickCount() - REGISTRYTIMEOUT)>recursiveticker)\r
202                 {\r
203                         recursiveticker = GetTickCount();\r
204                         showrecursive.read();\r
205                 }\r
206                 return (showrecursive);\r
207         }\r
208         BOOL IsFolderOverlay()\r
209         {\r
210                 if ((GetTickCount() - REGISTRYTIMEOUT)>folderoverlayticker)\r
211                 {\r
212                         folderoverlayticker = GetTickCount();\r
213                         folderoverlay.read();\r
214                 }\r
215                 return (folderoverlay);\r
216         }\r
217         BOOL IsSimpleContext()\r
218         {\r
219                 if ((GetTickCount() - REGISTRYTIMEOUT)>simplecontextticker)\r
220                 {\r
221                         simplecontextticker = GetTickCount();\r
222                         simplecontext.read();\r
223                 }\r
224                 return (simplecontext!=0);\r
225         }\r
226         BOOL IsUnversionedAsModified()\r
227         {\r
228                 if ((GetTickCount() - REGISTRYTIMEOUT)>unversionedasmodifiedticker)\r
229                 {\r
230                         unversionedasmodifiedticker = GetTickCount();\r
231                         unversionedasmodified.read();\r
232                 }\r
233                 return (unversionedasmodified);\r
234         }\r
235         BOOL ShowUnversionedOverlay()\r
236         {\r
237                 if ((GetTickCount() - REGISTRYTIMEOUT)>showunversionedoverlayticker)\r
238                 {\r
239                         showunversionedoverlayticker = GetTickCount();\r
240                         showunversionedoverlay.read();\r
241                 }\r
242                 return (showunversionedoverlay);\r
243         }\r
244         BOOL ShowIgnoredOverlay()\r
245         {\r
246                 if ((GetTickCount() - REGISTRYTIMEOUT)>showignoredoverlayticker)\r
247                 {\r
248                         showignoredoverlayticker = GetTickCount();\r
249                         showignoredoverlay.read();\r
250                 }\r
251                 return (showignoredoverlay);\r
252         }\r
253         BOOL IsGetLockTop()\r
254         {\r
255                 if ((GetTickCount() - REGISTRYTIMEOUT)>getlocktopticker)\r
256                 {\r
257                         getlocktopticker = GetTickCount();\r
258                         getlocktop.read();\r
259                 }\r
260                 return (getlocktop);\r
261         }\r
262         BOOL ShowExcludedAsNormal()\r
263         {\r
264                 if ((GetTickCount() - REGISTRYTIMEOUT)>excludedasnormalticker)\r
265                 {\r
266                         excludedasnormalticker = GetTickCount();\r
267                         excludedasnormal.read();\r
268                 }\r
269                 return (excludedasnormal);\r
270         }\r
271         BOOL IsRemote()\r
272         {\r
273                 DriveValid();\r
274                 return (driveremote);\r
275         }\r
276         BOOL IsFixed()\r
277         {\r
278                 DriveValid();\r
279                 return (drivefixed);\r
280         }\r
281         BOOL IsCDRom()\r
282         {\r
283                 DriveValid();\r
284                 return (drivecdrom);\r
285         }\r
286         BOOL IsRemovable()\r
287         {\r
288                 DriveValid();\r
289                 return (driveremove);\r
290         }\r
291         BOOL IsRAM()\r
292         {\r
293                 DriveValid();\r
294                 return (driveram);\r
295         }\r
296         BOOL IsUnknown()\r
297         {\r
298                 DriveValid();\r
299                 return (driveunknown);\r
300         }\r
301         BOOL IsContextPathAllowed(LPCTSTR path)\r
302         {\r
303                 Locker lock(m_critSec);\r
304                 ExcludeContextValid();\r
305                 for (std::vector<stdstring>::iterator I = excontextvector.begin(); I != excontextvector.end(); ++I)\r
306                 {\r
307                         if (I->empty())\r
308                                 continue;\r
309                         if (I->size() && I->at(I->size()-1)=='*')\r
310                         {\r
311                                 stdstring str = I->substr(0, I->size()-1);\r
312                                 if (_tcsnicmp(str.c_str(), path, str.size())==0)\r
313                                         return FALSE;\r
314                         }\r
315                         else if (_tcsicmp(I->c_str(), path)==0)\r
316                                 return FALSE;\r
317                 }\r
318                 return TRUE;\r
319         }\r
320         BOOL IsPathAllowed(LPCTSTR path)\r
321         {\r
322                 Locker lock(m_critSec);\r
323                 IncludeListValid();\r
324                 for (std::vector<stdstring>::iterator I = invector.begin(); I != invector.end(); ++I)\r
325                 {\r
326                         if (I->empty())\r
327                                 continue;\r
328                         if (I->at(I->size()-1)=='*')\r
329                         {\r
330                                 stdstring str = I->substr(0, I->size()-1);\r
331                                 if (_tcsnicmp(str.c_str(), path, str.size())==0)\r
332                                         return TRUE;\r
333                                 if (str.size() && (str.at(str.size()-1) == '\\') && (_tcsnicmp(str.c_str(), path, str.size()-1)==0))\r
334                                         return TRUE;\r
335                         }\r
336                         else if (_tcsicmp(I->c_str(), path)==0)\r
337                                 return TRUE;\r
338                         else if ((I->at(I->size()-1) == '\\') && \r
339                                 ((_tcsnicmp(I->c_str(), path, I->size())==0) || (_tcsicmp(I->c_str(), path)==0)) )\r
340                                 return TRUE;\r
341 \r
342                 }\r
343                 UINT drivetype = 0;\r
344                 int drivenumber = PathGetDriveNumber(path);\r
345                 if ((drivenumber >=0)&&(drivenumber < 25))\r
346                 {\r
347                         drivetype = drivetypecache[drivenumber];\r
348                         if ((drivetype == -1)||((GetTickCount() - DRIVETYPETIMEOUT)>drivetypeticker))\r
349                         {\r
350                                 if ((drivenumber == 0)||(drivenumber == 1))\r
351                                         drivetypecache[drivenumber] = DRIVE_REMOVABLE;\r
352                                 else\r
353                                 {\r
354                                         drivetypeticker = GetTickCount();\r
355                                         TCHAR pathbuf[MAX_PATH+4];              // MAX_PATH ok here. PathStripToRoot works with partial paths too.\r
356                                         _tcsncpy_s(pathbuf, MAX_PATH+4, path, MAX_PATH+3);\r
357                                         PathStripToRoot(pathbuf);\r
358                                         PathAddBackslash(pathbuf);\r
359                                         ATLTRACE2(_T("GetDriveType for %s, Drive %d\n"), pathbuf, drivenumber);\r
360                                         drivetype = GetDriveType(pathbuf);\r
361                                         drivetypecache[drivenumber] = drivetype;\r
362                                 }\r
363                         }\r
364                 }\r
365                 else\r
366                 {\r
367                         TCHAR pathbuf[MAX_PATH+4];              // MAX_PATH ok here. PathIsUNCServer works with partial paths too.\r
368                         _tcsncpy_s(pathbuf, MAX_PATH+4, path, MAX_PATH+3);\r
369                         if (PathIsUNCServer(pathbuf))\r
370                                 drivetype = DRIVE_REMOTE;\r
371                         else\r
372                         {\r
373                                 PathStripToRoot(pathbuf);\r
374                                 PathAddBackslash(pathbuf);\r
375                                 if (_tcsncmp(pathbuf, drivetypepathcache, MAX_PATH-1)==0)               // MAX_PATH ok.\r
376                                         drivetype = drivetypecache[26];\r
377                                 else\r
378                                 {\r
379                                         ATLTRACE2(_T("GetDriveType for %s\n"), pathbuf);\r
380                                         drivetype = GetDriveType(pathbuf);\r
381                                         drivetypecache[26] = drivetype;\r
382                                         _tcsncpy_s(drivetypepathcache, MAX_PATH, pathbuf, MAX_PATH);                    // MAX_PATH ok.\r
383                                 } \r
384                         }\r
385                 }\r
386                 if ((drivetype == DRIVE_REMOVABLE)&&(!IsRemovable()))\r
387                         return FALSE;\r
388                 if ((drivetype == DRIVE_REMOVABLE)&&(drivefloppy == 0)&&((drivenumber==0)||(drivenumber==1)))\r
389                         return FALSE;\r
390                 if ((drivetype == DRIVE_FIXED)&&(!IsFixed()))\r
391                         return FALSE;\r
392                 if (((drivetype == DRIVE_REMOTE)||(drivetype == DRIVE_NO_ROOT_DIR))&&(!IsRemote()))\r
393                         return FALSE;\r
394                 if ((drivetype == DRIVE_CDROM)&&(!IsCDRom()))\r
395                         return FALSE;\r
396                 if ((drivetype == DRIVE_RAMDISK)&&(!IsRAM()))\r
397                         return FALSE;\r
398                 if ((drivetype == DRIVE_UNKNOWN)&&(IsUnknown()))\r
399                         return FALSE;\r
400 \r
401                 ExcludeListValid();\r
402                 for (std::vector<stdstring>::iterator I = exvector.begin(); I != exvector.end(); ++I)\r
403                 {\r
404                         if (I->empty())\r
405                                 continue;\r
406                         if (I->size() && I->at(I->size()-1)=='*')\r
407                         {\r
408                                 stdstring str = I->substr(0, I->size()-1);\r
409                                 if (_tcsnicmp(str.c_str(), path, str.size())==0)\r
410                                         return FALSE;\r
411                         }\r
412                         else if (_tcsicmp(I->c_str(), path)==0)\r
413                                 return FALSE;\r
414                 }\r
415                 return TRUE;\r
416         }\r
417         DWORD GetLangID()\r
418         {\r
419                 if ((GetTickCount() - REGISTRYTIMEOUT) > langticker)\r
420                 {\r
421                         langticker = GetTickCount();\r
422                         langid.read();\r
423                 }\r
424                 return (langid);\r
425         }\r
426         NUMBERFMT * GetNumberFmt()\r
427         {\r
428                 if ((GetTickCount() - NUMBERFMTTIMEOUT) > columnrevformatticker)\r
429                 {\r
430                         TCHAR szBuffer[5];\r
431                         columnrevformatticker = GetTickCount();\r
432                         SecureZeroMemory(&columnrevformat, sizeof(NUMBERFMT));\r
433                         GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, &szDecSep[0], sizeof(szDecSep));\r
434                         GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, &szThousandsSep[0], sizeof(szThousandsSep));\r
435                         columnrevformat.lpDecimalSep = szDecSep;\r
436                         columnrevformat.lpThousandSep = szThousandsSep;\r
437                         GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, &szBuffer[0], sizeof(szBuffer));\r
438                         columnrevformat.Grouping = _ttoi(szBuffer);\r
439                         GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_INEGNUMBER, &szBuffer[0], sizeof(szBuffer));\r
440                         columnrevformat.NegativeOrder = _ttoi(szBuffer);\r
441                 }\r
442                 return &columnrevformat;\r
443         }\r
444         BOOL HasSVNAdminDir(LPCTSTR path, BOOL bIsDir, CString *ProjectTopDir = NULL)\r
445         {\r
446                 size_t len = _tcslen(path);\r
447                 TCHAR * buf = new TCHAR[len+1];\r
448                 _tcscpy_s(buf, len+1, path);\r
449                 if (! bIsDir)\r
450                 {\r
451                         TCHAR * ptr = _tcsrchr(buf, '\\');\r
452                         if (ptr != 0)\r
453                         {\r
454                                 *ptr = 0;\r
455                         }\r
456                 }\r
457                 if ((GetTickCount() - ADMINDIRTIMEOUT) < admindirticker)\r
458                 {\r
459                         std::map<stdstring, AdminDir_s>::iterator iter;\r
460                         sAdminDirCacheKey.assign(buf);\r
461                         if ((iter = admindircache.find(sAdminDirCacheKey)) != admindircache.end())\r
462                         {\r
463                                 delete [] buf;\r
464                                 if (ProjectTopDir && iter->second.bHasAdminDir)\r
465                                         *ProjectTopDir = iter->second.sProjectRoot.c_str();\r
466                                 return iter->second.bHasAdminDir;\r
467                         }\r
468                 }\r
469                 CString sProjectRoot;\r
470                 BOOL hasAdminDir = g_GitAdminDir.HasAdminDir(buf, true, &sProjectRoot);\r
471                 admindirticker = GetTickCount();\r
472                 Locker lock(m_critSec);\r
473 \r
474                 AdminDir_s &ad = admindircache[buf];\r
475                 ad.bHasAdminDir = hasAdminDir;\r
476                 if (hasAdminDir)\r
477                 {\r
478                         ad.sProjectRoot.assign(sProjectRoot);\r
479 \r
480                         if (ProjectTopDir)\r
481                                 *ProjectTopDir = sProjectRoot;\r
482                 }\r
483 \r
484                 delete [] buf;\r
485                 return hasAdminDir;\r
486         }\r
487         bool IsColumnsEveryWhere()\r
488         {\r
489                 if ((GetTickCount() - REGISTRYTIMEOUT) > columnseverywhereticker)\r
490                 {\r
491                         columnseverywhereticker = GetTickCount();\r
492                         columnseverywhere.read();\r
493                 } \r
494                 return !!(DWORD)columnseverywhere;\r
495         }\r
496 private:\r
497         void DriveValid()\r
498         {\r
499                 if ((GetTickCount() - REGISTRYTIMEOUT)>driveticker)\r
500                 {\r
501                         driveticker = GetTickCount();\r
502                         driveremote.read();\r
503                         drivefixed.read();\r
504                         drivecdrom.read();\r
505                         driveremove.read();\r
506                         drivefloppy.read();\r
507                 }\r
508         }\r
509         void ExcludeContextValid()\r
510         {\r
511                 if ((GetTickCount() - EXCLUDELISTTIMEOUT)>excontextticker)\r
512                 {\r
513                         Locker lock(m_critSec);\r
514                         excontextticker = GetTickCount();\r
515                         nocontextpaths.read();\r
516                         if (excludecontextstr.compare((stdstring)nocontextpaths)==0)\r
517                                 return;\r
518                         excludecontextstr = (stdstring)nocontextpaths;\r
519                         excontextvector.clear();\r
520                         size_t pos = 0, pos_ant = 0;\r
521                         pos = excludecontextstr.find(_T("\n"), pos_ant);\r
522                         while (pos != stdstring::npos)\r
523                         {\r
524                                 stdstring token = excludecontextstr.substr(pos_ant, pos-pos_ant);\r
525                                 excontextvector.push_back(token);\r
526                                 pos_ant = pos+1;\r
527                                 pos = excludecontextstr.find(_T("\n"), pos_ant);\r
528                         }\r
529                         if (!excludecontextstr.empty())\r
530                         {\r
531                                 excontextvector.push_back(excludecontextstr.substr(pos_ant, excludecontextstr.size()-1));\r
532                         }\r
533                         excludecontextstr = (stdstring)nocontextpaths;\r
534                 }\r
535         }\r
536         void ExcludeListValid()\r
537         {\r
538                 if ((GetTickCount() - EXCLUDELISTTIMEOUT)>excludelistticker)\r
539                 {\r
540                         Locker lock(m_critSec);\r
541                         excludelistticker = GetTickCount();\r
542                         excludelist.read();\r
543                         if (excludeliststr.compare((stdstring)excludelist)==0)\r
544                                 return;\r
545                         excludeliststr = (stdstring)excludelist;\r
546                         exvector.clear();\r
547                         size_t pos = 0, pos_ant = 0;\r
548                         pos = excludeliststr.find(_T("\n"), pos_ant);\r
549                         while (pos != stdstring::npos)\r
550                         {\r
551                                 stdstring token = excludeliststr.substr(pos_ant, pos-pos_ant);\r
552                                 exvector.push_back(token);\r
553                                 pos_ant = pos+1;\r
554                                 pos = excludeliststr.find(_T("\n"), pos_ant);\r
555                         }\r
556                         if (!excludeliststr.empty())\r
557                         {\r
558                                 exvector.push_back(excludeliststr.substr(pos_ant, excludeliststr.size()-1));\r
559                         }\r
560                         excludeliststr = (stdstring)excludelist;\r
561                 }\r
562         }\r
563         void IncludeListValid()\r
564         {\r
565                 if ((GetTickCount() - EXCLUDELISTTIMEOUT)>includelistticker)\r
566                 {\r
567                         Locker lock(m_critSec);\r
568                         includelistticker = GetTickCount();\r
569                         includelist.read();\r
570                         if (includeliststr.compare((stdstring)includelist)==0)\r
571                                 return;\r
572                         includeliststr = (stdstring)includelist;\r
573                         invector.clear();\r
574                         size_t pos = 0, pos_ant = 0;\r
575                         pos = includeliststr.find(_T("\n"), pos_ant);\r
576                         while (pos != stdstring::npos)\r
577                         {\r
578                                 stdstring token = includeliststr.substr(pos_ant, pos-pos_ant);\r
579                                 invector.push_back(token);\r
580                                 pos_ant = pos+1;\r
581                                 pos = includeliststr.find(_T("\n"), pos_ant);\r
582                         }\r
583                         if (!includeliststr.empty())\r
584                         {\r
585                                 invector.push_back(includeliststr.substr(pos_ant, includeliststr.size()-1));\r
586                         }\r
587                         includeliststr = (stdstring)includelist;\r
588                 }\r
589         }\r
590 \r
591         struct AdminDir_s\r
592         {\r
593                 BOOL bHasAdminDir;\r
594                 stdstring sProjectRoot;\r
595         };\r
596 \r
597         CRegStdWORD cachetype;\r
598         CRegStdWORD blockstatus;\r
599         CRegStdWORD langid;\r
600         CRegStdWORD showrecursive;\r
601         CRegStdWORD folderoverlay;\r
602         CRegStdWORD getlocktop;\r
603         CRegStdWORD driveremote;\r
604         CRegStdWORD drivefixed;\r
605         CRegStdWORD drivecdrom;\r
606         CRegStdWORD driveremove;\r
607         CRegStdWORD drivefloppy;\r
608         CRegStdWORD driveram;\r
609         CRegStdWORD driveunknown;\r
610         CRegStdWORD menulayoutlow;\r
611         CRegStdWORD menulayouthigh;\r
612         CRegStdWORD simplecontext;\r
613         CRegStdWORD menumasklow_lm;\r
614         CRegStdWORD menumaskhigh_lm;\r
615         CRegStdWORD menumasklow_cu;\r
616         CRegStdWORD menumaskhigh_cu;\r
617         CRegStdWORD unversionedasmodified;\r
618         CRegStdWORD showunversionedoverlay;\r
619         CRegStdWORD showignoredoverlay;\r
620         CRegStdWORD excludedasnormal;\r
621         CRegStdString excludelist;\r
622         CRegStdWORD columnseverywhere;\r
623         stdstring excludeliststr;\r
624         std::vector<stdstring> exvector;\r
625         CRegStdString includelist;\r
626         stdstring includeliststr;\r
627         std::vector<stdstring> invector;\r
628         DWORD cachetypeticker;\r
629         DWORD recursiveticker;\r
630         DWORD folderoverlayticker;\r
631         DWORD getlocktopticker;\r
632         DWORD driveticker;\r
633         DWORD drivetypeticker;\r
634         DWORD layoutticker;\r
635         DWORD menumaskticker;\r
636         DWORD langticker;\r
637         DWORD blockstatusticker;\r
638         DWORD columnrevformatticker;\r
639         DWORD excludelistticker;\r
640         DWORD includelistticker;\r
641         DWORD simplecontextticker;\r
642         DWORD unversionedasmodifiedticker;\r
643         DWORD showunversionedoverlayticker;\r
644         DWORD showignoredoverlayticker;\r
645         DWORD excludedasnormalticker;\r
646         DWORD columnseverywhereticker;\r
647         UINT  drivetypecache[27];\r
648         TCHAR drivetypepathcache[MAX_PATH];             // MAX_PATH ok.\r
649         NUMBERFMT columnrevformat;\r
650         TCHAR szDecSep[5];\r
651         TCHAR szThousandsSep[5];\r
652         std::map<stdstring, AdminDir_s> admindircache;\r
653         stdstring sAdminDirCacheKey;\r
654         CRegStdString nocontextpaths;\r
655         stdstring excludecontextstr;\r
656         std::vector<stdstring> excontextvector;\r
657         DWORD excontextticker;\r
658         DWORD admindirticker;\r
659         CComCriticalSection m_critSec;\r
660 };\r