summaryrefslogtreecommitdiff
path: root/zen/FindFilePlus
diff options
context:
space:
mode:
Diffstat (limited to 'zen/FindFilePlus')
-rw-r--r--zen/FindFilePlus/FindFilePlus.vcxproj173
-rw-r--r--zen/FindFilePlus/dll_main.cpp66
-rw-r--r--zen/FindFilePlus/find_file_plus.cpp452
-rw-r--r--zen/FindFilePlus/find_file_plus.h92
-rw-r--r--zen/FindFilePlus/init_dll_binding.h16
-rw-r--r--zen/FindFilePlus/load_dll.cpp23
-rw-r--r--zen/FindFilePlus/load_dll.h45
7 files changed, 0 insertions, 867 deletions
diff --git a/zen/FindFilePlus/FindFilePlus.vcxproj b/zen/FindFilePlus/FindFilePlus.vcxproj
deleted file mode 100644
index eb5c672e..00000000
--- a/zen/FindFilePlus/FindFilePlus.vcxproj
+++ /dev/null
@@ -1,173 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{814047ED-7701-494D-BBAF-AFEDF43EDC4E}</ProjectGuid>
- <RootNamespace>ShadowDll</RootNamespace>
- <Keyword>Win32Proj</Keyword>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v120_xp</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v120_xp</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v120_xp</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v120_xp</PlatformToolset>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup>
- <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\FreeFileSync\Build\Bin\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\FreeFileSync\Obj\$(ProjectName)_VCPP_$(PlatformName)_$(Configuration)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\FreeFileSync\Build\Bin\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\FreeFileSync\Obj\$(ProjectName)_VCPP_$(PlatformName)_$(Configuration)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\FreeFileSync\Build\Bin\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\FreeFileSync\Obj\$(ProjectName)_VCPP_$(PlatformName)_$(Configuration)\</IntDir>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\FreeFileSync\Build\Bin\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\FreeFileSync\Obj\$(ProjectName)_VCPP_$(PlatformName)_$(Configuration)\</IntDir>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)_$(Platform)</TargetName>
- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)_$(Platform)</TargetName>
- <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)_$(Platform)</TargetName>
- <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)_$(Platform)</TargetName>
- <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Data\C++\WinDDK\inc\ddk;C:\Data\C++\WinDDK\inc\api;C:\Data\C++\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath>
- <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\Data\C++\WinDDK\inc\ddk;C:\Data\C++\WinDDK\inc\api;C:\Data\C++\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath>
- <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\Data\C++\WinDDK\inc\ddk;C:\Data\C++\WinDDK\inc\api;C:\Data\C++\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath>
- <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\Data\C++\WinDDK\inc\ddk;C:\Data\C++\WinDDK\inc\api;C:\Data\C++\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>_X86_;_DEBUG;_WINDOWS;_USRDLL;FIND_FILE_PLUS_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- <WarningLevel>Level4</WarningLevel>
- <DisableSpecificWarnings>4100;4996;4512</DisableSpecificWarnings>
- <AdditionalIncludeDirectories>C:\Data\Projects;</AdditionalIncludeDirectories>
- <SmallerTypeCheck>true</SmallerTypeCheck>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
- </ClCompile>
- <Link>
- <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <SubSystem>Windows</SubSystem>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>_AMD64_;_DEBUG;_WINDOWS;_USRDLL;FIND_FILE_PLUS_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- <WarningLevel>Level4</WarningLevel>
- <DisableSpecificWarnings>4100;4996;4512</DisableSpecificWarnings>
- <AdditionalIncludeDirectories>C:\Data\Projects;</AdditionalIncludeDirectories>
- <SmallerTypeCheck>true</SmallerTypeCheck>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- </ClCompile>
- <Link>
- <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <SubSystem>Windows</SubSystem>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <Optimization>MaxSpeed</Optimization>
- <PreprocessorDefinitions>_X86_;NDEBUG;_WINDOWS;_USRDLL;FIND_FILE_PLUS_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <WarningLevel>Level4</WarningLevel>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- <DisableSpecificWarnings>4100;4996;4512</DisableSpecificWarnings>
- <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
- <AdditionalIncludeDirectories>C:\Data\Projects;</AdditionalIncludeDirectories>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
- </ClCompile>
- <Link>
- <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <SubSystem>Windows</SubSystem>
- <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <Optimization>MaxSpeed</Optimization>
- <PreprocessorDefinitions>_AMD64_;NDEBUG;_WINDOWS;_USRDLL;FIND_FILE_PLUS_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <WarningLevel>Level4</WarningLevel>
- <DisableSpecificWarnings>4100;4996;4512</DisableSpecificWarnings>
- <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
- <AdditionalIncludeDirectories>C:\Data\Projects;</AdditionalIncludeDirectories>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- </ClCompile>
- <Link>
- <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <SubSystem>Windows</SubSystem>
- <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="..\debug_memory_leaks.cpp" />
- <ClCompile Include="dll_main.cpp" />
- <ClCompile Include="find_file_plus.cpp" />
- <ClCompile Include="load_dll.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="find_file_plus.h" />
- <ClInclude Include="load_dll.h" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project> \ No newline at end of file
diff --git a/zen/FindFilePlus/dll_main.cpp b/zen/FindFilePlus/dll_main.cpp
deleted file mode 100644
index caa5930d..00000000
--- a/zen/FindFilePlus/dll_main.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
-// **************************************************************************
-
-#define WIN32_LEAN_AND_MEAN
-#include <zen/win.h>
-
-#include "init_dll_binding.h"
-
-/*
-http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx
-"DllMain is called while the loader-lock is held. [...] You cannot call any function in
-DllMain that directly or indirectly tries to acquire the loader lock. Otherwise, you will
-introduce the possibility that your application deadlocks or crashes."
-
-it's even worse: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx
-"If your DLL is linked with the C run-time library (CRT), the entry point provided by the CRT calls the constructors
-and destructors for global and static C++ objects. Therefore, these restrictions for DllMain also apply to constructors
-and destructors and any code that is called from them."
-
-Example: http://blog.barthe.ph/2009/07/30/no-stdlib-in-dllmai/
-
-Empirical study on DLL initialization order
--------------------------------------------
-I. statically linked DLL:
- DLL, static object constructors
- DLL, DllMain(): DLL_PROCESS_ATTACH
- main thread, static object constructors
- main thread, enter main()
- DLL, DllMain(): DLL_THREAD_ATTACH
- DLL, DllMain(): DLL_THREAD_DETACH
- main thread, exit main()
- main thread, static object destructors
- DLL, DllMain(): DLL_PROCESS_DETACH
- DLL, static object destructors
-
-II. dynamically linked DLL (living in main()):
- main thread, static object constructors
- main thread, main(): LoadLibrary
- DLL, static object constructors
- DLL, DllMain(): DLL_PROCESS_ATTACH
- main thread, main(): FreeLibrary
- DLL, DllMain(): DLL_PROCESS_DETACH
- DLL, static object destructors
- main thread, static object destructors
-*/
-
-//optional: add init/teardown logic here
-BOOL APIENTRY DllMain(HINSTANCE hinstDLL,
- DWORD fdwReason,
- LPVOID lpvReserved)
-{
- switch (fdwReason)
- {
- case DLL_PROCESS_ATTACH:
- if (!findplus::initDllBinding())
- return false;
- case DLL_PROCESS_DETACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- break;
- }
- return true;
-}
diff --git a/zen/FindFilePlus/find_file_plus.cpp b/zen/FindFilePlus/find_file_plus.cpp
deleted file mode 100644
index 247b916c..00000000
--- a/zen/FindFilePlus/find_file_plus.cpp
+++ /dev/null
@@ -1,452 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
-// **************************************************************************
-
-#include "find_file_plus.h"
-#include "init_dll_binding.h"
-//#include <windows.h> //these two don't play nice with each other
-#include "load_dll.h"
-#include <new>
-
-using namespace dll;
-using namespace findplus;
-
-
-namespace
-{
-struct NtFileError //exception class
-{
- NtFileError(NTSTATUS errorCode) : ntError(errorCode) {}
- NTSTATUS ntError;
-};
-
-
-//--------------------------------------------------------------------------------------------------------------
-typedef NTSTATUS (NTAPI* NtOpenFileFunc)(PHANDLE fileHandle,
- ACCESS_MASK desiredAccess,
- POBJECT_ATTRIBUTES objectAttributes,
- PIO_STATUS_BLOCK ioStatusBlock,
- ULONG shareAccess,
- ULONG openOptions);
-
-typedef NTSTATUS (NTAPI* NtCloseFunc)(HANDLE handle);
-
-typedef NTSTATUS (NTAPI* NtQueryDirectoryFileFunc)(HANDLE fileHandle,
- HANDLE event,
- PIO_APC_ROUTINE apcRoutine,
- PVOID apcContext,
- PIO_STATUS_BLOCK ioStatusBlock,
- PVOID fileInformation,
- ULONG length,
- FILE_INFORMATION_CLASS fileInformationClass,
- BOOLEAN ReturnSingleEntry,
- PUNICODE_STRING fileMask,
- BOOLEAN restartScan);
-
-typedef ULONG (NTAPI* RtlNtStatusToDosErrorFunc)(NTSTATUS /*__in status*/);
-
-typedef struct _RTL_RELATIVE_NAME_U
-{
- UNICODE_STRING RelativeName;
- HANDLE ContainingDirectory;
- PVOID /*PRTLP_CURDIR_REF*/ CurDirRef;
-} RTL_RELATIVE_NAME_U, *PRTL_RELATIVE_NAME_U;
-
-typedef BOOLEAN (NTAPI* RtlDosPathNameToNtPathName_UFunc)(PCWSTR dosFileName, //__in
- PUNICODE_STRING ntFileName, //__out
- PCWSTR* filePart, //__out
- PRTL_RELATIVE_NAME_U relativeName); //__out
-
-typedef BOOLEAN (NTAPI* RtlDosPathNameToRelativeNtPathName_UFunc)(PCWSTR dosFileName, //__in
- PUNICODE_STRING ntFileName, //__out
- PCWSTR* filePart, //__out
- PRTL_RELATIVE_NAME_U relativeName); //__out
-
-typedef BOOLEAN (NTAPI* RtlCreateUnicodeStringFunc)(PUNICODE_STRING DestinationString, //_Out_
- PCWSTR SourceString); //_In_
-
-typedef VOID (NTAPI* RtlFreeUnicodeStringFunc)(PUNICODE_STRING); //__inout unicodeString
-
-//--------------------------------------------------------------------------------------------------------------
-
-//it seems we cannot use any of the ntoskrnl.lib files in WinDDK as they produce access violations
-//fortunately dynamic binding works fine:
-const SysDllFun<NtOpenFileFunc> ntOpenFile (L"ntdll.dll", "NtOpenFile");
-const SysDllFun<NtCloseFunc> ntClose (L"ntdll.dll", "NtClose");
-const SysDllFun<NtQueryDirectoryFileFunc> ntQueryDirectoryFile (L"ntdll.dll", "NtQueryDirectoryFile");
-const SysDllFun<RtlNtStatusToDosErrorFunc> rtlNtStatusToDosError (L"ntdll.dll", "RtlNtStatusToDosError");
-const SysDllFun<RtlCreateUnicodeStringFunc> rtlCreateUnicodeString (L"ntdll.dll", "RtlCreateUnicodeString");
-const SysDllFun<RtlFreeUnicodeStringFunc> rtlFreeUnicodeString (L"ntdll.dll", "RtlFreeUnicodeString");
-const SysDllFun<RtlDosPathNameToNtPathName_UFunc> rtlDosPathNameToNtPathName_U(SysDllFun<RtlDosPathNameToRelativeNtPathName_UFunc>(L"ntdll.dll", "RtlDosPathNameToRelativeNtPathName_U") ?
- SysDllFun<RtlDosPathNameToRelativeNtPathName_UFunc>(L"ntdll.dll", "RtlDosPathNameToRelativeNtPathName_U") : //use the newer version if available
- SysDllFun<RtlDosPathNameToNtPathName_UFunc>(L"ntdll.dll", "RtlDosPathNameToNtPathName_U")); //fallback for XP
-//global constants only -> preserve thread safety!
-}
-
-
-bool findplus::initDllBinding() //evaluate in ::DllMain() when attaching process
-{
- //NT/ZwXxx Routines
- //http://msdn.microsoft.com/en-us/library/ff567122(v=VS.85).aspx
-
- //Run-Time Library (RTL) Routines
- //http://msdn.microsoft.com/en-us/library/ff563638(v=VS.85).aspx
-
- //verify dynamic dll binding
- return ntOpenFile &&
- ntClose &&
- ntQueryDirectoryFile &&
- rtlNtStatusToDosError &&
- rtlCreateUnicodeString &&
- rtlFreeUnicodeString &&
- rtlDosPathNameToNtPathName_U;
-
- //this may become handy some time: nt status code STATUS_ORDINAL_NOT_FOUND maps to win32 code ERROR_INVALID_ORDINAL
-}
-
-
-class findplus::FileSearcher
-{
-public:
- FileSearcher(const wchar_t* dirname); //throw NtFileError
- ~FileSearcher();
-
- bool readDir(FileInformation& output); //throw NtFileError; returns false if "no more files"
-
-private:
- template <class QueryPolicy> bool readDirImpl(FileInformation& output); //throw NtFileError
-
- UNICODE_STRING dirnameNt; //it seems hDir implicitly keeps a reference to this, at least ::FindFirstFile() does no cleanup before ::FindClose()!
- HANDLE hDir;
-
- ULONG nextEntryOffset; //!= 0 if entry is waiting in buffer
- //::FindNextFileW() uses 0x1000 = 4096 = sizeof(FILE_BOTH_DIR_INFORMATION) + sizeof(TCHAR) * 2000
- //=> let's use the same, even if our header is 16 byte larger; maybe there is some packet size advantage for networks? Note that larger buffers seem to degrade performance.
- static const ULONG BUFFER_SIZE = 4096;
- LONGLONG buffer[BUFFER_SIZE / sizeof(LONGLONG)]; //buffer needs to be aligned at LONGLONG boundary
-
- static_assert(BUFFER_SIZE % sizeof(LONGLONG) == 0, "ups, our buffer is trimmed!");
-};
-
-
-//a simple scope guard without <utility>, <type_traits>, <cassert> dependencies:
-template <typename F>
-class ScopeGuardLean
-{
-public:
- explicit ScopeGuardLean(F fun) : dismissed_(false), fun_(fun) {}
- ScopeGuardLean(ScopeGuardLean&& other) : dismissed_(other.dismissed_), fun_(std::move(other.fun_)) { other.dismiss(); }
-
- void dismiss() { dismissed_ = true; }
-
- ~ScopeGuardLean()
- {
- if (!dismissed_)
- try { fun_(); }
- catch (...) {}
- }
-
-private:
- ScopeGuardLean (const ScopeGuardLean&); // = delete
- ScopeGuardLean& operator=(const ScopeGuardLean&); //
-
- bool dismissed_;
- F fun_;
-};
-
-template <class F> inline
-ScopeGuardLean<F> makeGuard(F fun) { return ScopeGuardLean<F>(fun); }
-
-
-FileSearcher::FileSearcher(const wchar_t* dirname) :
- dirnameNt(), //[!]
- hDir(nullptr),
- nextEntryOffset(0)
-{
- auto guardConstructor = makeGuard([&] { this->~FileSearcher(); });
- //--------------------------------------------------------------------------------------------------------------
-
- //convert dosFileName, e.g. C:\Users or \\?\C:\Users to ntFileName \??\C:\Users
- //in contrast to ::FindFirstFile() implementation we don't evaluate the relativeName,
- //however tests indicate ntFileName is *always* filled with an absolute name, even if dosFileName is relative
-
- PCWSTR filePart = nullptr;
- RTL_RELATIVE_NAME_U relativeName = {};
-
- //NOTE: RtlDosPathNameToNtPathName_U may be used on all XP/Win7/Win8 for compatibility
- // RtlDosPathNameToNtPathName_U: used by Windows XP available with OS version 3.51 (Windows NT) and higher
- // RtlDosPathNameToRelativeNtPathName_U: used by Win7/Win8 available with OS version 5.2 (Windows Server 2003) and higher
- if (!rtlDosPathNameToNtPathName_U(dirname, //__in dosFileName,
- &dirnameNt, //__out ntFileName,
- &filePart, //__out FilePart - points into ntFileName
- &relativeName)) //__out relativeName - points into ntFileName; empty if dosFileName is absolute
- throw NtFileError(STATUS_OBJECT_PATH_NOT_FOUND); //translates to ERROR_PATH_NOT_FOUND, same behavior like ::FindFirstFileEx()
- //note 1: internally it distinguishes between "quick path" == \\?\ and "slow path" handling!
- //http://doxygen.reactos.org/d9/d6e/lib_2rtl_2path_8c_a11c87ad0f7752999b0b8972af6165d7a.html#a11c87ad0f7752999b0b8972af6165d7a
-
- //note 2: without \\?\, i.e. slow path handling it calls RtlGetFullPathName_Ustr() which removes trailing spaces!!!
- //http://doxygen.reactos.org/d9/d6e/lib_2rtl_2path_8c_a8624b864678ca64b031f5fc273e022af.html#a8624b864678ca64b031f5fc273e022af
- //FindFirstFile() gets lucky because it passes "<dirname>\*" which never has trailing space chars! >:(
-
- OBJECT_ATTRIBUTES objAttr = {};
- if (relativeName.RelativeName.Length == 0) //absolute name
- {
- InitializeObjectAttributes(&objAttr, //[out] POBJECT_ATTRIBUTES initializedAttributes,
- &dirnameNt, //[in] PUNICODE_STRING objectName,
- OBJ_CASE_INSENSITIVE, //[in] ULONG attributes,
- nullptr, //[in] HANDLE rootDirectory,
- nullptr); //[in, optional] PSECURITY_DESCRIPTOR securityDescriptor
- }
- else //relative name (it seems we alternatively could also use dirnameNt here?)
- {
- InitializeObjectAttributes(&objAttr, //[out] POBJECT_ATTRIBUTES initializedAttributes,
- &relativeName.RelativeName, //[in] PUNICODE_STRING objectName,
- OBJ_CASE_INSENSITIVE, //[in] ULONG attributes,
- relativeName.ContainingDirectory, //[in] HANDLE rootDirectory,
- nullptr); //[in, optional] PSECURITY_DESCRIPTOR securityDescriptor
- }
-
- {
- IO_STATUS_BLOCK status = {};
- NTSTATUS rv = ntOpenFile(&hDir, //__out PHANDLE FileHandle,
- FILE_LIST_DIRECTORY | SYNCHRONIZE, //__in ACCESS_MASK desiredAccess, - 100001 used by ::FindFirstFile() on all XP/Win7/Win8
- &objAttr, //__in POBJECT_ATTRIBUTES objectAttributes,
- &status, //__out PIO_STATUS_BLOCK ioStatusBlock,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, //__in ULONG shareAccess, - 7 on Win7/Win8, 3 on XP
- FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT); //__in ULONG openOptions - 4021 used on all XP/Win7/Win8
- if (!NT_SUCCESS(rv))
- throw NtFileError(rv);
- }
-
- guardConstructor.dismiss();
-}
-
-
-inline
-FileSearcher::~FileSearcher()
-{
- //cleanup in reverse order
- if (hDir)
- ntClose(hDir);
-
- if (dirnameNt.Buffer)
- rtlFreeUnicodeString(&dirnameNt); //cleanup identical to ::FindFirstFile()
- //note that most of this function seems inlined by the linker, so that its assembly looks equivalent to "RtlFreeHeap(RtlGetProcessHeap(), 0, ntPathName.Buffer)"
-}
-
-
-namespace
-{
-/*
-Common C-style policy handling directory traversal:
-
-struct QueryPolicy
-{
- typedef ... RawFileInfo;
- static const FILE_INFORMATION_CLASS fileInformationClass = ...;
- static void extractFileId(const RawFileInfo& rawInfo, FileInformation& fileInfo);
-};
-*/
-
-struct DirQueryDefault //as implemented in Win32 FindFirstFile()/FindNextFile()
-{
- typedef FILE_BOTH_DIR_INFORMATION RawFileInfo;
- static const FILE_INFORMATION_CLASS fileInformationClass = FileBothDirectoryInformation;
- static void extractFileId(const RawFileInfo& rawInfo, FileInformation& fileInfo) { fileInfo.fileId.QuadPart = 0; }
-};
-
-struct DirQueryFileId
-{
- typedef FILE_ID_BOTH_DIR_INFORMATION RawFileInfo;
- static const FILE_INFORMATION_CLASS fileInformationClass = FileIdBothDirectoryInformation;
- static void extractFileId(const RawFileInfo& rawInfo, FileInformation& fileInfo)
- {
- fileInfo.fileId.QuadPart = rawInfo.FileId.QuadPart; //may be 0 even in this context, e.g. for mapped FTP drive!
- static_assert(sizeof(fileInfo.fileId) == sizeof(rawInfo.FileId), "dang!");
- }
-};
-}
-
-
-inline
-bool FileSearcher::readDir(FileInformation& output) { return readDirImpl<DirQueryFileId>(output); } //throw NtFileError
-
-
-template <class QueryPolicy>
-bool FileSearcher::readDirImpl(FileInformation& output) //throw NtFileError; returns false if "no more files"
-{
- //although FILE_ID_FULL_DIR_INFORMATION should suffice for our purposes, there are problems on Windows XP for certain directories, e.g. "\\Vboxsvr\build"
- //making NtQueryDirectoryFile() return with STATUS_INVALID_PARAMETER while other directories, e.g. "C:\" work fine for some reason
- //FILE_ID_BOTH_DIR_INFORMATION on the other hand works on XP/Win7/Win8
- //performance: there is no noticeable difference between FILE_ID_BOTH_DIR_INFORMATION and FILE_ID_FULL_DIR_INFORMATION
-
- /* corresponding first access in ::FindFirstFileW()
-
- NTSTATUS rv = ntQueryDirectoryFile(hDir, //__in HANDLE fileHandle,
- nullptr, //__in_opt HANDLE event,
- nullptr, //__in_opt PIO_APC_ROUTINE apcRoutine,
- nullptr, //__in_opt PVOID apcContext,
- &status, //__out PIO_STATUS_BLOCK ioStatusBlock,
- &buffer, //__out_bcount(Length) PVOID fileInformation,
- BUFFER_SIZE, //__in ULONG length, ::FindFirstFileW() on all XP/Win7/Win8 uses sizeof(FILE_BOTH_DIR_INFORMATION) + sizeof(TCHAR) * MAX_PATH == 0x268
- FileIdBothDirectoryInformation, //__in FILE_INFORMATION_CLASS fileInformationClass - all XP/Win7/Win8 use "FileBothDirectoryInformation"
- true, //__in BOOLEAN returnSingleEntry,
- nullptr, //__in_opt PUNICODE_STRING mask,
- false); //__in BOOLEAN restartScan
- */
-
- //analog to ::FindNextFileW() with performance optimized access (in contrast to first access in ::FindFirstFileW())
- if (nextEntryOffset == 0)
- {
- IO_STATUS_BLOCK status = {};
- NTSTATUS rv = ntQueryDirectoryFile(hDir, //__in HANDLE fileHandle,
- nullptr, //__in_opt HANDLE event,
- nullptr, //__in_opt PIO_APC_ROUTINE apcRoutine,
- nullptr, //__in_opt PVOID apcContext,
- &status, //__out PIO_STATUS_BLOCK ioStatusBlock,
- &buffer, //__out_bcount(Length) PVOID fileInformation,
- BUFFER_SIZE, //__in ULONG length, ::FindNextFileW() on all XP/Win7/Win8 uses sizeof(FILE_BOTH_DIR_INFORMATION) + sizeof(TCHAR) * 2000 == 0x1000
- QueryPolicy::fileInformationClass, //__in FILE_INFORMATION_CLASS fileInformationClass - all XP/Win7/Win8 use "FileBothDirectoryInformation"
- false, //__in BOOLEAN returnSingleEntry,
- nullptr, //__in_opt PUNICODE_STRING mask,
- false); //__in BOOLEAN restartScan
- if (!NT_SUCCESS(rv))
- {
- /*
- fallback to default directory query method, if FileIdBothDirectoryInformation is not properly implemented
- this is required for NetDrive mounted Webdav, e.g. www.box.net and NT4, 2000 remote drives, et al.
-
- NT status code | Win32 error code
- --------------------------------|------------------------
- STATUS_INVALID_LEVEL | ERROR_INVALID_LEVEL
- STATUS_NOT_SUPPORTED | ERROR_NOT_SUPPORTED
- STATUS_UNEXPECTED_NETWORK_ERROR | ERROR_UNEXP_NET_ERR -> traverse network drive hosted by Win98
- STATUS_INVALID_PARAMETER | ERROR_INVALID_PARAMETER
- STATUS_INVALID_NETWORK_RESPONSE | ERROR_BAD_NET_RESP
- STATUS_INVALID_INFO_CLASS | ERROR_INVALID_PARAMETER
- STATUS_UNSUCCESSFUL | ERROR_GEN_FAILURE
- STATUS_ACCESS_VIOLATION | ERROR_NOACCESS ->FileIdBothDirectoryInformation on XP accessing UDF
- STATUS_NO_SUCH_FILE | ERROR_FILE_NOT_FOUND
-
- rv == STATUS_NO_SUCH_FILE:
- failure to find a file on first call returns STATUS_NO_SUCH_FILE, while subsequent accesses return STATUS_NO_MORE_FILES
- note: not all directories contain ".", ".." entries! E.g. a drive's root directory or NetDrive + ftp.gnu.org\CRYPTO.README"
- -> addon: this is NOT a directory, it looks like one in NetDrive, but it's a file in Opera
- STATUS_NO_SUCH_FILE is abused by some citrix shares instead of "STATUS_INVALID_PARAMETER" so we treat it as such!
- => since the directory is "truly empty" a fallback won't hurt
- */
- if (rv == STATUS_NO_MORE_FILES) //perf: don't throw an exception in this common case! => 8% perf boost for FFS comparison phase!
- return false;
-
- if (rv == STATUS_NOT_SUPPORTED ||
- rv == STATUS_INVALID_LEVEL ||
- rv == STATUS_NO_SUCH_FILE || //[!]
- rv == STATUS_UNEXPECTED_NETWORK_ERROR ||
- rv == STATUS_INVALID_PARAMETER ||
- rv == STATUS_INVALID_NETWORK_RESPONSE ||
- rv == STATUS_INVALID_INFO_CLASS ||
- //rv == STATUS_NOT_IMPLEMENTED || -> first confirm that these codes
- //rv == STATUS_INVALID_DEVICE_REQUEST || -> are in fact used!
- rv == STATUS_UNSUCCESSFUL ||
- rv == STATUS_ACCESS_VIOLATION)
- rv = STATUS_NOT_SUPPORTED;
-
- throw NtFileError(rv); //throws STATUS_NO_MORE_FILES when finished
- }
-
- // for (NTSTATUS i = 0xC0000000L; i != -1; ++i)
- // {
- // if (rtlNtStatusToDosError(i) == 59) //ERROR_UNEXP_NET_ERR
- // __debugbreak(); //__asm int 3;
- // }
-
- if (status.Information == 0) //except for the first call to call ::NtQueryDirectoryFile():
- throw NtFileError(STATUS_BUFFER_OVERFLOW); //if buffer size is too small, return value is STATUS_SUCCESS and Information == 0 -> we don't expect this!
- }
-
- typedef typename QueryPolicy::RawFileInfo RawFileInfo;
- const RawFileInfo& dirInfo = *reinterpret_cast<RawFileInfo*>(reinterpret_cast<char*>(buffer) + nextEntryOffset);
-
- if (dirInfo.NextEntryOffset == 0)
- nextEntryOffset = 0; //our offset is relative to the beginning of the buffer
- else
- nextEntryOffset += dirInfo.NextEntryOffset;
-
-
- auto toFileTime = [](const LARGE_INTEGER& rawTime) -> FILETIME
- {
- FILETIME tmp = { rawTime.LowPart, rawTime.HighPart };
- return tmp;
- };
-
- QueryPolicy::extractFileId(dirInfo, output);
-
- output.creationTime = toFileTime(dirInfo.CreationTime);
- output.lastWriteTime = toFileTime(dirInfo.LastWriteTime); //the similar field "ChangeTime" refers to changes to metadata in addition to write accesses
- output.fileSize.QuadPart = dirInfo.EndOfFile.QuadPart;
- output.fileAttributes = dirInfo.FileAttributes;
- output.shortNameLength = dirInfo.FileNameLength / sizeof(TCHAR); //FileNameLength is in bytes!
-
- if (dirInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) //analog to FindFirstFile(), confirmed for Win XP and Win 7
- output.reparseTag = dirInfo.EaSize; //
- else
- output.reparseTag = 0;
-
- if (dirInfo.FileNameLength + sizeof(TCHAR) > sizeof(output.shortName)) //this may actually happen if ::NtQueryDirectoryFile() decides to return a
- throw NtFileError(STATUS_BUFFER_OVERFLOW); //short name of length MAX_PATH + 1, 0-termination is not required!
-
- ::memcpy(output.shortName, dirInfo.FileName, dirInfo.FileNameLength);
- output.shortName[output.shortNameLength] = 0; //NOTE: FILE_ID_BOTH_DIR_INFORMATION::FileName in general is NOT 0-terminated! It is on XP/Win7, but NOT on Win8!
-
- static_assert(sizeof(output.creationTime) == sizeof(dirInfo.CreationTime), "dang!");
- static_assert(sizeof(output.lastWriteTime) == sizeof(dirInfo.LastWriteTime), "dang!");
- static_assert(sizeof(output.fileSize) == sizeof(dirInfo.EndOfFile), "dang!");
- static_assert(sizeof(output.fileAttributes) == sizeof(dirInfo.FileAttributes), "dang!");
- return true;
-}
-
-
-FindHandle findplus::openDir(const wchar_t* dirname)
-{
- try
- {
- return new FileSearcher(dirname); //throw NtFileError, std::bad_alloc
- }
- catch (const NtFileError& e)
- {
- setWin32Error(rtlNtStatusToDosError(e.ntError));
- return nullptr;
- }
- catch (const std::bad_alloc&) //not unlikely in file sync context! => handle!
- {
- setWin32Error(rtlNtStatusToDosError(STATUS_NO_MEMORY));
- return nullptr;
- }
-}
-
-
-bool findplus::readDir(FindHandle hnd, FileInformation& output)
-{
- try
- {
- if (!hnd->readDir(output)) //throw NtFileError
- {
- setWin32Error(rtlNtStatusToDosError(STATUS_NO_MORE_FILES));
- return false;
- }
- return true;
- }
- catch (const NtFileError& e)
- {
- setWin32Error(rtlNtStatusToDosError(e.ntError));
- return false;
- }
-}
-
-
-void findplus::closeDir(FindHandle hnd)
-{
- delete hnd;
-}
diff --git a/zen/FindFilePlus/find_file_plus.h b/zen/FindFilePlus/find_file_plus.h
deleted file mode 100644
index a26bdeb3..00000000
--- a/zen/FindFilePlus/find_file_plus.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
-// **************************************************************************
-
-#ifndef FIND_FIRST_FILE_PLUS_HEADER_087483434
-#define FIND_FIRST_FILE_PLUS_HEADER_087483434
-
-#ifdef FIND_FILE_PLUS_DLL_EXPORTS
-#define DLL_FUNCTION_DECLARATION extern "C" __declspec(dllexport)
-#else
-#define DLL_FUNCTION_DECLARATION extern "C" __declspec(dllimport)
-#endif
-
-
-#ifdef FIND_FILE_PLUS_DLL_EXPORTS
-#include <Ntifs.h> //driver level headers must be included *before* windows api headers!
-#endif
-#include <windef.h> //
-#undef min
-#undef max
-
-#include <zen/build_info.h>
-
-namespace findplus
-{
-/*--------------
- |declarations|
- --------------*/
-
-struct FileInformation
-{
- FILETIME creationTime;
- FILETIME lastWriteTime;
- ULARGE_INTEGER fileSize;
- ULARGE_INTEGER fileId; //optional: may be 0 if not supported
- DWORD fileAttributes;
- DWORD reparseTag; //set if "fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT"
- DWORD shortNameLength;
- WCHAR shortName[MAX_PATH + 1]; //shortName is 0-terminated
-}; //no need for #pragma pack -> all members are perfectly 4, 8 byte aligned!
-
-class FileSearcher;
-typedef FileSearcher* FindHandle;
-
-DLL_FUNCTION_DECLARATION
-FindHandle openDir(const wchar_t* dirname); //returns nullptr on error, call ::GetLastError()
-//note: do NOT place an asterisk at end, e.g. C:\SomeDir\*, as you would do for ::FindFirstFile()
-
-DLL_FUNCTION_DECLARATION
-bool readDir(FindHandle hnd, FileInformation& output); //returns false on error or if there are no more files; ::GetLastError() returns ERROR_NO_MORE_FILES in this case
-/*
-warning: may also return with ERROR_NOT_SUPPORTED if "FileIdBothDirectoryInformation" is not supported! We need a fallback:
-
- sometimes it's *not* sufficient to use fallback for NtQueryDirectoryFile() alone, we need to reset "hDir", since it may be fucked up by some poor file system layer implementation:
- - Samba before v3.0.22 (Mar 30, 2006) seems to have a bug which sucessfully returns 128 elements via NtQueryDirectoryFile() and FileIdBothDirectoryInformation,
- then fails with STATUS_INVALID_LEVEL. Fallback to FileBothDirectoryInformation will return STATUS_NO_MORE_FILES, even if there *are* more files
- - NtQueryDirectoryFile() may *not* respect "restartScan" for some weird Win2000 file system drivers, so we cannot rely on this as a replacement for a "hDir" reset
- - Windows 7 Remote Desktop sharing does not work unless "hDir" is reset!
- => let's assume worst case in general and do a reset!
- perf note: implementing this reset at a folder level is possible, but a huge perf-killer (additional open/close handle), therefore fallback must apply to a complete folder (sub-)tree!
- => caller needs to handle this and implement FindFirstFile()/FindNextFile() fallback!
-*/
-
-DLL_FUNCTION_DECLARATION
-void closeDir(FindHandle hnd);
-
-/*----------
- |typedefs|
- ----------*/
-typedef FindHandle (*FunType_openDir )(const wchar_t* dirname);
-typedef bool (*FunType_readDir )(FindHandle hnd, FileInformation& dirInfo);
-typedef void (*FunType_closeDir)(FindHandle hnd);
-
-/*--------------
- |symbol names|
- --------------*/
-//const pointers ensure internal linkage
-const char funName_openDir [] = "openDir";
-const char funName_readDir [] = "readDir";
-const char funName_closeDir[] = "closeDir";
-
-/*---------------
- |library names|
- ---------------*/
-inline const wchar_t* getDllName() { return zen::is64BitBuild ? L"FindFilePlus_x64.dll" : L"FindFilePlus_Win32.dll"; }
-}
-
-#undef DLL_FUNCTION_DECLARATION
-
-#endif //FIND_FIRST_FILE_PLUS_HEADER_087483434
diff --git a/zen/FindFilePlus/init_dll_binding.h b/zen/FindFilePlus/init_dll_binding.h
deleted file mode 100644
index 44591ab4..00000000
--- a/zen/FindFilePlus/init_dll_binding.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
-// **************************************************************************
-
-#ifndef INIT_DLL_BINDING_HEADER_ß018356031467832145
-#define INIT_DLL_BINDING_HEADER_ß018356031467832145
-
-namespace findplus
-{
-//load and check dll binding at startup
-bool initDllBinding(); //evaluate in ::DllMain() when attaching process
-}
-
-#endif //INIT_DLL_BINDING_HEADER_ß018356031467832145
diff --git a/zen/FindFilePlus/load_dll.cpp b/zen/FindFilePlus/load_dll.cpp
deleted file mode 100644
index c9396f6d..00000000
--- a/zen/FindFilePlus/load_dll.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
-// **************************************************************************
-
-#include "load_dll.h"
-#define WIN32_LEAN_AND_MEAN
-#include <zen/win.h>
-
-void* /*FARPROC*/ dll::loadSymbol(const wchar_t* libraryName, const char* functionName)
-{
- return ::GetProcAddress(::GetModuleHandle(libraryName), functionName);
- //cleanup neither required nor allowed (::FreeLibrary())
-
-}
-//note: void* and FARPROC function pointer have same binary size on Windows
-
-
-void dll::setWin32Error(unsigned long lastError)
-{
- ::SetLastError(lastError);
-}
diff --git a/zen/FindFilePlus/load_dll.h b/zen/FindFilePlus/load_dll.h
deleted file mode 100644
index d661c4b9..00000000
--- a/zen/FindFilePlus/load_dll.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
-// **************************************************************************
-
-#ifndef LOAD_DLL_HEADER_0312463214872163832174
-#define LOAD_DLL_HEADER_0312463214872163832174
-
-namespace dll
-{
-void setWin32Error(unsigned long lastError);
-
-//NOTE: uses ::GetModuleHandle => call for system DLLs only!
-template <class Func>
-class SysDllFun
-{
-public:
- SysDllFun(const wchar_t* systemLibrary, const char* functionName) :
- fun(reinterpret_cast<Func>(loadSymbol(systemLibrary, functionName))) {}
-
- operator Func() const { return fun; }
-
-private:
- Func fun;
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-void* /*FARPROC*/ loadSymbol(const wchar_t* libraryName, const char* functionName);
-}
-
-#endif //LOAD_DLL_HEADER_0312463214872163832174
bgstack15