Windows: npdll connected query returns no usage
[openafs.git] / src / WINNT / afsrdr / npdll / AFS_Npdll.c
index e63ee09..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"
@@ -912,9 +918,10 @@ NPCancelConnection( LPWSTR  lpName,
             // 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)
@@ -1155,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];
@@ -1195,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':';
@@ -1231,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);
 
@@ -1252,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'\\' )
                         {
@@ -2180,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
@@ -2533,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);
@@ -3917,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;
@@ -3940,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(
@@ -3950,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 );
@@ -3966,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;
 }