Windows: npdll do not retrieve auth id
[openafs.git] / src / WINNT / afsrdr / npdll / AFS_Npdll.c
index 9b889be..6487928 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
- * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2015 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 ULONG _cdecl AFSDbgPrint( PWCHAR Format, ... );
 
+static DWORD APIENTRY
+NPGetConnectionCommon( LPWSTR  lpLocalName,
+                       LPWSTR  lpRemoteName,
+                       LPDWORD lpBufferSize,
+                       BOOL    bDriveSubstOk);
+
+static DWORD APIENTRY
+NPGetConnection3Common( LPCWSTR lpLocalName,
+                        DWORD dwLevel,
+                        LPVOID lpBuffer,
+                        LPDWORD lpBufferSize,
+                        BOOL bDriveSubstOk);
+
+static DWORD APIENTRY
+NPGetUniversalNameCommon( LPCWSTR lpLocalPath,
+                          DWORD   dwInfoLevel,
+                          LPVOID  lpBuffer,
+                          LPDWORD lpBufferSize,
+                          BOOL    bDriveSubstOk);
+
+static BOOL
+DriveSubstitution( LPCWSTR drivestr,
+                   LPWSTR subststr,
+                   size_t substlen,
+                   DWORD * pStatus);
+
 #define WNNC_DRIVER( major, minor ) ( major * 0x00010000 + minor )
 
 #define OPENAFS_PROVIDER_NAME           L"OpenAFS Network"
@@ -107,9 +133,6 @@ static wchar_t wszServerComment[] = OPENAFS_SERVER_COMMENT;
 
 static BOOL bServerNameRead = FALSE;
 
