2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 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 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
66 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
67 AFS_TRACE_LEVEL_VERBOSE,
68 "AFSAddConnection Retrieved authentication id %I64X\n",
69 ConnectCB->AuthenticationId.QuadPart));
72 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
76 // Look for the connection
79 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
80 uniRemoteName.MaximumLength = uniRemoteName.Length;
82 uniRemoteName.Buffer = ConnectCB->RemoteName;
85 // Strip off any trailing slashes
88 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
91 uniRemoteName.Length -= sizeof( WCHAR);
94 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
96 while( pConnection != NULL)
99 if( pConnection->LocalName == ConnectCB->LocalName &&
100 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
101 RtlCompareUnicodeString( &uniRemoteName,
102 &pConnection->RemoteName,
109 pConnection = pConnection->fLink;
112 if( pConnection != NULL)
115 if( ConnectCB->LocalName != L'\0')
118 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
119 AFS_TRACE_LEVEL_VERBOSE,
120 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local %C authentication id %I64X\n",
122 ConnectCB->LocalName,
123 ConnectCB->AuthenticationId.QuadPart));
125 *ResultStatus = WN_ALREADY_CONNECTED;
130 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
131 AFS_TRACE_LEVEL_VERBOSE,
132 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local (NULL) authentication id %I64X\n",
134 ConnectCB->AuthenticationId.QuadPart));
136 *ResultStatus = WN_SUCCESS;
139 *ReturnOutputBufferLength = sizeof( ULONG);
141 try_return( ntStatus = STATUS_SUCCESS);
145 // Validate the remote name
148 if( uniRemoteName.Length > 2 * sizeof( WCHAR) &&
149 uniRemoteName.Buffer[ 0] == L'\\' &&
150 uniRemoteName.Buffer[ 1] == L'\\')
153 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 2];
155 uniRemoteName.Length -= (2 * sizeof( WCHAR));
158 if( uniRemoteName.Length >= AFSServerName.Length)
161 USHORT usLength = uniRemoteName.Length;
163 if (uniRemoteName.Buffer[AFSServerName.Length/sizeof( WCHAR)] != L'\\')
166 if( ConnectCB->LocalName != L'\0')
169 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
170 AFS_TRACE_LEVEL_VERBOSE,
171 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local %C authentication id %I64X\n",
173 ConnectCB->LocalName,
174 ConnectCB->AuthenticationId.QuadPart));
179 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
180 AFS_TRACE_LEVEL_VERBOSE,
181 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local (NULL) authentication id %I64X\n",
183 ConnectCB->AuthenticationId.QuadPart));
186 *ResultStatus = WN_BAD_NETNAME;
188 *ReturnOutputBufferLength = sizeof( ULONG);
190 try_return( ntStatus = STATUS_SUCCESS);
193 uniRemoteName.Length = AFSServerName.Length;
195 if( RtlCompareUnicodeString( &AFSServerName,
200 if( ConnectCB->LocalName != L'\0')
203 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
204 AFS_TRACE_LEVEL_VERBOSE,
205 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local %C authentication id %I64X\n",
207 ConnectCB->LocalName,
208 ConnectCB->AuthenticationId.QuadPart));
213 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
214 AFS_TRACE_LEVEL_VERBOSE,
215 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local (NULL) authentication id %I64X\n",
217 ConnectCB->AuthenticationId.QuadPart));
220 *ResultStatus = WN_BAD_NETNAME;
222 *ReturnOutputBufferLength = sizeof( ULONG);
224 try_return( ntStatus = STATUS_SUCCESS);
227 uniRemoteName.Length = usLength;
232 if( ConnectCB->LocalName != L'\0')
235 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
236 AFS_TRACE_LEVEL_VERBOSE,
237 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local %C authentication id %I64X\n",
239 ConnectCB->LocalName,
240 ConnectCB->AuthenticationId.QuadPart));
245 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
246 AFS_TRACE_LEVEL_VERBOSE,
247 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local (NULL) authentication id %I64X\n",
249 ConnectCB->AuthenticationId.QuadPart));
252 *ResultStatus = WN_BAD_NETNAME;
254 *ReturnOutputBufferLength = sizeof( ULONG);
256 try_return( ntStatus = STATUS_SUCCESS);
259 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
260 uniRemoteName.MaximumLength = uniRemoteName.Length;
262 uniRemoteName.Buffer = ConnectCB->RemoteName;
265 // Strip off any trailing slashes
268 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
271 uniRemoteName.Length -= sizeof( WCHAR);
275 // Allocate a new node and add it to our list
278 pConnection = (AFSProviderConnectionCB *)AFSExAllocatePoolWithTag( PagedPool,
279 sizeof( AFSProviderConnectionCB) +
280 uniRemoteName.Length,
283 if( pConnection == NULL)
286 *ResultStatus = WN_OUT_OF_MEMORY;
288 *ReturnOutputBufferLength = sizeof( ULONG);
290 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
293 RtlZeroMemory( pConnection,
294 sizeof( AFSProviderConnectionCB) + uniRemoteName.Length);
296 pConnection->LocalName = ConnectCB->LocalName;
298 pConnection->RemoteName.Length = uniRemoteName.Length;
299 pConnection->RemoteName.MaximumLength = pConnection->RemoteName.Length;
301 pConnection->RemoteName.Buffer = (WCHAR *)((char *)pConnection + sizeof( AFSProviderConnectionCB));
303 RtlCopyMemory( pConnection->RemoteName.Buffer,
304 uniRemoteName.Buffer,
305 pConnection->RemoteName.Length);
307 pConnection->Type = ConnectCB->Type;
309 pConnection->AuthenticationId = ConnectCB->AuthenticationId;
311 if( ConnectCB->LocalName != L'\0')
314 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
315 AFS_TRACE_LEVEL_VERBOSE,
316 "AFSAddConnection Adding connection remote name %wZ Local %C authentication id %I64X\n",
318 ConnectCB->LocalName,
319 ConnectCB->AuthenticationId.QuadPart));
324 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
325 AFS_TRACE_LEVEL_VERBOSE,
326 "AFSAddConnection Adding connection remote name %wZ Local (NULL) authentication id %I64X\n",
328 ConnectCB->AuthenticationId.QuadPart));
332 // Point to the component portion of the name
335 pConnection->ComponentName.Length = 0;
336 pConnection->ComponentName.MaximumLength = 0;
338 pConnection->ComponentName.Buffer = &pConnection->RemoteName.Buffer[ (pConnection->RemoteName.Length/sizeof( WCHAR)) - 1];
340 while( pConnection->ComponentName.Length <= pConnection->RemoteName.Length)
343 if( pConnection->ComponentName.Buffer[ 0] == L'\\')
346 pConnection->ComponentName.Buffer++;
351 pConnection->ComponentName.Length += sizeof( WCHAR);
352 pConnection->ComponentName.MaximumLength += sizeof( WCHAR);
354 pConnection->ComponentName.Buffer--;
358 // Go initialize the information about the connection
361 AFSInitializeConnectionInfo( pConnection,
365 // Insert the entry into our list
368 if( pRDRDevExt->Specific.RDR.ProviderConnectionList == NULL)
371 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection;
377 // Get the end of the list
380 pLastConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
382 while( pLastConnection->fLink != NULL)
385 pLastConnection = pLastConnection->fLink;
388 pLastConnection->fLink = pConnection;
391 *ResultStatus = WN_SUCCESS;
393 *ReturnOutputBufferLength = sizeof( ULONG);
397 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
405 AFSCancelConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
406 IN OUT AFSCancelConnectionResultCB *ConnectionResult,
407 IN OUT ULONG_PTR *ReturnOutputBufferLength)
410 NTSTATUS ntStatus = STATUS_SUCCESS;
411 AFSProviderConnectionCB *pConnection = NULL, *pLastConnection = NULL;
412 UNICODE_STRING uniRemoteName;
413 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
418 ConnectionResult->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
420 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
421 AFS_TRACE_LEVEL_VERBOSE,
422 "AFSCancelConnection Acquiring AFSProviderListLock lock %p EXCL %08lX\n",
423 &pRDRDevExt->Specific.RDR.ProviderListLock,
424 PsGetCurrentThread()));
426 if( ConnectCB->AuthenticationId.QuadPart == 0)
429 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
431 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
432 AFS_TRACE_LEVEL_VERBOSE,
433 "AFSCancelConnection Retrieved authentication id %I64X\n",
434 ConnectCB->AuthenticationId.QuadPart));
437 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
441 // Look for the connection
444 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
445 uniRemoteName.MaximumLength = uniRemoteName.Length;
447 uniRemoteName.Buffer = NULL;
449 if( uniRemoteName.Length > 0)
452 uniRemoteName.Buffer = ConnectCB->RemoteName;
455 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
457 while( pConnection != NULL)
460 if( ( ConnectCB->LocalName != L'\0' &&
461 pConnection->LocalName == ConnectCB->LocalName)
463 ( ConnectCB->LocalName == L'\0' &&
464 pConnection->LocalName == L'\0' &&
465 RtlCompareUnicodeString( &uniRemoteName,
466 &pConnection->RemoteName,
470 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
471 AFS_TRACE_LEVEL_VERBOSE,
472 "AFSCancelConnection Checking remote name %wZ to stored %wZ authentication id %I64X - %I64X\n",
474 &pConnection->RemoteName,
475 ConnectCB->AuthenticationId.QuadPart,
476 pConnection->AuthenticationId.QuadPart));
478 if( ConnectCB->AuthenticationId.QuadPart == pConnection->AuthenticationId.QuadPart &&
479 ( ConnectCB->LocalName == L'\0' ||
480 RtlCompareUnicodeString( &uniRemoteName,
481 &pConnection->RemoteName,
489 pLastConnection = pConnection;
491 pConnection = pConnection->fLink;
494 if( pConnection == NULL)
497 ConnectionResult->Status = WN_NOT_CONNECTED;
499 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
501 try_return( ntStatus);
504 if( pLastConnection == NULL)
507 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection->fLink;
512 pLastConnection->fLink = pConnection->fLink;
515 if( pConnection->Comment.Buffer != NULL)
518 AFSExFreePoolWithTag( pConnection->Comment.Buffer, 0);
521 ConnectionResult->LocalName = pConnection->LocalName;
523 AFSExFreePoolWithTag( pConnection, AFS_PROVIDER_CB);
525 ConnectionResult->Status = WN_SUCCESS;
527 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
531 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
538 AFSGetConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
539 IN OUT WCHAR *RemoteName,
540 IN ULONG RemoteNameBufferLength,
541 IN OUT ULONG_PTR *ReturnOutputBufferLength)
544 NTSTATUS ntStatus = STATUS_SUCCESS;
545 AFSProviderConnectionCB *pConnection = NULL;
546 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
551 if( ConnectCB->AuthenticationId.QuadPart == 0)
554 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
556 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
557 AFS_TRACE_LEVEL_VERBOSE,
558 "AFSGetConnection Retrieved authentication id %I64X\n",
559 ConnectCB->AuthenticationId.QuadPart));
562 if( ConnectCB->LocalName != L'\0')
565 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
566 AFS_TRACE_LEVEL_VERBOSE,
567 "AFSGetConnection Local %C authentication id %I64X\n",
568 ConnectCB->LocalName,
569 ConnectCB->AuthenticationId.QuadPart));
574 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
575 AFS_TRACE_LEVEL_VERBOSE,
576 "AFSGetConnection Local (NULL) authentication id %I64X\n",
577 ConnectCB->AuthenticationId.QuadPart));
580 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
581 AFS_TRACE_LEVEL_VERBOSE,
582 "AFSGetConnection Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
583 &pRDRDevExt->Specific.RDR.ProviderListLock,
584 PsGetCurrentThread()));
586 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
590 // Look for the connection
593 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
595 while( pConnection != NULL)
598 if( pConnection->LocalName != L'\0')
601 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
602 AFS_TRACE_LEVEL_VERBOSE,
603 "AFSGetConnection Comparing passed in %C to %C authentication id %I64X - %I64X\n",
604 ConnectCB->LocalName,
605 pConnection->LocalName,
606 ConnectCB->AuthenticationId.QuadPart,
607 pConnection->AuthenticationId.QuadPart));
612 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
613 AFS_TRACE_LEVEL_VERBOSE,
614 "AFSGetConnection Comparing passed in %C to (NULL) authentication id %I64X - %I64X\n",
615 ConnectCB->LocalName,
616 ConnectCB->AuthenticationId.QuadPart,
617 pConnection->AuthenticationId.QuadPart));
620 if( pConnection->LocalName == ConnectCB->LocalName &&
621 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart)
627 pConnection = pConnection->fLink;
630 if( pConnection == NULL)
633 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
634 AFS_TRACE_LEVEL_VERBOSE,
635 "AFSGetConnection INVALID_PARAMETER\n"));
637 try_return( ntStatus = STATUS_INVALID_PARAMETER);
640 if( RemoteNameBufferLength < pConnection->RemoteName.Length)
643 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
644 AFS_TRACE_LEVEL_VERBOSE,
645 "AFSGetConnection INSUFFICIENT_RESOURCES\n"));
647 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
650 RtlCopyMemory( RemoteName,
651 pConnection->RemoteName.Buffer,
652 pConnection->RemoteName.Length);
654 *ReturnOutputBufferLength = pConnection->RemoteName.Length;
658 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
665 AFSListConnections( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
666 IN ULONG ConnectionBufferLength,
667 IN OUT ULONG_PTR *ReturnOutputBufferLength)
670 NTSTATUS ntStatus = STATUS_SUCCESS;
671 AFSProviderConnectionCB *pConnection = NULL, *pRootConnection = NULL;
672 ULONG ulCopiedLength = 0, ulRemainingLength = ConnectionBufferLength;
673 ULONG ulScope, ulType;
674 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath;
675 BOOLEAN bGlobalEnumeration = FALSE;
677 LARGE_INTEGER liAuthenticationID = {0,0};
678 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
684 // Save off some data before moving on
687 ulScope = ConnectCB->Scope;
689 ulType = ConnectCB->Type;
691 if( ConnectCB->AuthenticationId.QuadPart == 0)
694 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
696 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
697 AFS_TRACE_LEVEL_VERBOSE,
698 "AFSListConnections Retrieved authentication id %I64X\n",
699 ConnectCB->AuthenticationId.QuadPart));
702 liAuthenticationID.QuadPart = ConnectCB->AuthenticationId.QuadPart;
704 uniRemoteName.Length = 0;
705 uniRemoteName.MaximumLength = 0;
706 uniRemoteName.Buffer = NULL;
708 uniServerName.Length = 0;
709 uniServerName.MaximumLength = 0;
710 uniServerName.Buffer = NULL;
712 uniShareName.Length = 0;
713 uniShareName.MaximumLength = 0;
714 uniShareName.Buffer = NULL;
716 if( ConnectCB->RemoteNameLength > 0)
719 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
720 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
722 uniRemoteName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
723 uniRemoteName.MaximumLength,
724 AFS_NETWORK_PROVIDER_1_TAG);
726 if( uniRemoteName.Buffer == NULL)
729 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
732 RtlCopyMemory( uniRemoteName.Buffer,
733 ConnectCB->RemoteName,
734 uniRemoteName.Length);
736 if( uniRemoteName.Buffer[ 0] == L'\\' &&
737 uniRemoteName.Buffer[ 1] == L'\\')
740 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
742 uniRemoteName.Length -= sizeof( WCHAR);
745 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
748 uniRemoteName.Length -= sizeof( WCHAR);
751 FsRtlDissectName( uniRemoteName,
755 uniRemoteName = uniRemainingPath;
757 if( uniRemoteName.Length > 0)
760 FsRtlDissectName( uniRemoteName,
766 // If this is an enumeration of the global share name then
767 // adjust it to be the server name itself
770 if( uniShareName.Length == 0)
773 bGlobalEnumeration = TRUE;
777 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
778 AFS_TRACE_LEVEL_VERBOSE,
779 "AFSListConnections Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
780 &pRDRDevExt->Specific.RDR.ProviderListLock,
781 PsGetCurrentThread()));
783 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
787 // If this is a globalnet enumeration with no name then enumerate the server list
790 if( ulScope == RESOURCE_GLOBALNET)
793 if( uniServerName.Buffer == NULL)
796 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
802 // Go locate the root entry for the name passed in
805 if( bGlobalEnumeration)
808 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
811 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
813 try_return( ntStatus);
816 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
821 pRootConnection = AFSLocateEnumRootEntry( &uniShareName);
823 if( pRootConnection == NULL)
826 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
828 try_return( ntStatus);
832 // Need to handle these enumerations from the directory listing
835 ntStatus = AFSEnumerateConnection( ConnectCB,
837 ConnectionBufferLength,
845 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
848 ulIndex = ConnectCB->CurrentIndex;
850 while( pConnection != NULL)
853 if( bGlobalEnumeration &&
854 BooleanFlagOn( pConnection->Flags, AFS_CONNECTION_FLAG_GLOBAL_SHARE))
857 pConnection = pConnection->fLink;
862 if( ulScope != RESOURCE_GLOBALNET &&
863 !BooleanFlagOn( pConnection->Usage, RESOURCEUSAGE_ATTACHED))
866 pConnection = pConnection->fLink;
871 if( pConnection->LocalName != L'\0')
874 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
875 AFS_TRACE_LEVEL_VERBOSE,
876 "AFSListConnections Processing entry %wZ %C authentication id %I64X - %I64X Scope %08lX\n",
877 &pConnection->RemoteName,
878 pConnection->LocalName,
879 liAuthenticationID.QuadPart,
880 pConnection->AuthenticationId.QuadPart,
881 pConnection->Scope));
886 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
887 AFS_TRACE_LEVEL_VERBOSE,
888 "AFSListConnections Processing entry %wZ NULL LocalName authentication id %I64X - %I64X Scope %08lX\n",
889 &pConnection->RemoteName,
890 liAuthenticationID.QuadPart,
891 pConnection->AuthenticationId.QuadPart,
892 pConnection->Scope));
895 if( ulScope != RESOURCE_GLOBALNET &&
896 pConnection->AuthenticationId.QuadPart != liAuthenticationID.QuadPart)
899 pConnection = pConnection->fLink;
909 pConnection = pConnection->fLink;
914 if( ulRemainingLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
915 pConnection->RemoteName.Length +
916 pConnection->Comment.Length)
922 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
924 RtlCopyMemory( ConnectCB->RemoteName,
925 pConnection->RemoteName.Buffer,
926 pConnection->RemoteName.Length);
928 ConnectCB->LocalName = pConnection->LocalName;
930 ConnectCB->Type = pConnection->Type;
932 ConnectCB->Scope = pConnection->Scope;
934 if( !bGlobalEnumeration)
937 ConnectCB->Scope = RESOURCE_CONNECTED;
940 ConnectCB->DisplayType = pConnection->DisplayType;
942 ConnectCB->Usage = pConnection->Usage;
944 ConnectCB->CommentLength = pConnection->Comment.Length;
946 if( pConnection->Comment.Length > 0)
949 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
950 ConnectCB->RemoteNameLength);
952 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
953 pConnection->Comment.Buffer,
954 ConnectCB->CommentLength);
957 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
958 ConnectCB->RemoteNameLength +
959 ConnectCB->CommentLength;
961 ulRemainingLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
962 ConnectCB->RemoteNameLength +
963 ConnectCB->CommentLength;
965 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
966 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
967 ConnectCB->RemoteNameLength +
968 ConnectCB->CommentLength);
970 pConnection = pConnection->fLink;
973 if( NT_SUCCESS( ntStatus))
976 *ReturnOutputBufferLength = ulCopiedLength;
979 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
983 if( uniRemoteName.Buffer != NULL)
986 AFSExFreePoolWithTag( uniRemoteName.Buffer, 0);
994 AFSInitializeConnectionInfo( IN AFSProviderConnectionCB *Connection,
995 IN ULONG DisplayType)
998 NTSTATUS ntStatus = STATUS_SUCCESS;
999 UNICODE_STRING uniName, uniComponentName, uniRemainingName;
1004 uniName = Connection->RemoteName;
1007 // Strip of the double leading slash if there is one
1010 if( uniName.Buffer[ 0] == L'\\' &&
1011 uniName.Buffer[ 1] == L'\\')
1014 uniName.Buffer = &uniName.Buffer[ 1];
1016 uniName.Length -= sizeof( WCHAR);
1020 FsRtlDissectName( uniName,
1025 // Initialize the information for the connection
1026 // First, if this is the server only then mark it accordingly
1029 if( uniRemainingName.Length == 0 ||
1030 DisplayType == RESOURCEDISPLAYTYPE_SERVER)
1033 Connection->Type = RESOURCETYPE_DISK;
1035 Connection->Scope = 0;
1037 Connection->DisplayType = RESOURCEDISPLAYTYPE_SERVER;
1039 Connection->Usage = RESOURCEUSAGE_CONTAINER;
1041 Connection->Comment.Length = 20;
1042 Connection->Comment.MaximumLength = 22;
1044 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1045 Connection->Comment.MaximumLength,
1046 AFS_NETWORK_PROVIDER_2_TAG);
1048 if( Connection->Comment.Buffer != NULL)
1051 RtlZeroMemory( Connection->Comment.Buffer,
1052 Connection->Comment.MaximumLength);
1054 RtlCopyMemory( Connection->Comment.Buffer,
1061 Connection->Comment.Length = 0;
1062 Connection->Comment.MaximumLength = 0;
1065 try_return( ntStatus);
1068 uniName = uniRemainingName;
1070 FsRtlDissectName( uniName,
1074 if( uniRemainingName.Length == 0 ||
1075 uniRemainingName.Buffer == NULL ||
1076 DisplayType == RESOURCEDISPLAYTYPE_SHARE)
1079 Connection->Type = RESOURCETYPE_DISK;
1081 Connection->DisplayType = RESOURCEDISPLAYTYPE_SHARE;
1083 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1085 if( Connection->LocalName != L'\0')
1088 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1090 Connection->Scope = RESOURCE_CONNECTED;
1095 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1097 Connection->Scope = RESOURCE_GLOBALNET;
1100 Connection->Comment.Length = 18;
1101 Connection->Comment.MaximumLength = 20;
1103 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1104 Connection->Comment.MaximumLength,
1105 AFS_NETWORK_PROVIDER_3_TAG);
1107 if( Connection->Comment.Buffer != NULL)
1110 RtlZeroMemory( Connection->Comment.Buffer,
1111 Connection->Comment.MaximumLength);
1113 RtlCopyMemory( Connection->Comment.Buffer,
1120 Connection->Comment.Length = 0;
1121 Connection->Comment.MaximumLength = 0;
1124 try_return( ntStatus);
1128 // This is a sub directory within a share
1131 Connection->Type = RESOURCETYPE_DISK;
1133 Connection->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1135 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1137 if( Connection->LocalName != L'\0')
1140 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1145 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1148 Connection->Scope = RESOURCE_CONNECTED;
1150 Connection->Comment.Length = 26;
1151 Connection->Comment.MaximumLength = 28;
1153 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1154 Connection->Comment.MaximumLength,
1155 AFS_NETWORK_PROVIDER_4_TAG);
1157 if( Connection->Comment.Buffer != NULL)
1160 RtlZeroMemory( Connection->Comment.Buffer,
1161 Connection->Comment.MaximumLength);
1163 RtlCopyMemory( Connection->Comment.Buffer,
1170 Connection->Comment.Length = 0;
1171 Connection->Comment.MaximumLength = 0;
1182 AFSProviderConnectionCB *
1183 AFSLocateEnumRootEntry( IN UNICODE_STRING *RemoteName)
1186 AFSProviderConnectionCB *pConnection = NULL;
1187 UNICODE_STRING uniRemoteName = *RemoteName;
1188 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1193 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
1196 try_return( pConnection);
1199 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
1201 while( pConnection != NULL)
1204 if( RtlCompareUnicodeString( &uniRemoteName,
1205 &pConnection->ComponentName,
1212 pConnection = pConnection->fLink;
1224 AFSEnumerateConnection( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
1225 IN AFSProviderConnectionCB *RootConnection,
1226 IN ULONG BufferLength,
1227 OUT PULONG CopiedLength)
1230 NTSTATUS ntStatus = STATUS_SUCCESS;
1231 ULONG ulCRC = 0, ulCopiedLength = 0;
1232 AFSDirectoryCB *pShareDirEntry = NULL;
1233 AFSDirectoryCB *pDirEntry = NULL, *pTargetDirEntry = NULL;
1240 if( AFSGlobalRoot == NULL)
1243 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1244 AFS_TRACE_LEVEL_ERROR,
1245 "AFSEnumerateConnection Global root not yet initialized\n"));
1247 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1250 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1254 // Grab our tree lock shared
1257 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1258 AFS_TRACE_LEVEL_VERBOSE,
1259 "AFSEnumerateConnection Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p SHARED %08lX\n",
1260 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1261 PsGetCurrentThread()));
1263 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1267 // Locate the dir entry for this node
1270 ntStatus = AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1274 if( pShareDirEntry == NULL ||
1275 !NT_SUCCESS( ntStatus))
1279 // Perform a case insensitive search
1282 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1285 ntStatus = AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1289 if( pShareDirEntry == NULL ||
1290 !NT_SUCCESS( ntStatus))
1293 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1295 try_return( ntStatus);
1299 lCount = InterlockedIncrement( &pShareDirEntry->DirOpenReferenceCount);
1301 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1302 AFS_TRACE_LEVEL_VERBOSE,
1303 "AFSEnumerateConnection1 Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1304 &pShareDirEntry->NameInformation.FileName,
1309 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1312 // Setup the request to evaluate the entry
1313 // On success, pTargetDirEntry has the DirOpenReferenceCount held
1316 ntStatus = AFSEvaluateRootEntry( pShareDirEntry,
1319 if( !NT_SUCCESS( ntStatus))
1322 try_return( ntStatus);
1325 AFSAcquireShared( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1329 // Enumerate the content
1332 pDirEntry = pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
1334 ulIndex = ConnectCB->CurrentIndex;
1336 while( pDirEntry != NULL)
1344 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1349 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1350 pDirEntry->NameInformation.FileName.Length)
1356 ConnectCB->LocalName = L'\0';
1358 ConnectCB->RemoteNameLength = pDirEntry->NameInformation.FileName.Length;
1360 RtlCopyMemory( ConnectCB->RemoteName,
1361 pDirEntry->NameInformation.FileName.Buffer,
1362 pDirEntry->NameInformation.FileName.Length);
1364 ConnectCB->Type = RESOURCETYPE_DISK;
1366 ConnectCB->Scope = RESOURCE_CONNECTED;
1368 if( BooleanFlagOn( pDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1371 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1376 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_FILE;
1379 ConnectCB->Usage = 0;
1381 ConnectCB->CommentLength = 0;
1383 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1384 pDirEntry->NameInformation.FileName.Length;
1386 BufferLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1387 pDirEntry->NameInformation.FileName.Length;
1389 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
1390 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1391 ConnectCB->RemoteNameLength);
1393 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1397 // Release the DirOpenReferenceCount obtained from AFSEvaluateRootEntry
1400 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
1402 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1403 AFS_TRACE_LEVEL_VERBOSE,
1404 "AFSEnumerateConnection Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1405 &pTargetDirEntry->NameInformation.FileName,
1410 ASSERT( lCount >= 0);
1412 *CopiedLength = ulCopiedLength;
1414 AFSReleaseResource( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1418 if( pShareDirEntry != NULL)
1420 lCount = InterlockedDecrement( &pShareDirEntry->DirOpenReferenceCount);
1422 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1423 AFS_TRACE_LEVEL_VERBOSE,
1424 "AFSEnumerateConnection1 Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1425 &pShareDirEntry->NameInformation.FileName,
1430 ASSERT( lCount >= 0);
1438 AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
1439 IN ULONG BufferLength,
1440 IN OUT ULONG_PTR *ReturnOutputBufferLength)
1443 NTSTATUS ntStatus = STATUS_SUCCESS;
1444 AFSProviderConnectionCB *pConnection = NULL, *pBestMatch = NULL;
1445 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath, uniFullName, uniRemainingPathLocal;
1446 USHORT usNameLen = 0, usMaxNameLen = 0;
1447 BOOLEAN bEnumerationEntry = FALSE;
1448 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1453 uniServerName.Length = 0;
1454 uniServerName.MaximumLength = 0;
1455 uniServerName.Buffer = NULL;
1457 uniShareName.Length = 0;
1458 uniShareName.MaximumLength = 0;
1459 uniShareName.Buffer = NULL;
1461 uniRemainingPathLocal.Length = 0;
1462 uniRemainingPathLocal.MaximumLength = 0;
1463 uniRemainingPathLocal.Buffer = NULL;
1465 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
1466 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
1467 uniRemoteName.Buffer = (WCHAR *)ConnectCB->RemoteName;
1469 if( ConnectCB->AuthenticationId.QuadPart == 0)
1472 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
1474 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1475 AFS_TRACE_LEVEL_VERBOSE,
1476 "AFSGetConnectionInfo Retrieved authentication id %I64X\n",
1477 ConnectCB->AuthenticationId.QuadPart));
1480 if( ConnectCB->LocalName != L'\0')
1483 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1484 AFS_TRACE_LEVEL_VERBOSE,
1485 "AFSGetConnectionInfo remote name %wZ Local %C authentication id %I64X\n",
1487 ConnectCB->LocalName,
1488 ConnectCB->AuthenticationId.QuadPart));
1493 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1494 AFS_TRACE_LEVEL_VERBOSE,
1495 "AFSGetConnectionInfo remote name %wZ Local (NULL) authentication id %I64X\n",
1497 ConnectCB->AuthenticationId.QuadPart));
1500 if( AFSGlobalRoot == NULL)
1503 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1504 AFS_TRACE_LEVEL_ERROR,
1505 "AFSGetConnectionInfo Global root not yet initialized\n"));
1507 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1510 uniFullName = uniRemoteName;
1512 if( uniRemoteName.Buffer[ 0] == L'\\' &&
1513 uniRemoteName.Buffer[ 1] == L'\\')
1516 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
1518 uniRemoteName.Length -= sizeof( WCHAR);
1521 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
1524 uniRemoteName.Length -= sizeof( WCHAR);
1526 uniFullName.Length -= sizeof( WCHAR);
1529 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1530 AFS_TRACE_LEVEL_VERBOSE,
1531 "AFSGetConnectionInfo Processing name %wZ\n",
1534 FsRtlDissectName( uniRemoteName,
1538 uniRemoteName = uniRemainingPath;
1540 if( uniRemoteName.Length > 0)
1543 FsRtlDissectName( uniRemoteName,
1548 if( RtlCompareUnicodeString( &uniServerName,
1553 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1556 if ( uniRemainingPath.Length > 0 )
1560 // Add back in the leading \ since it was stripped off above
1563 uniRemainingPath.Length += sizeof( WCHAR);
1564 if( uniRemainingPath.Length > uniRemainingPath.MaximumLength)
1566 uniRemainingPath.MaximumLength += sizeof( WCHAR);
1569 uniRemainingPath.Buffer--;
1571 uniRemainingPathLocal.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1572 uniRemainingPath.Length,
1573 AFS_NETWORK_PROVIDER_5_TAG);
1575 if( uniRemainingPathLocal.Buffer == NULL)
1578 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1579 AFS_TRACE_LEVEL_VERBOSE,
1580 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1582 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1585 uniRemainingPathLocal.MaximumLength = uniRemainingPath.Length;
1586 uniRemainingPathLocal.Length = uniRemainingPath.Length;
1588 RtlCopyMemory( uniRemainingPathLocal.Buffer,
1589 uniRemainingPath.Buffer,
1590 uniRemainingPath.Length);
1593 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1594 AFS_TRACE_LEVEL_VERBOSE,
1595 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1596 &pRDRDevExt->Specific.RDR.ProviderListLock,
1597 PsGetCurrentThread()));
1599 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1603 // If this is the server then return information about the
1607 if( uniShareName.Length == 0 &&
1608 RtlCompareUnicodeString( &uniServerName,
1613 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
1619 // See if we can locate it on our connection list
1622 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1624 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1625 AFS_TRACE_LEVEL_VERBOSE,
1626 "AFSGetConnectionInfo Searching for full name %wZ\n",
1629 while( pConnection != NULL)
1632 if( usMaxNameLen < pConnection->RemoteName.Length &&
1633 pConnection->RemoteName.Length <= uniFullName.Length)
1636 usNameLen = uniFullName.Length;
1638 uniFullName.Length = pConnection->RemoteName.Length;
1640 if( pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
1641 RtlCompareUnicodeString( &uniFullName,
1642 &pConnection->RemoteName,
1646 usMaxNameLen = pConnection->RemoteName.Length;
1648 pBestMatch = pConnection;
1650 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1651 AFS_TRACE_LEVEL_VERBOSE,
1652 "AFSGetConnectionInfo Found match for %wZ\n",
1653 &pConnection->RemoteName));
1656 uniFullName.Length = usNameLen;
1659 pConnection = pConnection->fLink;
1662 pConnection = pBestMatch;
1664 if( pConnection != NULL)
1667 bEnumerationEntry = TRUE;
1669 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1670 AFS_TRACE_LEVEL_VERBOSE,
1671 "AFSGetConnectionInfo Using best match for %wZ\n",
1672 &pConnection->RemoteName));
1675 if( pConnection == NULL)
1679 // Locate the entry for the share
1682 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1686 if( pConnection == NULL)
1688 UNICODE_STRING uniFullName;
1689 AFSDirEnumEntry *pDirEnumEntry = NULL;
1691 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1692 AFS_TRACE_LEVEL_VERBOSE,
1693 "AFSGetConnectionInfo No connection for full name %wZ\n",
1697 // Drop the lock, we will pick it up again later
1700 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1703 // OK, ask the CM about this component name
1706 ntStatus = AFSEvaluateTargetByName( NULL,
1707 &AFSGlobalRoot->ObjectInformation,
1712 if( !NT_SUCCESS( ntStatus))
1715 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1716 AFS_TRACE_LEVEL_VERBOSE,
1717 "AFSGetConnectionInfo Evaluation Failed share name %wZ\n",
1720 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1728 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_3_TAG);
1731 // The share name is valid
1732 // Allocate a new node and add it to our list
1734 uniFullName.MaximumLength = PAGE_SIZE;
1735 uniFullName.Length = 0;
1737 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1738 uniFullName.MaximumLength,
1739 AFS_NETWORK_PROVIDER_6_TAG);
1741 if( uniFullName.Buffer == NULL)
1744 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1745 AFS_TRACE_LEVEL_VERBOSE,
1746 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1748 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1751 uniFullName.Buffer[ 0] = L'\\';
1752 uniFullName.Buffer[ 1] = L'\\';
1754 uniFullName.Length = 2 * sizeof( WCHAR);
1756 RtlCopyMemory( &uniFullName.Buffer[ 2],
1757 AFSServerName.Buffer,
1758 AFSServerName.Length);
1760 uniFullName.Length += AFSServerName.Length;
1762 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
1764 uniFullName.Length += sizeof( WCHAR);
1766 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
1767 uniShareName.Buffer,
1768 uniShareName.Length);
1770 uniFullName.Length += uniShareName.Length;
1772 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1775 ntStatus = AFSAddConnectionEx( &uniFullName,
1776 RESOURCEDISPLAYTYPE_SHARE,
1779 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1781 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
1783 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1784 AFS_TRACE_LEVEL_VERBOSE,
1785 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1786 &pRDRDevExt->Specific.RDR.ProviderListLock,
1787 PsGetCurrentThread()));
1789 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1792 if ( NT_SUCCESS( ntStatus) )
1795 // Once again, locate the entry for the share we just created
1798 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1803 if( pConnection == NULL)
1806 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1807 AFS_TRACE_LEVEL_ERROR,
1808 "AFSGetConnectionInfo Failed to locate entry for full name %wZ\n",
1811 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1813 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1817 // Fill in the returned connection info block
1820 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1821 pConnection->RemoteName.Length +
1822 pConnection->Comment.Length +
1823 uniRemainingPath.Length)
1826 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1827 AFS_TRACE_LEVEL_VERBOSE,
1828 "AFSGetConnectionInfo Buffer too small for full name %wZ\n",
1831 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1833 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
1836 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1837 AFS_TRACE_LEVEL_VERBOSE,
1838 "AFSGetConnectionInfo Returning entry Scope %08lX partial name %wZ full name %wZ\n",
1839 pConnection->Scope, &pConnection->RemoteName, &uniFullName));
1841 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
1843 if( !bEnumerationEntry)
1846 RtlCopyMemory( ConnectCB->RemoteName,
1848 pConnection->RemoteName.Length);
1853 RtlCopyMemory( ConnectCB->RemoteName,
1854 pConnection->RemoteName.Buffer,
1855 pConnection->RemoteName.Length);
1858 ConnectCB->LocalName = pConnection->LocalName;
1860 ConnectCB->Type = pConnection->Type;
1862 ConnectCB->Scope = pConnection->Scope;
1864 ConnectCB->DisplayType = pConnection->DisplayType;
1866 ConnectCB->Usage = pConnection->Usage;
1868 ConnectCB->CommentLength = pConnection->Comment.Length;
1870 ConnectCB->RemainingPathLength = uniRemainingPathLocal.Length;
1872 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1873 AFS_TRACE_LEVEL_VERBOSE,
1874 "AFSGetConnectionInfo Returning lengths: remote %u comment %u remaining %u\n",
1875 ConnectCB->RemoteNameLength,
1876 ConnectCB->CommentLength,
1877 ConnectCB->RemainingPathLength));
1879 if( ConnectCB->CommentLength > 0)
1882 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1883 ConnectCB->RemoteNameLength);
1885 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
1886 pConnection->Comment.Buffer,
1887 ConnectCB->CommentLength);
1890 if ( ConnectCB->RemainingPathLength > 0 )
1893 ConnectCB->RemainingPathOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1894 ConnectCB->RemoteNameLength +
1895 ConnectCB->CommentLength);
1897 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->RemainingPathOffset),
1898 uniRemainingPathLocal.Buffer,
1899 uniRemainingPathLocal.Length);
1902 *ReturnOutputBufferLength = FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1903 ConnectCB->RemoteNameLength +
1904 ConnectCB->CommentLength +
1905 ConnectCB->RemainingPathLength;
1907 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1911 if ( uniRemainingPathLocal.Buffer )
1914 AFSExFreePoolWithTag( uniRemainingPathLocal.Buffer, 0);
1922 AFSIsDriveMapped( IN WCHAR DriveMapping)
1925 BOOLEAN bDriveMapped = FALSE;
1926 AFSProviderConnectionCB *pConnection = NULL;
1927 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1932 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1935 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1937 while( pConnection != NULL)
1940 if( pConnection->LocalName != L'\0' &&
1941 RtlUpcaseUnicodeChar( pConnection->LocalName) == RtlUpcaseUnicodeChar( DriveMapping))
1944 bDriveMapped = TRUE;
1949 pConnection = pConnection->fLink;
1952 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1955 return bDriveMapped;