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"
// 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",
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
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
// \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
#endif
}
-
-
return FALSE;
}
//
// 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;
}
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,
HANDLE hControlDevice = NULL;
HANDLE hToken = NULL;
LARGE_INTEGER liAuthId = {0,0};
+ HRESULT hr;
+ WCHAR wszFlagsString[1024]=L"";
__Enter
{
}
#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)
{
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
#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);
}
//
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)
{
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.
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",
else
{
+#ifdef AFS_DEBUG_TRACE
+ AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW assigned drive %s\n", wchLocalName);
+#endif
+
dwStatus = WN_SUCCESS;
}
DWORD dwBufferSize = 0;
BOOL bLocalName = TRUE;
HANDLE hControlDevice = NULL;
+ WCHAR wchLocalName[ 3];
WCHAR *pwchLocalName = NULL;
+ HRESULT hr;
__Enter
{
{
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)
//
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);
if( bLocalName)
{
- pConnectCB->LocalName = towupper(lpName[0]);
+ pConnectCB->LocalName = wchLocalName[0];
}
else
{
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;
#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);
}
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 &&
{
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.
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"NPCancelConnection uniConnectionName buffer too small (1)\n");
+#endif
+ try_return( dwStatus = WN_OUT_OF_MEMORY);
+ }
+
+ hr = StringCbCatW( uniConnectionName.Buffer,
+ uniConnectionName.MaximumLength,
+ L"\\;" );
- StringCchCatW( 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);
+ }
if( !bLocalName)
{
- WCHAR wchLocalName[ 3];
-
wchLocalName[ 0] = stCancelConn.LocalName;
wchLocalName[ 1] = L':';
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,
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;
dwPassedSize = *lpBufferSize;
- if ( !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName)))
+ if ( !bDriveSubstOk ||
+ !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName), &dwStatus))
{
wchLocalName[0] = towupper(lpLocalName[0]);
wchLocalName[1] = L':';
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);
if ( SUCCEEDED(hr))
{
- for ( dwCount = 0, pwch = lpRemoteName; *pwch; pwch++ )
+ for ( dwCount = 0, pwch = lpRemoteName; *pwch && pwch < lpRemoteName + (*lpBufferSize); pwch++ )
{
if ( *pwch == L'\\' )
{
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;
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':';
{
#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",
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);
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
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);
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
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)
pwchSearch--;
}
- if( pwchSearch != pwchRemoteName)
+ if( pwchSearch != pwchRemoteName &&
+ pwchSearch != pwchRemoteName + 1)
{
#ifdef AFS_DEBUG_TRACE
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,
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);
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;
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':';
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)
{
pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
memcpy( pUniversalInfo->lpUniversalName,
- wchSubstName,
+ pwchSubstName,
min( dwBufferSize, dwRemainingLength));
dwRemainingLength -= min( dwBufferSize, dwRemainingLength);
pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
memcpy( pRemoteInfo->lpUniversalName,
- wchSubstName,
+ pwchSubstName,
min( dwRemainingLength, dwBufferSize));
dwRemainingLength -= min( dwRemainingLength, dwBufferSize);
pRemoteInfo->lpConnectionName = (LPTSTR)((char *)pRemoteInfo->lpUniversalName + dwBufferSize);
memcpy( pRemoteInfo->lpConnectionName,
- wchSubstName,
+ pwchSubstName,
min( dwRemainingLength, dwBufferSize));
dwRemainingLength -= min( dwRemainingLength, dwBufferSize) - sizeof( WCHAR);
#ifdef AFS_DEBUG_TRACE
AFSDbgPrint( L"NPGetUniversalName drive substitution %s is not AFS\n",
- wchSubstName);
+ pwchSubstName);
#endif
try_return( dwStatus = WN_NOT_CONNECTED);
}
CloseHandle( hControlDevice);
}
+ if ( pwchSubstName)
+ {
+
+ HeapFree( GetProcessHeap(), 0, (PVOID) pwchSubstName);
+ }
+
if( pConnectCB != NULL)
{
Buffer[0] = L'\0';
+ if ( dwFlags == 0)
+ {
+ return L"NONE";
+ }
+
if ( dwFlags & WNFMT_MULTILINE )
{
StringCbCat( Buffer, sizeof(Buffer), L"MULTILINE|");
#ifdef AFS_DEBUG_TRACE
AFSDbgPrint( L"NPFormatNetworkName Remote %s Flags %s (0x%x) CharsPerLine %u\n",
lpRemoteName,
- dwFlags,
GetFormatFlags( dwFlags),
+ dwFlags,
dwAveCharPerLine);
#endif
{
HANDLE hControlDevice = NULL;
- WCHAR wchError[ 256];
hControlDevice = CreateFile( AFS_SYMLINK_W,
GENERIC_READ | GENERIC_WRITE,
return liAuthId;
}
-static BOOL
+static DWORD
Debug(void)
{
static int init = 0;
- static BOOL debug = 0;
+ static DWORD debug = 0;
if ( !init ) {
HKEY hk;
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(
HRESULT rc = S_OK;
WCHAR wszbuffer[512];
va_list marker;
+ DWORD debug = Debug();
- if ( !Debug() )
+ if (debug == 0)
return 0;
va_start( marker, Format );
#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;
}