-LARGE_INTEGER
-AFSRetrieveAuthId( void);
-
 void
 ReadProviderNameString( void)
 {
@@ -251,18 +274,28 @@ typedef struct _AFS_ENUM_CB
 // dos drive letter to which the source is mapped.
 //
 static BOOL
-DriveSubstitution(LPCWSTR drivestr, LPWSTR subststr, size_t substlen)
+DriveSubstitution(LPCWSTR drivestr, LPWSTR subststr, size_t substlen, DWORD * pStatus)
 {
     WCHAR drive[3];
-    WCHAR device[MAX_PATH + 1];
+    WCHAR device[MAX_PATH + 26];
     HRESULT hr = S_OK;
 
+    *pStatus = WN_SUCCESS;
+
     memset( subststr, 0, substlen);
     drive[0] = drivestr[0];
     drive[1] = drivestr[1];
     drive[2] = 0;
 
-    if ( QueryDosDevice(drive, device, MAX_PATH) )
+    if ( substlen < 3 * sizeof( WCHAR))
+    {
+        //
+        // Cannot represent "D:"
+        //
+        return FALSE;
+    }
+
+    if ( QueryDosDevice(drive, device, MAX_PATH + 26) )
     {
 #ifdef AFS_DEBUG_TRACE
         AFSDbgPrint( L"DriveSubstitution QueryDosDevice %s [%s -> %s]\n",
@@ -281,31 +314,34 @@ DriveSubstitution(LPCWSTR drivestr, LPWSTR subststr, size_t substlen)
             drive[1] = L':';
             drive[2] = L'\0';
 
-            if ( !DriveSubstitution(drive, subststr, substlen) )
+            if ( !DriveSubstitution(drive, subststr, substlen, pStatus) )
             {
 
                 subststr[0] = drive[0];
                 subststr[1] = L':';
                 subststr[2] = L'\0';
-
             }
 
             hr = S_OK;
 
             if ( device[6] )
             {
-                hr = StringCchCat( subststr, substlen, &device[6]);
+                hr = StringCbCat( subststr, substlen, &device[6]);
             }
             if ( SUCCEEDED(hr) && drivestr[2] )
             {
-                hr = StringCchCat( subststr, substlen, &drivestr[2]);
+                hr = StringCbCat( subststr, substlen, &drivestr[2]);
             }
 
             if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
             {
 
+                if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER )
+                    *pStatus = WN_MORE_DATA;
+
 #ifdef AFS_DEBUG_TRACE
-                    AFSDbgPrint( L"DriveSubstitution %s -> %s\n",
+                    AFSDbgPrint( L"DriveSubstitution (hr = %X) %s -> %s\n",
+                                 hr,
                                  drivestr,
                                  subststr);
 #endif
@@ -324,29 +360,26 @@ DriveSubstitution(LPCWSTR drivestr, LPWSTR subststr, size_t substlen)
 
             subststr[0] = L'\\';
 
-            hr = StringCbCopyN(&subststr[1], substlen - sizeof(WCHAR), &device[7], MAX_PATH);
+            hr = StringCbCopyN(&subststr[1], substlen - sizeof(WCHAR), &device[7], sizeof(device) - 7 * sizeof(WCHAR));
+
+            if ( SUCCEEDED(hr) && drivestr[2] )
+            {
+                hr = StringCbCat( subststr, substlen, &drivestr[2]);
+            }
 
             if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
             {
-                if ( drivestr[2] )
-                {
-                    hr = StringCchCat( subststr, substlen, &drivestr[2]);
-                }
-                else
-                {
-                    hr = S_OK;
-                }
 
-                if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
-                {
+                if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER )
+                    *pStatus = WN_MORE_DATA;
 
 #ifdef AFS_DEBUG_TRACE
-                    AFSDbgPrint( L"DriveSubstitution %s -> %s\n",
+                    AFSDbgPrint( L"DriveSubstitution (hr = %X) %s -> %s\n",
+                                 hr,
                                  drivestr,
                                  subststr);
 #endif
-                    return TRUE;
-                }
+                return TRUE;
             }
 
 #ifdef AFS_DEBUG_TRACE
@@ -360,32 +393,27 @@ DriveSubstitution(LPCWSTR drivestr, LPWSTR subststr, size_t substlen)
             // \Device\AFSRedirector\;X:\\afs\cellname
             //
 
-            hr = StringCbCopyN( subststr, substlen,
-                                 &device[3 + sizeof( AFS_RDR_DEVICE_NAME) / sizeof( WCHAR)],
-                                 MAX_PATH * sizeof( WCHAR));
+            hr = StringCbCopy( subststr, substlen,
+                               &device[3 + sizeof( AFS_RDR_DEVICE_NAME) / sizeof( WCHAR)]);
 
-            if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
+            if ( SUCCEEDED(hr) && drivestr[2] )
             {
+                hr = StringCbCat( subststr, substlen, &drivestr[2]);
+            }
 
-                if ( drivestr[2] )
-                {
-                    hr = StringCchCat( subststr, substlen, &drivestr[2]);
-                }
-                else
-                {
-                    hr = S_OK;
-                }
+            if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
+            {
 
-                if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
-                {
+                if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER )
+                    *pStatus = WN_MORE_DATA;
 
 #ifdef AFS_DEBUG_TRACE
-                    AFSDbgPrint( L"DriveSubstitution %s -> %s\n",
-                                 drivestr,
-                                 subststr);
+                AFSDbgPrint( L"DriveSubstitution (hr = %X) %s -> %s\n",
+                             hr,
+                             drivestr,
+                             subststr);
 #endif
-                    return TRUE;
-                }
+                return TRUE;
             }
 
 #ifdef AFS_DEBUG_TRACE
@@ -409,8 +437,6 @@ DriveSubstitution(LPCWSTR drivestr, LPWSTR subststr, size_t substlen)
 #endif
     }
 
-
-
     return FALSE;
 }
 
@@ -496,14 +522,14 @@ NPGetCaps( DWORD nIndex )
 
             //
             // No support for:
-            //   WNNC_CON_GETPERFORMANCE
             //   WNNC_CON_DEFER
             //
 
             rc = WNNC_CON_GETCONNECTIONS |
                  WNNC_CON_CANCELCONNECTION |
                  WNNC_CON_ADDCONNECTION |
-                 WNNC_CON_ADDCONNECTION3;
+                 WNNC_CON_ADDCONNECTION3 |
+                 WNNC_CON_GETPERFORMANCE;
 
             break;
         }
@@ -581,6 +607,93 @@ NPAddConnection( LPNETRESOURCE   lpNetResource,
     return NPAddConnection3( NULL, lpNetResource, lpPassword, lpUserName, 0 );
 }
 
+static void
+Add3FlagsToString( DWORD dwFlags, WCHAR *wszBuffer, size_t wch)
+{
+    HRESULT  hr;
+    int first = 1;
+
+    *wszBuffer = L'\0';
+
+    if (dwFlags & CONNECT_TEMPORARY) {
+
+        hr = StringCbCat( wszBuffer, wch, L"TEMPORARY");
+
+        if ( FAILED(hr)) {
+
+            return;
+        }
+
+        first = 0;
+    }
+
+    if (dwFlags & CONNECT_INTERACTIVE) {
+
+        if (!first) {
+
+            hr = StringCbCat( wszBuffer, wch, L"|");
+
+            if ( FAILED(hr)) {
+
+                return;
+            }
+        }
+
+        hr = StringCbCat( wszBuffer, wch, L"INTERACTIVE");
+
+        if ( FAILED(hr)) {
+
+            return;
+        }
+
+        first = 0;
+    }
+
+    if (dwFlags & CONNECT_PROMPT) {
+
+        if (!first) {
+
+            hr = StringCbCat( wszBuffer, wch, L"|");
+
+            if ( FAILED(hr)) {
+
+                return;
+            }
+        }
+
+        hr = StringCbCat( wszBuffer, wch, L"PROMPT");
+
+        if ( FAILED(hr)) {
+
+            return;
+        }
+
+        first = 0;
+    }
+
+    if (dwFlags & CONNECT_INTERACTIVE) {
+
+        if (!first) {
+
+            hr = StringCbCat( wszBuffer, wch, L"|");
+
+            if ( FAILED(hr)) {
+
+                return;
+            }
+        }
+
+        hr = StringCbCat( wszBuffer, wch, L"DEFERRED");
+
+        if ( FAILED(hr)) {
+
+            return;
+        }
+
+        first = 0;
+    }
+}
+
 DWORD
 APIENTRY
 NPAddConnection3( HWND            hwndOwner,
@@ -600,6 +713,8 @@ NPAddConnection3( HWND            hwndOwner,
     HANDLE   hControlDevice = NULL;
     HANDLE   hToken = NULL;
     LARGE_INTEGER liAuthId = {0,0};
+    HRESULT  hr;
+    WCHAR    wszFlagsString[1024]=L"";
 
     __Enter
     {
@@ -627,7 +742,13 @@ NPAddConnection3( HWND            hwndOwner,
         }
 
 #ifdef AFS_DEBUG_TRACE
-        AFSDbgPrint( L"NPAddConnection3 processing\n");
+        Add3FlagsToString( dwFlags, wszFlagsString, 1024);
+
+        AFSDbgPrint( L"NPAddConnection3 processing Remote %s User %s Pass %s Flags %s\n",
+                     lpNetResource->lpRemoteName,
+                     lpUserName == NULL? L"use-default": lpUserName[0] ? lpUserName : L"no-username",
+                     lpPassword == NULL? L"use-default": lpPassword[0] ? L"provided" : L"no-password",
+                     wszFlagsString);
 #endif
         if( lpNetResource->lpLocalName != NULL)
         {
@@ -637,8 +758,15 @@ NPAddConnection3( HWND            hwndOwner,
             wchLocalName[2] = L'\0';
         }
 
-        StringCchCopy(wchRemoteName, MAX_PATH+1, lpNetResource->lpRemoteName);
-        wchRemoteName[MAX_PATH] = L'\0';
+        hr = StringCbCopy(wchRemoteName, sizeof( wchRemoteName), lpNetResource->lpRemoteName);
+        if ( FAILED(hr))
+        {
+
+#ifdef AFS_DEBUG_TRACE
+            AFSDbgPrint( L"NPAddConnection3 lpRemoteName longer than MAX_PATH, returning WN_BAD_NETNAME\n");
+#endif
+            return WN_BAD_NETNAME;
+        }
 
         //
         // Allocate our buffer to pass to the redirector filter
@@ -686,14 +814,6 @@ NPAddConnection3( HWND            hwndOwner,
 
         pConnectCB->Type = lpNetResource->dwType;
 
-        pConnectCB->AuthenticationId = AFSRetrieveAuthId();
-
-#ifdef AFS_DEBUG_TRACE
-        AFSDbgPrint( L"NPAddConnection3 Retrieved authentication id %08lX-%08lX\n",
-                     pConnectCB->AuthenticationId.HighPart,
-                     pConnectCB->AuthenticationId.LowPart);
-#endif
-
         hControlDevice = OpenRedirector();
 
         if( hControlDevice == NULL)
@@ -720,7 +840,7 @@ NPAddConnection3( HWND            hwndOwner,
 #ifdef AFS_DEBUG_TRACE
             AFSDbgPrint( L"NPAddConnection3 Failed to add connection to file system %d\n", GetLastError());
 #endif
-            try_return( dwStatus = WN_OUT_OF_MEMORY);
+           try_return( dwStatus = WN_NET_ERROR);
         }
 
         //
@@ -731,11 +851,11 @@ NPAddConnection3( HWND            hwndOwner,
             lpNetResource->lpLocalName != NULL)
         {
 
-            WCHAR TempBuf[MAX_PATH+1];
+            WCHAR TempBuf[MAX_PATH+26];
 
             if( !QueryDosDeviceW( wchLocalName,
                                   TempBuf,
-                                  MAX_PATH+1))
+                                  MAX_PATH+26))
             {
 
                 if( GetLastError() != ERROR_FILE_NOT_FOUND)
@@ -752,17 +872,12 @@ NPAddConnection3( HWND            hwndOwner,
                 {
 
                     UNICODE_STRING uniConnectionName;
-                    UNICODE_STRING uniDeviceName;
-
-                    uniDeviceName.Length = (wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR));
-                    uniDeviceName.MaximumLength = uniDeviceName.Length;
-                    uniDeviceName.Buffer = AFS_RDR_DEVICE_NAME;
 
                     //
                     // Create a symbolic link object to the device we are redirecting
                     //
 
-                    uniConnectionName.MaximumLength = (USHORT)( uniDeviceName.Length +
+                    uniConnectionName.MaximumLength = (USHORT)( wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR) +
                                                                 pConnectCB->RemoteNameLength +
                                                                 8 +              // Local name and \;
                                                                 sizeof(WCHAR));   //  Space for NULL-termination.
@@ -782,21 +897,49 @@ NPAddConnection3( HWND            hwndOwner,
                         try_return( dwStatus = GetLastError());
                     }
 
-                    CopyMemory( uniConnectionName.Buffer,
-                                uniDeviceName.Buffer,
-                                uniDeviceName.Length);
+                    hr = StringCbCopyW( uniConnectionName.Buffer,
+                                        uniConnectionName.MaximumLength,
+                                        AFS_RDR_DEVICE_NAME);
+                    if ( FAILED(hr))
+                    {
+#ifdef AFS_DEBUG_TRACE
+                        AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
+#endif
+                        try_return( dwStatus = WN_OUT_OF_MEMORY);
+                    }
 
-                    StringCchCatW( uniConnectionName.Buffer,
-                                   uniConnectionName.MaximumLength,
-                                   L"\\;" );
+                    hr = StringCbCatW( uniConnectionName.Buffer,
+                                       uniConnectionName.MaximumLength,
+                                       L"\\;" );
+                    if ( FAILED(hr))
+                    {
+#ifdef AFS_DEBUG_TRACE
+                        AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
+#endif
+                        try_return( dwStatus = WN_OUT_OF_MEMORY);
+                    }
 
-                    StringCchCatW( uniConnectionName.Buffer,
-                                   uniConnectionName.MaximumLength,
-                                   wchLocalName);
+                    hr = StringCbCatW( uniConnectionName.Buffer,
+                                       uniConnectionName.MaximumLength,
+                                       wchLocalName);
+                    if ( FAILED(hr))
+                    {
+#ifdef AFS_DEBUG_TRACE
+                        AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
+#endif
+                        try_return( dwStatus = WN_OUT_OF_MEMORY);
+                    }
 
-                    StringCchCatW( uniConnectionName.Buffer,
-                                   uniConnectionName.MaximumLength,
-                                   wchRemoteName);
+                    hr = StringCbCatW( uniConnectionName.Buffer,
+                                       uniConnectionName.MaximumLength,
+                                       wchRemoteName);
+                    if ( FAILED(hr))
+                    {
+#ifdef AFS_DEBUG_TRACE
+                        AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
+#endif
+                        try_return( dwStatus = WN_OUT_OF_MEMORY);
+                    }
 
 #ifdef AFS_DEBUG_TRACE
                     AFSDbgPrint( L"NPAddConnection3 DefineDosDevice Local %s connection name %s\n",
@@ -817,6 +960,10 @@ NPAddConnection3( HWND            hwndOwner,
                     else
                     {
 
+#ifdef AFS_DEBUG_TRACE
+                        AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW assigned drive %s\n", wchLocalName);
+#endif
+
                         dwStatus = WN_SUCCESS;
                     }
 
@@ -869,7 +1016,9 @@ NPCancelConnection( LPWSTR  lpName,
     DWORD    dwBufferSize = 0;
     BOOL     bLocalName = TRUE;
     HANDLE   hControlDevice = NULL;
+    WCHAR    wchLocalName[ 3];
     WCHAR   *pwchLocalName = NULL;
+    HRESULT hr;
 
     __Enter
     {
@@ -889,18 +1038,36 @@ NPCancelConnection( LPWSTR  lpName,
         {
 
             bLocalName = FALSE;
-        }
 
-        if( bLocalName)
+            wchLocalName[0] = L'\0';
+
+            hr = StringCbCopyW( wchRemoteName, sizeof( wchRemoteName), lpName);
+
+            if ( FAILED(hr))
+            {
+#ifdef AFS_DEBUG_TRACE
+                AFSDbgPrint( L"NPCancelConnection lpName longer than MAX_PATH\n");
+#endif
+                try_return( dwStatus = WN_OUT_OF_MEMORY);
+            }
+
+            dwRemoteNameLength = (wcslen( wchRemoteName) * sizeof( WCHAR));
+        }
+        else
         {
 
+            wchLocalName[0] = towupper(lpName[0]);
+            wchLocalName[1] = L':';
+            wchLocalName[2] = L'\0';
+
             //
             // Get the remote name for the connection, if we are handling it
             //
 
-            dwStatus = NPGetConnection( lpName,
-                                        wchRemoteName,
-                                        &dwRemoteNameLength);
+            dwStatus = NPGetConnectionCommon( wchLocalName,
+                                              wchRemoteName,
+                                              &dwRemoteNameLength,
+                                              FALSE);
 
             if( dwStatus != WN_SUCCESS ||
                 dwRemoteNameLength == 0)
@@ -918,16 +1085,14 @@ NPCancelConnection( LPWSTR  lpName,
             //
             dwRemoteNameLength -= sizeof( WCHAR);
         }
-        else
-        {
-
-            StringCchCopyW( wchRemoteName, MAX_PATH+1, lpName);
-
-            dwRemoteNameLength = (wcslen( wchRemoteName) * sizeof( WCHAR));
-        }
 
         wchRemoteName[ dwRemoteNameLength/sizeof( WCHAR)] = L'\0';
 
+#ifdef AFS_DEBUG_TRACE
+        AFSDbgPrint( L"NPCancelConnection Attempting to cancel '%s' -> '%s'\n",
+                     wchLocalName, wchRemoteName);
+#endif
+
         dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + dwRemoteNameLength;
 
         pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
@@ -941,7 +1106,7 @@ NPCancelConnection( LPWSTR  lpName,
         if( bLocalName)
         {
 
-            pConnectCB->LocalName = towupper(lpName[0]);
+            pConnectCB->LocalName = wchLocalName[0];
         }
         else
         {
@@ -951,20 +1116,12 @@ NPCancelConnection( LPWSTR  lpName,
 
         pConnectCB->RemoteNameLength = (USHORT)dwRemoteNameLength;
 
-        StringCchCopyW( pConnectCB->RemoteName,
-                        MAX_PATH+1,
-                        wchRemoteName);
+        StringCbCopyW( pConnectCB->RemoteName,
+                       dwRemoteNameLength + sizeof( WCHAR),
+                       wchRemoteName);
 
         pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
 
-        pConnectCB->AuthenticationId = AFSRetrieveAuthId();
-
-#ifdef AFS_DEBUG_TRACE
-        AFSDbgPrint( L"NPCancelConnection Retrieved authentication id %08lX-%08lX\n",
-                     pConnectCB->AuthenticationId.HighPart,
-                     pConnectCB->AuthenticationId.LowPart);
-#endif
-
         hControlDevice = OpenRedirector();
 
         if( hControlDevice == NULL)
@@ -995,7 +1152,7 @@ NPCancelConnection( LPWSTR  lpName,
 #ifdef AFS_DEBUG_TRACE
             DWORD gle = GetLastError();
 
-            AFSDbgPrint( L"NPCancelConnection Failed to cancel connection to file system - gle 0x%x\n", gle);
+            AFSDbgPrint( L"NPCancelConnection DeviceIoControl failed - gle 0x%x\n", gle);
 #endif
             try_return( dwStatus = WN_NOT_CONNECTED);
         }
@@ -1003,10 +1160,19 @@ NPCancelConnection( LPWSTR  lpName,
         dwStatus = stCancelConn.Status;
 
 #ifdef AFS_DEBUG_TRACE
+        if ( dwStatus == WN_NOT_CONNECTED )
+        {
+
+            AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status WN_NOT_CONNECTED\n",
+                         lpName);
+        }
+        else
+        {
 
-        AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status %08lX\n",
-                     lpName,
-                     dwStatus);
+            AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status %08lX\n",
+                         lpName,
+                         dwStatus);
+        }
 #endif
 
         if( dwStatus == WN_SUCCESS &&
@@ -1015,17 +1181,12 @@ NPCancelConnection( LPWSTR  lpName,
         {
 
             UNICODE_STRING uniConnectionName;
-            UNICODE_STRING uniDeviceName;
-
-            uniDeviceName.Length = (wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR));
-            uniDeviceName.MaximumLength = uniDeviceName.Length;
-            uniDeviceName.Buffer = AFS_RDR_DEVICE_NAME;
 
             //
             // Create a symbolic link object to the device we are redirecting
             //
 
-            uniConnectionName.MaximumLength = (USHORT)( uniDeviceName.Length +
+            uniConnectionName.MaximumLength = (USHORT)( wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR) +
                                                         dwRemoteNameLength +
                                                         8 +             // Local name and \;
                                                         sizeof(WCHAR)); //  Space for NULL-termination.
@@ -1045,18 +1206,32 @@ NPCancelConnection( LPWSTR  lpName,
                 try_return( dwStatus = GetLastError());
             }
 
-            CopyMemory( uniConnectionName.Buffer,
-                        uniDeviceName.Buffer,
-                        uniDeviceName.Length);
+            hr = StringCbCopyW( uniConnectionName.Buffer,
+                                uniConnectionName.MaximumLength,
+                                AFS_RDR_DEVICE_NAME);
 
-            StringCchCatW( uniConnectionName.Buffer,
-                           uniConnectionName.MaximumLength,
-                           L"\\;" );
+            if ( FAILED(hr))
+            {
+#ifdef AFS_DEBUG_TRACE
+                AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (1)\n");
+#endif
+                try_return( dwStatus = WN_OUT_OF_MEMORY);
+            }
 
-            if( !bLocalName)
+            hr = StringCbCatW( uniConnectionName.Buffer,
+                               uniConnectionName.MaximumLength,
+                               L"\\;" );
+
+            if ( FAILED(hr))
             {
+#ifdef AFS_DEBUG_TRACE
+                AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (2)\n");
+#endif
+                try_return( dwStatus = WN_OUT_OF_MEMORY);
+            }
 
-                WCHAR wchLocalName[ 3];
+            if( !bLocalName)
+            {
 
                 wchLocalName[ 0] = stCancelConn.LocalName;
 
@@ -1064,25 +1239,49 @@ NPCancelConnection( LPWSTR  lpName,
 
                 wchLocalName[ 2] = L'\0';
 
-                StringCchCatW( uniConnectionName.Buffer,
-                               uniConnectionName.MaximumLength,
-                               wchLocalName);
+                hr = StringCbCatW( uniConnectionName.Buffer,
+                                   uniConnectionName.MaximumLength,
+                                   wchLocalName);
+
+                if ( FAILED(hr))
+                {
+#ifdef AFS_DEBUG_TRACE
+                    AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (3)\n");
+#endif
+                    try_return( dwStatus = WN_OUT_OF_MEMORY);
+                }
 
                 pwchLocalName = wchLocalName;
             }
             else
             {
 
-                StringCchCatW( uniConnectionName.Buffer,
-                               uniConnectionName.MaximumLength,
-                               lpName);
+                hr = StringCbCatW( uniConnectionName.Buffer,
+                                   uniConnectionName.MaximumLength,
+                                   lpName);
+
+                if ( FAILED(hr))
+                {
+#ifdef AFS_DEBUG_TRACE
+                    AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (4)\n");
+#endif
+                    try_return( dwStatus = WN_OUT_OF_MEMORY);
+                }
 
                 pwchLocalName = lpName;
             }
 
-            StringCchCatW( uniConnectionName.Buffer,
-                           uniConnectionName.MaximumLength,
-                           wchRemoteName);
+            hr = StringCbCatW( uniConnectionName.Buffer,
+                               uniConnectionName.MaximumLength,
+                               wchRemoteName);
+
+            if ( FAILED(hr))
+            {
+#ifdef AFS_DEBUG_TRACE
+                AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (5)\n");
+#endif
+                try_return( dwStatus = WN_OUT_OF_MEMORY);
+            }
 
             if( !DefineDosDevice( DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE,
                                   pwchLocalName,
@@ -1136,9 +1335,42 @@ NPGetConnection( LPWSTR  lpLocalName,
                  LPDWORD lpBufferSize)
 {
 
+    DWORD dwBufferSize = *lpBufferSize;
+    DWORD dwStatus;
+
+    dwStatus = NPGetConnectionCommon( lpLocalName,
+                                      lpRemoteName,
+                                      &dwBufferSize,
+                                      FALSE);
+
+    if ( dwStatus == WN_NOT_CONNECTED)
+    {
+
+        dwStatus = NPGetConnectionCommon( lpLocalName,
+                                          lpRemoteName,
+                                          lpBufferSize,
+                                          TRUE);
+    }
+    else
+    {
+
+        *lpBufferSize = dwBufferSize;
+    }
+
+    return dwStatus;
+}
+
+DWORD
+APIENTRY
+NPGetConnectionCommon( LPWSTR  lpLocalName,
+                       LPWSTR  lpRemoteName,
+                       LPDWORD lpBufferSize,
+                       BOOL    bDriveSubstOk)
+{
+
     DWORD    dwStatus = WN_NOT_CONNECTED;
     WCHAR    wchLocalName[3];
-    WCHAR    wchSubstName[MAX_PATH + 1];
+    WCHAR    wchSubstName[1024 + 26];
     AFSNetworkProviderConnectionCB   *pConnectCB = NULL;
     DWORD    dwError = 0;
     DWORD    dwBufferSize = 0;
@@ -1176,7 +1408,8 @@ NPGetConnection( LPWSTR  lpLocalName,
 
         dwPassedSize = *lpBufferSize;
 
-        if ( !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName)))
+        if ( !bDriveSubstOk ||
+             !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName), &dwStatus))
         {
             wchLocalName[0] = towupper(lpLocalName[0]);
             wchLocalName[1] = L':';
@@ -1212,17 +1445,21 @@ NPGetConnection( LPWSTR  lpLocalName,
                 HRESULT hr;
                 WCHAR  *pwch;
                 DWORD   dwCount = 0;
+                DWORD   dwRequiredSize;
 
 #ifdef AFS_DEBUG_TRACE
                 AFSDbgPrint( L"NPGetConnection drive substitution %s is AFS\n",
                              wchSubstName);
 #endif
 
+                dwRequiredSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
+
                 if ( lpRemoteName == NULL ||
-                     dwPassedSize == 0)
+                     dwPassedSize == 0 ||
+                     dwRequiredSize > *lpBufferSize)
                 {
 
-                    *lpBufferSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
+                    *lpBufferSize = dwRequiredSize;
 
                     try_return( dwStatus = WN_MORE_DATA);
 
@@ -1233,7 +1470,7 @@ NPGetConnection( LPWSTR  lpLocalName,
                 if ( SUCCEEDED(hr))
                 {
 
-                    for ( dwCount = 0, pwch = lpRemoteName; *pwch; pwch++ )
+                    for ( dwCount = 0, pwch = lpRemoteName; *pwch && pwch < lpRemoteName + (*lpBufferSize); pwch++ )
                     {
                         if ( *pwch == L'\\' )
                         {
@@ -1320,14 +1557,6 @@ NPGetConnection( LPWSTR  lpLocalName,
 
         pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
 
-        pConnectCB->AuthenticationId = AFSRetrieveAuthId();
-
-#ifdef AFS_DEBUG_TRACE
-        AFSDbgPrint( L"NPGetConnection Retrieved authentication id %08lX-%08lX\n",
-                     pConnectCB->AuthenticationId.HighPart,
-                     pConnectCB->AuthenticationId.LowPart);
-#endif
-
         hControlDevice = OpenRedirector();
 
         if( hControlDevice == NULL)
@@ -1406,17 +1635,52 @@ try_exit:
     return dwStatus;
 }
 
-DWORD
-APIENTRY
+DWORD APIENTRY
 NPGetConnection3( IN     LPCWSTR lpLocalName,
                   IN     DWORD dwLevel,
                   OUT    LPVOID lpBuffer,
                   IN OUT LPDWORD lpBufferSize)
 {
 
+    DWORD dwBufferSize = *lpBufferSize;
+    DWORD dwStatus;
+
+    dwStatus = NPGetConnection3Common( lpLocalName,
+                                       dwLevel,
+                                       lpBuffer,
+                                       &dwBufferSize,
+                                       FALSE);
+
+    if ( dwStatus == WN_NOT_CONNECTED)
+    {
+
+        dwStatus = NPGetConnection3Common( lpLocalName,
+                                           dwLevel,
+                                           lpBuffer,
+                                           lpBufferSize,
+                                           TRUE);
+    }
+    else
+    {
+
+        *lpBufferSize = dwBufferSize;
+    }
+
+    return dwStatus;
+}
+
+
+static DWORD APIENTRY
+NPGetConnection3Common( IN     LPCWSTR lpLocalName,
+                        IN     DWORD dwLevel,
+                        OUT    LPVOID lpBuffer,
+                        IN OUT LPDWORD lpBufferSize,
+                        IN     BOOL bDriveSubstOk)
+{
+
     DWORD    dwStatus = WN_NOT_CONNECTED;
     WCHAR    wchLocalName[3];
-    WCHAR    wchSubstName[MAX_PATH + 1];
+    WCHAR    wchSubstName[1024 + 26];
     AFSNetworkProviderConnectionCB   *pConnectCB = NULL;
     DWORD    dwError = 0;
     DWORD    dwBufferSize = 0;
@@ -1476,7 +1740,8 @@ NPGetConnection3( IN     LPCWSTR lpLocalName,
             try_return( dwStatus = WN_MORE_DATA);
         }
 
-        if ( !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName)))
+        if ( !bDriveSubstOk ||
+             !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName), &dwStatus))
         {
             wchLocalName[0] = towupper(lpLocalName[0]);
             wchLocalName[1] = L':';
@@ -1550,14 +1815,6 @@ NPGetConnection3( IN     LPCWSTR lpLocalName,
 
         pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
 
-        pConnectCB->AuthenticationId = AFSRetrieveAuthId();
-
-#ifdef AFS_DEBUG_TRACE
-        AFSDbgPrint( L"NPGetConnection3 Retrieved authentication id %08lX-%08lX\n",
-                     pConnectCB->AuthenticationId.HighPart,
-                     pConnectCB->AuthenticationId.LowPart);
-#endif
-
         hControlDevice = OpenRedirector();
 
         if( hControlDevice == NULL)
@@ -1644,10 +1901,10 @@ NPGetConnectionPerformance( LPCWSTR lpRemoteName,
         {
 
 #ifdef AFS_DEBUG_TRACE
-            AFSDbgPrint( L"NPGetConnectionPerformance AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
+            AFSDbgPrint( L"NPGetConnectionPerformance AFSRDFS is disabled, returning WN_NET_ERROR\n");
 #endif
 
-            return WN_NO_NETWORK;
+            return WN_NET_ERROR;
         }
 
         AFSDbgPrint( L"NPGetConnectionPerformance Entry for remote connection %S\n",
@@ -1670,8 +1927,6 @@ NPGetConnectionPerformance( LPCWSTR lpRemoteName,
 
         pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
 
-        pConnectCB->AuthenticationId = AFSRetrieveAuthId();
-
         hControlDevice = OpenRedirector();
 
         if( hControlDevice == NULL)
@@ -1702,13 +1957,13 @@ NPGetConnectionPerformance( LPCWSTR lpRemoteName,
             try_return( dwReturn = WN_NOT_CONNECTED);
         }
 
-        lpNetConnectInfo->dwFlags = WNCON_DYNAMIC;
+        lpNetConnectInfo->dwFlags = 0;
 
-        lpNetConnectInfo->dwSpeed = 500;
+        lpNetConnectInfo->dwSpeed = 0;
 
         lpNetConnectInfo->dwDelay = 0;
 
-        lpNetConnectInfo->dwOptDataSize = 0x1000;
+        lpNetConnectInfo->dwOptDataSize = 0x10000;
 
         AFSDbgPrint( L"NPGetConnectionPerformance Successfully returned information for remote connection %S\n",
                      lpRemoteName);
@@ -1954,6 +2209,7 @@ NPOpenEnum( DWORD          dwScope,
 
     DWORD   dwStatus = WN_SUCCESS;
     AFSEnumerationCB *pEnumCB = NULL;
+    HANDLE   hControlDevice = NULL;
 
 #ifdef AFS_DEBUG_TRACE
     if ( lpNetResource == NULL)
@@ -1990,6 +2246,21 @@ NPOpenEnum( DWORD          dwScope,
     }
 #endif
 
+    hControlDevice = OpenRedirector();
+
+    if( hControlDevice == NULL)
+    {
+
+#ifdef AFS_DEBUG_TRACE
+       AFSDbgPrint( L"NPOpenEnum OpenRedirector failure, returning WN_NET_ERROR\n");
+#endif
+
+       return WN_NO_NETWORK;
+    }
+
+    CloseHandle( hControlDevice);
+
+
     *lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( AFSEnumerationCB));
 
     if( *lphEnum == NULL)
@@ -2161,6 +2432,15 @@ NPEnumResource( HANDLE  hEnum,
             try_return( dwStatus = WN_NET_ERROR);
         }
 
+        if( pEnumCB->Type != RESOURCETYPE_ANY && pEnumCB->Type != RESOURCETYPE_DISK)
+        {
+
+#ifdef AFS_DEBUG_TRACE
+            AFSDbgPrint( L"NPEnumResource Non-DISK queries are not supported, returning WN_NO_MORE_ENTRIES\n");
+#endif
+            try_return( dwStatus = WN_NO_MORE_ENTRIES);
+        }
+
         //
         // Handle the special cases here
         //   0. Provider Network Root
@@ -2407,14 +2687,6 @@ NPEnumResource( HANDLE  hEnum,
                           pEnumCB->RemoteName);
         }
 
-        pConnectionCB->AuthenticationId = AFSRetrieveAuthId();
-
-#ifdef AFS_DEBUG_TRACE
-        AFSDbgPrint( L"NPEnumResource Retrieved authentication id %08lX-%08lX\n",
-                     pConnectionCB->AuthenticationId.HighPart,
-                     pConnectionCB->AuthenticationId.LowPart);
-#endif
-
         dwError = DeviceIoControl( hControlDevice,
                                    IOCTL_AFS_LIST_CONNECTIONS,
                                    pConnectionCB,
@@ -2514,7 +2786,17 @@ NPEnumResource( HANDLE  hEnum,
 
                 pNetResource->dwType = RESOURCETYPE_DISK;
             }
-            pNetResource->dwUsage       = pConnectionCB->Usage;
+
+            if ( pEnumCB->Scope == RESOURCE_CONNECTED)
+            {
+
+                pNetResource->dwUsage       = 0;
+            }
+            else
+            {
+
+                pNetResource->dwUsage       = pConnectionCB->Usage;
+            }
 
             // setup string area at opposite end of buffer
             StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
@@ -2697,6 +2979,16 @@ NPGetResourceParent( LPNETRESOURCE   lpNetResource,
     WCHAR   *pwchRemoteName = NULL, *pwchSearch = NULL, *pwchSystem = NULL;
     LPNETRESOURCE lpOutResource = (LPNETRESOURCE) lpBuffer;
 
+    if ( NPIsFSDisabled())
+    {
+
+#ifdef AFS_DEBUG_TRACE
+        AFSDbgPrint( L"NPGetResourceParent AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
+#endif
+
+        return WN_BAD_NETNAME;
+    }
+
     if ( lpNetResource == NULL)
     {
 #ifdef AFS_DEBUG_TRACE
@@ -2738,6 +3030,11 @@ NPGetResourceParent( LPNETRESOURCE   lpNetResource,
 
     pwchRemoteName = lpNetResource->lpRemoteName;
 
+    //
+    // The input will be of the form \\AFS\CELL\path.
+    // \\AFS has no parent and by definition returns an empty NETRESOURCE.
+    //
+
     pwchSearch = pwchRemoteName + (wcslen( pwchRemoteName) - 1);
 
     while( pwchSearch != pwchRemoteName)
@@ -2754,7 +3051,8 @@ NPGetResourceParent( LPNETRESOURCE   lpNetResource,
         pwchSearch--;
     }
 
-    if( pwchSearch != pwchRemoteName)
+    if( pwchSearch != pwchRemoteName &&
+        pwchSearch != pwchRemoteName + 1)
     {
 
 #ifdef AFS_DEBUG_TRACE
@@ -2863,14 +3161,6 @@ NPGetResourceInformation( LPNETRESOURCE   lpNetResource,
 
         pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
 
-        pConnectCB->AuthenticationId = AFSRetrieveAuthId();
-
-#ifdef AFS_DEBUG_TRACE
-        AFSDbgPrint( L"NPGetResourceInformation Retrieved authentication id %08lX-%08lX\n",
-                     pConnectCB->AuthenticationId.HighPart,
-                     pConnectCB->AuthenticationId.LowPart);
-#endif
-
         hControlDevice = OpenRedirector();
 
         if( hControlDevice == NULL)
@@ -2883,6 +3173,18 @@ NPGetResourceInformation( LPNETRESOURCE   lpNetResource,
             try_return( dwStatus = WN_NET_ERROR);
         }
 
+        uniRemoteName.Length = (USHORT)pConnectCB->RemoteNameLength;
+        uniRemoteName.MaximumLength = uniRemoteName.Length;
+        uniRemoteName.Buffer = pConnectCB->RemoteName;
+
+#ifdef AFS_DEBUG_TRACE
+        AFSDbgPrint( L"NPGetResourceInformation For remote name %wZ Scope %08lX Type %08lX Usage %08lX\n",
+                     &uniRemoteName,
+                     pConnectCB->Scope,
+                     pConnectCB->Type,
+                     pConnectCB->Usage);
+#endif
+
         dwError = DeviceIoControl( hControlDevice,
                                    IOCTL_AFS_GET_CONNECTION_INFORMATION,
                                    pConnectCB,
@@ -2903,18 +3205,6 @@ NPGetResourceInformation( LPNETRESOURCE   lpNetResource,
             try_return( dwStatus = WN_BAD_NETNAME);
         }
 
-        uniRemoteName.Length = (USHORT)pConnectCB->RemoteNameLength;
-        uniRemoteName.MaximumLength = uniRemoteName.Length;
-        uniRemoteName.Buffer = pConnectCB->RemoteName;
-
-#ifdef AFS_DEBUG_TRACE
-        AFSDbgPrint( L"NPGetResourceInformation For remote name %wZ Scope %08lX Type %08lX Usage %08lX\n",
-                     &uniRemoteName,
-                     pConnectCB->Scope,
-                     pConnectCB->Type,
-                     pConnectCB->Usage);
-#endif
-
         // Determine the space needed for this entry...
 
         ulRequiredLen = sizeof( NETRESOURCE);
@@ -3081,11 +3371,47 @@ DWORD APIENTRY
 NPGetUniversalName( LPCWSTR lpLocalPath,
                     DWORD   dwInfoLevel,
                     LPVOID  lpBuffer,
-                    LPDWORD lpBufferSize )
+                    LPDWORD lpBufferSize)
+{
+
+    DWORD dwBufferSize = *lpBufferSize;
+    DWORD dwStatus;
+
+    dwStatus = NPGetUniversalNameCommon( lpLocalPath,
+                                         dwInfoLevel,
+                                         lpBuffer,
+                                         &dwBufferSize,
+                                         FALSE);
+
+    if ( dwStatus == WN_NOT_CONNECTED)
+    {
+
+        dwStatus = NPGetUniversalNameCommon( lpLocalPath,
+                                             dwInfoLevel,
+                                             lpBuffer,
+                                             lpBufferSize,
+                                             TRUE);
+    }
+    else
+    {
+
+        *lpBufferSize = dwBufferSize;
+    }
+
+    return dwStatus;
+}
+
+static DWORD APIENTRY
+NPGetUniversalNameCommon( LPCWSTR lpLocalPath,
+                          DWORD   dwInfoLevel,
+                          LPVOID  lpBuffer,
+                          LPDWORD lpBufferSize,
+                          BOOL    bDriveSubstOk)
 {
     DWORD    dwStatus = WN_NOT_CONNECTED;
     WCHAR    wchLocalName[3];
-    WCHAR    wchSubstName[MAX_PATH + 1];
+    WCHAR   *pwchSubstName = NULL;
+    DWORD    dwSubstNameLength = 0;
     AFSNetworkProviderConnectionCB   *pConnectCB = NULL;
     DWORD    dwError = 0;
     DWORD    dwBufferSize = 0;
@@ -3138,9 +3464,22 @@ NPGetUniversalName( LPCWSTR lpLocalPath,
             try_return( dwStatus = WN_BAD_VALUE);
         }
 
+        dwSubstNameLength = 4096;
+
+        pwchSubstName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSubstNameLength);
+
+        if ( pwchSubstName == NULL)
+        {
+#ifdef AFS_DEBUG_TRACE
+            AFSDbgPrint( L"NPGetUniversalName unable to allocate substitution name buffer.\n");
+#endif
+            try_return( dwStatus = WN_OUT_OF_MEMORY);
+        }
+
         memset(lpBuffer, 0, dwPassedSize);
 
-        if ( !DriveSubstitution( lpLocalPath, wchSubstName, sizeof( wchSubstName)))
+        if ( !bDriveSubstOk ||
+             !DriveSubstitution( lpLocalPath, pwchSubstName, dwSubstNameLength, &dwStatus))
         {
             wchLocalName[0] = towupper(lpLocalPath[0]);
             wchLocalName[1] = L':';
@@ -3157,34 +3496,34 @@ NPGetUniversalName( LPCWSTR lpLocalPath,
 
             ReadServerNameString();
 
-            if ( wchSubstName[0] != L'\\' &&
-                 wchSubstName[1] == L':')
+            if ( pwchSubstName[0] != L'\\' &&
+                 pwchSubstName[1] == L':')
             {
 
-                wchLocalName[0] = towupper(wchSubstName[0]);
+                wchLocalName[0] = towupper(pwchSubstName[0]);
                 wchLocalName[1] = L':';
                 wchLocalName[2] = L'\0';
 
 #ifdef AFS_DEBUG_TRACE
                 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for drive substitution %s -> %s\n",
-                             wchSubstName,
+                             pwchSubstName,
                              wchLocalName);
 #endif
             }
-            else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
-                      ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
-                        wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
+            else if ( _wcsnicmp( pwchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
+                      ( pwchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
+                        pwchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
             {
                 HRESULT hr;
 
 #ifdef AFS_DEBUG_TRACE
                 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is AFS; Level 0x%x BufferSize 0x%x\n",
-                             wchSubstName,
+                             pwchSubstName,
                              dwInfoLevel,
                              dwPassedSize);
 #endif
 
-                dwBufferSize = (wcslen( wchSubstName) + 1) * sizeof( WCHAR);
+                dwBufferSize = (wcslen( pwchSubstName) + 1) * sizeof( WCHAR);
 
                 switch( dwInfoLevel)
                 {
@@ -3211,7 +3550,7 @@ NPGetUniversalName( LPCWSTR lpLocalPath,
                     pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
 
                     memcpy( pUniversalInfo->lpUniversalName,
-                            wchSubstName,
+                            pwchSubstName,
                             min( dwBufferSize, dwRemainingLength));
 
                     dwRemainingLength -= min( dwBufferSize, dwRemainingLength);
@@ -3254,7 +3593,7 @@ NPGetUniversalName( LPCWSTR lpLocalPath,
                     pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
 
                     memcpy( pRemoteInfo->lpUniversalName,
-                            wchSubstName,
+                            pwchSubstName,
                             min( dwRemainingLength, dwBufferSize));
 
                     dwRemainingLength -= min( dwRemainingLength, dwBufferSize);
@@ -3271,7 +3610,7 @@ NPGetUniversalName( LPCWSTR lpLocalPath,
                         pRemoteInfo->lpConnectionName = (LPTSTR)((char *)pRemoteInfo->lpUniversalName + dwBufferSize);
 
                         memcpy( pRemoteInfo->lpConnectionName,
-                                wchSubstName,
+                                pwchSubstName,
                                 min( dwRemainingLength, dwBufferSize));
 
                         dwRemainingLength -= min( dwRemainingLength, dwBufferSize) - sizeof( WCHAR);
@@ -3314,7 +3653,7 @@ NPGetUniversalName( LPCWSTR lpLocalPath,
 
 #ifdef AFS_DEBUG_TRACE
                 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is not AFS\n",
-                             wchSubstName);
+                             pwchSubstName);
 #endif
                 try_return( dwStatus = WN_NOT_CONNECTED);
             }
@@ -3335,14 +3674,6 @@ NPGetUniversalName( LPCWSTR lpLocalPath,
 
         pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
 
-        pConnectCB->AuthenticationId = AFSRetrieveAuthId();
-
-#ifdef AFS_DEBUG_TRACE
-        AFSDbgPrint( L"NPGetUniversalName Retrieved authentication id %08lX-%08lX\n",
-                     pConnectCB->AuthenticationId.HighPart,
-                     pConnectCB->AuthenticationId.LowPart);
-#endif
-
         hControlDevice = OpenRedirector();
 
         if( hControlDevice == NULL)
@@ -3547,6 +3878,12 @@ try_exit:
             CloseHandle( hControlDevice);
         }
 
+        if ( pwchSubstName)
+        {
+
+            HeapFree( GetProcessHeap(), 0, (PVOID) pwchSubstName);
+        }
+
         if( pConnectCB != NULL)
         {
 
@@ -3572,6 +3909,11 @@ GetFormatFlags( DWORD dwFlags)
 
     Buffer[0] = L'\0';
 
+    if ( dwFlags == 0)
+    {
+        return L"NONE";
+    }
+
     if ( dwFlags & WNFMT_MULTILINE )
     {
         StringCbCat( Buffer, sizeof(Buffer), L"MULTILINE|");
@@ -3616,8 +3958,8 @@ NPFormatNetworkName( LPTSTR  lpRemoteName,
 #ifdef AFS_DEBUG_TRACE
     AFSDbgPrint( L"NPFormatNetworkName Remote %s Flags %s (0x%x) CharsPerLine %u\n",
                  lpRemoteName,
-                 dwFlags,
                  GetFormatFlags( dwFlags),
+                 dwFlags,
                  dwAveCharPerLine);
 #endif
 
@@ -3777,7 +4119,6 @@ OpenRedirector()
 {
 
     HANDLE hControlDevice = NULL;
-    WCHAR wchError[ 256];
 
     hControlDevice = CreateFile( AFS_SYMLINK_W,
                                  GENERIC_READ | GENERIC_WRITE,
@@ -3830,95 +4171,97 @@ OpenRedirector()
     return hControlDevice;
 }
 
-LARGE_INTEGER
-AFSRetrieveAuthId()
+static DWORD
+Debug(void)
 {
+    static int init = 0;
+    static DWORD debug = 0;
 
-    LARGE_INTEGER liAuthId = {0,0};
-    HANDLE hToken = NULL;
-    TOKEN_STATISTICS stTokenInfo;
-    DWORD dwCopyBytes = 0;
-
-    if ( !OpenThreadToken( GetCurrentThread(),
-                           TOKEN_QUERY,
-                           FALSE,       // Impersonation
-                           &hToken))
-    {
-        if( !OpenProcessToken( GetCurrentProcess(),
-                               TOKEN_QUERY,
-                               &hToken))
-        {
+    if ( !init ) {
+        HKEY hk;
 
-#ifdef AFS_DEBUG_TRACE
-            AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve Thread and Process tokens 0x%X\n",
-                         GetLastError());
-#endif
-        }
-        else
+        if (RegOpenKey (HKEY_LOCAL_MACHINE,
+                         TEXT("SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider"), &hk) == 0)
         {
-
-#ifdef AFS_DEBUG_TRACE
-            AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Process Token\n");
-#endif
+            DWORD dwSize = sizeof(BOOL);
+            DWORD dwType = REG_DWORD;
+            RegQueryValueEx (hk, TEXT("Debug"), NULL, &dwType, (PBYTE)&debug, &dwSize);
+            RegCloseKey (hk);
         }
+        init = 1;
     }
-    else
-    {
 
-#ifdef AFS_DEBUG_TRACE
-        AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Thread Token\n");
-#endif
+    return debug;
+}
+
+static char *
+cm_Utf16ToUtf8Alloc(const WCHAR * s, int cch_src, int *pcch_dest)
+{
+    int cch_dest;
+    char * dest;
+
+    if (s == NULL || cch_src == 0 || *s == L'\0') {
+        if (pcch_dest)
+            *pcch_dest = ((cch_src != 0)?1:0);
+        return NULL;
     }
 
-    if ( hToken != NULL)
-    {
+    cch_dest = WideCharToMultiByte(CP_UTF8, 0, s, cch_src, NULL, 0, NULL, FALSE);
 
-        if( !GetTokenInformation( hToken,
-                                  TokenStatistics,
-                                  &stTokenInfo,
-                                  sizeof( TOKEN_STATISTICS),
-                                  &dwCopyBytes))
-        {
+    if (cch_dest == 0) {
+        if (pcch_dest)
+            *pcch_dest = cch_dest;
+        return NULL;
+    }
 
-#ifdef AFS_DEBUG_TRACE
-            AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve token information 0x%X\n",
-                         GetLastError());
-#endif
-        }
-        else
-        {
+    dest = HeapAlloc( GetProcessHeap(), 0, (cch_dest + 1) * sizeof(char));
 
-            liAuthId.HighPart = stTokenInfo.AuthenticationId.HighPart;
-            liAuthId.LowPart = stTokenInfo.AuthenticationId.LowPart;
-        }
+    WideCharToMultiByte(CP_UTF8, 0, s, cch_src, dest, cch_dest, NULL, FALSE);
+    dest[cch_dest] = 0;
 
-        CloseHandle( hToken);
-    }
+    if (pcch_dest)
+        *pcch_dest = cch_dest;
 
-    return liAuthId;
+    return dest;
 }
 
-static BOOL
-Debug(void)
+static void
+AppendDebugStringToLogFile(WCHAR *wszbuffer)
 {
-    static int init = 0;
-    static BOOL debug = 0;
+    HANDLE hFile;
+    int len;
+    char * buffer;
+    DWORD dwWritten;
+    BOOL bRet;
 
-    if ( !init ) {
-        HKEY hk;
+    if ( !wszbuffer || !wszbuffer[0] )
+        return;
 
-        if (RegOpenKey (HKEY_LOCAL_MACHINE,
-                         TEXT("SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider"), &hk) == 0)
-        {
-            DWORD dwSize = sizeof(BOOL);
-            DWORD dwType = REG_DWORD;
-            RegQueryValueEx (hk, TEXT("Debug"), NULL, &dwType, (PBYTE)&debug, &dwSize);
-            RegCloseKey (hk);
-        }
-        init = 1;
+    len = (int)wcslen(wszbuffer);
+
+    buffer = cm_Utf16ToUtf8Alloc(wszbuffer, len, &len);
+
+    if (!buffer)
+        return;
+
+    hFile = CreateFileW( L"C:\\TEMP\\AFSRDFSProvider.log",
+                         FILE_APPEND_DATA,
+                         FILE_SHARE_WRITE,
+                         NULL,
+                         OPEN_ALWAYS,
+                         FILE_ATTRIBUTE_NORMAL,
+                         NULL);
+
+    if ( hFile == INVALID_HANDLE_VALUE ) {
+        OutputDebugString(L"C:\\AFSRDFSProvider.log cannot be opened.\n");
+        return;
     }
 
-    return debug;
+    bRet = WriteFile( hFile, buffer, len, &dwWritten, NULL);
+
+    bRet = CloseHandle(hFile);
+
+    HeapFree(GetProcessHeap(), 0, buffer);
 }
 
 ULONG
@@ -3931,8 +4274,9 @@ AFSDbgPrint(
     HRESULT rc = S_OK;
     WCHAR wszbuffer[512];
     va_list marker;
+    DWORD debug = Debug();
 
-    if ( !Debug() )
+    if (debug == 0)
         return 0;
 
     va_start( marker, Format );
@@ -3945,12 +4289,16 @@ AFSDbgPrint(
 #endif
                            GetCurrentThreadId());
 
-        rc = StringCbVPrintfW( &wszbuffer[ 14], sizeof(wszbuffer) - 14, Format, marker);
+        rc = StringCbVPrintfW( &wszbuffer[ 14], sizeof(wszbuffer) - 14 * sizeof(WCHAR), Format, marker);
 
-        if (SUCCEEDED(rc))
-            OutputDebugString( wszbuffer );
-        else
+        if (SUCCEEDED(rc)) {
+            if (debug & 1)
+                OutputDebugString( wszbuffer );
+            if (debug & 2)
+                AppendDebugStringToLogFile(wszbuffer);
+        } else {
             OutputDebugString(L"AFSDbgPrint Failed to create string\n");
+        }
     }
     return SUCCEEDED(rc) ? 1 : 0;
 }