ls.exe -n does not work on NFS filesystems, e.g. Windows NFSv3 driver, OpenText/Exceed NFSv4 driver, ms-nfs41-client driver.
All these drivers implement the ServicesForUNIX API to obtain stat()-alike information.
The API is simply to get the EA "NfsV3Attributes" for for a file or directory, which contains a nfs3_attrs struct:
#define EA_NFSV3ATTRIBUTES "NfsV3Attributes"
#define EA_NFSV3ATTRIBUTES_LEN (15)
/*
* "NfsV3Attributes" uses |nfs3_attrs| as content
*/
/*
* Note that we cannot use <stdint.h> in the Windows kernel, so we
* use Windows Types here
*/
typedef struct _nfs3_attrs_timestruc_t {
INT32 tv_sec;
UINT32 tv_nsec;
} nfs3_attrs_timestruc_t;
typedef struct _nfs3_attrs {
UINT32 type, mode, nlink, uid, gid, filler1;
UINT64 size, used;
struct {
UINT32 specdata1;
UINT32 specdata2;
} rdev;
UINT64 fsid, fileid;
nfs3_attrs_timestruc_t atime, mtime, ctime;
} nfs3_attrs;
enum ftype3 {
NF3REG = 1,
NF3DIR,
NF3BLK,
NF3CHR,
NF3LNK,
NF3SOCK,
NF3FIFO
};
int get_nfs3attr(const char *progname, const char *filename)
{
int res = EXIT_FAILURE;
HANDLE fileHandle = CreateFileA(filename,
GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (fileHandle == INVALID_HANDLE_VALUE) {
(void)fprintf(stderr,
"%s: Error opening file '%s'. Last error was %d.\n",
progname,
filename,
(int)GetLastError());
return EXIT_FAILURE;
}
struct {
FILE_FULL_EA_INFORMATION ffeai;
char buf[sizeof(EA_NFSV3ATTRIBUTES) + sizeof(nfs3_attrs)];
} ffeai_buf;
struct {
FILE_GET_EA_INFORMATION fgeai;
char buf[sizeof(EA_NFSV3ATTRIBUTES)];
} fgeai_buf;
NTSTATUS status;
IO_STATUS_BLOCK io;
fgeai_buf.fgeai.NextEntryOffset = 0;
fgeai_buf.fgeai.EaNameLength = 15;
(void)strcpy(fgeai_buf.fgeai.EaName, EA_NFSV3ATTRIBUTES);
status = ZwQueryEaFile(fileHandle, &io,
&ffeai_buf.ffeai, sizeof(ffeai_buf), TRUE,
&fgeai_buf.fgeai, sizeof(fgeai_buf), NULL, TRUE);
switch (status) {
case STATUS_SUCCESS:
break;
case STATUS_NO_EAS_ON_FILE:
(void)fprintf(stderr, "No EAs on file, status=0x%lx.\n", (long)status);
res = EXIT_FAILURE;
goto done;
default:
(void)fprintf(stderr, "ZwQueryEaFile() failed with 0x%lx\n", (long)status);
res = EXIT_FAILURE;
goto done;
}
if (ffeai_buf.ffeai.EaValueLength < sizeof(nfs3_attrs)) {
(void)fprintf(stderr,
"EA '%s' size too small (%ld bytes), "
"expected at least %ld bytes for nfs3_attrs\n",
EA_NFSV3ATTRIBUTES,
(long)ffeai_buf.ffeai.EaValueLength,
(long)sizeof(nfs3_attrs));
res = EXIT_FAILURE;
goto done;
}
nfs3_attrs *n3a = (nfs3_attrs *)(ffeai_buf.ffeai.EaName
+ ffeai_buf.ffeai.EaNameLength + 1);
(void)printf("(\n");
(void)printf("\tfilename='%s'\n"
"\ttype=%d\n"
"\tmode=0%o\n"
"\tnlink=%d\n"
"\tuid=%d\n\tgid=%d\n"
"\tsize=%lld\n\tused=%lld\n"
"\trdev=( specdata1=0x%x specdata2=0x%x )\n"
"\tfsid=0x%llx\n\tfileid=0x%llx\n"
"\tatime=( tv_sec=%ld tv_nsec=%lu )\n"
"\tmtime=( tv_sec=%ld tv_nsec=%lu )\n"
"\tctime=( tv_sec=%ld tv_nsec=%lu )\n"
")\n",
filename,
(int)n3a->type,
(int)n3a->mode,
(int)n3a->nlink,
(int)n3a->uid,
(int)n3a->gid,
(long long)n3a->size,
(long long)n3a->used,
(int)n3a->rdev.specdata1,
(int)n3a->rdev.specdata2,
(unsigned long long)n3a->fsid,
(unsigned long long)n3a->fileid,
(long)n3a->atime.tv_sec, (unsigned long)n3a->atime.tv_nsec,
(long)n3a->mtime.tv_sec, (unsigned long)n3a->mtime.tv_nsec,
(long)n3a->ctime.tv_sec, (unsigned long)n3a->ctime.tv_nsec);
res = EXIT_SUCCESS;
done:
(void)CloseHandle(fileHandle);
return res;
}
ls.exe -n does not work on NFS filesystems, e.g. Windows NFSv3 driver, OpenText/Exceed NFSv4 driver, ms-nfs41-client driver.
All these drivers implement the ServicesForUNIX API to obtain stat()-alike information.
The API is simply to get the EA "NfsV3Attributes" for for a file or directory, which contains a
nfs3_attrsstruct:Example function, based on https://github.com/kofemann/ms-nfs41-client/blob/master/include/nfs_ea.h and https://github.com/kofemann/ms-nfs41-client/blob/master/tests/winfsinfo1/winfsinfo.c