Windows: npdll connected query returns no usage
[openafs.git] / src / WINNT / afsrdr / npdll / AFS_Npdll.c
index 9b889be..9faaf0a 100644 (file)
 
 ULONG _cdecl AFSDbgPrint( PWCHAR Format, ... );
 
+static DWORD APIENTRY
+NPGetConnectionCommon( LPWSTR  lpLocalName,
+                       LPWSTR  lpRemoteName,
+                       LPDWORD lpBufferSize,
+                       BOOL    bDriveSubstOk);
+
 #define WNNC_DRIVER( major, minor ) ( major * 0x00010000 + minor )
 
 #define OPENAFS_PROVIDER_NAME           L"OpenAFS Network"
@@ -817,6 +823,10 @@ NPAddConnection3( HWND            hwndOwner,
                     else
                     {
 
+#ifdef AFS_DEBUG_TRACE
+                        AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW assigned drive %s\n", wchLocalName);
+#endif
+
                         dwStatus = WN_SUCCESS;
                     }
 
@@ -869,6 +879,7 @@ NPCancelConnection( LPWSTR  lpName,
     DWORD    dwBufferSize = 0;
     BOOL     bLocalName = TRUE;
     HANDLE   hControlDevice = NULL;
+    WCHAR    wchLocalName[ 3];
     WCHAR   *pwchLocalName = NULL;
 
     __Enter
@@ -889,18 +900,28 @@ NPCancelConnection( LPWSTR  lpName,
         {
 
             bLocalName = FALSE;
-        }
 
-        if( bLocalName)
+            wchLocalName[0] = L'\0';
+
+            StringCchCopyW( wchRemoteName, MAX_PATH+1, lpName);
+
+            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 +939,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 +960,7 @@ NPCancelConnection( LPWSTR  lpName,
         if( bLocalName)
         {
 
-            pConnectCB->LocalName = towupper(lpName[0]);
+            pConnectCB->LocalName = wchLocalName[0];
         }
         else
         {
@@ -995,7 +1014,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 +1022,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 %08lX\n",
-                     lpName,
-                     dwStatus);
+            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);
+        }
 #endif
 
         if( dwStatus == WN_SUCCESS &&
@@ -1056,8 +1084,6 @@ NPCancelConnection( LPWSTR  lpName,
             if( !bLocalName)
             {
 
-                WCHAR wchLocalName[ 3];
-
                 wchLocalName[ 0] = stCancelConn.LocalName;
 
                 wchLocalName[ 1] = L':';
@@ -1136,6 +1162,20 @@ NPGetConnection( LPWSTR  lpLocalName,
                  LPDWORD lpBufferSize)
 {
 
+    return NPGetConnectionCommon( lpLocalName,
+                                  lpRemoteName,
+                                  lpBufferSize,
+                                  TRUE);
+}
+
+DWORD
+APIENTRY
+NPGetConnectionCommon( LPWSTR  lpLocalName,
+                       LPWSTR  lpRemoteName,
+                       LPDWORD lpBufferSize,
+                       BOOL    bDriveSubstOk)
+{
+
     DWORD    dwStatus = WN_NOT_CONNECTED;
     WCHAR    wchLocalName[3];
     WCHAR    wchSubstName[MAX_PATH + 1];
@@ -1176,7 +1216,8 @@ NPGetConnection( LPWSTR  lpLocalName,
 
         dwPassedSize = *lpBufferSize;
 
-        if ( !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName)))
+        if ( !bDriveSubstOk ||
+             !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName)))
         {
             wchLocalName[0] = towupper(lpLocalName[0]);
             wchLocalName[1] = L':';
@@ -1212,17 +1253,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 +1278,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'\\' )
                         {
@@ -2161,6 +2206,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
@@ -2514,7 +2568,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);
@@ -3898,11 +3962,11 @@ AFSRetrieveAuthId()
     return liAuthId;
 }
 
-static BOOL
+static DWORD
 Debug(void)
 {
     static int init = 0;
-    static BOOL debug = 0;
+    static DWORD debug = 0;
 
     if ( !init ) {
         HKEY hk;
@@ -3921,6 +3985,76 @@ Debug(void)
     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;
+    }
+
+    cch_dest = WideCharToMultiByte(CP_UTF8, 0, s, cch_src, NULL, 0, NULL, FALSE);
+
+    if (cch_dest == 0) {
+        if (pcch_dest)
+            *pcch_dest = cch_dest;
+        return NULL;
+    }
+
+    dest = HeapAlloc( GetProcessHeap(), 0, (cch_dest + 1) * sizeof(char));
+
+    WideCharToMultiByte(CP_UTF8, 0, s, cch_src, dest, cch_dest, NULL, FALSE);
+    dest[cch_dest] = 0;
+
+    if (pcch_dest)
+        *pcch_dest = cch_dest;
+
+    return dest;
+}
+
+static void
+AppendDebugStringToLogFile(WCHAR *wszbuffer)
+{
+    HANDLE hFile;
+    int len;
+    char * buffer;
+       DWORD dwWritten;
+       BOOL bRet;
+
+    if ( !wszbuffer || !wszbuffer[0] )
+        return;
+
+    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;
+    }
+
+    bRet = WriteFile( hFile, buffer, len, &dwWritten, NULL);
+
+    bRet = CloseHandle(hFile);
+
+    HeapFree(GetProcessHeap(), 0, buffer);
+}
+
 ULONG
 _cdecl
 AFSDbgPrint(
@@ -3931,8 +4065,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 );
@@ -3947,10 +4082,14 @@ AFSDbgPrint(
 
         rc = StringCbVPrintfW( &wszbuffer[ 14], sizeof(wszbuffer) - 14, 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;
 }