pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


msnfs41client_filerename_with_rootdir20260207.diff
Posted by Anonymous on Sat 7th Feb 2026 12:31
raw | new post

  1. diff --git a/cygwin/devel/msnfs41client.bash b/cygwin/devel/msnfs41client.bash
  2. index 7a21fbc..2968729 100755
  3. --- a/cygwin/devel/msnfs41client.bash
  4. +++ b/cygwin/devel/msnfs41client.bash
  5. @@ -691,7 +691,7 @@ function nfsclient_rundeamon
  6.                         "${nfsd_args[@]}"
  7.                 )
  8.                 "${nfsd_args[@]}"
  9. -       elif false ; then
  10. +       elif true ; then
  11.                 export _NT_ALT_SYMBOL_PATH="$(cygpath -w "$PWD");srv*https://msdl.microsoft.com/download/symbols"
  12.                 #
  13.                 # Useful cdb cmds:
  14. @@ -831,7 +831,7 @@ function nfsclient_system_rundeamon
  15.                 )
  16.  
  17.                 "${nfsd_args[@]}"
  18. -       elif false ; then
  19. +       elif true ; then
  20.                 export _NT_ALT_SYMBOL_PATH="$(cygpath -w "${sbinpath}");srv*https://msdl.microsoft.com/download/symbols"
  21.                 # - heap tests (eats lots of memory):
  22.                 # '-c' '!gflag +full;g' for heap tests
  23. diff --git a/daemon/setattr.c b/daemon/setattr.c
  24. index 5efcc1a..aa1af37 100644
  25. --- a/daemon/setattr.c
  26. +++ b/daemon/setattr.c
  27. @@ -61,14 +61,23 @@ static int parse_setattr(
  28.      status = get_safe_read_bufferpos(&buffer, &length,
  29.          args->buf_len, (const void **)&args->buf);
  30.      if (status) goto out;
  31. +    if (args->set_class == FileRenameInformation) {
  32. +        status = safe_read(&buffer, &length,
  33. +            &args->rootdir_state, sizeof(args->rootdir_state));
  34. +        if (status) goto out;
  35. +    }
  36. +    else {
  37. +        args->rootdir_state = NULL;
  38. +    }
  39.  
  40.      args->root = upcall->root_ref;
  41.      args->state = upcall->state_ref;
  42.  
  43. -    DPRINTF(1, ("parsing '%s': filename='%s' info_class=%d "
  44. -        "buf_len=%d\n",
  45. -        opcode2string(upcall->opcode),
  46. -        args->path, args->set_class, args->buf_len));
  47. +    DPRINTF(1,
  48. +        ("parsing '%s': "
  49. +        "filename='%s' info_class=%d rootdir_state=0x%p buf_len=%d\n",
  50. +        opcode2string(upcall->opcode), args->path,
  51. +        args->set_class, (void *)args->rootdir_state, args->buf_len));
  52.  out:
  53.      return status;
  54.  }
  55. @@ -634,63 +643,109 @@ static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
  56.          goto out;
  57.      }
  58.      else if ((dst_path.len > 0) && (dst_path.path[0] != '\\')) {
  59. -        nfs41_abs_path *src_path = &state->path;
  60. -
  61. -        AcquireSRWLockShared(&src_path->lock);
  62. -
  63.          /*
  64. -         * FIXME: We do not support relative paths like "abc\def\x.txt" yet,
  65. -         * this would require support for
  66. -         * |FILE_RENAME_INFORMATION.RootDirectory|
  67. +         * Relative paths like "abc\def\x.txt" are not allowed here
  68.           */
  69.          if (memchr(dst_path.path, '\\', dst_path.len)) {
  70. -            eprintf("handle_nfs41_rename(src_path->path='%s'): "
  71. -                "relative path in dst_path.name='%s' not supported\n",
  72. -                src_path->path, dst_path.path);
  73. +            eprintf("handle_nfs41_rename(state->path.path='%s'): "
  74. +                "relative path in dst_path.name='%s' not allowed\n",
  75. +                state->path.path, dst_path.path);
  76.              status = ERROR_INVALID_PARAMETER;
  77. -            ReleaseSRWLockShared(&src_path->lock);
  78.              goto out;
  79.          }
  80.  
  81.          if (dst_path.len > NFS41_MAX_COMPONENT_LEN) {
  82. -            eprintf("handle_nfs41_rename(src_path->path='%s'): "
  83. -                "relative path dst_path.name='%s' length > NFS41_MAX_COMPONENT_LEN\n",
  84. -                src_path->path, dst_path.path);
  85. +            eprintf("handle_nfs41_rename(state->path.path='%s'): "
  86. +                "relative path dst_path.name='%s' "
  87. +                "len > NFS41_MAX_COMPONENT_LEN\n",
  88. +                state->path.path, dst_path.path);
  89.              status = ERROR_INVALID_PARAMETER;
  90. -            ReleaseSRWLockShared(&src_path->lock);
  91.              goto out;
  92.          }
  93.  
  94. -        char tmprelname[NFS41_MAX_COMPONENT_LEN+1];
  95. +        if (args->rootdir_state != NULL) {
  96. +            nfs41_abs_path *rootdir_path = &args->rootdir_state->path;
  97.  
  98. -        /*
  99. -         * Save relative destination filename because we first copy the src
  100. -         * path to dst_path and then append our saved filename
  101. -         */
  102. -        (void)memcpy(tmprelname, dst_path.path, dst_path.len);
  103. -        size_t tmprelname_len = dst_path.len;
  104. +            AcquireSRWLockShared(&rootdir_path->lock);
  105.  
  106. -        DPRINTF(1,
  107. -            ("handle_nfs41_rename: "
  108. -            "relative destfile, "
  109. -            "src_path->path='%s' dst_path.name='%s'\n",
  110. -            src_path->path, dst_path.path));
  111. +            char tmprelname[NFS41_MAX_COMPONENT_LEN+1];
  112.  
  113. -        abs_path_copy(&dst_path, &state->path);
  114. -        ReleaseSRWLockShared(&src_path->lock);
  115. +            /*
  116. +             * Save relative destination filename because we first copy the src
  117. +             * path to dst_path and then append our saved filename
  118. +             */
  119. +            (void)memcpy(tmprelname, dst_path.path, dst_path.len);
  120. +            size_t tmprelname_len = dst_path.len;
  121.  
  122. -        fh_copy(&dst_dir.fh, &state->parent.fh);
  123. +            DPRINTF(0,
  124. +                ("handle_nfs41_rename: "
  125. +                "relative destfile, "
  126. +                "rootdir_path->path='%s' dst_path.name='%s'\n",
  127. +                rootdir_path->path, dst_path.path));
  128.  
  129. -        /*
  130. -         * Take the src path and replace the last path element with the
  131. -         * relative filename
  132. -         */
  133. -        last_component(dst_path.path, dst_path.path + dst_path.len, &dst_name);
  134. -        char *dst_name_name = (char *)dst_name.name;
  135. -        (void)memcpy(dst_name_name, tmprelname, tmprelname_len);
  136. -        dst_name_name[tmprelname_len] = '\0';
  137. -        dst_path.len = (unsigned short)
  138. -            (&dst_name_name[tmprelname_len] - &dst_path.path[0]);
  139. +            abs_path_copy(&dst_path, rootdir_path);
  140. +            ReleaseSRWLockShared(&rootdir_path->lock);
  141. +
  142. +            fh_copy(&dst_dir.fh, &args->rootdir_state->parent.fh);
  143. +
  144. +            /*
  145. +             * Append the relative filename to |rootdir_path|
  146. +             */
  147. +            char *append_pos = dst_path.path + dst_path.len;
  148. +            *(append_pos++) = '\\';
  149. +            (void)memcpy(append_pos, tmprelname, tmprelname_len);
  150. +            append_pos[tmprelname_len] = '\0';
  151. +
  152. +            dst_path.len = (unsigned short)strlen(dst_path.path);
  153. +            DPRINTF(0,
  154. +                ("XXX: new dst_path='%s' len=%d calculated_len=%d\n",
  155. +                dst_path.path,
  156. +                (int)dst_path.len,
  157. +                (int)(rootdir_path->len + 1 + tmprelname_len)));
  158. +        }
  159. +        else {
  160. +            nfs41_abs_path *src_path = &state->path;
  161. +
  162. +            AcquireSRWLockShared(&src_path->lock);
  163. +
  164. +            char tmprelname[NFS41_MAX_COMPONENT_LEN+1];
  165. +
  166. +            /*
  167. +             * Save relative destination filename because we first copy the src
  168. +             * path to dst_path and then append our saved filename
  169. +             */
  170. +            (void)memcpy(tmprelname, dst_path.path, dst_path.len);
  171. +            size_t tmprelname_len = dst_path.len;
  172. +
  173. +            DPRINTF(0,
  174. +                ("handle_nfs41_rename: "
  175. +                "relative destfile, "
  176. +                "src_path->path='%s' dst_path.name='%s'\n",
  177. +                src_path->path, dst_path.path));
  178. +
  179. +            abs_path_copy(&dst_path, &state->path);
  180. +            ReleaseSRWLockShared(&src_path->lock);
  181. +
  182. +            fh_copy(&dst_dir.fh, &state->parent.fh);
  183. +
  184. +            /*
  185. +             * Take the src path and replace the last path element with the
  186. +             * relative filename
  187. +             */
  188. +            last_component(dst_path.path, dst_path.path + dst_path.len, &dst_name);
  189. +            char *dst_name_name = (char *)dst_name.name;
  190. +            (void)memcpy(dst_name_name, tmprelname, tmprelname_len);
  191. +            dst_name_name[tmprelname_len] = '\0';
  192. +            dst_path.len = (unsigned short)
  193. +                (&dst_name_name[tmprelname_len] - &dst_path.path[0]);
  194. +        }
  195. +    }
  196. +    else {
  197. +        DPRINTF(0,
  198. +            ("handle_nfs41_rename: "
  199. +            "absolute dst path, "
  200. +            "src_name->name='%s' dst_path.name='%s'\n",
  201. +            src_name->name, dst_path.path));
  202.      }
  203.  
  204.      /* |dst_path| should be non-empty and start with a backslash */
  205. diff --git a/daemon/upcall.h b/daemon/upcall.h
  206. index 01a84ed..a38c9b7 100644
  207. --- a/daemon/upcall.h
  208. +++ b/daemon/upcall.h
  209. @@ -136,6 +136,8 @@ typedef struct __setattr_upcall_args {
  210.      const char *path;
  211.      nfs41_root *root;
  212.      nfs41_open_state *state;
  213. +    /* |RootDirectory| for |FILE_RENAME_INFORMATION| */
  214. +    nfs41_open_state *rootdir_state;
  215.      unsigned char *buf;
  216.      uint32_t buf_len;
  217.      int set_class;
  218. diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
  219. index 3835bca..c260a6d 100644
  220. --- a/sys/nfs41sys_driver.h
  221. +++ b/sys/nfs41sys_driver.h
  222. @@ -276,6 +276,8 @@ typedef struct _updowncall_entry {
  223.              FILE_INFORMATION_CLASS InfoClass;
  224.              PVOID buf;
  225.              ULONG buf_len;
  226. +             /* |RootDirectory| state for |FILE_RENAME_INFORMATION| */
  227. +            void *rootdir_state;
  228.          } SetFile;
  229.          struct {
  230.              DWORD mode;
  231. diff --git a/sys/nfs41sys_fileinfo.c b/sys/nfs41sys_fileinfo.c
  232. index 6de73b5..8d70ab8 100644
  233. --- a/sys/nfs41sys_fileinfo.c
  234. +++ b/sys/nfs41sys_fileinfo.c
  235. @@ -129,6 +129,10 @@ NTSTATUS marshal_nfs41_fileset(
  236.  
  237.      header_len = *len + length_as_utf8(entry->filename) +
  238.          2 * sizeof(ULONG) + entry->u.SetFile.buf_len;
  239. +    if (entry->u.SetFile.InfoClass == FileRenameInformation) {
  240. +        header_len += sizeof(void *);
  241. +    }
  242. +
  243.      if (header_len > buf_len) {
  244.          DbgP("marshal_nfs41_fileset: "
  245.              "upcall buffer too small: header_len(=%ld) > buf_len(=%ld)\n",
  246. @@ -144,6 +148,10 @@ NTSTATUS marshal_nfs41_fileset(
  247.      tmp += sizeof(ULONG);
  248.      RtlCopyMemory(tmp, entry->u.SetFile.buf, entry->u.SetFile.buf_len);
  249.      tmp += entry->u.SetFile.buf_len;
  250. +    if (entry->u.SetFile.InfoClass == FileRenameInformation) {
  251. +        RtlCopyMemory(tmp, &entry->u.SetFile.rootdir_state, sizeof(void *));
  252. +        tmp += sizeof(void *);
  253. +    }
  254.  
  255.      *len = (ULONG)(tmp - buf);
  256.      if (*len != header_len) {
  257. @@ -652,12 +660,6 @@ NTSTATUS check_nfs41_setattr_args(
  258.              status = STATUS_OBJECT_NAME_INVALID;
  259.              goto out;
  260.          }
  261. -        if (rinfo->RootDirectory) {
  262. -            DbgP("check_nfs41_setattr_args: "
  263. -                "rinfo->RootDirectory != NULL not supported\n");
  264. -            status = STATUS_INVALID_PARAMETER;
  265. -            goto out;
  266. -        }
  267.          break;
  268.      }
  269.      case FileLinkInformation:
  270. @@ -724,6 +726,8 @@ NTSTATUS nfs41_SetFileInformationImpl(
  271.      __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
  272.          NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
  273.      __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
  274. +    PFILE_OBJECT rootdirfo = NULL;
  275. +
  276.  #ifdef ENABLE_TIMINGS
  277.      LARGE_INTEGER t1, t2;
  278.      t1 = KeQueryPerformanceCounter(NULL);
  279. @@ -850,6 +854,38 @@ NTSTATUS nfs41_SetFileInformationImpl(
  280.          entry->u.SetFile.buf = RxContext->Info.Buffer;
  281.          entry->u.SetFile.buf_len = RxContext->Info.Length;
  282.      }
  283. +
  284. +    if (InfoClass == FileRenameInformation) {
  285. +        PFILE_RENAME_INFORMATION prinfo =
  286. +            (PFILE_RENAME_INFORMATION)entry->u.SetFile.buf;
  287. +        HANDLE rootdir_handle = prinfo->RootDirectory;
  288. +
  289. +        if ((rootdir_handle == NULL) ||
  290. +            (rootdir_handle == INVALID_HANDLE_VALUE)) {
  291. +            entry->u.SetFile.rootdir_state = NULL;
  292. +        }
  293. +        else {
  294. +            status = ObReferenceObjectByHandle(rootdir_handle,
  295. +                0,
  296. +                *IoFileObjectType,
  297. +                RxContext->CurrentIrp->RequestorMode,
  298. +                (void **)&rootdirfo,
  299. +                NULL);
  300. +            if (!NT_SUCCESS(status)) {
  301. +                DbgP("nfs41_SetFileInformationImpl: "
  302. +                    "rootdir ObReferenceObjectByHandle returned 0x%lx\n",
  303. +                    status);
  304. +                goto out;
  305. +            }
  306. +
  307. +            PFOBX rootdirfox = rootdirfo->FsContext2;
  308. +            PNFS41_SRV_OPEN rootdir_nfs41_srvopen =
  309. +                NFS41GetSrvOpenExtension(rootdirfox->SrvOpen);
  310. +            entry->u.SetFile.rootdir_state =
  311. +                rootdir_nfs41_srvopen->nfs41_open_state;
  312. +        }
  313. +    }
  314. +
  315.  #ifdef ENABLE_TIMINGS
  316.      InterlockedIncrement(&setattr.sops);
  317.      InterlockedAdd64(&setattr.size, entry->u.SetFile.buf_len);
  318. @@ -875,6 +911,11 @@ out:
  319.      if (entry) {
  320.          nfs41_UpcallDestroy(entry);
  321.      }
  322. +
  323. +    if (rootdirfo) {
  324. +        ObDereferenceObject(rootdirfo);
  325. +    }
  326. +
  327.  #ifdef ENABLE_TIMINGS
  328.      t2 = KeQueryPerformanceCounter(NULL);
  329.      InterlockedIncrement(&setattr.tops);

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at