- From 48d88f4f560d0bfeeb70477c3e4a3f89d7901cb3 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 20 Oct 2025 21:18:33 +0200
- Subject: [PATCH 1/2] dll,tests: Implement
- |NPGetResourceInformation()|+|NPGetResourceParent()|
- Implement |NPGetResourceInformation()|+|NPGetResourceParent()|.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- dll/nfs41_np.c | 301 +++++++++++++++++++++++++++++++++--
- tests/manual_testing.txt | 25 ++-
- tests/winfsinfo1/winfsinfo.c | 237 ++++++++++++++++++++++++++-
- 3 files changed, 552 insertions(+), 11 deletions(-)
- diff --git a/dll/nfs41_np.c b/dll/nfs41_np.c
- index d305614..eea58e8 100644
- --- a/dll/nfs41_np.c
- +++ b/dll/nfs41_np.c
- @@ -36,6 +36,13 @@
- #include "nfs41_np.h"
- #include "options.h"
- +/*
- + * Disable warning C4996 ("'wcscpy': This function or variable may be unsafe"),
- + * we only use |wcscpy()| on buffers whose size includes the |wcscpy()|'s input
- + * string length
- + */
- +#pragma warning (disable : 4996)
- +
- #define DBG 1
- #ifdef DBG
- @@ -460,8 +467,11 @@ NPGetCaps(
- case WNNC_START:
- rc = 1;
- break;
- - case WNNC_USER:
- case WNNC_DIALOG:
- + rc = WNNC_DLG_GETRESOURCEINFORMATION |
- + WNNC_DLG_GETRESOURCEPARENT;
- + break;
- + case WNNC_USER:
- case WNNC_ADMIN:
- case WNNC_CONNECTION_FLAGS:
- default:
- @@ -514,6 +524,27 @@ NPAddConnection(
- lpUserName, 0);
- }
- +static bool is_nfs_server_path(const wchar_t *serverpath)
- +{
- + if (serverpath[0] == L'\\') {
- + if ((wcsstr(serverpath, L"@NFS") != NULL) ||
- + (wcsstr(serverpath, L"@PUBNFS") != NULL)) {
- + return true;
- + }
- + }
- +
- + return false;
- +}
- +
- +static bool is_nfs_unc_path(const wchar_t *uncpath)
- +{
- + if (uncpath[0] == L'\\') {
- + return is_nfs_server_path(uncpath+1);
- + }
- +
- + return false;
- +}
- +
- DWORD APIENTRY
- NPAddConnection3(
- __in HWND hwndOwner,
- @@ -605,8 +636,7 @@ NPAddConnection3(
- ServerName[i] = L'\0';
- /* Check for "@NFS" or "@PUBNFS" tag in UNC path */
- - if ((wcsstr(ServerName, L"@NFS") == NULL) &&
- - (wcsstr(ServerName, L"@PUBNFS") == NULL)) {
- + if (is_nfs_server_path(ServerName) == false) {
- DbgP((L"ServerName name '%ls' not tagged with "
- "'@NFS' or '@PUBNFS'\n",
- ServerName));
- @@ -1337,10 +1367,133 @@ NPGetResourceParent(
- LPVOID lpBuffer,
- LPDWORD lpBufferSize )
- {
- - DbgP((L"NPGetResourceParent(pNetResource->lpRemoteName='%ls'): "
- - "WN_NOT_SUPPORTED\n",
- + DWORD Status;
- + LPNETRESOURCEW outNetResource = lpBuffer;
- +
- + DbgP((L"--> NPGetResourceParent(pNetResource->lpRemoteName='%ls')\n",
- lpNetResource->lpRemoteName));
- - return WN_NOT_SUPPORTED;
- +
- + /* Check for "@NFS" or "@PUBNFS" tag in UNC path */
- + if (is_nfs_unc_path(lpNetResource->lpRemoteName) == false) {
- + DbgP((L"lpNetResource->lpRemoteName name '%ls' not tagged with "
- + "'@NFS' or '@PUBNFS'\n",
- + lpNetResource->lpRemoteName));
- + Status = WN_BAD_NETNAME;
- + goto out;
- + }
- +
- + size_t requiredLen = sizeof(NETRESOURCEW) +
- + (wcslen(lpNetResource->lpRemoteName)+1)*sizeof(wchar_t);
- + if (*lpBufferSize < requiredLen) {
- + *lpBufferSize = (DWORD)requiredLen;
- + Status = WN_MORE_DATA;
- + goto out;
- + }
- +
- + wchar_t *lastbackslash = NULL;
- + size_t numbackslashes = 0;
- + wchar_t *s;
- + wchar_t ch;
- +
- + for (s = lpNetResource->lpRemoteName ; (ch = *s) != L'\0' ; s++ ) {
- + if ((ch == L'\\') && (*(s+1) != L'\0')) {
- + lastbackslash = s;
- + numbackslashes++;
- + }
- + }
- +
- + wchar_t *outstrbuff = (void *)(outNetResource+1);
- +
- + if (numbackslashes <= 3) {
- + /*
- + * |lpRemoteName|, |lpProvider|, |dwType|, |dwDisplayType|, and
- + * |dwUsage| are returned, and describe the output
- + * |lpNetResource->lpRemoteName|
- + */
- + outNetResource->dwScope = 0;
- + outNetResource->dwType = RESOURCETYPE_ANY;
- + outNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
- + outNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
- + outNetResource->lpLocalName = NULL;
- +
- + if (numbackslashes == 3) {
- + /*
- + * "First dir after server root" case:
- + * IN: '\0.49.202.230@NFS@2049\bigdisk'
- + * OUT: '\0.49.202.230@NFS@2049\'
- + */
- + size_t rm_len = lastbackslash - lpNetResource->lpRemoteName;
- + (void)memcpy(outstrbuff, lpNetResource->lpRemoteName, rm_len*sizeof(wchar_t));
- + outstrbuff[rm_len] = L'\0';
- + }
- + else {
- + /*
- + * "Server root" case:
- + * IN: '\0.49.202.230@NFS@2049\'
- + * OUT: '\0.49.202.230@NFS@2049\'
- + */
- + (void)wcscpy(outstrbuff, lpNetResource->lpRemoteName);
- + }
- +
- + outNetResource->lpRemoteName = outstrbuff;
- + outstrbuff += wcslen(outstrbuff)+1;
- +
- + outNetResource->lpComment = NULL;
- +
- + (void)wcscpy(outstrbuff, NFS41_PROVIDER_NAME_U);
- + outNetResource->lpProvider = outstrbuff;
- + outstrbuff += wcslen(outstrbuff)+1;
- +
- + *lpBufferSize = (DWORD)((char *)outstrbuff - (char *)lpBuffer);
- +
- + Status = WN_SUCCESS;
- + }
- + else {
- + /*
- + * |lpRemoteName|, |lpProvider|, |dwType|, |dwDisplayType|, and
- + * |dwUsage| are returned, and describe the output
- + * |lpNetResource->lpRemoteName|
- + */
- + outNetResource->dwScope = 0;
- + outNetResource->dwType = RESOURCETYPE_ANY;
- + outNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
- + outNetResource->dwUsage = RESOURCEUSAGE_CONNECTABLE;
- + outNetResource->lpLocalName = NULL;
- +
- + /*
- + * "Subdir" case:
- + * IN: '\0.49.202.230@NFS@2049\bigdisk\abc\def'
- + * OUT: '\0.49.202.230@NFS@2049\bigdisk\abc'
- + */
- + size_t rm_len = lastbackslash - lpNetResource->lpRemoteName;
- + (void)memcpy(outstrbuff, lpNetResource->lpRemoteName, rm_len*sizeof(wchar_t));
- + outstrbuff[rm_len] = L'\0';
- + outNetResource->lpRemoteName = outstrbuff;
- + outstrbuff += wcslen(outstrbuff)+1;
- +
- + outNetResource->lpComment = NULL;
- +
- + (void)wcscpy(outstrbuff, NFS41_PROVIDER_NAME_U);
- + outNetResource->lpProvider = outstrbuff;
- + outstrbuff += wcslen(outstrbuff)+1;
- +
- + *lpBufferSize = (DWORD)((char *)outstrbuff - (char *)lpBuffer);
- +
- + Status = WN_SUCCESS;
- + }
- +
- +out:
- + if (Status == WN_SUCCESS) {
- + DbgP((L"<-- NPGetResourceParent returns status=WN_SUCCESS, "
- + "outNetResource->lpRemoteName='%ls'\n",
- + outNetResource->lpRemoteName));
- + }
- + else {
- + DbgP((L"<-- NPGetResourceParent returns status=%d\n",
- + (int)Status));
- + }
- +
- + return Status;
- }
- DWORD APIENTRY
- @@ -1350,10 +1503,140 @@ NPGetResourceInformation(
- __inout LPDWORD lpBufferSize,
- __deref_out LPWSTR *lplpSystem )
- {
- - DbgP((L"NPGetResourceInformation(lpNetResource->lpRemoteName='%ls'): "
- - "WN_NOT_SUPPORTED\n",
- + DWORD Status;
- + LPNETRESOURCEW outNetResource = lpBuffer;
- +
- + DbgP((L"--> NPGetResourceInformation(lpNetResource->lpRemoteName='%ls')\n",
- lpNetResource->lpRemoteName));
- - return WN_NOT_SUPPORTED;
- +
- + /* Check for "@NFS" or "@PUBNFS" tag in UNC path */
- + if (is_nfs_unc_path(lpNetResource->lpRemoteName) == false) {
- + DbgP((L"lpNetResource->lpRemoteName name '%ls' not tagged with "
- + "'@NFS' or '@PUBNFS'\n",
- + lpNetResource->lpRemoteName));
- + Status = WN_BAD_NETNAME;
- + goto out;
- + }
- +
- + size_t requiredLen = sizeof(NETRESOURCEW) +
- + (wcslen(lpNetResource->lpRemoteName)+4)*sizeof(wchar_t);
- + if (*lpBufferSize < requiredLen) {
- + *lpBufferSize = (DWORD)requiredLen;
- + Status = WN_MORE_DATA;
- + goto out;
- + }
- +
- + wchar_t *s;
- + wchar_t *inremotename_systempart = NULL;
- + wchar_t ch;
- + int state = 0;
- + for (s = lpNetResource->lpRemoteName ; (ch = *s) != L'\0' ; s++) {
- + if ((ch == L'\\') && (state == 0)) {
- + /* s == '\...' */
- + state = 1;
- + }
- + else if ((ch == L'\\') && (*(s+1) != L'\0') && (state == 1)) {
- + /* s == '\\...' */
- + state = 2;
- + }
- + else if ((ch == L'\\') && (*(s+1) != L'\0') && (state == 2)) {
- + /* s == '\\foo\...' */
- + state = 3;
- + }
- + else if ((ch == L'\\') && (*(s+1) != L'\0') && (state == 3)) {
- + /* s == '\\foo\share1\...' */
- + inremotename_systempart = s;
- + state = 4;
- + }
- + }
- +
- + /*
- + * Fill out |outNetResource|, per Windows spec the |lpRemoteName|,
- + * |lpProvider|, |dwType|, |dwDisplayType|, and |dwUsage| fields
- + * are returned containing values, all other fields being set
- + * to |NULL|.
- + */
- + wchar_t *outstrbuff = (void *)(outNetResource+1);
- +
- + if (state == 2) {
- + outNetResource->dwScope = 0;
- + outNetResource->dwType = RESOURCETYPE_ANY;
- + outNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
- + outNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
- + outNetResource->lpLocalName = NULL;
- +
- + (void)wcscpy(outstrbuff, lpNetResource->lpRemoteName);
- + outNetResource->lpRemoteName = outstrbuff;
- + outstrbuff += wcslen(outstrbuff)+1;
- + outNetResource->lpComment = NULL;
- + (void)wcscpy(outstrbuff, NFS41_PROVIDER_NAME_U);
- + outNetResource->lpProvider = outstrbuff;
- + outstrbuff += wcslen(outstrbuff)+1;
- +
- + if (lplpSystem)
- + *lplpSystem = NULL;
- +
- + *lpBufferSize = (DWORD)((char *)outstrbuff - (char *)lpBuffer);
- +
- + Status = WN_SUCCESS;
- + }
- + else if ((state == 3) || (state == 4)) {
- + outNetResource->dwScope = 0;
- + outNetResource->dwType = RESOURCETYPE_DISK;
- + outNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
- + outNetResource->dwUsage = RESOURCEUSAGE_CONNECTABLE;
- + outNetResource->lpLocalName = NULL;
- +
- + if (state == 3) {
- + (void)wcscpy(outstrbuff, lpNetResource->lpRemoteName);
- + outNetResource->lpRemoteName = outstrbuff;
- + outstrbuff += wcslen(outstrbuff)+1;
- + outNetResource->lpComment = NULL;
- + (void)wcscpy(outstrbuff, NFS41_PROVIDER_NAME_U);
- + outNetResource->lpProvider = outstrbuff;
- + outstrbuff += wcslen(outstrbuff)+1;
- +
- + if (lplpSystem)
- + *lplpSystem = NULL;
- + }
- + else {
- + /* |outremotenamelen| includes the trailing '\' */
- + size_t outremotenamelen =
- + (inremotename_systempart-lpNetResource->lpRemoteName)+1;
- + (void)memcpy(outstrbuff, lpNetResource->lpRemoteName,
- + outremotenamelen*sizeof(wchar_t));
- + outstrbuff[outremotenamelen] = L'\0';
- + outNetResource->lpRemoteName = outstrbuff;
- + outstrbuff += wcslen(outstrbuff)+1;
- +
- + if (lplpSystem) {
- + (void)wcscpy(outstrbuff, inremotename_systempart);
- + *lplpSystem = outstrbuff;
- + outstrbuff += wcslen(outstrbuff)+1;
- + }
- +
- + outNetResource->lpComment = NULL;
- +
- + (void)wcscpy(outstrbuff, NFS41_PROVIDER_NAME_U);
- + outNetResource->lpProvider = outstrbuff;
- + outstrbuff += wcslen(outstrbuff)+1;
- + }
- +
- + *lpBufferSize = (DWORD)((char *)outstrbuff - (char *)lpBuffer);
- +
- + Status = WN_SUCCESS;
- + }
- + else {
- + DbgP((L"Unexpected state=%d, returning WN_BAD_NETNAME\n", state));
- + Status = WN_BAD_NETNAME;
- + goto out;
- + }
- +
- +out:
- + DbgP((L"<-- NPGetResourceInformation returns status=%d\n",
- + (int)Status));
- +
- + return Status;
- }
- DWORD APIENTRY
- diff --git a/tests/manual_testing.txt b/tests/manual_testing.txt
- index a969839..42f3828 100644
- --- a/tests/manual_testing.txt
- +++ b/tests/manual_testing.txt
- @@ -1,5 +1,5 @@
- #
- -# ms-nfs41-client manual testing sequence, 2025-10-15
- +# ms-nfs41-client manual testing sequence, 2025-10-20
- #
- # Draft version, needs to be turned into automated tests
- # if possible
- @@ -635,6 +635,29 @@ md5sum --binary sparsefile2.bin sparsefile2_clone.bin
- ---- snip ----
- +#
- +# Network provider API tests
- +#
- +1. Test |WNetGetResourceInformationW()|, input: "\dir1\dir2\dir3", output: should be the
- +directory of the mount ("\dir1"), followed by the remaining path in
- +"out_lpSystem" ('\dir2\dir3')
- +---- snip ----
- +# this should print "# Test OK"
- +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"'
- +---- snip ----
- +
- +2. Test |WNetGetResourceParentW()|:
- +Note that the returned information is about the parent dir/resource:
- +---- snip ----
- +$ winfsinfo get_wnetgetresourceparent '\0.49.202.230@PUBNFS@2049\bigdisk\builds\aaa' 'NFS41 Network' | fgrep dwDisplayType
- + dwDisplayType='RESOURCEDISPLAYTYPE_SHARE'
- +$ winfsinfo get_wnetgetresourceparent '\0.49.202.230@PUBNFS@2049\bigdisk\builds' 'NFS41 Network' | fgrep dwDisplayType
- + dwDisplayType='RESOURCEDISPLAYTYPE_SHARE'
- +$ winfsinfo get_wnetgetresourceparent '\0.49.202.230@PUBNFS@2049\bigdisk' 'NFS41 Network' | fgrep dwDisplayType
- + dwDisplayType='RESOURCEDISPLAYTYPE_SERVER'
- +---- snip ----
- +
- +
- #
- # Test whether TMPDIR, TEMP, TMP can be on a NFS filesystem
- #
- diff --git a/tests/winfsinfo1/winfsinfo.c b/tests/winfsinfo1/winfsinfo.c
- index ab9ced3..ca658dd 100644
- --- a/tests/winfsinfo1/winfsinfo.c
- +++ b/tests/winfsinfo1/winfsinfo.c
- @@ -1477,6 +1477,232 @@ done:
- return res;
- }
- +#define BUFFER_SIZE 2048
- +
- +static
- +wchar_t *ConvertToWideChar(const char* narrowString)
- +{
- + if (narrowString == NULL)
- + return NULL;
- +
- + int requiredSize = MultiByteToWideChar(CP_ACP, 0, narrowString, -1, NULL, 0);
- + if (requiredSize == 0) {
- + return NULL;
- + }
- +
- + wchar_t* wideString = (wchar_t*)malloc(requiredSize * sizeof(wchar_t));
- + if (wideString == NULL) {
- + return NULL;
- + }
- +
- + if (MultiByteToWideChar(CP_ACP, 0, narrowString, -1, wideString, requiredSize) == 0) {
- + free(wideString);
- + return NULL;
- + }
- +
- + return wideString;
- +}
- +
- +static
- +void print_netresource(LPNETRESOURCE lpNetResource, const char *cpv_varname)
- +{
- + (void)printf("\t%s=(\n", cpv_varname);
- +
- + const char *scopeString;
- + switch (lpNetResource->dwScope) {
- + case RESOURCE_CONNECTED: scopeString = "RESOURCE_CONNECTED"; break;
- + case RESOURCE_GLOBALNET: scopeString = "RESOURCE_GLOBALNET"; break;
- + case RESOURCE_REMEMBERED: scopeString = "RESOURCE_REMEMBERED"; break;
- + case RESOURCE_CONTEXT: scopeString = "RESOURCE_CONTEXT"; break;
- + default: scopeString = NULL;
- + }
- + if (scopeString != NULL)
- + (void)printf("\t\tdwScope='%s'\n", scopeString);
- + else
- + (void)printf("\t\tdwScope='0' # unknown scope\n");
- +
- + const char *typeString;
- + switch (lpNetResource->dwType) {
- + case RESOURCETYPE_ANY: typeString = "RESOURCETYPE_ANY"; break;
- + case RESOURCETYPE_DISK: typeString = "RESOURCETYPE_DISK"; break;
- + case RESOURCETYPE_PRINT: typeString = "RESOURCETYPE_PRINT"; break;
- + case RESOURCETYPE_RESERVED: typeString = "RESOURCETYPE_RESERVED"; break;
- + case RESOURCETYPE_UNKNOWN: typeString = "RESOURCETYPE_UNKNOWN"; break;
- + default: typeString = "Custom/Other Type";
- + }
- + (void)printf("\t\tdwType='%s'\n", typeString);
- +
- + const char *displayTypeString;
- + switch (lpNetResource->dwDisplayType) {
- + case RESOURCEDISPLAYTYPE_GENERIC: displayTypeString = "RESOURCEDISPLAYTYPE_GENERIC"; break;
- + case RESOURCEDISPLAYTYPE_DOMAIN: displayTypeString = "RESOURCEDISPLAYTYPE_DOMAIN"; break;
- + case RESOURCEDISPLAYTYPE_SERVER: displayTypeString = "RESOURCEDISPLAYTYPE_SERVER"; break;
- + case RESOURCEDISPLAYTYPE_SHARE: displayTypeString = "RESOURCEDISPLAYTYPE_SHARE"; break;
- + case RESOURCEDISPLAYTYPE_GROUP: displayTypeString = "RESOURCEDISPLAYTYPE_GROUP"; break;
- + case RESOURCEDISPLAYTYPE_NETWORK: displayTypeString = "RESOURCEDISPLAYTYPE_NETWORK"; break;
- + case RESOURCEDISPLAYTYPE_ROOT: displayTypeString = "RESOURCEDISPLAYTYPE_ROOT"; break;
- +// case RESOURCEDISPLAYTYPE_SHARES: displayTypeString = "RESOURCEDISPLAYTYPE_SHARES"; break;
- + case RESOURCEDISPLAYTYPE_FILE: displayTypeString = "RESOURCEDISPLAYTYPE_FILE"; break;
- + default: displayTypeString = "UnknownDisplayType";
- + }
- + (void)printf("\t\tdwDisplayType='%s'\n", displayTypeString);
- +
- + (void)printf("\t\ttypeset -A dwUsage=(\n");
- + if (lpNetResource->dwUsage & RESOURCEUSAGE_CONTAINER)
- + (void)printf("\t\t\t['RESOURCEUSAGE_CONTAINER']=0x%lx\n", (long)RESOURCEUSAGE_CONTAINER);
- + if (lpNetResource->dwUsage & RESOURCEUSAGE_CONNECTABLE)
- + (void)printf("\t\t\t['RESOURCEUSAGE_CONNECTABLE']=0x%lx\n", (long)RESOURCEUSAGE_CONNECTABLE);
- + (void)printf("\t\t)\n");
- +
- + (void)printf("\t\tlpLocalName='%ls'\n",
- + lpNetResource->lpLocalName ? lpNetResource->lpLocalName : L"(NULL)");
- +
- + (void)printf("\t\tlpRemoteName='%ls'\n",
- + lpNetResource->lpRemoteName ? lpNetResource->lpRemoteName : L"(NULL)");
- +
- + (void)printf("\t\tlpComment='%ls'\n",
- + lpNetResource->lpComment ? lpNetResource->lpComment : L"(NULL)");
- +
- + (void)printf("\t\tlpProvider='%ls'\n",
- + lpNetResource->lpProvider ? lpNetResource->lpProvider : L"(NULL)");
- + (void)printf("\t)\n");
- +}
- +
- +static
- +int get_wnetgetresourceinformation(const char *progname, const char *sharename)
- +{
- + wchar_t *lpszRemoteNameW = NULL;
- + BYTE *pBuffer = NULL;
- + int retval = EXIT_FAILURE;
- +
- + lpszRemoteNameW = ConvertToWideChar(sharename);
- + if (lpszRemoteNameW == NULL) {
- + (void)fprintf(stderr,
- + "%s: Error: Could not convert remote name '%s' to wchar_t.\n",
- + progname, sharename);
- + return EXIT_FAILURE;
- + }
- +
- + pBuffer = (BYTE*)malloc(BUFFER_SIZE);
- + if (pBuffer == NULL) {
- + (void)fprintf(stderr, "Error: Failed to allocate memory buffer.\n");
- + goto cleanup;
- + }
- +
- + (void)memset(pBuffer, 0, BUFFER_SIZE);
- +
- + LPNETRESOURCE lpNetResource = (LPNETRESOURCE)pBuffer;
- + DWORD dwBufferSize = BUFFER_SIZE;
- + wchar_t *lpSystem = NULL;
- +
- + lpNetResource->lpRemoteName = lpszRemoteNameW;
- +
- + DWORD dwResult = WNetGetResourceInformationW(lpNetResource,
- + pBuffer, &dwBufferSize,
- + &lpSystem);
- +
- + if (dwResult == NO_ERROR) {
- + (void)printf("(\n");
- + (void)printf("\tlpRemoteName='%ls'\n", lpszRemoteNameW);
- +
- + print_netresource(lpNetResource, "out_netresource");
- + (void)printf("\tout_lpSystem='%ls'\n",
- + lpSystem ? lpSystem : L"(NULL)");
- +
- + (void)printf(")\n");
- +
- + retval = EXIT_SUCCESS;
- + } else if (dwResult == ERROR_NOT_CONTAINER) {
- + (void)fprintf(stderr, "Error %lu: The resource is not a container.\n",
- + dwResult);
- + } else if (dwResult == ERROR_MORE_DATA) {
- + (void)fprintf(stderr,
- + "Error %lu: The buffer size (%ld bytes) was too small. Required size: %lu bytes.\n",
- + dwResult, (long)BUFFER_SIZE, dwBufferSize);
- + } else {
- + (void)fprintf(stderr,
- + "Error %lu: Failed to get resource information.\n",
- + dwResult);
- + }
- +
- +cleanup:
- + free(pBuffer);
- + free(lpszRemoteNameW);
- +
- + return retval;
- +}
- +
- +static
- +int get_wnetgetresourceparent(const char *progname, const char *sharename, const char *provider)
- +{
- + wchar_t *lpszRemoteNameW = NULL;
- + wchar_t *lpszProviderW = NULL;
- + BYTE *pBuffer = NULL;
- + int retval = EXIT_FAILURE;
- +
- + lpszRemoteNameW = ConvertToWideChar(sharename);
- + if (lpszRemoteNameW == NULL) {
- + (void)fprintf(stderr,
- + "%s: Error: Could not convert remote name '%s' to wchar_t.\n",
- + progname, sharename);
- + return EXIT_FAILURE;
- + }
- +
- + lpszProviderW = ConvertToWideChar(provider);
- + if (lpszProviderW == NULL) {
- + (void)fprintf(stderr,
- + "%s: Error: Could not convert provider '%s' to wchar_t.\n",
- + progname, provider);
- + return EXIT_FAILURE;
- + }
- +
- + pBuffer = (BYTE*)malloc(BUFFER_SIZE);
- + if (pBuffer == NULL) {
- + (void)fprintf(stderr, "Error: Failed to allocate memory buffer.\n");
- + goto cleanup;
- + }
- +
- + (void)memset(pBuffer, 0, BUFFER_SIZE);
- +
- + LPNETRESOURCE lpNetResource = (LPNETRESOURCE)pBuffer;
- + DWORD dwBufferSize = BUFFER_SIZE;
- +
- + lpNetResource->lpRemoteName = lpszRemoteNameW;
- + lpNetResource->lpProvider = lpszProviderW;
- +
- + DWORD dwResult = WNetGetResourceParentW(lpNetResource,
- + pBuffer, &dwBufferSize);
- +
- + if (dwResult == NO_ERROR) {
- + (void)printf("(\n");
- + (void)printf("\tlpRemoteName='%ls'\n", lpszRemoteNameW);
- +
- + print_netresource(lpNetResource, "out_netresource");
- +
- + (void)printf(")\n");
- +
- + retval = EXIT_SUCCESS;
- + } else if (dwResult == ERROR_NOT_CONTAINER) {
- + (void)fprintf(stderr, "Error %lu: The resource is not a container.\n",
- + dwResult);
- + } else if (dwResult == ERROR_MORE_DATA) {
- + (void)fprintf(stderr,
- + "Error %lu: The buffer size (%ld bytes) was too small. Required size: %lu bytes.\n",
- + dwResult, (long)BUFFER_SIZE, dwBufferSize);
- + } else {
- + (void)fprintf(stderr,
- + "Error %lu: Failed to get resource information.\n",
- + dwResult);
- + }
- +
- +cleanup:
- + free(pBuffer);
- + free(lpszProviderW);
- + free(lpszRemoteNameW);
- +
- + return retval;
- +}
- +
- static
- void usage(void)
- {
- @@ -1502,7 +1728,10 @@ void usage(void)
- "fileremoteprotocolinfo|"
- "fileidinfo|"
- "filenetworkphysicalnameinfo|"
- - "fsctlqueryallocatedranges"
- + "fsctlqueryallocatedranges|"
- + "get_wnetgetresourceinformation|"
- + "get_wnetgetresourceparent"
- +
- "> path\n");
- }
- @@ -1584,6 +1813,12 @@ int main(int ac, char *av[])
- else if (!strcmp(subcmd, "fsctlqueryallocatedranges")) {
- return fsctlqueryallocatedranges(av[0], av[2]);
- }
- + else if (!strcmp(subcmd, "get_wnetgetresourceinformation")) {
- + return get_wnetgetresourceinformation(av[0], av[2]);
- + }
- + else if (!strcmp(subcmd, "get_wnetgetresourceparent")) {
- + return get_wnetgetresourceparent(av[0], av[2], av[3]);
- + }
- else {
- (void)fprintf(stderr, "%s: Unknown subcmd '%s'\n", av[0], subcmd);
- return EXIT_FAILURE;
- --
- 2.51.0
- From cc4e4387bfda835d4ec27e2eb9e2b245a3abc112 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 20 Oct 2025 21:50:20 +0200
- Subject: [PATCH 2/2] dll: |StoreConnectionInfo()| should store the correct
- scope/type/displaytype info
- |StoreConnectionInfo()| should store the correct scope/type/displaytype
- information.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- dll/nfs41_np.c | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
- diff --git a/dll/nfs41_np.c b/dll/nfs41_np.c
- index eea58e8..401dbe2 100644
- --- a/dll/nfs41_np.c
- +++ b/dll/nfs41_np.c
- @@ -321,10 +321,9 @@ static DWORD StoreConnectionInfo(
- pNfs41NetResource = &pSharedMemory->NetResources[i];
- pNfs41NetResource->InUse = TRUE;
- - pNfs41NetResource->dwScope = lpNetResource->dwScope;
- - pNfs41NetResource->dwType = lpNetResource->dwType;
- - pNfs41NetResource->dwDisplayType =
- - lpNetResource->dwDisplayType;
- + pNfs41NetResource->dwScope = 0;
- + pNfs41NetResource->dwType = RESOURCETYPE_DISK;
- + pNfs41NetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
- pNfs41NetResource->dwUsage = RESOURCEUSAGE_CONNECTABLE;
- #ifdef NFS41_DRIVER_USE_AUTHENTICATIONID_FOR_MOUNT_NAMESPACE
- pNfs41NetResource->MountAuthId = authenticationid;
- --
- 2.51.0
msnfs41client: Patches for NFS41 Network Provider+misc, 2025-10-20
Posted by Anonymous on Mon 20th Oct 2025 21:28
raw | new post
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.