* 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.
This commit is contained in:
		| @@ -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: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user