diff --git a/daemon/from_kernel.h b/daemon/from_kernel.h index 3d51573..c14c398 100644 --- a/daemon/from_kernel.h +++ b/daemon/from_kernel.h @@ -204,6 +204,16 @@ typedef struct _FILE_GET_EA_INFORMATION { CHAR EaName[1]; } FILE_GET_EA_INFORMATION, *PFILE_GET_EA_INFORMATION; +typedef struct _FILE_NETWORK_OPEN_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; +} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION; + /* wdm.h */ typedef enum _FSINFOCLASS { FileFsVolumeInformation = 1, diff --git a/daemon/getattr.c b/daemon/getattr.c index 42c37ff..d54eb72 100644 --- a/daemon/getattr.c +++ b/daemon/getattr.c @@ -112,6 +112,9 @@ static int handle_getattr(nfs41_upcall *upcall) case FileInternalInformation: args->intr_info.IndexNumber.QuadPart = info.fileid; break; + case FileNetworkOpenInformation: + nfs_to_network_openinfo(&info, &args->network_info); + break; default: eprintf("unhandled file query class %d\n", args->query_class); status = ERROR_INVALID_PARAMETER; @@ -156,6 +159,13 @@ static int marshall_getattr(unsigned char *buffer, uint32_t *length, nfs41_upcal status = safe_write(&buffer, length, &args->intr_info, info_len); if (status) goto out; break; + case FileNetworkOpenInformation: + info_len = sizeof(args->network_info); + status = safe_write(&buffer, length, &info_len, sizeof(info_len)); + if (status) goto out; + status = safe_write(&buffer, length, &args->network_info, info_len); + if (status) goto out; + break; default: eprintf("unknown file query class %d\n", args->query_class); status = 103; diff --git a/daemon/upcall.h b/daemon/upcall.h index 560722f..80f5c0d 100644 --- a/daemon/upcall.h +++ b/daemon/upcall.h @@ -90,6 +90,7 @@ typedef struct __getattr_upcall_args { FILE_STANDARD_INFO std_info; FILE_ATTRIBUTE_TAG_INFO tag_info; FILE_INTERNAL_INFORMATION intr_info; + FILE_NETWORK_OPEN_INFORMATION network_info; int query_class; int buf_len; int query_reply_len; diff --git a/daemon/util.c b/daemon/util.c index 41c18a1..ca955fe 100644 --- a/daemon/util.c +++ b/daemon/util.c @@ -186,6 +186,21 @@ void nfs_to_standard_info( TRUE : FALSE; } +void nfs_to_network_openinfo( + IN const nfs41_file_info *info, + OUT PFILE_NETWORK_OPEN_INFORMATION net_out) +{ + + nfs_time_to_file_time(&info->time_create, &net_out->CreationTime); + nfs_time_to_file_time(&info->time_access, &net_out->LastAccessTime); + nfs_time_to_file_time(&info->time_modify, &net_out->LastWriteTime); + /* XXX: was using 'change' attr, but that wasn't giving a time */ + nfs_time_to_file_time(&info->time_modify, &net_out->ChangeTime); + net_out->AllocationSize.QuadPart = + net_out->EndOfFile.QuadPart = (LONGLONG)info->size; + net_out->FileAttributes = nfs_file_info_to_attributes(info); +} + void get_file_time( OUT PLARGE_INTEGER file_time) { diff --git a/daemon/util.h b/daemon/util.h index c4f8e5e..f9baaed 100644 --- a/daemon/util.h +++ b/daemon/util.h @@ -23,6 +23,7 @@ #define __NFS41_DAEMON_UTIL_H__ #include "nfs41_types.h" +#include "from_kernel.h" extern DWORD NFS41D_VERSION; struct __nfs41_session; @@ -102,6 +103,9 @@ void nfs_to_basic_info( void nfs_to_standard_info( IN const nfs41_file_info *info, OUT PFILE_STANDARD_INFO std_out); +void nfs_to_network_openinfo( + IN const nfs41_file_info *info, + OUT PFILE_NETWORK_OPEN_INFORMATION std_out); /* http://msdn.microsoft.com/en-us/library/ms724290%28VS.85%29.aspx: * A file time is a 64-bit value that represents the number of diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c index 439e060..e34c5ea 100644 --- a/sys/nfs41_driver.c +++ b/sys/nfs41_driver.c @@ -5044,6 +5044,7 @@ NTSTATUS nfs41_QueryFileInformation( case FileStandardInformation: case FileInternalInformation: case FileAttributeTagInformation: + case FileNetworkOpenInformation: break; default: print_error("nfs41_QueryFileInformation: unhandled class %d\n", InfoClass);