[Ms-nfs41-client-devel] Fwd: Implementing mkfifo, mknod support with NFS_SPECFILE_FIFO and NFS_SPECFILE_SOCK?

Corinna Vinschen corinna-cygwin@cygwin.com
Tue Feb 4 11:17:12 GMT 2025


On Feb  4 12:08, Corinna Vinschen via Cygwin wrote:
> $ cat > mk-dev-nfs.c <<EOF
> [...]

Copy/Paste error, try this one:

#include <stdio.h>
#include <windows.h>
#include <winternl.h>

typedef struct {
    DWORD  ReparseTag;
    WORD   ReparseDataLength;
    WORD   Reserved;
    struct {
	BYTE   DataBuffer[1];
    } GenericReparseBuffer;
    struct {
	ULONGLONG	Type;
	union {
	  struct {
	    ULONG	Major;
	    ULONG	Minor;
	  } Device;
	  WCHAR		LnkBuffer[1];
	};
    } NfsReparseBuffer;
} MY_REPARSE_DATA_BUFFER, *MY_PREPARSE_DATA_BUFFER;

#define NFS_SPECFILE_LNK	0x00000000014B4E4CL
#define NFS_SPECFILE_CHR	0x0000000000524843L
#define NFS_SPECFILE_BLK	0x00000000004B4C42L
#define NFS_SPECFILE_FIFO	0x000000004F464946L
#define	NFS_SPECFILE_SOCK	0x000000004B434F53L

int
main (int argc, char **argv)
{
  HANDLE fh;
  char buf[65536];
  DWORD size_ret;
  MY_PREPARSE_DATA_BUFFER rp;

  if (argc < 3)
    {
      fprintf (stderr, "usage: %s <name> b|c|f|s [major] [minor]\n", argv[0]);
      return 1;
    }
  fh = CreateFile (argv[1],
                   GENERIC_WRITE,
                   0,
                   NULL,
                   CREATE_ALWAYS,
                   FILE_FLAG_BACKUP_SEMANTICS
                   | FILE_FLAG_OPEN_REPARSE_POINT,
                   NULL);
  if (fh == INVALID_HANDLE_VALUE)
    {
      fprintf (stderr, "CreateFile: %d\n", GetLastError ());
      return 1;
    }

  rp = (MY_PREPARSE_DATA_BUFFER) buf;
  rp->ReparseTag = IO_REPARSE_TAG_NFS;
  rp->ReparseDataLength = sizeof (ULONGLONG);
  switch (argv[2][0])
    {
    case 'b':
    case 'c':
      if (argc != 5)
        {
	  fprintf (stderr, "usage: %s <name> b|c|f|s [major] [minor]\n",
		   argv[0]);
	  return 1;
	}
      rp->ReparseDataLength += 2 * sizeof (ULONG);
      rp->NfsReparseBuffer.Type = argv[2][0] == 'b' ?
				  NFS_SPECFILE_BLK
				  : NFS_SPECFILE_CHR;
      rp->NfsReparseBuffer.Device.Major = strtoul (argv[3], NULL, 0);
      rp->NfsReparseBuffer.Device.Minor = strtoul (argv[4], NULL, 0);
      break;
    case 'f':
      rp->NfsReparseBuffer.Type = NFS_SPECFILE_FIFO;
      break;
    case 's':
      rp->NfsReparseBuffer.Type = NFS_SPECFILE_SOCK;
      break;
    }

  if (! DeviceIoControl (fh, FSCTL_SET_REPARSE_POINT,
                         (LPVOID) buf,
                         REPARSE_GUID_DATA_BUFFER_HEADER_SIZE
                         + rp->ReparseDataLength,
                         NULL, 0, &size_ret, NULL))
    {
      fprintf (stderr, "DeviceIoControl: %d\n", GetLastError ());
      CloseHandle (fh);
      DeleteFile (argv[1]);
      return 1;
    }
  CloseHandle (fh);
  return 0;
}


More information about the Cygwin mailing list