// D import file generated from '../../../../libphobos/libdruntime/core/sys/windows/dll.d'
module core.sys.windows.dll;
version (Windows)
{
	import core.sys.windows.windows;
	import core.stdc.string;
	import core.runtime;
	public import core.sys.windows.threadaux;

	extern (C) version (Win32)
	{
		extern __gshared void* _tlsstart;

		extern __gshared void* _tlsend;

		extern __gshared void* _tls_callbacks_a;

		extern __gshared int _tls_index;

	}

	extern (C) 
	{
		void rt_moduleTlsCtor();
		void rt_moduleTlsDtor();
	}
	private 
	{
		version (Win32)
		{
			struct dll_aux
			{
				struct LdrpTlsListEntry
				{
					LdrpTlsListEntry* next;
					LdrpTlsListEntry* prev;
					void* tlsstart;
					void* tlsend;
					void* ptr_tlsindex;
					void* callbacks;
					void* zerofill;
					int tlsindex;
				}
				extern (Windows) alias nothrow void* fnRtlAllocateHeap(void* HeapHandle, uint Flags, size_t Size);

				static nothrow void* findCodeSequence(void* adr, int len, ref ubyte[] pattern);

				static nothrow void* findCodeReference(void* adr, int len, ref ubyte[] pattern, bool relative);

				static __gshared int* pNtdllBaseTag;

				static __gshared ubyte[] jmp_LdrpInitialize = [51,237,233];

				static __gshared ubyte[] jmp__LdrpInitialize = [93,233];

				static __gshared ubyte[] jmp__LdrpInitialize_xp64 = [93,144,144,144,144,144];

				static __gshared ubyte[] call_LdrpInitializeThread = [255,117,8,232];

				static __gshared ubyte[] call_LdrpAllocateTls = [0,0,232];

				static __gshared ubyte[] call_LdrpAllocateTls_svr03 = [101,252,0,232];

				static __gshared ubyte[] jne_LdrpAllocateTls = [15,133];

				static __gshared ubyte[] mov_LdrpNumberOfTlsEntries = [139,13];

				static __gshared ubyte[] mov_NtdllBaseTag = [81,139,13];

				static __gshared ubyte[] mov_NtdllBaseTag_srv03 = [80,161];

				static __gshared ubyte[] mov_LdrpTlsList = [139,61];

				static nothrow LdrpTlsListEntry* addTlsListEntry(void** peb, void* tlsstart, void* tlsend, void* tls_callbacks_a, int* tlsindex);

				static nothrow bool addTlsData(void** teb, void* tlsstart, void* tlsend, int tlsindex);

				alias bool BOOLEAN;
				struct UNICODE_STRING
				{
					short Length;
					short MaximumLength;
					wchar* Buffer;
				}
				struct LIST_ENTRY
				{
					LIST_ENTRY* next;
					LIST_ENTRY* prev;
				}
				struct LDR_MODULE
				{
					LIST_ENTRY InLoadOrderModuleList;
					LIST_ENTRY InMemoryOrderModuleList;
					LIST_ENTRY InInitializationOrderModuleList;
					PVOID BaseAddress;
					PVOID EntryPoint;
					ULONG SizeOfImage;
					UNICODE_STRING FullDllName;
					UNICODE_STRING BaseDllName;
					ULONG Flags;
					SHORT LoadCount;
					SHORT TlsIndex;
					LIST_ENTRY HashTableEntry;
					ULONG TimeDateStamp;
				}
				struct PEB_LDR_DATA
				{
					ULONG Length;
					BOOLEAN Initialized;
					PVOID SsHandle;
					LIST_ENTRY InLoadOrderModuleList;
					LIST_ENTRY InMemoryOrderModuleList;
					LIST_ENTRY InInitializationOrderModuleList;
				}
				static nothrow LDR_MODULE* findLdrModule(HINSTANCE hInstance, void** peb);

				static nothrow bool setDllTlsUsage(HINSTANCE hInstance, void** peb);

			}
		}
		public 
		{
			bool dll_fixTLS(HINSTANCE hInstance, void* tlsstart, void* tlsend, void* tls_callbacks_a, int* tlsindex);
			bool dll_process_attach(HINSTANCE hInstance, bool attach_threads, void* tlsstart, void* tlsend, void* tls_callbacks_a, int* tlsindex);
			bool dll_process_attach(HINSTANCE hInstance, bool attach_threads = true);
			void dll_process_detach(HINSTANCE hInstance, bool detach_threads = true);
			static bool tlsCtorRun;

			static this();
			bool dll_thread_attach(bool attach_thread = true, bool initTls = true);
			bool dll_thread_detach(bool detach_thread = true, bool exitTls = true);
		}
	}
}
