summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/cygheap.h
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2012-03-05 11:50:25 +0000
committerCorinna Vinschen <corinna@vinschen.de>2012-03-05 11:50:25 +0000
commita3904c655efec2edc27f72b68280afb4a144cc9a (patch)
tree397b8ea082ac19d78d5c8521c2a4a2517415e83d /winsup/cygwin/cygheap.h
parent75effa37fcb63c1e72918f6689660e4c3b11a5e8 (diff)
downloadcygnal-a3904c655efec2edc27f72b68280afb4a144cc9a.tar.gz
cygnal-a3904c655efec2edc27f72b68280afb4a144cc9a.tar.bz2
cygnal-a3904c655efec2edc27f72b68280afb4a144cc9a.zip
* cygheap.h (enum fcwd_version_t): Move here from path.cc.
(class fcwd_access_t): Ditto. Only declare methods. (class cwdstuff): Move fast_cwd_ptr and fast_cwd_version from shared DLL section here. * path.cc: Keep fcwd_access_t method definitions. (fcwd_access_t::fast_cwd_version): New method. (find_fast_cwd_pointer): Change comment. Mention test on W8CP. (cwdstuff::init): Initialize fast_cwd_ptr and fast_cwd_version.
Diffstat (limited to 'winsup/cygwin/cygheap.h')
-rw-r--r--winsup/cygwin/cygheap.h92
1 files changed, 91 insertions, 1 deletions
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index 054297bd7..154ad6a84 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -204,7 +204,87 @@ public:
/* cwd cache stuff. */
-class muto;
+enum fcwd_version_t {
+ FCWD_OLD,
+ FCWD_W7,
+ FCWD_W8
+};
+
+/* This class is used to store the CWD starting with Windows Vista.
+ The CWD storage in the RTL_USER_PROCESS_PARAMETERS block is only
+ an afterthought now. The actual CWD storage is a FAST_CWD structure
+ which is allocated on the process heap. The new method only requires
+ minimal locking and it's much more multi-thread friendly. Presumably
+ it minimizes contention when accessing the CWD.
+ The class fcwd_access_t is supposed to encapsulate the gory implementation
+ details depending on OS version from the calling functions. */
+class fcwd_access_t {
+ /* This is the layout used in Windows 8 developer preview. */
+ struct FAST_CWD_8 {
+ LONG ReferenceCount; /* Only release when this is 0. */
+ HANDLE DirectoryHandle;
+ ULONG OldDismountCount; /* Reflects the system DismountCount
+ at the time the CWD has been set. */
+ UNICODE_STRING Path; /* Path's Buffer member always refers
+ to the following Buffer array. */
+ LONG FSCharacteristics; /* Taken from FileFsDeviceInformation */
+ WCHAR Buffer[MAX_PATH];
+ };
+ /* This is the layout used in Windows 7 and Vista. */
+ struct FAST_CWD_7 {
+ UNICODE_STRING Path; /* Path's Buffer member always refers
+ to the following Buffer array. */
+ HANDLE DirectoryHandle;
+ LONG FSCharacteristics; /* Taken from FileFsDeviceInformation */
+ LONG ReferenceCount; /* Only release when this is 0. */
+ ULONG OldDismountCount; /* Reflects the system DismountCount
+ at the time the CWD has been set. */
+ WCHAR Buffer[MAX_PATH];
+ };
+ /* This is the old FAST_CWD structure up to the patch from KB 2393802,
+ release in February 2011. */
+ struct FAST_CWD_OLD {
+ LONG ReferenceCount; /* Only release when this is 0. */
+ HANDLE DirectoryHandle;
+ ULONG OldDismountCount; /* Reflects the system DismountCount
+ at the time the CWD has been set. */
+ UNICODE_STRING Path; /* Path's Buffer member always refers
+ to the following Buffer array. */
+ WCHAR Buffer[MAX_PATH];
+ };
+ union {
+ FAST_CWD_OLD fold;
+ FAST_CWD_7 f7;
+ FAST_CWD_8 f8;
+ };
+
+#define IMPLEMENT(type, name) \
+ type name () { \
+ switch (fast_cwd_version ()) { \
+ case FCWD_OLD: \
+ default: \
+ return fold.name; \
+ case FCWD_W7: \
+ return f7.name; \
+ case FCWD_W8: \
+ return f8.name; \
+ } \
+ }
+ IMPLEMENT (LONG &, ReferenceCount)
+ IMPLEMENT (HANDLE &, DirectoryHandle)
+ IMPLEMENT (ULONG &, OldDismountCount)
+ IMPLEMENT (UNICODE_STRING &, Path)
+ IMPLEMENT (WCHAR *, Buffer)
+ void SetFSCharacteristics (LONG val);
+ static fcwd_version_t &fast_cwd_version (void);
+
+public:
+ void CopyPath (UNICODE_STRING &target);
+ void Free (PVOID heap);
+ void FillIn (HANDLE dir, PUNICODE_STRING name, ULONG old_dismount_count);
+ static void SetDirHandleFromBufferPointer (PWCHAR buf_p, HANDLE dir);
+ static void SetVersionFromPointer (PBYTE buf_p, bool is_buffer);
+};
class cwdstuff
{
@@ -217,6 +297,16 @@ private:
a native Win32 application. See cwdstuff::set for
how it gets set. See child_info_spawn::worker for how
it's evaluated. */
+
+ friend class fcwd_access_t;
+ /* fast_cwd_ptr is a pointer to the global RtlpCurDirRef pointer in
+ ntdll.dll pointing to the FAST_CWD structure which constitutes the CWD.
+ Unfortunately RtlpCurDirRef is not exported from ntdll.dll. */
+ fcwd_access_t **fast_cwd_ptr;
+ /* Type of FAST_CWD used on this system. Keeping this information
+ available in shared memory avoids to test for the version every time
+ around. Default to new version. */
+ fcwd_version_t fast_cwd_version;
void override_win32_cwd (bool, ULONG);
public: