mpr: Implement WNetGetUniversalNameW on top of WNetGetConnectionW and minor fixes to that function

Maarten Lankhorst m.b.lankhorst at gmail.com
Mon May 21 15:46:58 CDT 2007


Small fixes to WNetGetConnectionW to get proper response for network
drives. I thought it was too small to send it seperately.
-------------- next part --------------
>From b975f15447ba92bcb01d2ba0eba2b13299287edc Mon Sep 17 00:00:00 2001
From: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date: Mon, 21 May 2007 21:30:53 +0200
Subject: [PATCH] mpr: Implement WNetGetUniversalNameW on top of WNetGetConnectionW

---
 dlls/mpr/wnet.c |  108 ++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 80 insertions(+), 28 deletions(-)

diff --git a/dlls/mpr/wnet.c b/dlls/mpr/wnet.c
index 356bf14..8f89898 100644
--- a/dlls/mpr/wnet.c
+++ b/dlls/mpr/wnet.c
@@ -1623,10 +1623,10 @@ DWORD WINAPI WNetGetConnectionW( LPCWSTR lpLocalName,
 
     if (!lpLocalName)
         ret = WN_BAD_POINTER;
-    else if (!lpRemoteName)
-        ret = WN_BAD_POINTER;
     else if (!lpBufferSize)
         ret = WN_BAD_POINTER;
+    else if (!lpRemoteName && *lpBufferSize)
+        ret = WN_BAD_POINTER;
     else if (!lpLocalName[0])
         ret = WN_BAD_LOCALNAME;
     else
@@ -1637,8 +1637,12 @@ DWORD WINAPI WNetGetConnectionW( LPCWSTR lpLocalName,
             {
             case DRIVE_REMOTE:
             {
-                WCHAR remote[MAX_PATH];
+                WCHAR rremote[MAX_PATH], *remote = rremote;
                 if (!QueryDosDeviceW( lpLocalName, remote, MAX_PATH )) remote[0] = 0;
+                else { /* Convert \unc\host to \\host */
+                    remote += 2;
+                    remote[0] = '\\';
+                }
                 if (strlenW(remote) + 1 > *lpBufferSize)
                 {
                     *lpBufferSize = strlenW(remote) + 1;
@@ -1706,6 +1710,9 @@ DWORD WINAPI WNetGetUniversalNameA ( LPCSTR lpLocalPath, DWORD dwInfoLevel,
     LPVOID wlpBuffer = NULL;
     DWORD structsize;
 
+    TRACE( "(%s, 0x%08X, %p, %p)\n",
+           debugstr_a(lpLocalPath), dwInfoLevel, lpBuffer, lpBufferSize);
+
     switch (dwInfoLevel)
     {
     case REMOTE_NAME_INFO_LEVEL: structsize = sizeof(UNIVERSAL_NAME_INFOA); break;
@@ -1716,9 +1723,6 @@ DWORD WINAPI WNetGetUniversalNameA ( LPCSTR lpLocalPath, DWORD dwInfoLevel,
         goto err;
     }
 
-    TRACE( "(%s, 0x%08X, %p, %p)\n",
-           debugstr_a(lpLocalPath), dwInfoLevel, lpBuffer, lpBufferSize);
-
     if (*lpBufferSize <= structsize)
     {
         err = WN_MORE_DATA;
@@ -1773,38 +1777,86 @@ DWORD WINAPI WNetGetUniversalNameA ( LPCSTR lpLocalPath, DWORD dwInfoLevel,
 DWORD WINAPI WNetGetUniversalNameW ( LPCWSTR lpLocalPath, DWORD dwInfoLevel,
                                      LPVOID lpBuffer, LPDWORD lpBufferSize )
 {
-    DWORD err, size;
+    DWORD err, size, nsize, bufsize;
+    LPWSTR fullName = NULL;
+    WCHAR station[] = { 'A', ':', 0 };
 
-    FIXME( "(%s, 0x%08X, %p, %p): stub\n",
+    TRACE( "(%s, 0x%08X, %p, %p)\n",
            debugstr_w(lpLocalPath), dwInfoLevel, lpBuffer, lpBufferSize);
 
-    switch (dwInfoLevel)
-    {
-    case UNIVERSAL_NAME_INFO_LEVEL:
+    if (!lpBufferSize || !lpLocalPath || (!lpBuffer && *lpBufferSize))
     {
-        LPUNIVERSAL_NAME_INFOW info = (LPUNIVERSAL_NAME_INFOW)lpBuffer;
+       err = WN_BAD_POINTER;
+       goto err;
+    }
 
-        size = sizeof(*info) + (lstrlenW(lpLocalPath) + 1) * sizeof(WCHAR);
-        if (*lpBufferSize < size)
-        {
-            err = WN_MORE_DATA;
-            break;
-        }
-        info->lpUniversalName = (LPWSTR)((char *)info + sizeof(*info));
-        lstrcpyW(info->lpUniversalName, lpLocalPath);
-        *lpBufferSize = size;
-        err = WN_NO_ERROR;
-        break;
+    if (!lpLocalPath[0] || lpLocalPath[1] != ':')
+    {
+        err = WN_BAD_LOCALNAME;
+        goto err;
     }
-    case REMOTE_NAME_INFO_LEVEL:
-        err = WN_NO_NETWORK;
-        break;
 
-    default:
+    station[0] = lpLocalPath[0];
+
+    if (dwInfoLevel == UNIVERSAL_NAME_INFO_LEVEL) {
+        LPUNIVERSAL_NAME_INFOW info = lpBuffer;
+        size = sizeof(*info);
+
+        if (*lpBufferSize > size)
+            fullName = info->lpUniversalName = (LPVOID)((DWORD_PTR)info + size);
+    } else if (dwInfoLevel == REMOTE_NAME_INFO_LEVEL) {
+        LPREMOTE_NAME_INFOW info = lpBuffer;
+        size = sizeof(*info);
+
+        if (*lpBufferSize > size)
+            fullName = info->lpUniversalName = (LPVOID)((DWORD_PTR)info + size);
+    } else {
+        FIXME("Unhandled dwInfoLevel %d\n", dwInfoLevel);
         err = WN_BAD_VALUE;
-        break;
+        goto err;
+    }
+
+    if (fullName)
+        nsize = *lpBufferSize - size;
+    else
+        nsize = 0;
+
+    /* Determine if it's a local path or not */
+    err = WNetGetConnectionW(station, fullName, &nsize);
+
+    /* Append local path to nsize */
+    nsize += sizeof(WCHAR) * strlenW(&lpLocalPath[2]);
+
+    /* Calculate buffer size and set it */
+    bufsize = size + nsize;
+    if (dwInfoLevel == REMOTE_NAME_INFO_LEVEL)
+        bufsize += nsize + sizeof(WCHAR);
+    if (*lpBufferSize < bufsize)
+        err = WN_MORE_DATA;
+    *lpBufferSize = bufsize;
+    if (err == WN_MORE_DATA)
+        goto err;
+
+    if (dwInfoLevel == REMOTE_NAME_INFO_LEVEL) {
+        LPREMOTE_NAME_INFOW info = lpBuffer;
+        if (err != WN_SUCCESS)
+            goto err;
+
+        strcpyW(info->lpConnectionName, fullName);
+        strcpyW(info->lpRemainingPath, &lpLocalPath[2]);
     }
 
+    if (err == WN_SUCCESS) {
+        strcpyW(&fullName[strlenW(fullName)], &lpLocalPath[2]);
+    }
+    else if (err == WN_NOT_CONNECTED) {
+        err = WN_SUCCESS;
+        strcpyW(fullName, lpLocalPath);
+    }
+
+    TRACE("Returning path %s\n", debugstr_w(fullName));
+
+    err:
     SetLastError(err);
     return err;
 }
-- 
1.4.4.2



More information about the wine-patches mailing list