diff --git a/build/VStudio/launcher/launchctl.vcxproj b/build/VStudio/launcher/launchctl.vcxproj index bdf8043a..324c29a3 100644 --- a/build/VStudio/launcher/launchctl.vcxproj +++ b/build/VStudio/launcher/launchctl.vcxproj @@ -105,7 +105,8 @@ false Default MultiThreaded - /Gs16384 %(AdditionalOptions) + + Console @@ -125,7 +126,8 @@ false Default MultiThreaded - /Gs16384 %(AdditionalOptions) + + Console @@ -146,7 +148,8 @@ ..\..\..\src;..\..\..\inc false MultiThreaded - /Gs16384 %(AdditionalOptions) + + Console @@ -169,7 +172,8 @@ ..\..\..\src;..\..\..\inc false MultiThreaded - /Gs16384 %(AdditionalOptions) + + Console diff --git a/build/VStudio/launcher/launcher.vcxproj b/build/VStudio/launcher/launcher.vcxproj index fbc3f536..f4cff181 100644 --- a/build/VStudio/launcher/launcher.vcxproj +++ b/build/VStudio/launcher/launcher.vcxproj @@ -105,7 +105,8 @@ Default false MultiThreaded - /Gs16384 %(AdditionalOptions) + + Console @@ -126,7 +127,8 @@ Default false MultiThreaded - /Gs16384 %(AdditionalOptions) + + Console @@ -148,7 +150,8 @@ ..\..\..\src;..\..\..\inc false MultiThreaded - /Gs16384 %(AdditionalOptions) + + Console @@ -172,7 +175,8 @@ ..\..\..\src;..\..\..\inc false MultiThreaded - /Gs16384 %(AdditionalOptions) + + Console diff --git a/build/VStudio/winfsp_dll.vcxproj b/build/VStudio/winfsp_dll.vcxproj index e283cd60..aafc9c99 100644 --- a/build/VStudio/winfsp_dll.vcxproj +++ b/build/VStudio/winfsp_dll.vcxproj @@ -173,7 +173,8 @@ copy /b $(OutDir)fuse-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse-$(Platfor MultiThreaded Default false - /Gs16384 %(AdditionalOptions) + + Windows @@ -200,7 +201,8 @@ copy /b $(OutDir)fuse-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse-$(Platfor MultiThreaded Default false - /Gs16384 %(AdditionalOptions) + + Windows @@ -228,7 +230,8 @@ copy /b $(OutDir)fuse-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse-$(Platfor ..\..\src;..\..\inc MultiThreaded false - /Gs16384 %(AdditionalOptions) + + Windows @@ -258,7 +261,8 @@ copy /b $(OutDir)fuse-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse-$(Platfor ..\..\src;..\..\inc MultiThreaded false - /Gs16384 %(AdditionalOptions) + + Windows diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index d45957c5..b574288a 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -69,13 +69,13 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_VOLUME_NAME_SIZEMAX <= 260 * sizeof(WCHAR), "Max volume name size is greater than MAX_PATH."); -#define FSP_FSCTL_TRANSACT_PATH_SIZEMAX 2048 +#define FSP_FSCTL_TRANSACT_PATH_SIZEMAX (1024 * sizeof(WCHAR)) -#define FSP_FSCTL_TRANSACT_REQ_SIZEMAX (4096 - 64) /* 64: size for internal request header */ -#define FSP_FSCTL_TRANSACT_RSP_SIZEMAX (4096 - 64) /* symmetry! */ +#define FSP_FSCTL_TRANSACT_REQ_SIZEMAX (16 * 1024 - 64) /* 64: size for internal request header */ +#define FSP_FSCTL_TRANSACT_RSP_SIZEMAX (16 * 1024) #define FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMAX (FSP_FSCTL_TRANSACT_REQ_SIZEMAX - sizeof(FSP_FSCTL_TRANSACT_REQ)) #define FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX (FSP_FSCTL_TRANSACT_RSP_SIZEMAX - sizeof(FSP_FSCTL_TRANSACT_RSP)) -#define FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN 16384 +#define FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN (64 * 1024) #define FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN FSP_FSCTL_TRANSACT_REQ_SIZEMAX #define FSP_FSCTL_TRANSACT_USERCONTEXT(s,i) (((PUINT64)&(s).UserContext)[i]) diff --git a/src/dll/fsop.c b/src/dll/fsop.c index c1a3cf9b..27376423 100644 --- a/src/dll/fsop.c +++ b/src/dll/fsop.c @@ -951,7 +951,7 @@ FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem, if (0 == FileSystem->Interface->GetSecurity) return STATUS_INVALID_DEVICE_REQUEST; - SecurityDescriptorSize = FSP_FSCTL_TRANSACT_RSP_SIZEMAX - sizeof *Response; + SecurityDescriptorSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX; Result = FileSystem->Interface->GetSecurity(FileSystem, Request, (PVOID)USERCONTEXT(Request->Req.QuerySecurity), Response->Buffer, &SecurityDescriptorSize); @@ -989,7 +989,7 @@ FSP_API NTSTATUS FspFileSystemOpQueryStreamInformation(FSP_FILE_SYSTEM *FileSyst Result = FileSystem->Interface->GetStreamInfo(FileSystem, Request, (PVOID)USERCONTEXT(Request->Req.QueryStreamInformation), Response->Buffer, - FSP_FSCTL_TRANSACT_RSP_SIZEMAX - sizeof *Response, + FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX, &BytesTransferred); if (!NT_SUCCESS(Result)) return Result; @@ -1088,23 +1088,18 @@ FSP_API BOOLEAN FspFileSystemFindReparsePoint(FSP_FILE_SYSTEM *FileSystem, return FALSE; } -FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, +FSP_API NTSTATUS FspFileSystemResolveReparsePointsInternal(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*GetReparsePointByName)( FSP_FILE_SYSTEM *FileSystem, PVOID Context, PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize), PVOID Context, + PREPARSE_DATA_BUFFER ReparseData, SIZE_T ReparseDataSize0, PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent0, PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize) { PREPARSE_DATA_BUFFER OutputReparseData; PWSTR TargetPath, RemainderPath, LastPathComponent, NewRemainderPath, ReparseTargetPath; WCHAR RemainderChar; - union - { - REPARSE_DATA_BUFFER V; - UINT8 B[FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX]; - } ReparseDataBuf; - PREPARSE_DATA_BUFFER ReparseData = &ReparseDataBuf.V; SIZE_T ReparseDataSize, RemainderPathSize, ReparseTargetPathLength; BOOLEAN ResolveLastPathComponent; ULONG MaxTries = 32; @@ -1188,7 +1183,7 @@ FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, } RemainderChar = *RemainderPath; *RemainderPath = L'\0'; - ReparseDataSize = sizeof ReparseDataBuf; + ReparseDataSize = ReparseDataSize0; Result = GetReparsePointByName(FileSystem, Context, TargetPath, '\0' != RemainderChar, ReparseData, &ReparseDataSize); *RemainderPath = RemainderChar; @@ -1277,6 +1272,32 @@ reparse_data_exit: return STATUS_REPARSE; } +FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem, + NTSTATUS (*GetReparsePointByName)( + FSP_FILE_SYSTEM *FileSystem, PVOID Context, + PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize), + PVOID Context, + PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, + PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize) +{ + PREPARSE_DATA_BUFFER ReparseData; + NTSTATUS Result; + + ReparseData = MemAlloc(FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX); + if (0 == ReparseData) + return STATUS_INSUFFICIENT_RESOURCES; + + Result = FspFileSystemResolveReparsePointsInternal(FileSystem, + GetReparsePointByName, Context, + ReparseData, FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX, + FileName, ReparsePointIndex, ResolveLastPathComponent, + PIoStatus, Buffer, PSize); + + MemFree(ReparseData); + + return Result; +} + FSP_API NTSTATUS FspFileSystemCanReplaceReparsePoint( PVOID CurrentReparseData, SIZE_T CurrentReparseDataSize, PVOID ReplaceReparseData, SIZE_T ReplaceReparseDataSize) diff --git a/src/shared/minimal.h b/src/shared/minimal.h index d0bfdd7a..a734edaa 100644 --- a/src/shared/minimal.h +++ b/src/shared/minimal.h @@ -26,11 +26,10 @@ * - "C/C++ > Code Generation > Basic Runtime Checks" must be set to "Default" * - "C/C++ > Code Generation > Runtime Library" must be set to "Multi-threaded (/MT)". * - "C/C++ > Code Generation > Security Check" must be disabled (/GS-). - * - "C/C++ > Command Line > Additional Options" add "/Gs16384" to disable __chkstk probes. * - "Linker > Input > Ignore All Default Libraries" must be "Yes". * * - * Update: + * Update 1: * * It is possible to have the "Linker > Input > Ignore All Default Libraries" * setting to "No" and still eliminate most dependencies on the MSVCRT libraries. @@ -44,6 +43,22 @@ * that are not required (or worse create a half-baked CRT). For example, the WinFsp * DLL ensures this by setting the "Linker > Input > Ignore All Default Libraries" * to "Yes" on 64-bit builds and "No" on 32-bit builds. + * + * + * Update 2: + * + * Using the /Gs[size] compiler option with a large size is a very bad idea. + * Turns out that the compiler uses the _chkstk call to ensure that enough + * stack space has been committed even when a function accesses locations in + * the stack below the guard page. + * + * The following links explain the problem very well: + * - http://stackoverflow.com/questions/8400118/what-is-the-purpose-of-the-chkstk-function#8400171 + * - https://support.microsoft.com/en-us/kb/100775 + * + * A library/program that does not wish to use the MSVCRT libraries (and hence + * does not have _chkstk available) must take care to not use more than a page + * (4096 bytes) of stack within a single function. */ #undef RtlFillMemory diff --git a/src/sys/driver.h b/src/sys/driver.h index 4cffe2af..699123e3 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -735,7 +735,7 @@ enum FspFsvolDeviceDirInfoCacheCapacity = 100, FspFsvolDeviceDirInfoCacheItemSizeMax = FSP_FSCTL_ALIGN_UP(16384, PAGE_SIZE), FspFsvolDeviceStreamInfoCacheCapacity = 100, - FspFsvolDeviceStreamInfoCacheItemSizeMax = 4096, + FspFsvolDeviceStreamInfoCacheItemSizeMax = FSP_FSCTL_ALIGN_UP(16384, PAGE_SIZE), }; typedef struct {