2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2015 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSNetworkProviderSupport.cpp
39 #include "AFSCommon.h"
42 AFSAddConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
43 IN OUT PULONG ResultStatus,
44 IN OUT ULONG_PTR *ReturnOutputBufferLength)
47 NTSTATUS ntStatus = STATUS_SUCCESS;
48 AFSProviderConnectionCB *pConnection = NULL, *pLastConnection = NULL;
49 UNICODE_STRING uniRemoteName;
50 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
55 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
56 AFS_TRACE_LEVEL_VERBOSE,
57 "AFSAddConnection Acquiring AFSProviderListLock lock %p EXCL %08lX\n",
58 &pRDRDevExt->Specific.RDR.ProviderListLock,
59 PsGetCurrentThread()));
61 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
63 if ( !NT_SUCCESS( ntStatus))
66 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
67 AFS_TRACE_LEVEL_ERROR,
68 "AFSAddConnection Unable to retrieve authentication id %08lX\n",
74 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
75 AFS_TRACE_LEVEL_VERBOSE,
76 "AFSAddConnection Retrieved authentication id %I64X\n",
77 ConnectCB->AuthenticationId.QuadPart));
79 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
83 // Look for the connection
86 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
87 uniRemoteName.MaximumLength = uniRemoteName.Length;
89 uniRemoteName.Buffer = ConnectCB->RemoteName;
92 // Strip off any trailing slashes
95 if( uniRemoteName.Length >= sizeof( WCHAR)
96 && uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
99 uniRemoteName.Length -= sizeof( WCHAR);
102 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
104 while( pConnection != NULL)
107 if( pConnection->LocalName == ConnectCB->LocalName &&
108 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
109 RtlCompareUnicodeString( &uniRemoteName,
110 &pConnection->RemoteName,
117 pConnection = pConnection->fLink;
120 if( pConnection != NULL)
123 if( ConnectCB->LocalName != L'\0')
126 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
127 AFS_TRACE_LEVEL_VERBOSE,
128 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local %C authentication id %I64X\n",
130 ConnectCB->LocalName,
131 ConnectCB->AuthenticationId.QuadPart));
133 *ResultStatus = WN_ALREADY_CONNECTED;
138 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
139 AFS_TRACE_LEVEL_VERBOSE,
140 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local (NULL) authentication id %I64X\n",
142 ConnectCB->AuthenticationId.QuadPart));
144 *ResultStatus = WN_SUCCESS;
147 *ReturnOutputBufferLength = sizeof( ULONG);
149 try_return( ntStatus = STATUS_SUCCESS);
153 // Validate the remote name
156 if( uniRemoteName.Length > 2 * sizeof( WCHAR) &&
157 uniRemoteName.Buffer[ 0] == L'\\' &&
158 uniRemoteName.Buffer[ 1] == L'\\')
161 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 2];
163 uniRemoteName.Length -= (2 * sizeof( WCHAR));
166 if( uniRemoteName.Length >= AFSServerName.Length)
169 USHORT usLength = uniRemoteName.Length;
171 if (uniRemoteName.Buffer[AFSServerName.Length/sizeof( WCHAR)] != L'\\')
174 if( ConnectCB->LocalName != L'\0')
177 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
178 AFS_TRACE_LEVEL_VERBOSE,
179 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local %C authentication id %I64X\n",
181 ConnectCB->LocalName,
182 ConnectCB->AuthenticationId.QuadPart));
187 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
188 AFS_TRACE_LEVEL_VERBOSE,
189 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local (NULL) authentication id %I64X\n",
191 ConnectCB->AuthenticationId.QuadPart));
194 *ResultStatus = WN_BAD_NETNAME;
196 *ReturnOutputBufferLength = sizeof( ULONG);
198 try_return( ntStatus = STATUS_SUCCESS);
201 uniRemoteName.Length = AFSServerName.Length;
203 if( RtlCompareUnicodeString( &AFSServerName,
208 if( ConnectCB->LocalName != L'\0')
211 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
212 AFS_TRACE_LEVEL_VERBOSE,
213 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local %C authentication id %I64X\n",
215 ConnectCB->LocalName,
216 ConnectCB->AuthenticationId.QuadPart));
221 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
222 AFS_TRACE_LEVEL_VERBOSE,
223 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local (NULL) authentication id %I64X\n",
225 ConnectCB->AuthenticationId.QuadPart));
228 *ResultStatus = WN_BAD_NETNAME;
230 *ReturnOutputBufferLength = sizeof( ULONG);
232 try_return( ntStatus = STATUS_SUCCESS);
235 uniRemoteName.Length = usLength;
240 if( ConnectCB->LocalName != L'\0')
243 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
244 AFS_TRACE_LEVEL_VERBOSE,
245 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local %C authentication id %I64X\n",
247 ConnectCB->LocalName,
248 ConnectCB->AuthenticationId.QuadPart));
253 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
254 AFS_TRACE_LEVEL_VERBOSE,
255 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local (NULL) authentication id %I64X\n",
257 ConnectCB->AuthenticationId.QuadPart));
260 *ResultStatus = WN_BAD_NETNAME;
262 *ReturnOutputBufferLength = sizeof( ULONG);
264 try_return( ntStatus = STATUS_SUCCESS);
267 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
268 uniRemoteName.MaximumLength = uniRemoteName.Length;
270 uniRemoteName.Buffer = ConnectCB->RemoteName;
273 // Strip off any trailing slashes
276 if( uniRemoteName.Length >= sizeof( WCHAR)
277 && uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
280 uniRemoteName.Length -= sizeof( WCHAR);
284 // Allocate a new node and add it to our list
287 pConnection = (AFSProviderConnectionCB *)AFSExAllocatePoolWithTag( PagedPool,
288 sizeof( AFSProviderConnectionCB) +
289 uniRemoteName.Length,
292 if( pConnection == NULL)
295 *ResultStatus = WN_OUT_OF_MEMORY;
297 *ReturnOutputBufferLength = sizeof( ULONG);
299 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
302 RtlZeroMemory( pConnection,
303 sizeof( AFSProviderConnectionCB) + uniRemoteName.Length);
305 pConnection->LocalName = ConnectCB->LocalName;
307 pConnection->RemoteName.Length = uniRemoteName.Length;
308 pConnection->RemoteName.MaximumLength = pConnection->RemoteName.Length;
310 pConnection->RemoteName.Buffer = (WCHAR *)((char *)pConnection + sizeof( AFSProviderConnectionCB));
312 RtlCopyMemory( pConnection->RemoteName.Buffer,
313 uniRemoteName.Buffer,
314 pConnection->RemoteName.Length);
316 pConnection->Type = ConnectCB->Type;
318 pConnection->AuthenticationId = ConnectCB->AuthenticationId;
320 if( ConnectCB->LocalName != L'\0')
323 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
324 AFS_TRACE_LEVEL_VERBOSE,
325 "AFSAddConnection Adding connection remote name %wZ Local %C authentication id %I64X\n",
327 ConnectCB->LocalName,
328 ConnectCB->AuthenticationId.QuadPart));
333 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
334 AFS_TRACE_LEVEL_VERBOSE,
335 "AFSAddConnection Adding connection remote name %wZ Local (NULL) authentication id %I64X\n",
337 ConnectCB->AuthenticationId.QuadPart));
341 // Point to the component portion of the name
344 pConnection->ComponentName.Length = 0;
345 pConnection->ComponentName.MaximumLength = 0;
347 pConnection->ComponentName.Buffer = &pConnection->RemoteName.Buffer[ (pConnection->RemoteName.Length/sizeof( WCHAR)) - 1];
349 while( pConnection->ComponentName.Length <= pConnection->RemoteName.Length)
352 if( pConnection->ComponentName.Buffer[ 0] == L'\\')
355 pConnection->ComponentName.Buffer++;
360 pConnection->ComponentName.Length += sizeof( WCHAR);
361 pConnection->ComponentName.MaximumLength += sizeof( WCHAR);
363 pConnection->ComponentName.Buffer--;
367 // Go initialize the information about the connection
370 AFSInitializeConnectionInfo( pConnection,
374 // Insert the entry into our list
377 if( pRDRDevExt->Specific.RDR.ProviderConnectionList == NULL)
380 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection;
386 // Get the end of the list
389 pLastConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
391 while( pLastConnection->fLink != NULL)
394 pLastConnection = pLastConnection->fLink;
397 pLastConnection->fLink = pConnection;
400 *ResultStatus = WN_SUCCESS;
402 *ReturnOutputBufferLength = sizeof( ULONG);
406 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
414 AFSCancelConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
415 IN OUT AFSCancelConnectionResultCB *ConnectionResult,
416 IN OUT ULONG_PTR *ReturnOutputBufferLength)
419 NTSTATUS ntStatus = STATUS_SUCCESS;
420 AFSProviderConnectionCB *pConnection = NULL, *pLastConnection = NULL;
421 UNICODE_STRING uniRemoteName;
422 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
427 ConnectionResult->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
429 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
430 AFS_TRACE_LEVEL_VERBOSE,
431 "AFSCancelConnection Acquiring AFSProviderListLock lock %p EXCL %08lX\n",
432 &pRDRDevExt->Specific.RDR.ProviderListLock,
433 PsGetCurrentThread()));
435 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
437 if ( !NT_SUCCESS( ntStatus))
440 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
441 AFS_TRACE_LEVEL_ERROR,
442 "AFSCancelConnection Unable to retrieve authentication id %08lX\n",
448 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
449 AFS_TRACE_LEVEL_VERBOSE,
450 "AFSCancelConnection Retrieved authentication id %I64X\n",
451 ConnectCB->AuthenticationId.QuadPart));
453 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
457 // Look for the connection
460 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
461 uniRemoteName.MaximumLength = uniRemoteName.Length;
463 uniRemoteName.Buffer = NULL;
465 if( uniRemoteName.Length > 0)
468 uniRemoteName.Buffer = ConnectCB->RemoteName;
471 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
473 while( pConnection != NULL)
476 if( ( ConnectCB->LocalName != L'\0' &&
477 pConnection->LocalName == ConnectCB->LocalName)
479 ( ConnectCB->LocalName == L'\0' &&
480 pConnection->LocalName == L'\0' &&
481 RtlCompareUnicodeString( &uniRemoteName,
482 &pConnection->RemoteName,
486 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
487 AFS_TRACE_LEVEL_VERBOSE,
488 "AFSCancelConnection Checking remote name %wZ to stored %wZ authentication id %I64X - %I64X\n",
490 &pConnection->RemoteName,
491 ConnectCB->AuthenticationId.QuadPart,
492 pConnection->AuthenticationId.QuadPart));
494 if( ConnectCB->AuthenticationId.QuadPart == pConnection->AuthenticationId.QuadPart &&
495 ( ConnectCB->LocalName == L'\0' ||
496 RtlCompareUnicodeString( &uniRemoteName,
497 &pConnection->RemoteName,
505 pLastConnection = pConnection;
507 pConnection = pConnection->fLink;
510 if( pConnection == NULL)
513 ConnectionResult->Status = WN_NOT_CONNECTED;
515 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
517 try_return( ntStatus);
520 if( pLastConnection == NULL)
523 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection->fLink;
528 pLastConnection->fLink = pConnection->fLink;
531 if( pConnection->Comment.Buffer != NULL)
534 AFSExFreePoolWithTag( pConnection->Comment.Buffer, 0);
537 ConnectionResult->LocalName = pConnection->LocalName;
539 AFSExFreePoolWithTag( pConnection, AFS_PROVIDER_CB);
541 ConnectionResult->Status = WN_SUCCESS;
543 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
547 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
554 AFSGetConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
555 IN OUT WCHAR *RemoteName,
556 IN ULONG RemoteNameBufferLength,
557 IN OUT ULONG_PTR *ReturnOutputBufferLength)
560 NTSTATUS ntStatus = STATUS_SUCCESS;
561 AFSProviderConnectionCB *pConnection = NULL;
562 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
567 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
569 if ( !NT_SUCCESS( ntStatus))
572 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
573 AFS_TRACE_LEVEL_ERROR,
574 "AFSGetConnection Unable to retrieve authentication id %08lX\n",
580 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
581 AFS_TRACE_LEVEL_VERBOSE,
582 "AFSGetConnection Retrieved authentication id %I64X\n",
583 ConnectCB->AuthenticationId.QuadPart));
585 if( ConnectCB->LocalName != L'\0')
588 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
589 AFS_TRACE_LEVEL_VERBOSE,
590 "AFSGetConnection Local %C authentication id %I64X\n",
591 ConnectCB->LocalName,
592 ConnectCB->AuthenticationId.QuadPart));
597 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
598 AFS_TRACE_LEVEL_VERBOSE,
599 "AFSGetConnection Local (NULL) authentication id %I64X\n",
600 ConnectCB->AuthenticationId.QuadPart));
603 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
604 AFS_TRACE_LEVEL_VERBOSE,
605 "AFSGetConnection Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
606 &pRDRDevExt->Specific.RDR.ProviderListLock,
607 PsGetCurrentThread()));
609 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
613 // Look for the connection
616 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
618 while( pConnection != NULL)
621 if( pConnection->LocalName != L'\0')
624 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
625 AFS_TRACE_LEVEL_VERBOSE,
626 "AFSGetConnection Comparing passed in %C to %C authentication id %I64X - %I64X\n",
627 ConnectCB->LocalName,
628 pConnection->LocalName,
629 ConnectCB->AuthenticationId.QuadPart,
630 pConnection->AuthenticationId.QuadPart));
635 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
636 AFS_TRACE_LEVEL_VERBOSE,
637 "AFSGetConnection Comparing passed in %C to (NULL) authentication id %I64X - %I64X\n",
638 ConnectCB->LocalName,
639 ConnectCB->AuthenticationId.QuadPart,
640 pConnection->AuthenticationId.QuadPart));
643 if( pConnection->LocalName == ConnectCB->LocalName &&
644 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart)
650 pConnection = pConnection->fLink;
653 if( pConnection == NULL)
656 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
657 AFS_TRACE_LEVEL_VERBOSE,
658 "AFSGetConnection INVALID_PARAMETER\n"));
660 try_return( ntStatus = STATUS_INVALID_PARAMETER);
663 if( RemoteNameBufferLength < pConnection->RemoteName.Length)
666 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
667 AFS_TRACE_LEVEL_VERBOSE,
668 "AFSGetConnection INSUFFICIENT_RESOURCES\n"));
670 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
673 RtlCopyMemory( RemoteName,
674 pConnection->RemoteName.Buffer,
675 pConnection->RemoteName.Length);
677 *ReturnOutputBufferLength = pConnection->RemoteName.Length;
681 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
688 AFSListConnections( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
689 IN ULONG ConnectionBufferLength,
690 IN OUT ULONG_PTR *ReturnOutputBufferLength)
693 NTSTATUS ntStatus = STATUS_SUCCESS;
694 AFSProviderConnectionCB *pConnection = NULL, *pRootConnection = NULL;
695 ULONG ulCopiedLength = 0, ulRemainingLength = ConnectionBufferLength;
696 ULONG ulScope, ulType;
697 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath;
698 BOOLEAN bGlobalEnumeration = FALSE;
700 LARGE_INTEGER liAuthenticationID = {0,0};
701 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
707 // Save off some data before moving on
710 ulScope = ConnectCB->Scope;
712 ulType = ConnectCB->Type;
714 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
716 if ( !NT_SUCCESS( ntStatus))
719 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
720 AFS_TRACE_LEVEL_ERROR,
721 "AFSListConnection Unable to retrieve authentication id %08lX\n",
727 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
728 AFS_TRACE_LEVEL_VERBOSE,
729 "AFSListConnections Retrieved authentication id %I64X\n",
730 ConnectCB->AuthenticationId.QuadPart));
732 liAuthenticationID.QuadPart = ConnectCB->AuthenticationId.QuadPart;
734 uniRemoteName.Length = 0;
735 uniRemoteName.MaximumLength = 0;
736 uniRemoteName.Buffer = NULL;
738 uniServerName.Length = 0;
739 uniServerName.MaximumLength = 0;
740 uniServerName.Buffer = NULL;
742 uniShareName.Length = 0;
743 uniShareName.MaximumLength = 0;
744 uniShareName.Buffer = NULL;
746 if( ConnectCB->RemoteNameLength > 0)
749 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
750 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
752 uniRemoteName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
753 uniRemoteName.MaximumLength,
754 AFS_NETWORK_PROVIDER_1_TAG);
756 if( uniRemoteName.Buffer == NULL)
759 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
762 RtlCopyMemory( uniRemoteName.Buffer,
763 ConnectCB->RemoteName,
764 uniRemoteName.Length);
766 if( uniRemoteName.Length >= 2 * sizeof( WCHAR)
767 && uniRemoteName.Buffer[ 0] == L'\\'
768 && uniRemoteName.Buffer[ 1] == L'\\')
771 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
773 uniRemoteName.Length -= sizeof( WCHAR);
776 if( uniRemoteName.Length >= sizeof( WCHAR)
777 && uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
780 uniRemoteName.Length -= sizeof( WCHAR);
783 FsRtlDissectName( uniRemoteName,
787 uniRemoteName = uniRemainingPath;
789 if( uniRemoteName.Length > 0)
792 FsRtlDissectName( uniRemoteName,
798 // If this is an enumeration of the global share name then
799 // adjust it to be the server name itself
802 if( uniShareName.Length == 0)
805 bGlobalEnumeration = TRUE;
809 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
810 AFS_TRACE_LEVEL_VERBOSE,
811 "AFSListConnections Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
812 &pRDRDevExt->Specific.RDR.ProviderListLock,
813 PsGetCurrentThread()));
815 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
819 // If this is a globalnet enumeration with no name then enumerate the server list
822 if( ulScope == RESOURCE_GLOBALNET)
825 if( uniServerName.Buffer == NULL)
828 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
834 // Go locate the root entry for the name passed in
837 if( bGlobalEnumeration)
840 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
843 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
845 try_return( ntStatus);
848 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
853 pRootConnection = AFSLocateEnumRootEntry( &uniShareName);
855 if( pRootConnection == NULL)
858 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
860 try_return( ntStatus);
864 // Need to handle these enumerations from the directory listing
867 ntStatus = AFSEnumerateConnection( ConnectCB,
869 ConnectionBufferLength,
877 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
880 ulIndex = ConnectCB->CurrentIndex;
882 while( pConnection != NULL)
885 if( bGlobalEnumeration &&
886 BooleanFlagOn( pConnection->Flags, AFS_CONNECTION_FLAG_GLOBAL_SHARE))
889 pConnection = pConnection->fLink;
894 if( ulScope != RESOURCE_GLOBALNET &&
895 !BooleanFlagOn( pConnection->Usage, RESOURCEUSAGE_ATTACHED))
898 pConnection = pConnection->fLink;
903 if( pConnection->LocalName != L'\0')
906 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
907 AFS_TRACE_LEVEL_VERBOSE,
908 "AFSListConnections Processing entry %wZ %C authentication id %I64X - %I64X Scope %08lX\n",
909 &pConnection->RemoteName,
910 pConnection->LocalName,
911 liAuthenticationID.QuadPart,
912 pConnection->AuthenticationId.QuadPart,
913 pConnection->Scope));
918 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
919 AFS_TRACE_LEVEL_VERBOSE,
920 "AFSListConnections Processing entry %wZ NULL LocalName authentication id %I64X - %I64X Scope %08lX\n",
921 &pConnection->RemoteName,
922 liAuthenticationID.QuadPart,
923 pConnection->AuthenticationId.QuadPart,
924 pConnection->Scope));
927 if( ulScope != RESOURCE_GLOBALNET &&
928 pConnection->AuthenticationId.QuadPart != liAuthenticationID.QuadPart)
931 pConnection = pConnection->fLink;
941 pConnection = pConnection->fLink;
946 if( ulRemainingLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
947 pConnection->RemoteName.Length +
948 pConnection->Comment.Length)
954 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
956 RtlCopyMemory( ConnectCB->RemoteName,
957 pConnection->RemoteName.Buffer,
958 pConnection->RemoteName.Length);
960 ConnectCB->LocalName = pConnection->LocalName;
962 ConnectCB->Type = pConnection->Type;
964 ConnectCB->Scope = pConnection->Scope;
966 if( !bGlobalEnumeration)
969 ConnectCB->Scope = RESOURCE_CONNECTED;
972 ConnectCB->DisplayType = pConnection->DisplayType;
974 ConnectCB->Usage = pConnection->Usage;
976 ConnectCB->CommentLength = pConnection->Comment.Length;
978 if( pConnection->Comment.Length > 0)
981 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
982 ConnectCB->RemoteNameLength);
984 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
985 pConnection->Comment.Buffer,
986 ConnectCB->CommentLength);
989 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
990 ConnectCB->RemoteNameLength +
991 ConnectCB->CommentLength;
993 ulRemainingLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
994 ConnectCB->RemoteNameLength +
995 ConnectCB->CommentLength;
997 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
998 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
999 ConnectCB->RemoteNameLength +
1000 ConnectCB->CommentLength);
1002 pConnection = pConnection->fLink;
1005 if( NT_SUCCESS( ntStatus))
1008 *ReturnOutputBufferLength = ulCopiedLength;
1011 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1015 if( uniRemoteName.Buffer != NULL)
1018 AFSExFreePoolWithTag( uniRemoteName.Buffer, 0);
1026 AFSInitializeConnectionInfo( IN AFSProviderConnectionCB *Connection,
1027 IN ULONG DisplayType)
1030 NTSTATUS ntStatus = STATUS_SUCCESS;
1031 UNICODE_STRING uniName, uniComponentName, uniRemainingName;
1036 uniName = Connection->RemoteName;
1039 // Strip off the double leading slash if there is one
1042 if( uniName.Length >= 2 * sizeof( WCHAR)
1043 && uniName.Buffer[ 0] == L'\\'
1044 && uniName.Buffer[ 1] == L'\\')
1047 uniName.Buffer = &uniName.Buffer[ 1];
1049 uniName.Length -= sizeof( WCHAR);
1053 FsRtlDissectName( uniName,
1058 // Initialize the information for the connection
1059 // First, if this is the server only then mark it accordingly
1062 if( uniRemainingName.Length == 0 ||
1063 DisplayType == RESOURCEDISPLAYTYPE_SERVER)
1066 Connection->Type = RESOURCETYPE_DISK;
1068 Connection->Scope = 0;
1070 Connection->DisplayType = RESOURCEDISPLAYTYPE_SERVER;
1072 Connection->Usage = RESOURCEUSAGE_CONTAINER;
1074 Connection->Comment.Length = 20;
1075 Connection->Comment.MaximumLength = 22;
1077 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1078 Connection->Comment.MaximumLength,
1079 AFS_NETWORK_PROVIDER_2_TAG);
1081 if( Connection->Comment.Buffer != NULL)
1084 RtlZeroMemory( Connection->Comment.Buffer,
1085 Connection->Comment.MaximumLength);
1087 RtlCopyMemory( Connection->Comment.Buffer,
1094 Connection->Comment.Length = 0;
1095 Connection->Comment.MaximumLength = 0;
1098 try_return( ntStatus);
1101 uniName = uniRemainingName;
1103 FsRtlDissectName( uniName,
1107 if( uniRemainingName.Length == 0 ||
1108 uniRemainingName.Buffer == NULL ||
1109 DisplayType == RESOURCEDISPLAYTYPE_SHARE)
1112 Connection->Type = RESOURCETYPE_DISK;
1114 Connection->DisplayType = RESOURCEDISPLAYTYPE_SHARE;
1116 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1118 if( Connection->LocalName != L'\0')
1121 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1123 Connection->Scope = RESOURCE_CONNECTED;
1128 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1130 Connection->Scope = RESOURCE_GLOBALNET;
1133 Connection->Comment.Length = 18;
1134 Connection->Comment.MaximumLength = 20;
1136 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1137 Connection->Comment.MaximumLength,
1138 AFS_NETWORK_PROVIDER_3_TAG);
1140 if( Connection->Comment.Buffer != NULL)
1143 RtlZeroMemory( Connection->Comment.Buffer,
1144 Connection->Comment.MaximumLength);
1146 RtlCopyMemory( Connection->Comment.Buffer,
1153 Connection->Comment.Length = 0;
1154 Connection->Comment.MaximumLength = 0;
1157 try_return( ntStatus);
1161 // This is a sub directory within a share
1164 Connection->Type = RESOURCETYPE_DISK;
1166 Connection->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1168 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1170 if( Connection->LocalName != L'\0')
1173 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1178 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1181 Connection->Scope = RESOURCE_CONNECTED;
1183 Connection->Comment.Length = 26;
1184 Connection->Comment.MaximumLength = 28;
1186 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1187 Connection->Comment.MaximumLength,
1188 AFS_NETWORK_PROVIDER_4_TAG);
1190 if( Connection->Comment.Buffer != NULL)
1193 RtlZeroMemory( Connection->Comment.Buffer,
1194 Connection->Comment.MaximumLength);
1196 RtlCopyMemory( Connection->Comment.Buffer,
1203 Connection->Comment.Length = 0;
1204 Connection->Comment.MaximumLength = 0;
1215 AFSProviderConnectionCB *
1216 AFSLocateEnumRootEntry( IN UNICODE_STRING *RemoteName)
1219 AFSProviderConnectionCB *pConnection = NULL;
1220 UNICODE_STRING uniRemoteName = *RemoteName;
1221 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1226 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
1229 try_return( pConnection);
1232 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
1234 while( pConnection != NULL)
1237 if( RtlCompareUnicodeString( &uniRemoteName,
1238 &pConnection->ComponentName,
1245 pConnection = pConnection->fLink;
1257 AFSEnumerateConnection( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
1258 IN AFSProviderConnectionCB *RootConnection,
1259 IN ULONG BufferLength,
1260 OUT PULONG CopiedLength)
1263 NTSTATUS ntStatus = STATUS_SUCCESS;
1264 ULONG ulCRC = 0, ulCopiedLength = 0;
1265 AFSDirectoryCB *pShareDirEntry = NULL;
1266 AFSDirectoryCB *pDirEntry = NULL, *pTargetDirEntry = NULL;
1273 if( AFSGlobalRoot == NULL)
1276 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1277 AFS_TRACE_LEVEL_ERROR,
1278 "AFSEnumerateConnection Global root not yet initialized\n"));
1280 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1283 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1287 // Grab our tree lock shared
1290 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1291 AFS_TRACE_LEVEL_VERBOSE,
1292 "AFSEnumerateConnection Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p SHARED %08lX\n",
1293 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1294 PsGetCurrentThread()));
1296 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1300 // Locate the dir entry for this node
1303 ntStatus = AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1307 if( pShareDirEntry == NULL ||
1308 !NT_SUCCESS( ntStatus))
1312 // Perform a case insensitive search
1315 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1318 ntStatus = AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1322 if( pShareDirEntry == NULL ||
1323 !NT_SUCCESS( ntStatus))
1326 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1328 try_return( ntStatus);
1332 lCount = InterlockedIncrement( &pShareDirEntry->DirOpenReferenceCount);
1334 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1335 AFS_TRACE_LEVEL_VERBOSE,
1336 "AFSEnumerateConnection1 Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1337 &pShareDirEntry->NameInformation.FileName,
1342 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1345 // Setup the request to evaluate the entry
1346 // On success, pTargetDirEntry has the DirOpenReferenceCount held
1349 ntStatus = AFSEvaluateRootEntry( pShareDirEntry,
1352 if( !NT_SUCCESS( ntStatus))
1355 try_return( ntStatus);
1358 AFSAcquireShared( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1362 // Enumerate the content
1365 pDirEntry = pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
1367 ulIndex = ConnectCB->CurrentIndex;
1369 while( pDirEntry != NULL)
1377 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1382 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1383 pDirEntry->NameInformation.FileName.Length)
1389 ConnectCB->LocalName = L'\0';
1391 ConnectCB->RemoteNameLength = pDirEntry->NameInformation.FileName.Length;
1393 RtlCopyMemory( ConnectCB->RemoteName,
1394 pDirEntry->NameInformation.FileName.Buffer,
1395 pDirEntry->NameInformation.FileName.Length);
1397 ConnectCB->Type = RESOURCETYPE_DISK;
1399 ConnectCB->Scope = RESOURCE_CONNECTED;
1401 if( BooleanFlagOn( pDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1404 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1409 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_FILE;
1412 ConnectCB->Usage = 0;
1414 ConnectCB->CommentLength = 0;
1416 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1417 pDirEntry->NameInformation.FileName.Length;
1419 BufferLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1420 pDirEntry->NameInformation.FileName.Length;
1422 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
1423 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1424 ConnectCB->RemoteNameLength);
1426 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1430 // Release the DirOpenReferenceCount obtained from AFSEvaluateRootEntry
1433 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
1435 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1436 AFS_TRACE_LEVEL_VERBOSE,
1437 "AFSEnumerateConnection Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1438 &pTargetDirEntry->NameInformation.FileName,
1443 ASSERT( lCount >= 0);
1445 *CopiedLength = ulCopiedLength;
1447 AFSReleaseResource( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1451 if( pShareDirEntry != NULL)
1453 lCount = InterlockedDecrement( &pShareDirEntry->DirOpenReferenceCount);
1455 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1456 AFS_TRACE_LEVEL_VERBOSE,
1457 "AFSEnumerateConnection1 Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1458 &pShareDirEntry->NameInformation.FileName,
1463 ASSERT( lCount >= 0);
1471 AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
1472 IN ULONG BufferLength,
1473 IN OUT ULONG_PTR *ReturnOutputBufferLength)
1476 NTSTATUS ntStatus = STATUS_SUCCESS;
1477 AFSProviderConnectionCB *pConnection = NULL, *pBestMatch = NULL;
1478 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath, uniFullName, uniRemainingPathLocal;
1479 BOOLEAN bEnumerationEntry = FALSE;
1480 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1485 uniServerName.Length = 0;
1486 uniServerName.MaximumLength = 0;
1487 uniServerName.Buffer = NULL;
1489 uniShareName.Length = 0;
1490 uniShareName.MaximumLength = 0;
1491 uniShareName.Buffer = NULL;
1493 uniRemainingPathLocal.Length = 0;
1494 uniRemainingPathLocal.MaximumLength = 0;
1495 uniRemainingPathLocal.Buffer = NULL;
1497 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
1498 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
1499 uniRemoteName.Buffer = (WCHAR *)ConnectCB->RemoteName;
1501 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
1503 if ( !NT_SUCCESS( ntStatus))
1506 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1507 AFS_TRACE_LEVEL_ERROR,
1508 "AFSGetConnectionInfo Unable to retrieve authentication id %08lX\n",
1514 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1515 AFS_TRACE_LEVEL_VERBOSE,
1516 "AFSGetConnectionInfo Retrieved authentication id %I64X\n",
1517 ConnectCB->AuthenticationId.QuadPart));
1519 if( ConnectCB->LocalName != L'\0')
1522 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1523 AFS_TRACE_LEVEL_VERBOSE,
1524 "AFSGetConnectionInfo remote name %wZ Local %C authentication id %I64X\n",
1526 ConnectCB->LocalName,
1527 ConnectCB->AuthenticationId.QuadPart));
1532 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1533 AFS_TRACE_LEVEL_VERBOSE,
1534 "AFSGetConnectionInfo remote name %wZ Local (NULL) authentication id %I64X\n",
1536 ConnectCB->AuthenticationId.QuadPart));
1539 if( AFSGlobalRoot == NULL)
1542 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1543 AFS_TRACE_LEVEL_ERROR,
1544 "AFSGetConnectionInfo Global root not yet initialized\n"));
1546 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1549 uniFullName = uniRemoteName;
1551 if( uniRemoteName.Length >= 2 * sizeof( WCHAR)
1552 && uniRemoteName.Buffer[ 0] == L'\\'
1553 && uniRemoteName.Buffer[ 1] == L'\\')
1556 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
1558 uniRemoteName.Length -= sizeof( WCHAR);
1561 if( uniRemoteName.Length >= sizeof( WCHAR)
1562 && uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
1565 uniRemoteName.Length -= sizeof( WCHAR);
1567 uniFullName.Length -= sizeof( WCHAR);
1570 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1571 AFS_TRACE_LEVEL_VERBOSE,
1572 "AFSGetConnectionInfo Processing name %wZ\n",
1575 FsRtlDissectName( uniRemoteName,
1579 uniRemoteName = uniRemainingPath;
1581 if( uniRemoteName.Length > 0)
1584 FsRtlDissectName( uniRemoteName,
1589 if( RtlCompareUnicodeString( &uniServerName,
1594 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1597 if ( uniRemainingPath.Length > 0 )
1601 // Add back in the leading \ since it was stripped off above
1604 uniRemainingPath.Length += sizeof( WCHAR);
1605 if( uniRemainingPath.Length > uniRemainingPath.MaximumLength)
1607 uniRemainingPath.MaximumLength += sizeof( WCHAR);
1610 uniRemainingPath.Buffer--;
1612 uniRemainingPathLocal.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1613 uniRemainingPath.Length,
1614 AFS_NETWORK_PROVIDER_5_TAG);
1616 if( uniRemainingPathLocal.Buffer == NULL)
1619 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1620 AFS_TRACE_LEVEL_VERBOSE,
1621 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1623 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1626 uniRemainingPathLocal.MaximumLength = uniRemainingPath.Length;
1627 uniRemainingPathLocal.Length = uniRemainingPath.Length;
1629 RtlCopyMemory( uniRemainingPathLocal.Buffer,
1630 uniRemainingPath.Buffer,
1631 uniRemainingPath.Length);
1634 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1635 AFS_TRACE_LEVEL_VERBOSE,
1636 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1637 &pRDRDevExt->Specific.RDR.ProviderListLock,
1638 PsGetCurrentThread()));
1640 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1644 // If this is the server then return information about the
1648 if( uniShareName.Length == 0 &&
1649 RtlCompareUnicodeString( &uniServerName,
1654 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
1659 USHORT usNameLen = 0, usMaxNameLen = 0;
1662 // AFSGetConnectionInfo() is called to generate responses for
1663 // NPGetResourceInformation and NPGetConnectionPerformance.
1664 // The former can be called with a Connection->RemoteName that
1665 // consists of \\server\share\dir1\dir2\...\dirN where one or
1666 // all of the directories do not have to be processed by the
1667 // network provider. For example, one of the directories might
1668 // be a reparse point that redirects to another network provider.
1669 // It might also be the case that a directory might be in the
1670 // \\afs file namespace but not be accessible with the current
1671 // credentials. That doesn't make the connection invalid.
1672 // As such the network provider is not required to validate the
1673 // entire RemoteName. This can result in false positives.
1676 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1678 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1679 AFS_TRACE_LEVEL_VERBOSE,
1680 "AFSGetConnectionInfo Searching for full name %wZ\n",
1683 while (pConnection != NULL)
1687 // A partial match can be valid but it must occur on a
1688 // component boundary.
1691 if (pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
1692 usMaxNameLen < pConnection->RemoteName.Length &&
1693 (pConnection->RemoteName.Length == uniFullName.Length ||
1694 pConnection->RemoteName.Length < uniFullName.Length &&
1695 (uniFullName.Buffer[pConnection->RemoteName.Length/sizeof(WCHAR)] == L'\\' ||
1696 uniFullName.Buffer[pConnection->RemoteName.Length/sizeof(WCHAR)] == L'/')))
1699 usNameLen = uniFullName.Length;
1701 uniFullName.Length = pConnection->RemoteName.Length;
1703 if (RtlCompareUnicodeString( &uniFullName,
1704 &pConnection->RemoteName,
1708 usMaxNameLen = pConnection->RemoteName.Length;
1710 pBestMatch = pConnection;
1712 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1713 AFS_TRACE_LEVEL_VERBOSE,
1714 "AFSGetConnectionInfo Found match for %wZ\n",
1715 &pConnection->RemoteName));
1718 uniFullName.Length = usNameLen;
1721 pConnection = pConnection->fLink;
1724 pConnection = pBestMatch;
1726 if( pConnection != NULL)
1729 bEnumerationEntry = TRUE;
1731 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1732 AFS_TRACE_LEVEL_VERBOSE,
1733 "AFSGetConnectionInfo Using best match for %wZ\n",
1734 &pConnection->RemoteName));
1740 // Locate the entry for the share
1743 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1745 if (pConnection != NULL)
1748 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1749 AFS_TRACE_LEVEL_VERBOSE,
1750 "AFSGetConnectionInfo Using share connection %wZ\n",
1751 &pConnection->RemoteName));
1756 if( pConnection == NULL)
1758 UNICODE_STRING uniFullName;
1759 AFSDirEnumEntry *pDirEnumEntry = NULL;
1761 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1762 AFS_TRACE_LEVEL_VERBOSE,
1763 "AFSGetConnectionInfo No connection for full name %wZ\n",
1767 // Drop the lock, we will pick it up again later
1770 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1773 // OK, ask the CM about this component name
1776 ntStatus = AFSEvaluateTargetByName( NULL,
1777 &AFSGlobalRoot->ObjectInformation,
1782 if( !NT_SUCCESS( ntStatus))
1785 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1786 AFS_TRACE_LEVEL_VERBOSE,
1787 "AFSGetConnectionInfo Evaluation Failed share name %wZ\n",
1790 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1798 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_3_TAG);
1801 // The share name is valid
1802 // Allocate a new node and add it to our list
1804 uniFullName.MaximumLength = PAGE_SIZE;
1805 uniFullName.Length = 0;
1807 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1808 uniFullName.MaximumLength,
1809 AFS_NETWORK_PROVIDER_6_TAG);
1811 if( uniFullName.Buffer == NULL)
1814 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1815 AFS_TRACE_LEVEL_VERBOSE,
1816 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1818 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1821 uniFullName.Buffer[ 0] = L'\\';
1822 uniFullName.Buffer[ 1] = L'\\';
1824 uniFullName.Length = 2 * sizeof( WCHAR);
1826 RtlCopyMemory( &uniFullName.Buffer[ 2],
1827 AFSServerName.Buffer,
1828 AFSServerName.Length);
1830 uniFullName.Length += AFSServerName.Length;
1832 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
1834 uniFullName.Length += sizeof( WCHAR);
1836 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
1837 uniShareName.Buffer,
1838 uniShareName.Length);
1840 uniFullName.Length += uniShareName.Length;
1842 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1845 ntStatus = AFSAddConnectionEx( &uniFullName,
1846 RESOURCEDISPLAYTYPE_SHARE,
1849 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1851 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
1853 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1854 AFS_TRACE_LEVEL_VERBOSE,
1855 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1856 &pRDRDevExt->Specific.RDR.ProviderListLock,
1857 PsGetCurrentThread()));
1859 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1862 if ( NT_SUCCESS( ntStatus) )
1865 // Once again, locate the entry for the share we just created
1868 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1873 if( pConnection == NULL)
1876 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1877 AFS_TRACE_LEVEL_ERROR,
1878 "AFSGetConnectionInfo Failed to locate entry for full name %wZ\n",
1881 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1883 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1887 // Fill in the returned connection info block
1890 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1891 pConnection->RemoteName.Length +
1892 pConnection->Comment.Length +
1893 uniRemainingPath.Length)
1896 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1897 AFS_TRACE_LEVEL_VERBOSE,
1898 "AFSGetConnectionInfo Buffer too small for full name %wZ\n",
1901 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1903 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
1906 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1907 AFS_TRACE_LEVEL_VERBOSE,
1908 "AFSGetConnectionInfo Returning entry Scope %08lX partial name %wZ full name %wZ\n",
1909 pConnection->Scope, &pConnection->RemoteName, &uniFullName));
1911 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
1913 if( !bEnumerationEntry)
1916 RtlCopyMemory( ConnectCB->RemoteName,
1918 pConnection->RemoteName.Length);
1923 RtlCopyMemory( ConnectCB->RemoteName,
1924 pConnection->RemoteName.Buffer,
1925 pConnection->RemoteName.Length);
1928 ConnectCB->LocalName = pConnection->LocalName;
1930 ConnectCB->Type = pConnection->Type;
1932 ConnectCB->Scope = pConnection->Scope;
1934 ConnectCB->DisplayType = pConnection->DisplayType;
1936 ConnectCB->Usage = pConnection->Usage;
1938 ConnectCB->CommentLength = pConnection->Comment.Length;
1940 ConnectCB->RemainingPathLength = uniRemainingPathLocal.Length;
1942 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1943 AFS_TRACE_LEVEL_VERBOSE,
1944 "AFSGetConnectionInfo Returning lengths: remote %u comment %u remaining %u\n",
1945 ConnectCB->RemoteNameLength,
1946 ConnectCB->CommentLength,
1947 ConnectCB->RemainingPathLength));
1949 if( ConnectCB->CommentLength > 0)
1952 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1953 ConnectCB->RemoteNameLength);
1955 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
1956 pConnection->Comment.Buffer,
1957 ConnectCB->CommentLength);
1960 if ( ConnectCB->RemainingPathLength > 0 )
1963 ConnectCB->RemainingPathOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1964 ConnectCB->RemoteNameLength +
1965 ConnectCB->CommentLength);
1967 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->RemainingPathOffset),
1968 uniRemainingPathLocal.Buffer,
1969 uniRemainingPathLocal.Length);
1972 *ReturnOutputBufferLength = FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1973 ConnectCB->RemoteNameLength +
1974 ConnectCB->CommentLength +
1975 ConnectCB->RemainingPathLength;
1977 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1981 if ( uniRemainingPathLocal.Buffer )
1984 AFSExFreePoolWithTag( uniRemainingPathLocal.Buffer, 0);
1992 AFSIsDriveMapped( IN WCHAR DriveMapping)
1995 BOOLEAN bDriveMapped = FALSE;
1996 AFSProviderConnectionCB *pConnection = NULL;
1997 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2002 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
2005 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
2007 while( pConnection != NULL)
2010 if( pConnection->LocalName != L'\0' &&
2011 RtlUpcaseUnicodeChar( pConnection->LocalName) == RtlUpcaseUnicodeChar( DriveMapping))
2014 bDriveMapped = TRUE;
2019 pConnection = pConnection->fLink;
2022 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
2025 return bDriveMapped;