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 + 26];
HRESULT hr = S_OK;
+ *pStatus = WN_SUCCESS;
+
memset( subststr, 0, substlen);
drive[0] = drivestr[0];
drive[1] = drivestr[1];
drive[1] = L':';
drive[2] = L'\0';
- if ( !DriveSubstitution(drive, subststr, substlen) )
+ if ( !DriveSubstitution(drive, subststr, substlen, pStatus) )
{
subststr[0] = drive[0];
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], sizeof(device));
+ 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 = StringCbCat( 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
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 = StringCbCat( 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 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)
{
#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);
}
//
LPDWORD lpBufferSize)
{
- return NPGetConnectionCommon( lpLocalName,
- lpRemoteName,
- lpBufferSize,
- TRUE);
+ 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
dwPassedSize = *lpBufferSize;
if ( !bDriveSubstOk ||
- !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName)))
+ !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName), &dwStatus))
{
wchLocalName[0] = towupper(lpLocalName[0]);
wchLocalName[1] = 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[1024 + 26];
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);
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];
try_return( dwStatus = WN_BAD_VALUE);
}
- dwSubstNameLength = (dwLocalPathLength + 26) * sizeof( WCHAR);
+ dwSubstNameLength = 4096;
pwchSubstName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSubstNameLength);
memset(lpBuffer, 0, dwPassedSize);
- if ( !DriveSubstitution( lpLocalPath, pwchSubstName, dwSubstNameLength))
+ if ( !bDriveSubstOk ||
+ !DriveSubstitution( lpLocalPath, pwchSubstName, dwSubstNameLength, &dwStatus))
{
wchLocalName[0] = towupper(lpLocalPath[0]);
wchLocalName[1] = L':';
#ifdef AFS_DEBUG_TRACE
AFSDbgPrint( L"NPFormatNetworkName Remote %s Flags %s (0x%x) CharsPerLine %u\n",
lpRemoteName,
- dwFlags,
GetFormatFlags( dwFlags),
+ dwFlags,
dwAveCharPerLine);
#endif
#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)) {
if (debug & 1)