1 // TortoiseGit - a Windows shell extension for easy version control
3 // External Cache Copyright (C) 2007,2009-2012 - TortoiseSVN
4 // Copyright (C) 2008-2013 - TortoiseGit
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "CacheInterface.h"
22 #include "SmartHandle.h"
25 CString
GetCachePipeName()
27 return TGIT_CACHE_PIPE_NAME
+ GetCacheID();
30 CString
GetCacheCommandPipeName()
32 return TGIT_CACHE_COMMANDPIPE_NAME
+ GetCacheID();
35 CString
GetCacheMutexName()
37 return TGIT_CACHE_MUTEX_NAME
+ GetCacheID();
43 CAutoGeneralHandle token
;
44 BOOL result
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, token
.GetPointer());
48 GetTokenInformation(token
, TokenStatistics
, NULL
, 0, &len
);
49 if (len
>= sizeof (TOKEN_STATISTICS
))
51 std::unique_ptr
<BYTE
[]> data (new BYTE
[len
]);
52 GetTokenInformation(token
, TokenStatistics
, data
.get(), len
, &len
);
53 LUID uid
= ((PTOKEN_STATISTICS
)data
.get())->AuthenticationId
;
54 t
.Format(_T("-%08x%08x"), uid
.HighPart
, uid
.LowPart
);
60 bool SendCacheCommand(BYTE command
, const WCHAR
* path
/* = NULL */)
67 GetCacheCommandPipeName(), // pipe name
68 GENERIC_READ
| // read and write access
71 NULL
, // default security attributes
72 OPEN_EXISTING
, // opens existing pipe
73 FILE_FLAG_OVERLAPPED
, // default attributes
74 NULL
); // no template file
78 } while ((!hPipe
) && (retrycount
));
82 CTraceToOutputDebugString::Instance()(__FUNCTION__
": Could not connect to pipe\n");
86 // The pipe connected; change to message-read mode.
87 DWORD dwMode
= PIPE_READMODE_MESSAGE
;
88 if (SetNamedPipeHandleState(
90 &dwMode
, // new pipe mode
91 NULL
, // don't set maximum bytes
92 NULL
)) // don't set maximum time
96 SecureZeroMemory(&cmd
, sizeof(TGITCacheCommand
));
97 cmd
.command
= command
;
99 _tcsncpy_s(cmd
.path
, path
, _TRUNCATE
);
102 BOOL fSuccess
= FALSE
;
105 fSuccess
= WriteFile(
106 hPipe
, // handle to pipe
107 &cmd
, // buffer to write from
108 sizeof(cmd
), // number of bytes to write
109 &cbWritten
, // number of bytes written
110 NULL
); // not overlapped I/O
112 if (! fSuccess
|| sizeof(cmd
) != cbWritten
)
114 } while ((retrycount
) && (! fSuccess
|| sizeof(cmd
) != cbWritten
));
116 if (! fSuccess
|| sizeof(cmd
) != cbWritten
)
118 CTraceToOutputDebugString::Instance()(__FUNCTION__
": Could not write to pipe\n");
119 DisconnectNamedPipe(hPipe
);
122 // now tell the cache we don't need it's command thread anymore
123 SecureZeroMemory(&cmd
, sizeof(TGITCacheCommand
));
124 cmd
.command
= TGITCACHECOMMAND_END
;
126 hPipe
, // handle to pipe
127 &cmd
, // buffer to write from
128 sizeof(cmd
), // number of bytes to write
129 &cbWritten
, // number of bytes written
130 NULL
); // not overlapped I/O
131 DisconnectNamedPipe(hPipe
);
135 CTraceToOutputDebugString::Instance()(__FUNCTION__
": SetNamedPipeHandleState failed");
142 CBlockCacheForPath::CBlockCacheForPath(const WCHAR
* aPath
)
144 wcsncpy_s(path
, aPath
, MAX_PATH
);
147 SendCacheCommand(TGITCACHECOMMAND_BLOCK
, path
);
148 // Wait a short while to make sure the cache has
149 // processed this command. Without this, we risk
150 // executing the svn command before the cache has
151 // blocked the path and already gets change notifications.
155 CBlockCacheForPath::~CBlockCacheForPath()
158 while (retry
-- && !SendCacheCommand(TGITCACHECOMMAND_UNBLOCK
, path
))