pastebin - collaborative debugging tool
rovema.kpaste.net RSS


msnfs41client: Patches for NFS41 Network Provider+misc, 2025-10-20
Posted by Anonymous on Mon 20th Oct 2025 21:28
raw | new post

  1. From 48d88f4f560d0bfeeb70477c3e4a3f89d7901cb3 Mon Sep 17 00:00:00 2001
  2. From: Roland Mainz <roland.mainz@nrubsig.org>
  3. Date: Mon, 20 Oct 2025 21:18:33 +0200
  4. Subject: [PATCH 1/2] dll,tests: Implement
  5.  |NPGetResourceInformation()|+|NPGetResourceParent()|
  6.  
  7. Implement |NPGetResourceInformation()|+|NPGetResourceParent()|.
  8.  
  9. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  10. ---
  11. dll/nfs41_np.c               | 301 +++++++++++++++++++++++++++++++++--
  12.  tests/manual_testing.txt     |  25 ++-
  13.  tests/winfsinfo1/winfsinfo.c | 237 ++++++++++++++++++++++++++-
  14.  3 files changed, 552 insertions(+), 11 deletions(-)
  15.  
  16. diff --git a/dll/nfs41_np.c b/dll/nfs41_np.c
  17. index d305614..eea58e8 100644
  18. --- a/dll/nfs41_np.c
  19. +++ b/dll/nfs41_np.c
  20. @@ -36,6 +36,13 @@
  21.  #include "nfs41_np.h"
  22.  #include "options.h"
  23.  
  24. +/*
  25. + * Disable warning C4996 ("'wcscpy': This function or variable may be unsafe"),
  26. + * we only use |wcscpy()| on buffers whose size includes the |wcscpy()|'s input
  27. + * string length
  28. + */
  29. +#pragma warning (disable : 4996)
  30. +
  31.  #define DBG 1
  32.  
  33.  #ifdef DBG
  34. @@ -460,8 +467,11 @@ NPGetCaps(
  35.          case WNNC_START:
  36.              rc = 1;
  37.              break;
  38. -        case WNNC_USER:
  39.          case WNNC_DIALOG:
  40. +            rc = WNNC_DLG_GETRESOURCEINFORMATION |
  41. +                WNNC_DLG_GETRESOURCEPARENT;
  42. +            break;
  43. +        case WNNC_USER:
  44.          case WNNC_ADMIN:
  45.          case WNNC_CONNECTION_FLAGS:
  46.          default:
  47. @@ -514,6 +524,27 @@ NPAddConnection(
  48.          lpUserName, 0);
  49.  }
  50.  
  51. +static bool is_nfs_server_path(const wchar_t *serverpath)
  52. +{
  53. +    if (serverpath[0] == L'\\') {
  54. +        if ((wcsstr(serverpath, L"@NFS") != NULL) ||
  55. +            (wcsstr(serverpath, L"@PUBNFS") != NULL)) {
  56. +            return true;
  57. +        }
  58. +    }
  59. +
  60. +    return false;
  61. +}
  62. +
  63. +static bool is_nfs_unc_path(const wchar_t *uncpath)
  64. +{
  65. +    if (uncpath[0] == L'\\') {
  66. +        return is_nfs_server_path(uncpath+1);
  67. +    }
  68. +
  69. +    return false;
  70. +}
  71. +
  72.  DWORD APIENTRY
  73.  NPAddConnection3(
  74.      __in HWND           hwndOwner,
  75. @@ -605,8 +636,7 @@ NPAddConnection3(
  76.      ServerName[i] = L'\0';
  77.  
  78.      /* Check for "@NFS" or "@PUBNFS" tag in UNC path */
  79. -    if ((wcsstr(ServerName, L"@NFS") == NULL) &&
  80. -        (wcsstr(ServerName, L"@PUBNFS") == NULL)) {
  81. +    if (is_nfs_server_path(ServerName) == false) {
  82.          DbgP((L"ServerName name '%ls' not tagged with "
  83.              "'@NFS' or '@PUBNFS'\n",
  84.              ServerName));
  85. @@ -1337,10 +1367,133 @@ NPGetResourceParent(
  86.      LPVOID          lpBuffer,
  87.      LPDWORD         lpBufferSize )
  88.  {
  89. -    DbgP((L"NPGetResourceParent(pNetResource->lpRemoteName='%ls'): "
  90. -        "WN_NOT_SUPPORTED\n",
  91. +    DWORD Status;
  92. +    LPNETRESOURCEW outNetResource = lpBuffer;
  93. +
  94. +    DbgP((L"--> NPGetResourceParent(pNetResource->lpRemoteName='%ls')\n",
  95.          lpNetResource->lpRemoteName));
  96. -    return WN_NOT_SUPPORTED;
  97. +
  98. +    /* Check for "@NFS" or "@PUBNFS" tag in UNC path */
  99. +    if (is_nfs_unc_path(lpNetResource->lpRemoteName) == false) {
  100. +        DbgP((L"lpNetResource->lpRemoteName name '%ls' not tagged with "
  101. +            "'@NFS' or '@PUBNFS'\n",
  102. +            lpNetResource->lpRemoteName));
  103. +        Status = WN_BAD_NETNAME;
  104. +        goto out;
  105. +    }
  106. +
  107. +    size_t requiredLen = sizeof(NETRESOURCEW) +
  108. +        (wcslen(lpNetResource->lpRemoteName)+1)*sizeof(wchar_t);
  109. +    if (*lpBufferSize < requiredLen) {
  110. +        *lpBufferSize = (DWORD)requiredLen;
  111. +        Status = WN_MORE_DATA;
  112. +        goto out;
  113. +    }
  114. +
  115. +    wchar_t *lastbackslash = NULL;
  116. +    size_t numbackslashes = 0;
  117. +    wchar_t *s;
  118. +    wchar_t ch;
  119. +
  120. +    for (s = lpNetResource->lpRemoteName ; (ch = *s) != L'\0' ; s++ ) {
  121. +        if ((ch == L'\\') && (*(s+1) != L'\0')) {
  122. +            lastbackslash = s;
  123. +            numbackslashes++;
  124. +        }
  125. +    }
  126. +
  127. +    wchar_t *outstrbuff = (void *)(outNetResource+1);
  128. +
  129. +    if (numbackslashes <= 3) {
  130. +        /*
  131. +         * |lpRemoteName|, |lpProvider|, |dwType|, |dwDisplayType|, and
  132. +         * |dwUsage| are returned, and describe the output
  133. +         * |lpNetResource->lpRemoteName|
  134. +         */
  135. +        outNetResource->dwScope = 0;
  136. +        outNetResource->dwType = RESOURCETYPE_ANY;
  137. +        outNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
  138. +        outNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
  139. +        outNetResource->lpLocalName = NULL;
  140. +
  141. +        if (numbackslashes == 3) {
  142. +            /*
  143. +             * "First dir after server root" case:
  144. +             * IN:  '\0.49.202.230@NFS@2049\bigdisk'
  145. +             * OUT: '\0.49.202.230@NFS@2049\'
  146. +             */
  147. +            size_t rm_len = lastbackslash - lpNetResource->lpRemoteName;
  148. +            (void)memcpy(outstrbuff, lpNetResource->lpRemoteName, rm_len*sizeof(wchar_t));
  149. +            outstrbuff[rm_len] = L'\0';
  150. +        }
  151. +        else {
  152. +            /*
  153. +             * "Server root" case:
  154. +             * IN:  '\0.49.202.230@NFS@2049\'
  155. +             * OUT: '\0.49.202.230@NFS@2049\'
  156. +             */
  157. +            (void)wcscpy(outstrbuff, lpNetResource->lpRemoteName);
  158. +        }
  159. +
  160. +        outNetResource->lpRemoteName = outstrbuff;
  161. +        outstrbuff += wcslen(outstrbuff)+1;
  162. +
  163. +        outNetResource->lpComment = NULL;
  164. +
  165. +        (void)wcscpy(outstrbuff, NFS41_PROVIDER_NAME_U);
  166. +        outNetResource->lpProvider = outstrbuff;
  167. +        outstrbuff += wcslen(outstrbuff)+1;
  168. +
  169. +        *lpBufferSize = (DWORD)((char *)outstrbuff - (char *)lpBuffer);
  170. +
  171. +        Status = WN_SUCCESS;
  172. +    }
  173. +    else {
  174. +        /*
  175. +         * |lpRemoteName|, |lpProvider|, |dwType|, |dwDisplayType|, and
  176. +         * |dwUsage| are returned, and describe the output
  177. +         * |lpNetResource->lpRemoteName|
  178. +         */
  179. +        outNetResource->dwScope = 0;
  180. +        outNetResource->dwType = RESOURCETYPE_ANY;
  181. +        outNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
  182. +        outNetResource->dwUsage = RESOURCEUSAGE_CONNECTABLE;
  183. +        outNetResource->lpLocalName = NULL;
  184. +
  185. +        /*
  186. +         * "Subdir" case:
  187. +         * IN:  '\0.49.202.230@NFS@2049\bigdisk\abc\def'
  188. +         * OUT: '\0.49.202.230@NFS@2049\bigdisk\abc'
  189. +         */
  190. +        size_t rm_len = lastbackslash - lpNetResource->lpRemoteName;
  191. +        (void)memcpy(outstrbuff, lpNetResource->lpRemoteName, rm_len*sizeof(wchar_t));
  192. +        outstrbuff[rm_len] = L'\0';
  193. +        outNetResource->lpRemoteName = outstrbuff;
  194. +        outstrbuff += wcslen(outstrbuff)+1;
  195. +
  196. +        outNetResource->lpComment = NULL;
  197. +
  198. +        (void)wcscpy(outstrbuff, NFS41_PROVIDER_NAME_U);
  199. +        outNetResource->lpProvider = outstrbuff;
  200. +        outstrbuff += wcslen(outstrbuff)+1;
  201. +
  202. +        *lpBufferSize = (DWORD)((char *)outstrbuff - (char *)lpBuffer);
  203. +
  204. +        Status = WN_SUCCESS;
  205. +    }
  206. +
  207. +out:
  208. +    if (Status == WN_SUCCESS) {
  209. +        DbgP((L"<-- NPGetResourceParent returns status=WN_SUCCESS, "
  210. +            "outNetResource->lpRemoteName='%ls'\n",
  211. +            outNetResource->lpRemoteName));
  212. +    }
  213. +    else {
  214. +        DbgP((L"<-- NPGetResourceParent returns status=%d\n",
  215. +            (int)Status));
  216. +    }
  217. +
  218. +    return Status;
  219.  }
  220.  
  221.  DWORD APIENTRY
  222. @@ -1350,10 +1503,140 @@ NPGetResourceInformation(
  223.      __inout LPDWORD lpBufferSize,
  224.      __deref_out LPWSTR *lplpSystem )
  225.  {
  226. -    DbgP((L"NPGetResourceInformation(lpNetResource->lpRemoteName='%ls'): "
  227. -        "WN_NOT_SUPPORTED\n",
  228. +    DWORD Status;
  229. +    LPNETRESOURCEW outNetResource = lpBuffer;
  230. +
  231. +    DbgP((L"--> NPGetResourceInformation(lpNetResource->lpRemoteName='%ls')\n",
  232.          lpNetResource->lpRemoteName));
  233. -    return WN_NOT_SUPPORTED;
  234. +
  235. +    /* Check for "@NFS" or "@PUBNFS" tag in UNC path */
  236. +    if (is_nfs_unc_path(lpNetResource->lpRemoteName) == false) {
  237. +        DbgP((L"lpNetResource->lpRemoteName name '%ls' not tagged with "
  238. +            "'@NFS' or '@PUBNFS'\n",
  239. +            lpNetResource->lpRemoteName));
  240. +        Status = WN_BAD_NETNAME;
  241. +        goto out;
  242. +    }
  243. +
  244. +    size_t requiredLen = sizeof(NETRESOURCEW) +
  245. +        (wcslen(lpNetResource->lpRemoteName)+4)*sizeof(wchar_t);
  246. +    if (*lpBufferSize < requiredLen) {
  247. +        *lpBufferSize = (DWORD)requiredLen;
  248. +        Status = WN_MORE_DATA;
  249. +        goto out;
  250. +    }
  251. +
  252. +    wchar_t *s;
  253. +    wchar_t *inremotename_systempart = NULL;
  254. +    wchar_t ch;
  255. +    int state = 0;
  256. +    for (s = lpNetResource->lpRemoteName ; (ch = *s) != L'\0' ; s++) {
  257. +        if ((ch == L'\\') && (state == 0)) {
  258. +            /* s == '\...' */
  259. +            state = 1;
  260. +        }
  261. +        else if ((ch == L'\\') && (*(s+1) != L'\0') && (state == 1)) {
  262. +            /* s == '\\...' */
  263. +            state = 2;
  264. +        }
  265. +        else if ((ch == L'\\') && (*(s+1) != L'\0') && (state == 2)) {
  266. +            /* s == '\\foo\...' */
  267. +            state = 3;
  268. +        }
  269. +        else if ((ch == L'\\') && (*(s+1) != L'\0') && (state == 3)) {
  270. +            /* s == '\\foo\share1\...' */
  271. +            inremotename_systempart = s;
  272. +            state = 4;
  273. +        }
  274. +    }
  275. +
  276. +    /*
  277. +     * Fill out |outNetResource|, per Windows spec the |lpRemoteName|,
  278. +     * |lpProvider|, |dwType|, |dwDisplayType|, and |dwUsage| fields
  279. +     * are returned containing values, all other fields being set
  280. +     * to |NULL|.
  281. +     */
  282. +    wchar_t *outstrbuff = (void *)(outNetResource+1);
  283. +
  284. +    if (state == 2) {
  285. +        outNetResource->dwScope = 0;
  286. +        outNetResource->dwType = RESOURCETYPE_ANY;
  287. +        outNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
  288. +        outNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
  289. +        outNetResource->lpLocalName = NULL;
  290. +
  291. +        (void)wcscpy(outstrbuff, lpNetResource->lpRemoteName);
  292. +        outNetResource->lpRemoteName = outstrbuff;
  293. +        outstrbuff += wcslen(outstrbuff)+1;
  294. +        outNetResource->lpComment = NULL;
  295. +        (void)wcscpy(outstrbuff, NFS41_PROVIDER_NAME_U);
  296. +        outNetResource->lpProvider = outstrbuff;
  297. +        outstrbuff += wcslen(outstrbuff)+1;
  298. +
  299. +        if (lplpSystem)
  300. +            *lplpSystem = NULL;
  301. +
  302. +        *lpBufferSize = (DWORD)((char *)outstrbuff - (char *)lpBuffer);
  303. +
  304. +        Status = WN_SUCCESS;
  305. +    }
  306. +    else if ((state == 3) || (state == 4)) {
  307. +        outNetResource->dwScope = 0;
  308. +        outNetResource->dwType = RESOURCETYPE_DISK;
  309. +        outNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
  310. +        outNetResource->dwUsage = RESOURCEUSAGE_CONNECTABLE;
  311. +        outNetResource->lpLocalName = NULL;
  312. +
  313. +        if (state == 3) {
  314. +            (void)wcscpy(outstrbuff, lpNetResource->lpRemoteName);
  315. +            outNetResource->lpRemoteName = outstrbuff;
  316. +            outstrbuff += wcslen(outstrbuff)+1;
  317. +            outNetResource->lpComment = NULL;
  318. +            (void)wcscpy(outstrbuff, NFS41_PROVIDER_NAME_U);
  319. +            outNetResource->lpProvider = outstrbuff;
  320. +            outstrbuff += wcslen(outstrbuff)+1;
  321. +
  322. +            if (lplpSystem)
  323. +                *lplpSystem = NULL;
  324. +        }
  325. +        else {
  326. +            /* |outremotenamelen| includes the trailing '\' */
  327. +            size_t outremotenamelen =
  328. +                (inremotename_systempart-lpNetResource->lpRemoteName)+1;
  329. +            (void)memcpy(outstrbuff, lpNetResource->lpRemoteName,
  330. +                outremotenamelen*sizeof(wchar_t));
  331. +            outstrbuff[outremotenamelen] = L'\0';
  332. +            outNetResource->lpRemoteName = outstrbuff;
  333. +            outstrbuff += wcslen(outstrbuff)+1;
  334. +
  335. +            if (lplpSystem) {
  336. +                (void)wcscpy(outstrbuff, inremotename_systempart);
  337. +                *lplpSystem = outstrbuff;
  338. +                outstrbuff += wcslen(outstrbuff)+1;
  339. +            }
  340. +
  341. +            outNetResource->lpComment = NULL;
  342. +
  343. +            (void)wcscpy(outstrbuff, NFS41_PROVIDER_NAME_U);
  344. +            outNetResource->lpProvider = outstrbuff;
  345. +            outstrbuff += wcslen(outstrbuff)+1;
  346. +        }
  347. +
  348. +        *lpBufferSize = (DWORD)((char *)outstrbuff - (char *)lpBuffer);
  349. +
  350. +        Status = WN_SUCCESS;
  351. +    }
  352. +    else {
  353. +        DbgP((L"Unexpected state=%d, returning WN_BAD_NETNAME\n", state));
  354. +        Status = WN_BAD_NETNAME;
  355. +        goto out;
  356. +    }
  357. +
  358. +out:
  359. +    DbgP((L"<-- NPGetResourceInformation returns status=%d\n",
  360. +        (int)Status));
  361. +
  362. +    return Status;
  363.  }
  364.  
  365.  DWORD APIENTRY
  366. diff --git a/tests/manual_testing.txt b/tests/manual_testing.txt
  367. index a969839..42f3828 100644
  368. --- a/tests/manual_testing.txt
  369. +++ b/tests/manual_testing.txt
  370. @@ -1,5 +1,5 @@
  371.  #
  372. -# ms-nfs41-client manual testing sequence, 2025-10-15
  373. +# ms-nfs41-client manual testing sequence, 2025-10-20
  374.  #
  375.  # Draft version, needs to be turned into automated tests
  376.  # if possible
  377. @@ -635,6 +635,29 @@ md5sum --binary sparsefile2.bin sparsefile2_clone.bin
  378.  ---- snip ----
  379.  
  380.  
  381. +#
  382. +# Network provider API tests
  383. +#
  384. +1. Test |WNetGetResourceInformationW()|, input: "\dir1\dir2\dir3", output: should be the
  385. +directory of the mount ("\dir1"), followed by the remaining path in
  386. +"out_lpSystem" ('\dir2\dir3')
  387. +---- snip ----
  388. +# this should print "# Test OK"
  389. +winfsinfo get_wnetgetresourceinformation '\0.49.202.230@PUBNFS@2049\dir1\dir2\dir3' | ksh93 -x -c 'set -o nounset ; compound c ; read -C c ; print -v c ; [[ "${c.lpRemoteName}" == "${c.out_netresource.lpRemoteName%*\\}${c.out_lpSystem}" ]] && print "# Test OK"'
  390. +---- snip ----
  391. +
  392. +2. Test |WNetGetResourceParentW()|:
  393. +Note that the returned information is about the parent dir/resource:
  394. +---- snip ----
  395. +$ winfsinfo get_wnetgetresourceparent '\0.49.202.230@PUBNFS@2049\bigdisk\builds\aaa' 'NFS41 Network' | fgrep dwDisplayType
  396. +                dwDisplayType='RESOURCEDISPLAYTYPE_SHARE'
  397. +$ winfsinfo get_wnetgetresourceparent '\0.49.202.230@PUBNFS@2049\bigdisk\builds' 'NFS41 Network' | fgrep dwDisplayType
  398. +                dwDisplayType='RESOURCEDISPLAYTYPE_SHARE'
  399. +$ winfsinfo get_wnetgetresourceparent '\0.49.202.230@PUBNFS@2049\bigdisk' 'NFS41 Network' | fgrep dwDisplayType
  400. +                dwDisplayType='RESOURCEDISPLAYTYPE_SERVER'
  401. +---- snip ----
  402. +
  403. +
  404.  #
  405.  # Test whether TMPDIR, TEMP, TMP can be on a NFS filesystem
  406.  #
  407. diff --git a/tests/winfsinfo1/winfsinfo.c b/tests/winfsinfo1/winfsinfo.c
  408. index ab9ced3..ca658dd 100644
  409. --- a/tests/winfsinfo1/winfsinfo.c
  410. +++ b/tests/winfsinfo1/winfsinfo.c
  411. @@ -1477,6 +1477,232 @@ done:
  412.      return res;
  413.  }
  414.  
  415. +#define BUFFER_SIZE 2048
  416. +
  417. +static
  418. +wchar_t *ConvertToWideChar(const char* narrowString)
  419. +{
  420. +    if (narrowString == NULL)
  421. +        return NULL;
  422. +
  423. +    int requiredSize = MultiByteToWideChar(CP_ACP, 0, narrowString, -1, NULL, 0);
  424. +    if (requiredSize == 0) {
  425. +        return NULL;
  426. +    }
  427. +
  428. +    wchar_t* wideString = (wchar_t*)malloc(requiredSize * sizeof(wchar_t));
  429. +    if (wideString == NULL) {
  430. +        return NULL;
  431. +    }
  432. +
  433. +    if (MultiByteToWideChar(CP_ACP, 0, narrowString, -1, wideString, requiredSize) == 0) {
  434. +        free(wideString);
  435. +        return NULL;
  436. +    }
  437. +
  438. +    return wideString;
  439. +}
  440. +
  441. +static
  442. +void print_netresource(LPNETRESOURCE lpNetResource, const char *cpv_varname)
  443. +{
  444. +    (void)printf("\t%s=(\n", cpv_varname);
  445. +
  446. +    const char *scopeString;
  447. +    switch (lpNetResource->dwScope) {
  448. +        case RESOURCE_CONNECTED: scopeString = "RESOURCE_CONNECTED"; break;
  449. +        case RESOURCE_GLOBALNET: scopeString = "RESOURCE_GLOBALNET"; break;
  450. +        case RESOURCE_REMEMBERED: scopeString = "RESOURCE_REMEMBERED"; break;
  451. +        case RESOURCE_CONTEXT: scopeString = "RESOURCE_CONTEXT"; break;
  452. +        default: scopeString = NULL;
  453. +    }
  454. +    if (scopeString != NULL)
  455. +        (void)printf("\t\tdwScope='%s'\n", scopeString);
  456. +    else
  457. +        (void)printf("\t\tdwScope='0' # unknown scope\n");
  458. +
  459. +    const char *typeString;
  460. +    switch (lpNetResource->dwType) {
  461. +        case RESOURCETYPE_ANY: typeString = "RESOURCETYPE_ANY"; break;
  462. +        case RESOURCETYPE_DISK: typeString = "RESOURCETYPE_DISK"; break;
  463. +        case RESOURCETYPE_PRINT: typeString = "RESOURCETYPE_PRINT"; break;
  464. +        case RESOURCETYPE_RESERVED: typeString = "RESOURCETYPE_RESERVED"; break;
  465. +        case RESOURCETYPE_UNKNOWN: typeString = "RESOURCETYPE_UNKNOWN"; break;
  466. +        default: typeString = "Custom/Other Type";
  467. +    }
  468. +    (void)printf("\t\tdwType='%s'\n", typeString);
  469. +
  470. +    const char *displayTypeString;
  471. +    switch (lpNetResource->dwDisplayType) {
  472. +        case RESOURCEDISPLAYTYPE_GENERIC: displayTypeString = "RESOURCEDISPLAYTYPE_GENERIC"; break;
  473. +        case RESOURCEDISPLAYTYPE_DOMAIN: displayTypeString = "RESOURCEDISPLAYTYPE_DOMAIN"; break;
  474. +        case RESOURCEDISPLAYTYPE_SERVER: displayTypeString = "RESOURCEDISPLAYTYPE_SERVER"; break;
  475. +        case RESOURCEDISPLAYTYPE_SHARE: displayTypeString = "RESOURCEDISPLAYTYPE_SHARE"; break;
  476. +        case RESOURCEDISPLAYTYPE_GROUP: displayTypeString = "RESOURCEDISPLAYTYPE_GROUP"; break;
  477. +        case RESOURCEDISPLAYTYPE_NETWORK: displayTypeString = "RESOURCEDISPLAYTYPE_NETWORK"; break;
  478. +        case RESOURCEDISPLAYTYPE_ROOT: displayTypeString = "RESOURCEDISPLAYTYPE_ROOT"; break;
  479. +//            case RESOURCEDISPLAYTYPE_SHARES: displayTypeString = "RESOURCEDISPLAYTYPE_SHARES"; break;
  480. +        case RESOURCEDISPLAYTYPE_FILE: displayTypeString = "RESOURCEDISPLAYTYPE_FILE"; break;
  481. +        default: displayTypeString = "UnknownDisplayType";
  482. +    }
  483. +    (void)printf("\t\tdwDisplayType='%s'\n", displayTypeString);
  484. +
  485. +    (void)printf("\t\ttypeset -A dwUsage=(\n");
  486. +    if (lpNetResource->dwUsage & RESOURCEUSAGE_CONTAINER)
  487. +        (void)printf("\t\t\t['RESOURCEUSAGE_CONTAINER']=0x%lx\n",   (long)RESOURCEUSAGE_CONTAINER);
  488. +    if (lpNetResource->dwUsage & RESOURCEUSAGE_CONNECTABLE)
  489. +        (void)printf("\t\t\t['RESOURCEUSAGE_CONNECTABLE']=0x%lx\n", (long)RESOURCEUSAGE_CONNECTABLE);
  490. +    (void)printf("\t\t)\n");
  491. +
  492. +    (void)printf("\t\tlpLocalName='%ls'\n",
  493. +        lpNetResource->lpLocalName ? lpNetResource->lpLocalName : L"(NULL)");
  494. +
  495. +    (void)printf("\t\tlpRemoteName='%ls'\n",
  496. +        lpNetResource->lpRemoteName ? lpNetResource->lpRemoteName : L"(NULL)");
  497. +
  498. +    (void)printf("\t\tlpComment='%ls'\n",
  499. +        lpNetResource->lpComment ? lpNetResource->lpComment : L"(NULL)");
  500. +
  501. +    (void)printf("\t\tlpProvider='%ls'\n",
  502. +        lpNetResource->lpProvider ? lpNetResource->lpProvider : L"(NULL)");
  503. +    (void)printf("\t)\n");
  504. +}
  505. +
  506. +static
  507. +int get_wnetgetresourceinformation(const char *progname, const char *sharename)
  508. +{
  509. +    wchar_t *lpszRemoteNameW = NULL;
  510. +    BYTE *pBuffer = NULL;
  511. +    int retval = EXIT_FAILURE;
  512. +
  513. +    lpszRemoteNameW = ConvertToWideChar(sharename);
  514. +    if (lpszRemoteNameW == NULL) {
  515. +        (void)fprintf(stderr,
  516. +            "%s: Error: Could not convert remote name '%s' to wchar_t.\n",
  517. +            progname, sharename);
  518. +        return EXIT_FAILURE;
  519. +    }
  520. +
  521. +    pBuffer = (BYTE*)malloc(BUFFER_SIZE);
  522. +    if (pBuffer == NULL) {
  523. +        (void)fprintf(stderr, "Error: Failed to allocate memory buffer.\n");
  524. +        goto cleanup;
  525. +    }
  526. +
  527. +    (void)memset(pBuffer, 0, BUFFER_SIZE);
  528. +
  529. +    LPNETRESOURCE lpNetResource = (LPNETRESOURCE)pBuffer;
  530. +    DWORD dwBufferSize = BUFFER_SIZE;
  531. +    wchar_t *lpSystem = NULL;
  532. +
  533. +    lpNetResource->lpRemoteName = lpszRemoteNameW;
  534. +
  535. +    DWORD dwResult = WNetGetResourceInformationW(lpNetResource,
  536. +        pBuffer, &dwBufferSize,
  537. +        &lpSystem);
  538. +
  539. +    if (dwResult == NO_ERROR) {
  540. +        (void)printf("(\n");
  541. +        (void)printf("\tlpRemoteName='%ls'\n", lpszRemoteNameW);
  542. +
  543. +        print_netresource(lpNetResource, "out_netresource");
  544. +        (void)printf("\tout_lpSystem='%ls'\n",
  545. +            lpSystem ? lpSystem : L"(NULL)");
  546. +
  547. +        (void)printf(")\n");
  548. +
  549. +        retval = EXIT_SUCCESS;
  550. +    } else if (dwResult == ERROR_NOT_CONTAINER) {
  551. +        (void)fprintf(stderr, "Error %lu: The resource is not a container.\n",
  552. +            dwResult);
  553. +    } else if (dwResult == ERROR_MORE_DATA) {
  554. +        (void)fprintf(stderr,
  555. +            "Error %lu: The buffer size (%ld bytes) was too small. Required size: %lu bytes.\n",
  556. +            dwResult, (long)BUFFER_SIZE, dwBufferSize);
  557. +    } else {
  558. +        (void)fprintf(stderr,
  559. +            "Error %lu: Failed to get resource information.\n",
  560. +            dwResult);
  561. +    }
  562. +
  563. +cleanup:
  564. +    free(pBuffer);
  565. +    free(lpszRemoteNameW);
  566. +
  567. +    return retval;
  568. +}
  569. +
  570. +static
  571. +int get_wnetgetresourceparent(const char *progname, const char *sharename, const char *provider)
  572. +{
  573. +    wchar_t *lpszRemoteNameW = NULL;
  574. +    wchar_t *lpszProviderW = NULL;
  575. +    BYTE *pBuffer = NULL;
  576. +    int retval = EXIT_FAILURE;
  577. +
  578. +    lpszRemoteNameW = ConvertToWideChar(sharename);
  579. +    if (lpszRemoteNameW == NULL) {
  580. +        (void)fprintf(stderr,
  581. +            "%s: Error: Could not convert remote name '%s' to wchar_t.\n",
  582. +            progname, sharename);
  583. +        return EXIT_FAILURE;
  584. +    }
  585. +
  586. +    lpszProviderW = ConvertToWideChar(provider);
  587. +    if (lpszProviderW == NULL) {
  588. +        (void)fprintf(stderr,
  589. +            "%s: Error: Could not convert provider '%s' to wchar_t.\n",
  590. +            progname, provider);
  591. +        return EXIT_FAILURE;
  592. +    }
  593. +
  594. +    pBuffer = (BYTE*)malloc(BUFFER_SIZE);
  595. +    if (pBuffer == NULL) {
  596. +        (void)fprintf(stderr, "Error: Failed to allocate memory buffer.\n");
  597. +        goto cleanup;
  598. +    }
  599. +
  600. +    (void)memset(pBuffer, 0, BUFFER_SIZE);
  601. +
  602. +    LPNETRESOURCE lpNetResource = (LPNETRESOURCE)pBuffer;
  603. +    DWORD dwBufferSize = BUFFER_SIZE;
  604. +
  605. +    lpNetResource->lpRemoteName = lpszRemoteNameW;
  606. +    lpNetResource->lpProvider = lpszProviderW;
  607. +
  608. +    DWORD dwResult = WNetGetResourceParentW(lpNetResource,
  609. +        pBuffer, &dwBufferSize);
  610. +
  611. +    if (dwResult == NO_ERROR) {
  612. +        (void)printf("(\n");
  613. +        (void)printf("\tlpRemoteName='%ls'\n", lpszRemoteNameW);
  614. +
  615. +        print_netresource(lpNetResource, "out_netresource");
  616. +
  617. +        (void)printf(")\n");
  618. +
  619. +        retval = EXIT_SUCCESS;
  620. +    } else if (dwResult == ERROR_NOT_CONTAINER) {
  621. +        (void)fprintf(stderr, "Error %lu: The resource is not a container.\n",
  622. +            dwResult);
  623. +    } else if (dwResult == ERROR_MORE_DATA) {
  624. +        (void)fprintf(stderr,
  625. +            "Error %lu: The buffer size (%ld bytes) was too small. Required size: %lu bytes.\n",
  626. +            dwResult, (long)BUFFER_SIZE, dwBufferSize);
  627. +    } else {
  628. +        (void)fprintf(stderr,
  629. +            "Error %lu: Failed to get resource information.\n",
  630. +            dwResult);
  631. +    }
  632. +
  633. +cleanup:
  634. +    free(pBuffer);
  635. +    free(lpszProviderW);
  636. +    free(lpszRemoteNameW);
  637. +
  638. +    return retval;
  639. +}
  640. +
  641.  static
  642.  void usage(void)
  643.  {
  644. @@ -1502,7 +1728,10 @@ void usage(void)
  645.          "fileremoteprotocolinfo|"
  646.          "fileidinfo|"
  647.          "filenetworkphysicalnameinfo|"
  648. -        "fsctlqueryallocatedranges"
  649. +        "fsctlqueryallocatedranges|"
  650. +        "get_wnetgetresourceinformation|"
  651. +        "get_wnetgetresourceparent"
  652. +
  653.          "> path\n");
  654.  }
  655.  
  656. @@ -1584,6 +1813,12 @@ int main(int ac, char *av[])
  657.      else if (!strcmp(subcmd, "fsctlqueryallocatedranges")) {
  658.          return fsctlqueryallocatedranges(av[0], av[2]);
  659.      }
  660. +    else if (!strcmp(subcmd, "get_wnetgetresourceinformation")) {
  661. +        return get_wnetgetresourceinformation(av[0], av[2]);
  662. +    }
  663. +    else if (!strcmp(subcmd, "get_wnetgetresourceparent")) {
  664. +        return get_wnetgetresourceparent(av[0], av[2], av[3]);
  665. +    }
  666.      else {
  667.          (void)fprintf(stderr, "%s: Unknown subcmd '%s'\n", av[0], subcmd);
  668.          return EXIT_FAILURE;
  669. --
  670. 2.51.0
  671.  
  672. From cc4e4387bfda835d4ec27e2eb9e2b245a3abc112 Mon Sep 17 00:00:00 2001
  673. From: Roland Mainz <roland.mainz@nrubsig.org>
  674. Date: Mon, 20 Oct 2025 21:50:20 +0200
  675. Subject: [PATCH 2/2] dll: |StoreConnectionInfo()| should store the correct
  676.  scope/type/displaytype info
  677.  
  678. |StoreConnectionInfo()| should store the correct scope/type/displaytype
  679. information.
  680.  
  681. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  682. ---
  683. dll/nfs41_np.c | 7 +++----
  684.  1 file changed, 3 insertions(+), 4 deletions(-)
  685.  
  686. diff --git a/dll/nfs41_np.c b/dll/nfs41_np.c
  687. index eea58e8..401dbe2 100644
  688. --- a/dll/nfs41_np.c
  689. +++ b/dll/nfs41_np.c
  690. @@ -321,10 +321,9 @@ static DWORD StoreConnectionInfo(
  691.      pNfs41NetResource = &pSharedMemory->NetResources[i];
  692.  
  693.      pNfs41NetResource->InUse            = TRUE;
  694. -    pNfs41NetResource->dwScope          = lpNetResource->dwScope;
  695. -    pNfs41NetResource->dwType           = lpNetResource->dwType;
  696. -    pNfs41NetResource->dwDisplayType    =
  697. -        lpNetResource->dwDisplayType;
  698. +    pNfs41NetResource->dwScope          = 0;
  699. +    pNfs41NetResource->dwType           = RESOURCETYPE_DISK;
  700. +    pNfs41NetResource->dwDisplayType    = RESOURCEDISPLAYTYPE_SHARE;
  701.      pNfs41NetResource->dwUsage          = RESOURCEUSAGE_CONNECTABLE;
  702.  #ifdef NFS41_DRIVER_USE_AUTHENTICATIONID_FOR_MOUNT_NAMESPACE
  703.      pNfs41NetResource->MountAuthId      = authenticationid;
  704. --
  705. 2.51.0

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