mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys,dll: support file name normalization
This commit is contained in:
parent
a653a010ce
commit
8d38a0dac6
@ -28,7 +28,7 @@ extern "C" {
|
|||||||
#if defined(WINFSP_SYS_INTERNAL) || defined(WINFSP_DLL_INTERNAL)
|
#if defined(WINFSP_SYS_INTERNAL) || defined(WINFSP_DLL_INTERNAL)
|
||||||
#define FSP_FSCTL_STATIC_ASSERT(e,m) static_assert(e,m)
|
#define FSP_FSCTL_STATIC_ASSERT(e,m) static_assert(e,m)
|
||||||
#else
|
#else
|
||||||
#define FSP_FSCTL_STATIC_ASSERT(e,m)
|
#define FSP_FSCTL_STATIC_ASSERT(e,m) static_assert(1,"")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FSP_FSCTL_DRIVER_NAME "WinFsp"
|
#define FSP_FSCTL_DRIVER_NAME "WinFsp"
|
||||||
@ -176,6 +176,12 @@ typedef struct
|
|||||||
UINT64 IndexNumber;
|
UINT64 IndexNumber;
|
||||||
} FSP_FSCTL_FILE_INFO;
|
} FSP_FSCTL_FILE_INFO;
|
||||||
typedef struct
|
typedef struct
|
||||||
|
{
|
||||||
|
FSP_FSCTL_FILE_INFO FileInfo;
|
||||||
|
PWSTR NormalizedName;
|
||||||
|
UINT16 NormalizedNameSize;
|
||||||
|
} FSP_FSCTL_OPEN_FILE_INFO;
|
||||||
|
typedef struct
|
||||||
{
|
{
|
||||||
UINT16 Size;
|
UINT16 Size;
|
||||||
FSP_FSCTL_FILE_INFO FileInfo;
|
FSP_FSCTL_FILE_INFO FileInfo;
|
||||||
@ -374,6 +380,7 @@ typedef struct
|
|||||||
UINT64 UserContext2; /* user context associated with file descriptor (handle) */
|
UINT64 UserContext2; /* user context associated with file descriptor (handle) */
|
||||||
UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
|
UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
|
||||||
FSP_FSCTL_FILE_INFO FileInfo;
|
FSP_FSCTL_FILE_INFO FileInfo;
|
||||||
|
FSP_FSCTL_TRANSACT_BUF FileName;
|
||||||
} Opened;
|
} Opened;
|
||||||
/* IoStatus.Status == STATUS_REPARSE */
|
/* IoStatus.Status == STATUS_REPARSE */
|
||||||
struct
|
struct
|
||||||
@ -425,6 +432,9 @@ typedef struct
|
|||||||
FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[];
|
FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[];
|
||||||
} FSP_FSCTL_TRANSACT_RSP;
|
} FSP_FSCTL_TRANSACT_RSP;
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX > FSP_FSCTL_TRANSACT_PATH_SIZEMAX,
|
||||||
|
"FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX must be greater than FSP_FSCTL_TRANSACT_PATH_SIZEMAX "
|
||||||
|
"to detect when a normalized name has been set during a Create/Open request.");
|
||||||
static inline BOOLEAN FspFsctlTransactCanProduceRequest(
|
static inline BOOLEAN FspFsctlTransactCanProduceRequest(
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, PVOID RequestBufEnd)
|
FSP_FSCTL_TRANSACT_REQ *Request, PVOID RequestBufEnd)
|
||||||
{
|
{
|
||||||
|
@ -1040,6 +1040,54 @@ FSP_API NTSTATUS FspFileSystemOpQueryStreamInformation(FSP_FILE_SYSTEM *FileSyst
|
|||||||
/*
|
/*
|
||||||
* Helpers
|
* Helpers
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* Get open information buffer.
|
||||||
|
*
|
||||||
|
* This is a helper for implementing the Create and Open operations. It cannot be used with
|
||||||
|
* any other operations.
|
||||||
|
*
|
||||||
|
* The FileInfo parameter to Create and Open is typed as pointer to FSP_FSCTL_FILE_INFO. The
|
||||||
|
* true type of this parameter is pointer to FSP_FSCTL_OPEN_FILE_INFO. This simple function
|
||||||
|
* converts from one type to the other.
|
||||||
|
*
|
||||||
|
* The FSP_FSCTL_OPEN_FILE_INFO type contains a FSP_FSCTL_FILE_INFO as well as the fields
|
||||||
|
* NormalizedName and NormalizedNameSize. These fields can be used for file name normalization.
|
||||||
|
* File name normalization is used to ensure that the FSD and the OS know the correct case
|
||||||
|
* of a newly opened file name.
|
||||||
|
*
|
||||||
|
* For case-sensitive file systems this functionality should be ignored. The FSD will always
|
||||||
|
* assume that the normalized file name is the same as the file name used to open the file.
|
||||||
|
*
|
||||||
|
* For case-insensitive file systems this functionality may be ignored. In this case the FSD
|
||||||
|
* will assume that the normalized file name is the upper case version of the file name used
|
||||||
|
* to open the file. The file system will work correctly and the only way an application will
|
||||||
|
* be able to tell that the file system does not preserve case in normalized file names is by
|
||||||
|
* issuing a GetFinalPathNameByHandle API call (or NtQueryInformationFile with
|
||||||
|
* FileNameInformation/FileNormalizedNameInformation).
|
||||||
|
*
|
||||||
|
* For case-insensitive file systems this functionality may also be used. In this case the
|
||||||
|
* user mode file system may use the NormalizedName and NormalizedNameSize parameters to
|
||||||
|
* report to the FSD the normalized file name. It should be noted that the normalized file
|
||||||
|
* name may only differ in case from the file name used to open the file. The NormalizedName
|
||||||
|
* field will point to a buffer that can receive the normalized file name. The
|
||||||
|
* NormalizedNameSize field will contain the size of the normalized file name buffer. On
|
||||||
|
* completion of the Create or Open operation it should contain the actual size of the
|
||||||
|
* normalized file name copied into the normalized file name buffer. The normalized file name
|
||||||
|
* should not contain a terminating zero.
|
||||||
|
*
|
||||||
|
* @param FileInfo
|
||||||
|
* The FileInfo parameter as passed to Create or Open operation.
|
||||||
|
* @return
|
||||||
|
* A pointer to the open information buffer for this Create or Open operation.
|
||||||
|
* @see
|
||||||
|
* Create
|
||||||
|
* Open
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
FSP_FSCTL_OPEN_FILE_INFO *FspFileSystemGetOpenFileInfo(FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
|
{
|
||||||
|
return (FSP_FSCTL_OPEN_FILE_INFO *)FileInfo;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Add directory information to a buffer.
|
* Add directory information to a buffer.
|
||||||
*
|
*
|
||||||
|
120
src/dll/fsop.c
120
src/dll/fsop.c
@ -353,7 +353,7 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
UINT32 GrantedAccess;
|
UINT32 GrantedAccess;
|
||||||
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor;
|
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor;
|
||||||
PVOID FileNode;
|
PVOID FileNode;
|
||||||
FSP_FSCTL_FILE_INFO FileInfo;
|
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||||
|
|
||||||
Result = FspFileSystemCreateCheck(FileSystem, Request, Response, TRUE,
|
Result = FspFileSystemCreateCheck(FileSystem, Request, Response, TRUE,
|
||||||
&GrantedAccess, &ParentDescriptor);
|
&GrantedAccess, &ParentDescriptor);
|
||||||
@ -366,19 +366,29 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
FileNode = 0;
|
FileNode = 0;
|
||||||
memset(&FileInfo, 0, sizeof FileInfo);
|
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||||
|
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||||
|
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||||
Result = FileSystem->Interface->Create(FileSystem, Request,
|
Result = FileSystem->Interface->Create(FileSystem, Request,
|
||||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||||
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
|
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
|
||||||
&FileNode, &FileInfo);
|
&FileNode, &OpenFileInfo.FileInfo);
|
||||||
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
|
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
|
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
|
||||||
|
{
|
||||||
|
Response->Size = (UINT16)(sizeof *Response + OpenFileInfo.NormalizedNameSize);
|
||||||
|
Response->Rsp.Create.Opened.FileName.Offset = 0;
|
||||||
|
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||||
|
}
|
||||||
|
|
||||||
Response->IoStatus.Information = FILE_CREATED;
|
Response->IoStatus.Information = FILE_CREATED;
|
||||||
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
||||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||||
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
|
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||||
|
&OpenFileInfo.FileInfo, sizeof OpenFileInfo.FileInfo);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,24 +398,34 @@ static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
UINT32 GrantedAccess;
|
UINT32 GrantedAccess;
|
||||||
PVOID FileNode;
|
PVOID FileNode;
|
||||||
FSP_FSCTL_FILE_INFO FileInfo;
|
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||||
|
|
||||||
Result = FspFileSystemOpenCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
Result = FspFileSystemOpenCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
||||||
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
|
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
FileNode = 0;
|
FileNode = 0;
|
||||||
memset(&FileInfo, 0, sizeof FileInfo);
|
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||||
|
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||||
|
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||||
Result = FileSystem->Interface->Open(FileSystem, Request,
|
Result = FileSystem->Interface->Open(FileSystem, Request,
|
||||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||||
&FileNode, &FileInfo);
|
&FileNode, &OpenFileInfo.FileInfo);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
|
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
|
||||||
|
{
|
||||||
|
Response->Size = (UINT16)(sizeof *Response + OpenFileInfo.NormalizedNameSize);
|
||||||
|
Response->Rsp.Create.Opened.FileName.Offset = 0;
|
||||||
|
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||||
|
}
|
||||||
|
|
||||||
Response->IoStatus.Information = FILE_OPENED;
|
Response->IoStatus.Information = FILE_OPENED;
|
||||||
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
||||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||||
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
|
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||||
|
&OpenFileInfo.FileInfo, sizeof OpenFileInfo.FileInfo);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +436,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
UINT32 GrantedAccess;
|
UINT32 GrantedAccess;
|
||||||
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor;
|
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor;
|
||||||
PVOID FileNode;
|
PVOID FileNode;
|
||||||
FSP_FSCTL_FILE_INFO FileInfo;
|
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||||
BOOLEAN Create = FALSE;
|
BOOLEAN Create = FALSE;
|
||||||
|
|
||||||
Result = FspFileSystemOpenCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
Result = FspFileSystemOpenCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
||||||
@ -430,10 +450,12 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (!Create)
|
if (!Create)
|
||||||
{
|
{
|
||||||
FileNode = 0;
|
FileNode = 0;
|
||||||
memset(&FileInfo, 0, sizeof FileInfo);
|
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||||
|
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||||
|
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||||
Result = FileSystem->Interface->Open(FileSystem, Request,
|
Result = FileSystem->Interface->Open(FileSystem, Request,
|
||||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||||
&FileNode, &FileInfo);
|
&FileNode, &OpenFileInfo.FileInfo);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
|
if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
|
||||||
@ -455,20 +477,30 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
FileNode = 0;
|
FileNode = 0;
|
||||||
memset(&FileInfo, 0, sizeof FileInfo);
|
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||||
|
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||||
|
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||||
Result = FileSystem->Interface->Create(FileSystem, Request,
|
Result = FileSystem->Interface->Create(FileSystem, Request,
|
||||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||||
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
|
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
|
||||||
&FileNode, &FileInfo);
|
&FileNode, &OpenFileInfo.FileInfo);
|
||||||
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
|
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
|
||||||
|
{
|
||||||
|
Response->Size = (UINT16)(sizeof *Response + OpenFileInfo.NormalizedNameSize);
|
||||||
|
Response->Rsp.Create.Opened.FileName.Offset = 0;
|
||||||
|
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||||
|
}
|
||||||
|
|
||||||
Response->IoStatus.Information = Create ? FILE_CREATED : FILE_OPENED;
|
Response->IoStatus.Information = Create ? FILE_CREATED : FILE_OPENED;
|
||||||
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
||||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||||
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
|
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||||
|
&OpenFileInfo.FileInfo, sizeof OpenFileInfo.FileInfo);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,7 +510,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
UINT32 GrantedAccess;
|
UINT32 GrantedAccess;
|
||||||
PVOID FileNode;
|
PVOID FileNode;
|
||||||
FSP_FSCTL_FILE_INFO FileInfo;
|
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||||
BOOLEAN Supersede = FILE_SUPERSEDE == ((Request->Req.Create.CreateOptions >> 24) & 0xff);
|
BOOLEAN Supersede = FILE_SUPERSEDE == ((Request->Req.Create.CreateOptions >> 24) & 0xff);
|
||||||
|
|
||||||
Result = FspFileSystemOverwriteCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
Result = FspFileSystemOverwriteCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
||||||
@ -486,17 +518,27 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
FileNode = 0;
|
FileNode = 0;
|
||||||
memset(&FileInfo, 0, sizeof FileInfo);
|
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||||
|
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||||
|
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||||
Result = FileSystem->Interface->Open(FileSystem, Request,
|
Result = FileSystem->Interface->Open(FileSystem, Request,
|
||||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||||
&FileNode, &FileInfo);
|
&FileNode, &OpenFileInfo.FileInfo);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
|
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
|
||||||
|
{
|
||||||
|
Response->Size = (UINT16)(sizeof *Response + OpenFileInfo.NormalizedNameSize);
|
||||||
|
Response->Rsp.Create.Opened.FileName.Offset = 0;
|
||||||
|
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||||
|
}
|
||||||
|
|
||||||
Response->IoStatus.Information = Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN;
|
Response->IoStatus.Information = Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN;
|
||||||
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
||||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||||
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
|
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||||
|
&OpenFileInfo.FileInfo, sizeof OpenFileInfo.FileInfo);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,7 +549,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
|||||||
UINT32 GrantedAccess;
|
UINT32 GrantedAccess;
|
||||||
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor;
|
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor;
|
||||||
PVOID FileNode;
|
PVOID FileNode;
|
||||||
FSP_FSCTL_FILE_INFO FileInfo;
|
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||||
BOOLEAN Create = FALSE;
|
BOOLEAN Create = FALSE;
|
||||||
|
|
||||||
Result = FspFileSystemOverwriteCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
Result = FspFileSystemOverwriteCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
||||||
@ -521,10 +563,12 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
|||||||
if (!Create)
|
if (!Create)
|
||||||
{
|
{
|
||||||
FileNode = 0;
|
FileNode = 0;
|
||||||
memset(&FileInfo, 0, sizeof FileInfo);
|
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||||
|
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||||
|
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||||
Result = FileSystem->Interface->Open(FileSystem, Request,
|
Result = FileSystem->Interface->Open(FileSystem, Request,
|
||||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||||
&FileNode, &FileInfo);
|
&FileNode, &OpenFileInfo.FileInfo);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
|
if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
|
||||||
@ -546,20 +590,30 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
|||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
FileNode = 0;
|
FileNode = 0;
|
||||||
memset(&FileInfo, 0, sizeof FileInfo);
|
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||||
|
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||||
|
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||||
Result = FileSystem->Interface->Create(FileSystem, Request,
|
Result = FileSystem->Interface->Create(FileSystem, Request,
|
||||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||||
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
|
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
|
||||||
&FileNode, &FileInfo);
|
&FileNode, &OpenFileInfo.FileInfo);
|
||||||
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
|
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
|
||||||
|
{
|
||||||
|
Response->Size = (UINT16)(sizeof *Response + OpenFileInfo.NormalizedNameSize);
|
||||||
|
Response->Rsp.Create.Opened.FileName.Offset = 0;
|
||||||
|
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||||
|
}
|
||||||
|
|
||||||
Response->IoStatus.Information = Create ? FILE_CREATED : FILE_OVERWRITTEN;
|
Response->IoStatus.Information = Create ? FILE_CREATED : FILE_OVERWRITTEN;
|
||||||
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
||||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||||
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
|
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||||
|
&OpenFileInfo.FileInfo, sizeof OpenFileInfo.FileInfo);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,7 +625,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
|
|||||||
PWSTR Parent, Suffix;
|
PWSTR Parent, Suffix;
|
||||||
UINT32 GrantedAccess;
|
UINT32 GrantedAccess;
|
||||||
PVOID FileNode;
|
PVOID FileNode;
|
||||||
FSP_FSCTL_FILE_INFO FileInfo;
|
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||||
UINT32 Information;
|
UINT32 Information;
|
||||||
|
|
||||||
Result = FspFileSystemOpenTargetDirectoryCheck(FileSystem, Request, Response, &GrantedAccess);
|
Result = FspFileSystemOpenTargetDirectoryCheck(FileSystem, Request, Response, &GrantedAccess);
|
||||||
@ -579,11 +633,13 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
|
|||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
FileNode = 0;
|
FileNode = 0;
|
||||||
memset(&FileInfo, 0, sizeof FileInfo);
|
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||||
|
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||||
|
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||||
FspPathSuffix((PWSTR)Request->Buffer, &Parent, &Suffix, Root);
|
FspPathSuffix((PWSTR)Request->Buffer, &Parent, &Suffix, Root);
|
||||||
Result = FileSystem->Interface->Open(FileSystem, Request,
|
Result = FileSystem->Interface->Open(FileSystem, Request,
|
||||||
Parent, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
Parent, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||||
&FileNode, &FileInfo);
|
&FileNode, &OpenFileInfo.FileInfo);
|
||||||
FspPathCombine((PWSTR)Request->Buffer, Suffix);
|
FspPathCombine((PWSTR)Request->Buffer, Suffix);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
@ -595,10 +651,18 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
|
|||||||
Information = NT_SUCCESS(Result) ? FILE_EXISTS : FILE_DOES_NOT_EXIST;
|
Information = NT_SUCCESS(Result) ? FILE_EXISTS : FILE_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
|
||||||
|
{
|
||||||
|
Response->Size = (UINT16)(sizeof *Response + OpenFileInfo.NormalizedNameSize);
|
||||||
|
Response->Rsp.Create.Opened.FileName.Offset = 0;
|
||||||
|
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||||
|
}
|
||||||
|
|
||||||
Response->IoStatus.Information = Information;
|
Response->IoStatus.Information = Information;
|
||||||
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
||||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||||
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
|
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||||
|
&OpenFileInfo.FileInfo, sizeof OpenFileInfo.FileInfo);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +488,7 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset,
|
RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset,
|
||||||
SecurityDescriptor, SecurityDescriptorSize);
|
SecurityDescriptor, SecurityDescriptorSize);
|
||||||
|
|
||||||
/* fix FileNode->FileName if we were doing SL_OPEN_TARGET_DIRECTORY */
|
/* fix FileNode->FileName if we are doing SL_OPEN_TARGET_DIRECTORY */
|
||||||
if (Request->Req.Create.OpenTargetDirectory)
|
if (Request->Req.Create.OpenTargetDirectory)
|
||||||
{
|
{
|
||||||
UNICODE_STRING Suffix;
|
UNICODE_STRING Suffix;
|
||||||
@ -605,6 +605,7 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
FSP_FILE_DESC *FileDesc = FspIopRequestContext(Request, RequestFileDesc);
|
FSP_FILE_DESC *FileDesc = FspIopRequestContext(Request, RequestFileDesc);
|
||||||
FSP_FILE_NODE *FileNode = FileDesc->FileNode;
|
FSP_FILE_NODE *FileNode = FileDesc->FileNode;
|
||||||
FSP_FILE_NODE *OpenedFileNode;
|
FSP_FILE_NODE *OpenedFileNode;
|
||||||
|
UNICODE_STRING NormalizedName;
|
||||||
PREPARSE_DATA_BUFFER ReparseData;
|
PREPARSE_DATA_BUFFER ReparseData;
|
||||||
UNICODE_STRING ReparseTargetPrefix0, ReparseTargetPrefix1, ReparseTargetPath;
|
UNICODE_STRING ReparseTargetPrefix0, ReparseTargetPrefix1, ReparseTargetPath;
|
||||||
|
|
||||||
@ -760,6 +761,35 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* populate the FileNode/FileDesc fields from the Response */
|
/* populate the FileNode/FileDesc fields from the Response */
|
||||||
|
if (!FsvolDeviceExtension->VolumeParams.CaseSensitiveSearch)
|
||||||
|
{
|
||||||
|
/* is there a normalized file name as part of the response? */
|
||||||
|
if (0 == Response->Rsp.Create.Opened.FileName.Size)
|
||||||
|
{
|
||||||
|
/* if not, the default is to upper case the name */
|
||||||
|
|
||||||
|
FspFileNameUpcase(&FileNode->FileName, &FileNode->FileName, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* if yes, verify it and then set it */
|
||||||
|
|
||||||
|
if (Response->Buffer + Response->Rsp.Create.Opened.FileName.Size >
|
||||||
|
(PUINT8)Response + Response->Size)
|
||||||
|
FSP_RETURN(Result = STATUS_OBJECT_NAME_INVALID);
|
||||||
|
|
||||||
|
NormalizedName.Length = NormalizedName.MaximumLength =
|
||||||
|
Response->Rsp.Create.Opened.FileName.Size;
|
||||||
|
NormalizedName.Buffer = (PVOID)Response->Buffer;
|
||||||
|
|
||||||
|
/* normalized file name can only differ in case from requested one */
|
||||||
|
if (0 != FspFileNameCompare(&FileNode->FileName, &NormalizedName, TRUE, 0))
|
||||||
|
FSP_RETURN(Result = STATUS_OBJECT_NAME_INVALID);
|
||||||
|
|
||||||
|
ASSERT(FileNode->FileName.Length == NormalizedName.Length);
|
||||||
|
RtlCopyMemory(FileNode->FileName.Buffer, NormalizedName.Buffer, NormalizedName.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
FileNode->UserContext = Response->Rsp.Create.Opened.UserContext;
|
FileNode->UserContext = Response->Rsp.Create.Opened.UserContext;
|
||||||
FileNode->IndexNumber = Response->Rsp.Create.Opened.FileInfo.IndexNumber;
|
FileNode->IndexNumber = Response->Rsp.Create.Opened.FileInfo.IndexNumber;
|
||||||
FileNode->IsDirectory = BooleanFlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes,
|
FileNode->IsDirectory = BooleanFlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes,
|
||||||
|
@ -699,6 +699,11 @@ static RTL_GENERIC_COMPARE_RESULTS NTAPI FspFsvolDeviceCompareContextByName(
|
|||||||
PUNICODE_STRING SecondFileName = *(PUNICODE_STRING *)SecondElement;
|
PUNICODE_STRING SecondFileName = *(PUNICODE_STRING *)SecondElement;
|
||||||
LONG ComparisonResult;
|
LONG ComparisonResult;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since FileNode FileName's are now always normalized, we could perhaps get away
|
||||||
|
* with using CaseInsensitive == FALSE at all times. For safety reasons we avoid
|
||||||
|
* doing so here.
|
||||||
|
*/
|
||||||
ComparisonResult = FspFileNameCompare(FirstFileName, SecondFileName, CaseInsensitive, 0);
|
ComparisonResult = FspFileNameCompare(FirstFileName, SecondFileName, CaseInsensitive, 0);
|
||||||
|
|
||||||
if (0 > ComparisonResult)
|
if (0 > ComparisonResult)
|
||||||
|
@ -437,6 +437,10 @@ BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, PUNICODE_STRING StreamPart, PUL
|
|||||||
BOOLEAN FspFileNameIsValidPattern(PUNICODE_STRING Pattern);
|
BOOLEAN FspFileNameIsValidPattern(PUNICODE_STRING Pattern);
|
||||||
VOID FspFileNameSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix);
|
VOID FspFileNameSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix);
|
||||||
#if 0
|
#if 0
|
||||||
|
NTSTATUS FspFileNameUpcase(
|
||||||
|
PUNICODE_STRING DestinationName,
|
||||||
|
PUNICODE_STRING SourceName,
|
||||||
|
PCWCH UpcaseTable);
|
||||||
LONG FspFileNameCompare(
|
LONG FspFileNameCompare(
|
||||||
PUNICODE_STRING Name1,
|
PUNICODE_STRING Name1,
|
||||||
PUNICODE_STRING Name2,
|
PUNICODE_STRING Name2,
|
||||||
@ -448,6 +452,7 @@ BOOLEAN FspFileNameIsPrefix(
|
|||||||
BOOLEAN IgnoreCase,
|
BOOLEAN IgnoreCase,
|
||||||
PCWCH UpcaseTable);
|
PCWCH UpcaseTable);
|
||||||
#else
|
#else
|
||||||
|
#define FspFileNameUpcase(D,S,U) (ASSERT(0 == (U)), RtlUpcaseUnicodeString(D,S,FALSE))
|
||||||
#define FspFileNameCompare(N1,N2,I,U) (ASSERT(0 == (U)), RtlCompareUnicodeString(N1,N2,I))
|
#define FspFileNameCompare(N1,N2,I,U) (ASSERT(0 == (U)), RtlCompareUnicodeString(N1,N2,I))
|
||||||
#define FspFileNameIsPrefix(N1,N2,I,U) (ASSERT(0 == (U)), RtlPrefixUnicodeString(N1,N2,I))
|
#define FspFileNameIsPrefix(N1,N2,I,U) (ASSERT(0 == (U)), RtlPrefixUnicodeString(N1,N2,I))
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,6 +27,11 @@
|
|||||||
*/
|
*/
|
||||||
#define MEMFS_NAMED_STREAMS
|
#define MEMFS_NAMED_STREAMS
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the MEMFS_NAME_NORMALIZATION macro to include name normalization support.
|
||||||
|
*/
|
||||||
|
#define MEMFS_NAME_NORMALIZATION
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define the DEBUG_BUFFER_CHECK macro on Windows 8 or above. This includes
|
* Define the DEBUG_BUFFER_CHECK macro on Windows 8 or above. This includes
|
||||||
* a check for the Write buffer to ensure that it is read-only.
|
* a check for the Write buffer to ensure that it is read-only.
|
||||||
@ -500,7 +505,11 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
{
|
{
|
||||||
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
|
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
|
||||||
|
#if defined(MEMFS_NAME_NORMALIZATION)
|
||||||
|
WCHAR FileNameBuf[MAX_PATH];
|
||||||
|
#endif
|
||||||
MEMFS_FILE_NODE *FileNode;
|
MEMFS_FILE_NODE *FileNode;
|
||||||
|
MEMFS_FILE_NODE *ParentNode;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
BOOLEAN Inserted;
|
BOOLEAN Inserted;
|
||||||
|
|
||||||
@ -511,7 +520,8 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (0 != FileNode)
|
if (0 != FileNode)
|
||||||
return STATUS_OBJECT_NAME_COLLISION;
|
return STATUS_OBJECT_NAME_COLLISION;
|
||||||
|
|
||||||
if (!MemfsFileNodeMapGetParent(Memfs->FileNodeMap, FileName, &Result))
|
ParentNode = MemfsFileNodeMapGetParent(Memfs->FileNodeMap, FileName, &Result);
|
||||||
|
if (0 == ParentNode)
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
if (MemfsFileNodeMapCount(Memfs->FileNodeMap) >= Memfs->MaxFileNodes)
|
if (MemfsFileNodeMapCount(Memfs->FileNodeMap) >= Memfs->MaxFileNodes)
|
||||||
@ -520,6 +530,31 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (AllocationSize > Memfs->MaxFileSize)
|
if (AllocationSize > Memfs->MaxFileSize)
|
||||||
return STATUS_DISK_FULL;
|
return STATUS_DISK_FULL;
|
||||||
|
|
||||||
|
#if defined(MEMFS_NAME_NORMALIZATION)
|
||||||
|
if (MemfsFileNodeMapIsCaseInsensitive(Memfs->FileNodeMap))
|
||||||
|
{
|
||||||
|
WCHAR Root[2] = L"\\";
|
||||||
|
PWSTR Remain, Suffix;
|
||||||
|
size_t RemainLength, BSlashLength, SuffixLength;
|
||||||
|
|
||||||
|
FspPathSuffix(FileName, &Remain, &Suffix, Root);
|
||||||
|
assert(0 == MemfsCompareString(Remain, -1, ParentNode->FileName, -1, TRUE));
|
||||||
|
FspPathCombine(FileName, Suffix);
|
||||||
|
|
||||||
|
RemainLength = wcslen(ParentNode->FileName);
|
||||||
|
BSlashLength = 1 < RemainLength;
|
||||||
|
SuffixLength = wcslen(Suffix);
|
||||||
|
if (MAX_PATH <= RemainLength + BSlashLength + SuffixLength)
|
||||||
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
|
||||||
|
memcpy(FileNameBuf, ParentNode->FileName, RemainLength * sizeof(WCHAR));
|
||||||
|
memcpy(FileNameBuf + RemainLength, L"\\", BSlashLength * sizeof(WCHAR));
|
||||||
|
memcpy(FileNameBuf + RemainLength + BSlashLength, Suffix, (SuffixLength + 1) * sizeof(WCHAR));
|
||||||
|
|
||||||
|
FileName = FileNameBuf;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Result = MemfsFileNodeCreate(FileName, &FileNode);
|
Result = MemfsFileNodeCreate(FileName, &FileNode);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
@ -567,6 +602,17 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
*PFileNode = FileNode;
|
*PFileNode = FileNode;
|
||||||
MemfsFileNodeGetFileInfo(FileNode, FileInfo);
|
MemfsFileNodeGetFileInfo(FileNode, FileInfo);
|
||||||
|
|
||||||
|
#if defined(MEMFS_NAME_NORMALIZATION)
|
||||||
|
if (MemfsFileNodeMapIsCaseInsensitive(Memfs->FileNodeMap))
|
||||||
|
{
|
||||||
|
FSP_FSCTL_OPEN_FILE_INFO *OpenFileInfo = FspFileSystemGetOpenFileInfo(FileInfo);
|
||||||
|
|
||||||
|
wcscpy_s(OpenFileInfo->NormalizedName, OpenFileInfo->NormalizedNameSize / sizeof(WCHAR),
|
||||||
|
FileNode->FileName);
|
||||||
|
OpenFileInfo->NormalizedNameSize = (UINT16)(wcslen(FileNode->FileName) * sizeof(WCHAR));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,6 +651,17 @@ static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
*PFileNode = FileNode;
|
*PFileNode = FileNode;
|
||||||
MemfsFileNodeGetFileInfo(FileNode, FileInfo);
|
MemfsFileNodeGetFileInfo(FileNode, FileInfo);
|
||||||
|
|
||||||
|
#if defined(MEMFS_NAME_NORMALIZATION)
|
||||||
|
if (MemfsFileNodeMapIsCaseInsensitive(Memfs->FileNodeMap))
|
||||||
|
{
|
||||||
|
FSP_FSCTL_OPEN_FILE_INFO *OpenFileInfo = FspFileSystemGetOpenFileInfo(FileInfo);
|
||||||
|
|
||||||
|
wcscpy_s(OpenFileInfo->NormalizedName, OpenFileInfo->NormalizedNameSize / sizeof(WCHAR),
|
||||||
|
FileNode->FileName);
|
||||||
|
OpenFileInfo->NormalizedNameSize = (UINT16)(wcslen(FileNode->FileName) * sizeof(WCHAR));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,11 +243,11 @@ static void reparse_symlink_dotest0(ULONG Flags, PWSTR Prefix,
|
|||||||
else
|
else
|
||||||
ASSERT(PNameInfo->FileNameLength == wcslen(FilePath + 1) * sizeof(WCHAR));
|
ASSERT(PNameInfo->FileNameLength == wcslen(FilePath + 1) * sizeof(WCHAR));
|
||||||
if (-1 == Flags)
|
if (-1 == Flags)
|
||||||
ASSERT(0 == memcmp(FilePath + 6, PNameInfo->FileName, PNameInfo->FileNameLength));
|
ASSERT(0 == mywcscmp(FilePath + 6, -1, PNameInfo->FileName, PNameInfo->FileNameLength / sizeof(WCHAR)));
|
||||||
else if (0 == Prefix)
|
else if (0 == Prefix)
|
||||||
ASSERT(0 == memcmp(L"\\file0", PNameInfo->FileName, PNameInfo->FileNameLength));
|
ASSERT(0 == mywcscmp(L"\\file0", -1, PNameInfo->FileName, PNameInfo->FileNameLength / sizeof(WCHAR)));
|
||||||
else
|
else
|
||||||
ASSERT(0 == memcmp(FilePath + 1, PNameInfo->FileName, PNameInfo->FileNameLength));
|
ASSERT(0 == mywcscmp(FilePath + 1, -1, PNameInfo->FileName, PNameInfo->FileNameLength / sizeof(WCHAR)));
|
||||||
|
|
||||||
CloseHandle(Handle);
|
CloseHandle(Handle);
|
||||||
|
|
||||||
@ -400,11 +400,11 @@ static BOOL my_namecheck_fn(ULONG Flags, PWSTR Prefix, void *memfs, PWSTR FileNa
|
|||||||
else
|
else
|
||||||
ASSERT(PNameInfo->FileNameLength == wcslen(ExpectedPath + 1) * sizeof(WCHAR));
|
ASSERT(PNameInfo->FileNameLength == wcslen(ExpectedPath + 1) * sizeof(WCHAR));
|
||||||
if (-1 == Flags)
|
if (-1 == Flags)
|
||||||
ASSERT(0 == memcmp(ExpectedPath + 6, PNameInfo->FileName, PNameInfo->FileNameLength));
|
ASSERT(0 == mywcscmp(ExpectedPath + 6, -1, PNameInfo->FileName, PNameInfo->FileNameLength / sizeof(WCHAR)));
|
||||||
else if (0 == Prefix)
|
else if (0 == Prefix)
|
||||||
ASSERT(0 == memcmp(ExpectedPath, PNameInfo->FileName, PNameInfo->FileNameLength));
|
ASSERT(0 == mywcscmp(ExpectedPath, -1, PNameInfo->FileName, PNameInfo->FileNameLength / sizeof(WCHAR)));
|
||||||
else
|
else
|
||||||
ASSERT(0 == memcmp(ExpectedPath + 1, PNameInfo->FileName, PNameInfo->FileNameLength));
|
ASSERT(0 == mywcscmp(ExpectedPath + 1, -1, PNameInfo->FileName, PNameInfo->FileNameLength / sizeof(WCHAR)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(Handle);
|
CloseHandle(Handle);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user