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 if( ConnectCB->AuthenticationId.QuadPart == 0)
64 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
66 if ( !NT_SUCCESS( ntStatus))
69 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
70 AFS_TRACE_LEVEL_ERROR,
71 "AFSAddConnection Unable to retrieve authentication id %08lX\n",
77 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
78 AFS_TRACE_LEVEL_VERBOSE,
79 "AFSAddConnection Retrieved authentication id %I64X\n",
80 ConnectCB->AuthenticationId.QuadPart));
83 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
87 // Look for the connection
90 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
91 uniRemoteName.MaximumLength = uniRemoteName.Length;
93 uniRemoteName.Buffer = ConnectCB->RemoteName;
96 // Strip off any trailing slashes
99 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
102 uniRemoteName.Length -= sizeof( WCHAR);
105 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
107 while( pConnection != NULL)
110 if( pConnection->LocalName == ConnectCB->LocalName &&
111 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
112 RtlCompareUnicodeString( &uniRemoteName,
113 &pConnection->RemoteName,
120 pConnection = pConnection->fLink;
123 if( pConnection != NULL)
126 if( ConnectCB->LocalName != L'\0')
129 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
130 AFS_TRACE_LEVEL_VERBOSE,
131 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local %C authentication id %I64X\n",
133 ConnectCB->LocalName,
134 ConnectCB->AuthenticationId.QuadPart));
136 *ResultStatus = WN_ALREADY_CONNECTED;
141 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
142 AFS_TRACE_LEVEL_VERBOSE,
143 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local (NULL) authentication id %I64X\n",
145 ConnectCB->AuthenticationId.QuadPart));
147 *ResultStatus = WN_SUCCESS;
150 *ReturnOutputBufferLength = sizeof( ULONG);
152 try_return( ntStatus = STATUS_SUCCESS);
156 // Validate the remote name
159 if( uniRemoteName.Length > 2 * sizeof( WCHAR) &&
160 uniRemoteName.Buffer[ 0] == L'\\' &&
161 uniRemoteName.Buffer[ 1] == L'\\')
164 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 2];
166 uniRemoteName.Length -= (2 * sizeof( WCHAR));
169 if( uniRemoteName.Length >= AFSServerName.Length)
172 USHORT usLength = uniRemoteName.Length;
174 if (uniRemoteName.Buffer[AFSServerName.Length/sizeof( WCHAR)] != L'\\')
177 if( ConnectCB->LocalName != L'\0')
180 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
181 AFS_TRACE_LEVEL_VERBOSE,
182 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local %C authentication id %I64X\n",
184 ConnectCB->LocalName,
185 ConnectCB->AuthenticationId.QuadPart));
190 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
191 AFS_TRACE_LEVEL_VERBOSE,
192 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local (NULL) authentication id %I64X\n",
194 ConnectCB->AuthenticationId.QuadPart));
197 *ResultStatus = WN_BAD_NETNAME;
199 *ReturnOutputBufferLength = sizeof( ULONG);
201 try_return( ntStatus = STATUS_SUCCESS);
204 uniRemoteName.Length = AFSServerName.Length;
206 if( RtlCompareUnicodeString( &AFSServerName,
211 if( ConnectCB->LocalName != L'\0')
214 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
215 AFS_TRACE_LEVEL_VERBOSE,
216 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local %C authentication id %I64X\n",
218 ConnectCB->LocalName,
219 ConnectCB->AuthenticationId.QuadPart));
224 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
225 AFS_TRACE_LEVEL_VERBOSE,
226 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local (NULL) authentication id %I64X\n",
228 ConnectCB->AuthenticationId.QuadPart));
231 *ResultStatus = WN_BAD_NETNAME;
233 *ReturnOutputBufferLength = sizeof( ULONG);
235 try_return( ntStatus = STATUS_SUCCESS);
238 uniRemoteName.Length = usLength;
243 if( ConnectCB->LocalName != L'\0')
246 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
247 AFS_TRACE_LEVEL_VERBOSE,
248 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local %C authentication id %I64X\n",
250 ConnectCB->LocalName,
251 ConnectCB->AuthenticationId.QuadPart));
256 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
257 AFS_TRACE_LEVEL_VERBOSE,
258 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local (NULL) authentication id %I64X\n",
260 ConnectCB->AuthenticationId.QuadPart));
263 *ResultStatus = WN_BAD_NETNAME;
265 *ReturnOutputBufferLength = sizeof( ULONG);
267 try_return( ntStatus = STATUS_SUCCESS);
270 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
271 uniRemoteName.MaximumLength = uniRemoteName.Length;
273 uniRemoteName.Buffer = ConnectCB->RemoteName;
276 // Strip off any trailing slashes
279 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
282 uniRemoteName.Length -= sizeof( WCHAR);
286 // Allocate a new node and add it to our list
289 pConnection = (AFSProviderConnectionCB *)AFSExAllocatePoolWithTag( PagedPool,
290 sizeof( AFSProviderConnectionCB) +
291 uniRemoteName.Length,
294 if( pConnection == NULL)
297 *ResultStatus = WN_OUT_OF_MEMORY;
299 *ReturnOutputBufferLength = sizeof( ULONG);
301 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
304 RtlZeroMemory( pConnection,
305 sizeof( AFSProviderConnectionCB) + uniRemoteName.Length);
307 pConnection->LocalName = ConnectCB->LocalName;
309 pConnection->RemoteName.Length = uniRemoteName.Length;
310 pConnection->RemoteName.MaximumLength = pConnection->RemoteName.Length;
312 pConnection->RemoteName.Buffer = (WCHAR *)((char *)pConnection + sizeof( AFSProviderConnectionCB));
314 RtlCopyMemory( pConnection->RemoteName.Buffer,
315 uniRemoteName.Buffer,
316 pConnection->RemoteName.Length);
318 pConnection->Type = ConnectCB->Type;
320 pConnection->AuthenticationId = ConnectCB->AuthenticationId;
322 if( ConnectCB->LocalName != L'\0')
325 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
326 AFS_TRACE_LEVEL_VERBOSE,
327 "AFSAddConnection Adding connection remote name %wZ Local %C authentication id %I64X\n",
329 ConnectCB->LocalName,
330 ConnectCB->AuthenticationId.QuadPart));
335 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
336 AFS_TRACE_LEVEL_VERBOSE,
337 "AFSAddConnection Adding connection remote name %wZ Local (NULL) authentication id %I64X\n",
339 ConnectCB->AuthenticationId.QuadPart));
343 // Point to the component portion of the name
346 pConnection->ComponentName.Length = 0;
347 pConnection->ComponentName.MaximumLength = 0;
349 pConnection->ComponentName.Buffer = &pConnection->RemoteName.Buffer[ (pConnection->RemoteName.Length/sizeof( WCHAR)) - 1];
351 while( pConnection->ComponentName.Length <= pConnection->RemoteName.Length)
354 if( pConnection->ComponentName.Buffer[ 0] == L'\\')
357 pConnection->ComponentName.Buffer++;
362 pConnection->ComponentName.Length += sizeof( WCHAR);
363 pConnection->ComponentName.MaximumLength += sizeof( WCHAR);
365 pConnection->ComponentName.Buffer--;
369 // Go initialize the information about the connection
372 AFSInitializeConnectionInfo( pConnection,
376 // Insert the entry into our list
379 if( pRDRDevExt->Specific.RDR.ProviderConnectionList == NULL)
382 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection;
388 // Get the end of the list
391 pLastConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
393 while( pLastConnection->fLink != NULL)
396 pLastConnection = pLastConnection->fLink;
399 pLastConnection->fLink = pConnection;
402 *ResultStatus = WN_SUCCESS;
404 *ReturnOutputBufferLength = sizeof( ULONG);
408 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
416 AFSCancelConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
417 IN OUT AFSCancelConnectionResultCB *ConnectionResult,
418 IN OUT ULONG_PTR *ReturnOutputBufferLength)
421 NTSTATUS ntStatus = STATUS_SUCCESS;
422 AFSProviderConnectionCB *pConnection = NULL, *pLastConnection = NULL;
423 UNICODE_STRING uniRemoteName;
424 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
429 ConnectionResult->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
431 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
432 AFS_TRACE_LEVEL_VERBOSE,
433 "AFSCancelConnection Acquiring AFSProviderListLock lock %p EXCL %08lX\n",
434 &pRDRDevExt->Specific.RDR.ProviderListLock,
435 PsGetCurrentThread()));
437 if( ConnectCB->AuthenticationId.QuadPart == 0)
440 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
442 if ( !NT_SUCCESS( ntStatus))
445 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
446 AFS_TRACE_LEVEL_ERROR,
447 "AFSCancelConnection Unable to retrieve authentication id %08lX\n",
453 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
454 AFS_TRACE_LEVEL_VERBOSE,
455 "AFSCancelConnection Retrieved authentication id %I64X\n",
456 ConnectCB->AuthenticationId.QuadPart));
459 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
463 // Look for the connection
466 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
467 uniRemoteName.MaximumLength = uniRemoteName.Length;
469 uniRemoteName.Buffer = NULL;
471 if( uniRemoteName.Length > 0)
474 uniRemoteName.Buffer = ConnectCB->RemoteName;
477 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
479 while( pConnection != NULL)
482 if( ( ConnectCB->LocalName != L'\0' &&
483 pConnection->LocalName == ConnectCB->LocalName)
485 ( ConnectCB->LocalName == L'\0' &&
486 pConnection->LocalName == L'\0' &&
487 RtlCompareUnicodeString( &uniRemoteName,
488 &pConnection->RemoteName,
492 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
493 AFS_TRACE_LEVEL_VERBOSE,
494 "AFSCancelConnection Checking remote name %wZ to stored %wZ authentication id %I64X - %I64X\n",
496 &pConnection->RemoteName,
497 ConnectCB->AuthenticationId.QuadPart,
498 pConnection->AuthenticationId.QuadPart));
500 if( ConnectCB->AuthenticationId.QuadPart == pConnection->AuthenticationId.QuadPart &&
501 ( ConnectCB->LocalName == L'\0' ||
502 RtlCompareUnicodeString( &uniRemoteName,
503 &pConnection->RemoteName,
511 pLastConnection = pConnection;
513 pConnection = pConnection->fLink;
516 if( pConnection == NULL)
519 ConnectionResult->Status = WN_NOT_CONNECTED;
521 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
523 try_return( ntStatus);
526 if( pLastConnection == NULL)
529 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection->fLink;
534 pLastConnection->fLink = pConnection->fLink;
537 if( pConnection->Comment.Buffer != NULL)
540 AFSExFreePoolWithTag( pConnection->Comment.Buffer, 0);
543 ConnectionResult->LocalName = pConnection->LocalName;
545 AFSExFreePoolWithTag( pConnection, AFS_PROVIDER_CB);
547 ConnectionResult->Status = WN_SUCCESS;
549 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
553 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
560 AFSGetConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
561 IN OUT WCHAR *RemoteName,
562 IN ULONG RemoteNameBufferLength,
563 IN OUT ULONG_PTR *ReturnOutputBufferLength)
566 NTSTATUS ntStatus = STATUS_SUCCESS;
567 AFSProviderConnectionCB *pConnection = NULL;
568 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
573 if( ConnectCB->AuthenticationId.QuadPart == 0)
576 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
578 if ( !NT_SUCCESS( ntStatus))
581 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
582 AFS_TRACE_LEVEL_ERROR,
583 "AFSGetConnection Unable to retrieve authentication id %08lX\n",
589 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
590 AFS_TRACE_LEVEL_VERBOSE,
591 "AFSGetConnection Retrieved authentication id %I64X\n",
592 ConnectCB->AuthenticationId.QuadPart));
595 if( ConnectCB->LocalName != L'\0')
598 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
599 AFS_TRACE_LEVEL_VERBOSE,
600 "AFSGetConnection Local %C authentication id %I64X\n",
601 ConnectCB->LocalName,
602 ConnectCB->AuthenticationId.QuadPart));
607 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
608 AFS_TRACE_LEVEL_VERBOSE,
609 "AFSGetConnection Local (NULL) authentication id %I64X\n",
610 ConnectCB->AuthenticationId.QuadPart));
613 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
614 AFS_TRACE_LEVEL_VERBOSE,
615 "AFSGetConnection Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
616 &pRDRDevExt->Specific.RDR.ProviderListLock,
617 PsGetCurrentThread()));
619 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
623 // Look for the connection
626 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
628 while( pConnection != NULL)
631 if( pConnection->LocalName != L'\0')
634 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
635 AFS_TRACE_LEVEL_VERBOSE,
636 "AFSGetConnection Comparing passed in %C to %C authentication id %I64X - %I64X\n",
637 ConnectCB->LocalName,
638 pConnection->LocalName,
639 ConnectCB->AuthenticationId.QuadPart,
640 pConnection->AuthenticationId.QuadPart));
645 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
646 AFS_TRACE_LEVEL_VERBOSE,
647 "AFSGetConnection Comparing passed in %C to (NULL) authentication id %I64X - %I64X\n",
648 ConnectCB->LocalName,
649 ConnectCB->AuthenticationId.QuadPart,
650 pConnection->AuthenticationId.QuadPart));
653 if( pConnection->LocalName == ConnectCB->LocalName &&
654 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart)
660 pConnection = pConnection->fLink;
663 if( pConnection == NULL)
666 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
667 AFS_TRACE_LEVEL_VERBOSE,
668 "AFSGetConnection INVALID_PARAMETER\n"));
670 try_return( ntStatus = STATUS_INVALID_PARAMETER);
673 if( RemoteNameBufferLength < pConnection->RemoteName.Length)
676 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
677 AFS_TRACE_LEVEL_VERBOSE,
678 "AFSGetConnection INSUFFICIENT_RESOURCES\n"));
680 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
683 RtlCopyMemory( RemoteName,
684 pConnection->RemoteName.Buffer,
685 pConnection->RemoteName.Length);
687 *ReturnOutputBufferLength = pConnection->RemoteName.Length;
691 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
698 AFSListConnections( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
699 IN ULONG ConnectionBufferLength,
700 IN OUT ULONG_PTR *ReturnOutputBufferLength)
703 NTSTATUS ntStatus = STATUS_SUCCESS;
704 AFSProviderConnectionCB *pConnection = NULL, *pRootConnection = NULL;
705 ULONG ulCopiedLength = 0, ulRemainingLength = ConnectionBufferLength;
706 ULONG ulScope, ulType;
707 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath;
708 BOOLEAN bGlobalEnumeration = FALSE;
710 LARGE_INTEGER liAuthenticationID = {0,0};
711 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
717 // Save off some data before moving on
720 ulScope = ConnectCB->Scope;
722 ulType = ConnectCB->Type;
724 if( ConnectCB->AuthenticationId.QuadPart == 0)
727 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
729 if ( !NT_SUCCESS( ntStatus))
732 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
733 AFS_TRACE_LEVEL_ERROR,
734 "AFSListConnection Unable to retrieve authentication id %08lX\n",
740 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
741 AFS_TRACE_LEVEL_VERBOSE,
742 "AFSListConnections Retrieved authentication id %I64X\n",
743 ConnectCB->AuthenticationId.QuadPart));
746 liAuthenticationID.QuadPart = ConnectCB->AuthenticationId.QuadPart;
748 uniRemoteName.Length = 0;
749 uniRemoteName.MaximumLength = 0;
750 uniRemoteName.Buffer = NULL;
752 uniServerName.Length = 0;
753 uniServerName.MaximumLength = 0;
754 uniServerName.Buffer = NULL;
756 uniShareName.Length = 0;
757 uniShareName.MaximumLength = 0;
758 uniShareName.Buffer = NULL;
760 if( ConnectCB->RemoteNameLength > 0)
763 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
764 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
766 uniRemoteName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
767 uniRemoteName.MaximumLength,
768 AFS_NETWORK_PROVIDER_1_TAG);
770 if( uniRemoteName.Buffer == NULL)
773 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
776 RtlCopyMemory( uniRemoteName.Buffer,
777 ConnectCB->RemoteName,
778 uniRemoteName.Length);
780 if( uniRemoteName.Buffer[ 0] == L'\\' &&
781 uniRemoteName.Buffer[ 1] == L'\\')
784 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
786 uniRemoteName.Length -= sizeof( WCHAR);
789 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
792 uniRemoteName.Length -= sizeof( WCHAR);
795 FsRtlDissectName( uniRemoteName,
799 uniRemoteName = uniRemainingPath;
801 if( uniRemoteName.Length > 0)
804 FsRtlDissectName( uniRemoteName,
810 // If this is an enumeration of the global share name then
811 // adjust it to be the server name itself
814 if( uniShareName.Length == 0)
817 bGlobalEnumeration = TRUE;
821 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
822 AFS_TRACE_LEVEL_VERBOSE,
823 "AFSListConnections Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
824 &pRDRDevExt->Specific.RDR.ProviderListLock,
825 PsGetCurrentThread()));
827 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
831 // If this is a globalnet enumeration with no name then enumerate the server list
834 if( ulScope == RESOURCE_GLOBALNET)
837 if( uniServerName.Buffer == NULL)
840 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
846 // Go locate the root entry for the name passed in
849 if( bGlobalEnumeration)
852 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
855 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
857 try_return( ntStatus);
860 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
865 pRootConnection = AFSLocateEnumRootEntry( &uniShareName);
867 if( pRootConnection == NULL)
870 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
872 try_return( ntStatus);
876 // Need to handle these enumerations from the directory listing
879 ntStatus = AFSEnumerateConnection( ConnectCB,
881 ConnectionBufferLength,
889 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
892 ulIndex = ConnectCB->CurrentIndex;
894 while( pConnection != NULL)
897 if( bGlobalEnumeration &&
898 BooleanFlagOn( pConnection->Flags, AFS_CONNECTION_FLAG_GLOBAL_SHARE))
901 pConnection = pConnection->fLink;
906 if( ulScope != RESOURCE_GLOBALNET &&
907 !BooleanFlagOn( pConnection->Usage, RESOURCEUSAGE_ATTACHED))
910 pConnection = pConnection->fLink;
915 if( pConnection->LocalName != L'\0')
918 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
919 AFS_TRACE_LEVEL_VERBOSE,
920 "AFSListConnections Processing entry %wZ %C authentication id %I64X - %I64X Scope %08lX\n",
921 &pConnection->RemoteName,
922 pConnection->LocalName,
923 liAuthenticationID.QuadPart,
924 pConnection->AuthenticationId.QuadPart,
925 pConnection->Scope));
930 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
931 AFS_TRACE_LEVEL_VERBOSE,
932 "AFSListConnections Processing entry %wZ NULL LocalName authentication id %I64X - %I64X Scope %08lX\n",
933 &pConnection->RemoteName,
934 liAuthenticationID.QuadPart,
935 pConnection->AuthenticationId.QuadPart,
936 pConnection->Scope));
939 if( ulScope != RESOURCE_GLOBALNET &&
940 pConnection->AuthenticationId.QuadPart != liAuthenticationID.QuadPart)
943 pConnection = pConnection->fLink;
953 pConnection = pConnection->fLink;
958 if( ulRemainingLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
959 pConnection->RemoteName.Length +
960 pConnection->Comment.Length)
966 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
968 RtlCopyMemory( ConnectCB->RemoteName,
969 pConnection->RemoteName.Buffer,
970 pConnection->RemoteName.Length);
972 ConnectCB->LocalName = pConnection->LocalName;
974 ConnectCB->Type = pConnection->Type;
976 ConnectCB->Scope = pConnection->Scope;
978 if( !bGlobalEnumeration)
981 ConnectCB->Scope = RESOURCE_CONNECTED;
984 ConnectCB->DisplayType = pConnection->DisplayType;
986 ConnectCB->Usage = pConnection->Usage;
988 ConnectCB->CommentLength = pConnection->Comment.Length;
990 if( pConnection->Comment.Length > 0)
993 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
994 ConnectCB->RemoteNameLength);
996 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
997 pConnection->Comment.Buffer,
998 ConnectCB->CommentLength);
1001 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1002 ConnectCB->RemoteNameLength +
1003 ConnectCB->CommentLength;
1005 ulRemainingLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1006 ConnectCB->RemoteNameLength +
1007 ConnectCB->CommentLength;
1009 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
1010 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1011 ConnectCB->RemoteNameLength +
1012 ConnectCB->CommentLength);
1014 pConnection = pConnection->fLink;
1017 if( NT_SUCCESS( ntStatus))
1020 *ReturnOutputBufferLength = ulCopiedLength;
1023 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1027 if( uniRemoteName.Buffer != NULL)
1030 AFSExFreePoolWithTag( uniRemoteName.Buffer, 0);
1038 AFSInitializeConnectionInfo( IN AFSProviderConnectionCB *Connection,
1039 IN ULONG DisplayType)
1042 NTSTATUS ntStatus = STATUS_SUCCESS;
1043 UNICODE_STRING uniName, uniComponentName, uniRemainingName;
1048 uniName = Connection->RemoteName;
1051 // Strip of the double leading slash if there is one
1054 if( uniName.Buffer[ 0] == L'\\' &&
1055 uniName.Buffer[ 1] == L'\\')
1058 uniName.Buffer = &uniName.Buffer[ 1];
1060 uniName.Length -= sizeof( WCHAR);
1064 FsRtlDissectName( uniName,
1069 // Initialize the information for the connection
1070 // First, if this is the server only then mark it accordingly
1073 if( uniRemainingName.Length == 0 ||
1074 DisplayType == RESOURCEDISPLAYTYPE_SERVER)
1077 Connection->Type = RESOURCETYPE_DISK;
1079 Connection->Scope = 0;
1081 Connection->DisplayType = RESOURCEDISPLAYTYPE_SERVER;
1083 Connection->Usage = RESOURCEUSAGE_CONTAINER;
1085 Connection->Comment.Length = 20;
1086 Connection->Comment.MaximumLength = 22;
1088 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1089 Connection->Comment.MaximumLength,
1090 AFS_NETWORK_PROVIDER_2_TAG);
1092 if( Connection->Comment.Buffer != NULL)
1095 RtlZeroMemory( Connection->Comment.Buffer,
1096 Connection->Comment.MaximumLength);
1098 RtlCopyMemory( Connection->Comment.Buffer,
1105 Connection->Comment.Length = 0;
1106 Connection->Comment.MaximumLength = 0;
1109 try_return( ntStatus);
1112 uniName = uniRemainingName;
1114 FsRtlDissectName( uniName,
1118 if( uniRemainingName.Length == 0 ||
1119 uniRemainingName.Buffer == NULL ||
1120 DisplayType == RESOURCEDISPLAYTYPE_SHARE)
1123 Connection->Type = RESOURCETYPE_DISK;
1125 Connection->DisplayType = RESOURCEDISPLAYTYPE_SHARE;
1127 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1129 if( Connection->LocalName != L'\0')
1132 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1134 Connection->Scope = RESOURCE_CONNECTED;
1139 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1141 Connection->Scope = RESOURCE_GLOBALNET;
1144 Connection->Comment.Length = 18;
1145 Connection->Comment.MaximumLength = 20;
1147 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1148 Connection->Comment.MaximumLength,
1149 AFS_NETWORK_PROVIDER_3_TAG);
1151 if( Connection->Comment.Buffer != NULL)
1154 RtlZeroMemory( Connection->Comment.Buffer,
1155 Connection->Comment.MaximumLength);
1157 RtlCopyMemory( Connection->Comment.Buffer,
1164 Connection->Comment.Length = 0;
1165 Connection->Comment.MaximumLength = 0;
1168 try_return( ntStatus);
1172 // This is a sub directory within a share
1175 Connection->Type = RESOURCETYPE_DISK;
1177 Connection->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1179 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1181 if( Connection->LocalName != L'\0')
1184 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1189 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1192 Connection->Scope = RESOURCE_CONNECTED;
1194 Connection->Comment.Length = 26;
1195 Connection->Comment.MaximumLength = 28;
1197 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1198 Connection->Comment.MaximumLength,
1199 AFS_NETWORK_PROVIDER_4_TAG);
1201 if( Connection->Comment.Buffer != NULL)
1204 RtlZeroMemory( Connection->Comment.Buffer,
1205 Connection->Comment.MaximumLength);
1207 RtlCopyMemory( Connection->Comment.Buffer,
1214 Connection->Comment.Length = 0;
1215 Connection->Comment.MaximumLength = 0;
1226 AFSProviderConnectionCB *
1227 AFSLocateEnumRootEntry( IN UNICODE_STRING *RemoteName)
1230 AFSProviderConnectionCB *pConnection = NULL;
1231 UNICODE_STRING uniRemoteName = *RemoteName;
1232 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1237 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
1240 try_return( pConnection);
1243 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
1245 while( pConnection != NULL)
1248 if( RtlCompareUnicodeString( &uniRemoteName,
1249 &pConnection->ComponentName,
1256 pConnection = pConnection->fLink;
1268 AFSEnumerateConnection( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
1269 IN AFSProviderConnectionCB *RootConnection,
1270 IN ULONG BufferLength,
1271 OUT PULONG CopiedLength)
1274 NTSTATUS ntStatus = STATUS_SUCCESS;
1275 ULONG ulCRC = 0, ulCopiedLength = 0;
1276 AFSDirectoryCB *pShareDirEntry = NULL;
1277 AFSDirectoryCB *pDirEntry = NULL, *pTargetDirEntry = NULL;
1284 if( AFSGlobalRoot == NULL)
1287 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1288 AFS_TRACE_LEVEL_ERROR,
1289 "AFSEnumerateConnection Global root not yet initialized\n"));
1291 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1294 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1298 // Grab our tree lock shared
1301 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1302 AFS_TRACE_LEVEL_VERBOSE,
1303 "AFSEnumerateConnection Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p SHARED %08lX\n",
1304 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1305 PsGetCurrentThread()));
1307 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1311 // Locate the dir entry for this node
1314 ntStatus = AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1318 if( pShareDirEntry == NULL ||
1319 !NT_SUCCESS( ntStatus))
1323 // Perform a case insensitive search
1326 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1329 ntStatus = AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1333 if( pShareDirEntry == NULL ||
1334 !NT_SUCCESS( ntStatus))
1337 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1339 try_return( ntStatus);
1343 lCount = InterlockedIncrement( &pShareDirEntry->DirOpenReferenceCount);
1345 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1346 AFS_TRACE_LEVEL_VERBOSE,
1347 "AFSEnumerateConnection1 Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1348 &pShareDirEntry->NameInformation.FileName,
1353 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1356 // Setup the request to evaluate the entry
1357 // On success, pTargetDirEntry has the DirOpenReferenceCount held
1360 ntStatus = AFSEvaluateRootEntry( pShareDirEntry,
1363 if( !NT_SUCCESS( ntStatus))
1366 try_return( ntStatus);
1369 AFSAcquireShared( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1373 // Enumerate the content
1376 pDirEntry = pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
1378 ulIndex = ConnectCB->CurrentIndex;
1380 while( pDirEntry != NULL)
1388 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1393 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1394 pDirEntry->NameInformation.FileName.Length)
1400 ConnectCB->LocalName = L'\0';
1402 ConnectCB->RemoteNameLength = pDirEntry->NameInformation.FileName.Length;
1404 RtlCopyMemory( ConnectCB->RemoteName,
1405 pDirEntry->NameInformation.FileName.Buffer,
1406 pDirEntry->NameInformation.FileName.Length);
1408 ConnectCB->Type = RESOURCETYPE_DISK;
1410 ConnectCB->Scope = RESOURCE_CONNECTED;
1412 if( BooleanFlagOn( pDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1415 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1420 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_FILE;
1423 ConnectCB->Usage = 0;
1425 ConnectCB->CommentLength = 0;
1427 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1428 pDirEntry->NameInformation.FileName.Length;
1430 BufferLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1431 pDirEntry->NameInformation.FileName.Length;
1433 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
1434 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1435 ConnectCB->RemoteNameLength);
1437 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1441 // Release the DirOpenReferenceCount obtained from AFSEvaluateRootEntry
1444 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
1446 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1447 AFS_TRACE_LEVEL_VERBOSE,
1448 "AFSEnumerateConnection Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1449 &pTargetDirEntry->NameInformation.FileName,
1454 ASSERT( lCount >= 0);
1456 *CopiedLength = ulCopiedLength;
1458 AFSReleaseResource( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1462 if( pShareDirEntry != NULL)
1464 lCount = InterlockedDecrement( &pShareDirEntry->DirOpenReferenceCount);
1466 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1467 AFS_TRACE_LEVEL_VERBOSE,
1468 "AFSEnumerateConnection1 Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1469 &pShareDirEntry->NameInformation.FileName,
1474 ASSERT( lCount >= 0);
1482 AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
1483 IN ULONG BufferLength,
1484 IN OUT ULONG_PTR *ReturnOutputBufferLength)
1487 NTSTATUS ntStatus = STATUS_SUCCESS;
1488 AFSProviderConnectionCB *pConnection = NULL, *pBestMatch = NULL;
1489 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath, uniFullName, uniRemainingPathLocal;
1490 BOOLEAN bEnumerationEntry = FALSE;
1491 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1496 uniServerName.Length = 0;
1497 uniServerName.MaximumLength = 0;
1498 uniServerName.Buffer = NULL;
1500 uniShareName.Length = 0;
1501 uniShareName.MaximumLength = 0;
1502 uniShareName.Buffer = NULL;
1504 uniRemainingPathLocal.Length = 0;
1505 uniRemainingPathLocal.MaximumLength = 0;
1506 uniRemainingPathLocal.Buffer = NULL;
1508 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
1509 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
1510 uniRemoteName.Buffer = (WCHAR *)ConnectCB->RemoteName;
1512 if( ConnectCB->AuthenticationId.QuadPart == 0)
1515 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
1517 if ( !NT_SUCCESS( ntStatus))
1520 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1521 AFS_TRACE_LEVEL_ERROR,
1522 "AFSGetConnectionInfo Unable to retrieve authentication id %08lX\n",
1528 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1529 AFS_TRACE_LEVEL_VERBOSE,
1530 "AFSGetConnectionInfo Retrieved authentication id %I64X\n",
1531 ConnectCB->AuthenticationId.QuadPart));
1534 if( ConnectCB->LocalName != L'\0')
1537 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1538 AFS_TRACE_LEVEL_VERBOSE,
1539 "AFSGetConnectionInfo remote name %wZ Local %C authentication id %I64X\n",
1541 ConnectCB->LocalName,
1542 ConnectCB->AuthenticationId.QuadPart));
1547 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1548 AFS_TRACE_LEVEL_VERBOSE,
1549 "AFSGetConnectionInfo remote name %wZ Local (NULL) authentication id %I64X\n",
1551 ConnectCB->AuthenticationId.QuadPart));
1554 if( AFSGlobalRoot == NULL)
1557 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1558 AFS_TRACE_LEVEL_ERROR,
1559 "AFSGetConnectionInfo Global root not yet initialized\n"));
1561 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1564 uniFullName = uniRemoteName;
1566 if( uniRemoteName.Buffer[ 0] == L'\\' &&
1567 uniRemoteName.Buffer[ 1] == L'\\')
1570 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
1572 uniRemoteName.Length -= sizeof( WCHAR);
1575 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
1578 uniRemoteName.Length -= sizeof( WCHAR);
1580 uniFullName.Length -= sizeof( WCHAR);
1583 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1584 AFS_TRACE_LEVEL_VERBOSE,
1585 "AFSGetConnectionInfo Processing name %wZ\n",
1588 FsRtlDissectName( uniRemoteName,
1592 uniRemoteName = uniRemainingPath;
1594 if( uniRemoteName.Length > 0)
1597 FsRtlDissectName( uniRemoteName,
1602 if( RtlCompareUnicodeString( &uniServerName,
1607 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1610 if ( uniRemainingPath.Length > 0 )
1614 // Add back in the leading \ since it was stripped off above
1617 uniRemainingPath.Length += sizeof( WCHAR);
1618 if( uniRemainingPath.Length > uniRemainingPath.MaximumLength)
1620 uniRemainingPath.MaximumLength += sizeof( WCHAR);
1623 uniRemainingPath.Buffer--;
1625 uniRemainingPathLocal.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1626 uniRemainingPath.Length,
1627 AFS_NETWORK_PROVIDER_5_TAG);
1629 if( uniRemainingPathLocal.Buffer == NULL)
1632 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1633 AFS_TRACE_LEVEL_VERBOSE,
1634 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1636 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1639 uniRemainingPathLocal.MaximumLength = uniRemainingPath.Length;
1640 uniRemainingPathLocal.Length = uniRemainingPath.Length;
1642 RtlCopyMemory( uniRemainingPathLocal.Buffer,
1643 uniRemainingPath.Buffer,
1644 uniRemainingPath.Length);
1647 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1648 AFS_TRACE_LEVEL_VERBOSE,
1649 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1650 &pRDRDevExt->Specific.RDR.ProviderListLock,
1651 PsGetCurrentThread()));
1653 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1657 // If this is the server then return information about the
1661 if( uniShareName.Length == 0 &&
1662 RtlCompareUnicodeString( &uniServerName,
1667 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
1672 USHORT usNameLen = 0, usMaxNameLen = 0;
1675 // AFSGetConnectionInfo() is called to generate responses for
1676 // NPGetResourceInformation and NPGetConnectionPerformance.
1677 // The former can be called with a Connection->RemoteName that
1678 // consists of \\server\share\dir1\dir2\...\dirN where one or
1679 // all of the directories do not have to be processed by the
1680 // network provider. For example, one of the directories might
1681 // be a reparse point that redirects to another network provider.
1682 // It might also be the case that a directory might be in the
1683 // \\afs file namespace but not be accessible with the current
1684 // credentials. That doesn't make the connection invalid.
1685 // As such the network provider is not required to validate the
1686 // entire RemoteName. This can result in false positives.
1689 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1691 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1692 AFS_TRACE_LEVEL_VERBOSE,
1693 "AFSGetConnectionInfo Searching for full name %wZ\n",
1696 while (pConnection != NULL)
1700 // A partial match can be valid but it must occur on a
1701 // component boundary.
1704 if (pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
1705 usMaxNameLen < pConnection->RemoteName.Length &&
1706 (pConnection->RemoteName.Length == uniFullName.Length ||
1707 pConnection->RemoteName.Length < uniFullName.Length &&
1708 (uniFullName.Buffer[pConnection->RemoteName.Length/sizeof(WCHAR)] == L'\\' ||
1709 uniFullName.Buffer[pConnection->RemoteName.Length/sizeof(WCHAR)] == L'/')))
1712 usNameLen = uniFullName.Length;
1714 uniFullName.Length = pConnection->RemoteName.Length;
1716 if (RtlCompareUnicodeString( &uniFullName,
1717 &pConnection->RemoteName,
1721 usMaxNameLen = pConnection->RemoteName.Length;
1723 pBestMatch = pConnection;
1725 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1726 AFS_TRACE_LEVEL_VERBOSE,
1727 "AFSGetConnectionInfo Found match for %wZ\n",
1728 &pConnection->RemoteName));
1731 uniFullName.Length = usNameLen;
1734 pConnection = pConnection->fLink;
1737 pConnection = pBestMatch;
1739 if( pConnection != NULL)
1742 bEnumerationEntry = TRUE;
1744 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1745 AFS_TRACE_LEVEL_VERBOSE,
1746 "AFSGetConnectionInfo Using best match for %wZ\n",
1747 &pConnection->RemoteName));
1753 // Locate the entry for the share
1756 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1758 if (pConnection != NULL)
1761 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1762 AFS_TRACE_LEVEL_VERBOSE,
1763 "AFSGetConnectionInfo Using share connection %wZ\n",
1764 &pConnection->RemoteName));
1769 if( pConnection == NULL)
1771 UNICODE_STRING uniFullName;
1772 AFSDirEnumEntry *pDirEnumEntry = NULL;
1774 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1775 AFS_TRACE_LEVEL_VERBOSE,
1776 "AFSGetConnectionInfo No connection for full name %wZ\n",
1780 // Drop the lock, we will pick it up again later
1783 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1786 // OK, ask the CM about this component name
1789 ntStatus = AFSEvaluateTargetByName( NULL,
1790 &AFSGlobalRoot->ObjectInformation,
1795 if( !NT_SUCCESS( ntStatus))
1798 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1799 AFS_TRACE_LEVEL_VERBOSE,
1800 "AFSGetConnectionInfo Evaluation Failed share name %wZ\n",
1803 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1811 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_3_TAG);
1814 // The share name is valid
1815 // Allocate a new node and add it to our list
1817 uniFullName.MaximumLength = PAGE_SIZE;
1818 uniFullName.Length = 0;
1820 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1821 uniFullName.MaximumLength,
1822 AFS_NETWORK_PROVIDER_6_TAG);
1824 if( uniFullName.Buffer == NULL)
1827 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1828 AFS_TRACE_LEVEL_VERBOSE,
1829 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1831 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1834 uniFullName.Buffer[ 0] = L'\\';
1835 uniFullName.Buffer[ 1] = L'\\';
1837 uniFullName.Length = 2 * sizeof( WCHAR);
1839 RtlCopyMemory( &uniFullName.Buffer[ 2],
1840 AFSServerName.Buffer,
1841 AFSServerName.Length);
1843 uniFullName.Length += AFSServerName.Length;
1845 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
1847 uniFullName.Length += sizeof( WCHAR);
1849 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
1850 uniShareName.Buffer,
1851 uniShareName.Length);
1853 uniFullName.Length += uniShareName.Length;
1855 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1858 ntStatus = AFSAddConnectionEx( &uniFullName,
1859 RESOURCEDISPLAYTYPE_SHARE,
1862 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1864 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
1866 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1867 AFS_TRACE_LEVEL_VERBOSE,
1868 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1869 &pRDRDevExt->Specific.RDR.ProviderListLock,
1870 PsGetCurrentThread()));
1872 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1875 if ( NT_SUCCESS( ntStatus) )
1878 // Once again, locate the entry for the share we just created
1881 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1886 if( pConnection == NULL)
1889 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1890 AFS_TRACE_LEVEL_ERROR,
1891 "AFSGetConnectionInfo Failed to locate entry for full name %wZ\n",
1894 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1896 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1900 // Fill in the returned connection info block
1903 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1904 pConnection->RemoteName.Length +
1905 pConnection->Comment.Length +
1906 uniRemainingPath.Length)
1909 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1910 AFS_TRACE_LEVEL_VERBOSE,
1911 "AFSGetConnectionInfo Buffer too small for full name %wZ\n",
1914 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1916 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
1919 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1920 AFS_TRACE_LEVEL_VERBOSE,
1921 "AFSGetConnectionInfo Returning entry Scope %08lX partial name %wZ full name %wZ\n",
1922 pConnection->Scope, &pConnection->RemoteName, &uniFullName));
1924 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
1926 if( !bEnumerationEntry)
1929 RtlCopyMemory( ConnectCB->RemoteName,
1931 pConnection->RemoteName.Length);
1936 RtlCopyMemory( ConnectCB->RemoteName,
1937 pConnection->RemoteName.Buffer,
1938 pConnection->RemoteName.Length);
1941 ConnectCB->LocalName = pConnection->LocalName;
1943 ConnectCB->Type = pConnection->Type;
1945 ConnectCB->Scope = pConnection->Scope;
1947 ConnectCB->DisplayType = pConnection->DisplayType;
1949 ConnectCB->Usage = pConnection->Usage;
1951 ConnectCB->CommentLength = pConnection->Comment.Length;
1953 ConnectCB->RemainingPathLength = uniRemainingPathLocal.Length;
1955 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1956 AFS_TRACE_LEVEL_VERBOSE,
1957 "AFSGetConnectionInfo Returning lengths: remote %u comment %u remaining %u\n",
1958 ConnectCB->RemoteNameLength,
1959 ConnectCB->CommentLength,
1960 ConnectCB->RemainingPathLength));
1962 if( ConnectCB->CommentLength > 0)
1965 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1966 ConnectCB->RemoteNameLength);
1968 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
1969 pConnection->Comment.Buffer,
1970 ConnectCB->CommentLength);
1973 if ( ConnectCB->RemainingPathLength > 0 )
1976 ConnectCB->RemainingPathOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1977 ConnectCB->RemoteNameLength +
1978 ConnectCB->CommentLength);
1980 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->RemainingPathOffset),
1981 uniRemainingPathLocal.Buffer,
1982 uniRemainingPathLocal.Length);
1985 *ReturnOutputBufferLength = FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1986 ConnectCB->RemoteNameLength +
1987 ConnectCB->CommentLength +
1988 ConnectCB->RemainingPathLength;
1990 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1994 if ( uniRemainingPathLocal.Buffer )
1997 AFSExFreePoolWithTag( uniRemainingPathLocal.Buffer, 0);
2005 AFSIsDriveMapped( IN WCHAR DriveMapping)
2008 BOOLEAN bDriveMapped = FALSE;
2009 AFSProviderConnectionCB *pConnection = NULL;
2010 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2015 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
2018 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
2020 while( pConnection != NULL)
2023 if( pConnection->LocalName != L'\0' &&
2024 RtlUpcaseUnicodeChar( pConnection->LocalName) == RtlUpcaseUnicodeChar( DriveMapping))
2027 bDriveMapped = TRUE;
2032 pConnection = pConnection->fLink;
2035 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
2038 return bDriveMapped;