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;
51 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
56 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
57 AFS_TRACE_LEVEL_VERBOSE,
58 "AFSAddConnection Acquiring AFSProviderListLock lock %08lX EXCL %08lX\n",
59 &pRDRDevExt->Specific.RDR.ProviderListLock,
60 PsGetCurrentThread());
62 if( ConnectCB->AuthenticationId.QuadPart == 0)
65 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
67 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
68 AFS_TRACE_LEVEL_VERBOSE,
69 "AFSAddConnection Retrieved authentication id %I64X\n",
70 ConnectCB->AuthenticationId.QuadPart);
73 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
77 // Look for the connection
80 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
81 uniRemoteName.MaximumLength = uniRemoteName.Length;
83 uniRemoteName.Buffer = ConnectCB->RemoteName;
86 // Strip off any trailing slashes
89 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
92 uniRemoteName.Length -= sizeof( WCHAR);
95 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
97 while( pConnection != NULL)
100 if( pConnection->LocalName == ConnectCB->LocalName &&
101 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
102 RtlCompareUnicodeString( &uniRemoteName,
103 &pConnection->RemoteName,
110 pConnection = pConnection->fLink;
113 if( pConnection != NULL)
116 if( ConnectCB->LocalName != L'\0')
119 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
120 AFS_TRACE_LEVEL_VERBOSE,
121 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local %C authentication id %I64X\n",
123 ConnectCB->LocalName,
124 ConnectCB->AuthenticationId.QuadPart);
129 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
130 AFS_TRACE_LEVEL_VERBOSE,
131 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local (NULL) authentication id %I64X\n",
133 ConnectCB->AuthenticationId.QuadPart);
136 *ResultStatus = WN_ALREADY_CONNECTED;
138 *ReturnOutputBufferLength = sizeof( ULONG);
140 try_return( ntStatus);
144 // Validate the remote name
147 if( uniRemoteName.Length > 2 * sizeof( WCHAR) &&
148 uniRemoteName.Buffer[ 0] == L'\\' &&
149 uniRemoteName.Buffer[ 1] == L'\\')
152 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 2];
154 uniRemoteName.Length -= (2 * sizeof( WCHAR));
157 if( uniRemoteName.Length >= AFSServerName.Length)
160 USHORT usLength = uniRemoteName.Length;
162 if (uniRemoteName.Buffer[AFSServerName.Length/sizeof( WCHAR)] != L'\\')
165 if( ConnectCB->LocalName != L'\0')
168 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
169 AFS_TRACE_LEVEL_VERBOSE,
170 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local %C authentication id %I64X\n",
172 ConnectCB->LocalName,
173 ConnectCB->AuthenticationId.QuadPart);
178 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
179 AFS_TRACE_LEVEL_VERBOSE,
180 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local (NULL) authentication id %I64X\n",
182 ConnectCB->AuthenticationId.QuadPart);
185 *ResultStatus = WN_BAD_NETNAME;
187 *ReturnOutputBufferLength = sizeof( ULONG);
189 try_return( ntStatus = STATUS_SUCCESS);
192 uniRemoteName.Length = AFSServerName.Length;
194 if( RtlCompareUnicodeString( &AFSServerName,
199 if( ConnectCB->LocalName != L'\0')
202 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
203 AFS_TRACE_LEVEL_VERBOSE,
204 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local %C authentication id %I64X\n",
206 ConnectCB->LocalName,
207 ConnectCB->AuthenticationId.QuadPart);
212 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
213 AFS_TRACE_LEVEL_VERBOSE,
214 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local (NULL) authentication id %I64X\n",
216 ConnectCB->AuthenticationId.QuadPart);
219 *ResultStatus = WN_BAD_NETNAME;
221 *ReturnOutputBufferLength = sizeof( ULONG);
223 try_return( ntStatus = STATUS_SUCCESS);
226 uniRemoteName.Length = usLength;
231 if( ConnectCB->LocalName != L'\0')
234 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
235 AFS_TRACE_LEVEL_VERBOSE,
236 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local %C authentication id %I64X\n",
238 ConnectCB->LocalName,
239 ConnectCB->AuthenticationId.QuadPart);
244 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
245 AFS_TRACE_LEVEL_VERBOSE,
246 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local (NULL) authentication id %I64X\n",
248 ConnectCB->AuthenticationId.QuadPart);
251 *ResultStatus = WN_BAD_NETNAME;
253 *ReturnOutputBufferLength = sizeof( ULONG);
255 try_return( ntStatus = STATUS_SUCCESS);
258 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
259 uniRemoteName.MaximumLength = uniRemoteName.Length;
261 uniRemoteName.Buffer = ConnectCB->RemoteName;
264 // Strip off any trailing slashes
267 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
270 uniRemoteName.Length -= sizeof( WCHAR);
274 // Allocate a new node and add it to our list
277 pConnection = (AFSProviderConnectionCB *)AFSExAllocatePoolWithTag( PagedPool,
278 sizeof( AFSProviderConnectionCB) +
279 uniRemoteName.Length,
282 if( pConnection == NULL)
285 *ResultStatus = WN_OUT_OF_MEMORY;
287 *ReturnOutputBufferLength = sizeof( ULONG);
289 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
292 RtlZeroMemory( pConnection,
293 sizeof( AFSProviderConnectionCB) + uniRemoteName.Length);
295 pConnection->LocalName = ConnectCB->LocalName;
297 pConnection->RemoteName.Length = uniRemoteName.Length;
298 pConnection->RemoteName.MaximumLength = pConnection->RemoteName.Length;
300 pConnection->RemoteName.Buffer = (WCHAR *)((char *)pConnection + sizeof( AFSProviderConnectionCB));
302 RtlCopyMemory( pConnection->RemoteName.Buffer,
303 uniRemoteName.Buffer,
304 pConnection->RemoteName.Length);
306 pConnection->Type = ConnectCB->Type;
308 pConnection->AuthenticationId = ConnectCB->AuthenticationId;
310 if( ConnectCB->LocalName != L'\0')
313 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
314 AFS_TRACE_LEVEL_VERBOSE,
315 "AFSAddConnection Adding connection remote name %wZ Local %C authentication id %I64X\n",
317 ConnectCB->LocalName,
318 ConnectCB->AuthenticationId.QuadPart);
323 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
324 AFS_TRACE_LEVEL_VERBOSE,
325 "AFSAddConnection Adding connection remote name %wZ Local (NULL) authentication id %I64X\n",
327 ConnectCB->AuthenticationId.QuadPart);
331 // Point to the component portion of the name
334 pConnection->ComponentName.Length = 0;
335 pConnection->ComponentName.MaximumLength = 0;
337 pConnection->ComponentName.Buffer = &pConnection->RemoteName.Buffer[ (pConnection->RemoteName.Length/sizeof( WCHAR)) - 1];
339 while( pConnection->ComponentName.Length <= pConnection->RemoteName.Length)
342 if( pConnection->ComponentName.Buffer[ 0] == L'\\')
345 pConnection->ComponentName.Buffer++;
350 pConnection->ComponentName.Length += sizeof( WCHAR);
351 pConnection->ComponentName.MaximumLength += sizeof( WCHAR);
353 pConnection->ComponentName.Buffer--;
357 // Go initialize the information about the connection
360 AFSInitializeConnectionInfo( pConnection,
364 // Insert the entry into our list
367 if( pRDRDevExt->Specific.RDR.ProviderConnectionList == NULL)
370 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection;
376 // Get the end of the list
379 pLastConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
381 while( pLastConnection->fLink != NULL)
384 pLastConnection = pLastConnection->fLink;
387 pLastConnection->fLink = pConnection;
390 *ResultStatus = WN_SUCCESS;
392 *ReturnOutputBufferLength = sizeof( ULONG);
396 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
404 AFSCancelConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
405 IN OUT AFSCancelConnectionResultCB *ConnectionResult,
406 IN OUT ULONG_PTR *ReturnOutputBufferLength)
409 NTSTATUS ntStatus = STATUS_SUCCESS;
410 AFSProviderConnectionCB *pConnection = NULL, *pLastConnection = NULL;
411 UNICODE_STRING uniRemoteName;
412 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
417 ConnectionResult->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
419 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
420 AFS_TRACE_LEVEL_VERBOSE,
421 "AFSCancelConnection Acquiring AFSProviderListLock lock %08lX EXCL %08lX\n",
422 &pRDRDevExt->Specific.RDR.ProviderListLock,
423 PsGetCurrentThread());
425 if( ConnectCB->AuthenticationId.QuadPart == 0)
428 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
430 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
431 AFS_TRACE_LEVEL_VERBOSE,
432 "AFSCancelConnection Retrieved authentication id %I64X\n",
433 ConnectCB->AuthenticationId.QuadPart);
436 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
440 // Look for the connection
443 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
444 uniRemoteName.MaximumLength = uniRemoteName.Length;
446 uniRemoteName.Buffer = NULL;
448 if( uniRemoteName.Length > 0)
451 uniRemoteName.Buffer = ConnectCB->RemoteName;
454 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
456 while( pConnection != NULL)
459 if( ( ConnectCB->LocalName != L'\0' &&
460 pConnection->LocalName == ConnectCB->LocalName)
462 ( RtlCompareUnicodeString( &uniRemoteName,
463 &pConnection->RemoteName,
467 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
468 AFS_TRACE_LEVEL_VERBOSE,
469 "AFSCancelConnection Checking remote name %wZ to stored %wZ authentication id %I64X - %I64X\n",
471 &pConnection->RemoteName,
472 ConnectCB->AuthenticationId.QuadPart,
473 pConnection->AuthenticationId.QuadPart);
475 if( ConnectCB->AuthenticationId.QuadPart == pConnection->AuthenticationId.QuadPart &&
476 ( ConnectCB->LocalName == L'\0' ||
477 RtlCompareUnicodeString( &uniRemoteName,
478 &pConnection->RemoteName,
486 pLastConnection = pConnection;
488 pConnection = pConnection->fLink;
491 if( pConnection == NULL)
494 ConnectionResult->Status = WN_NOT_CONNECTED;
496 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
498 try_return( ntStatus);
501 if( pLastConnection == NULL)
504 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection->fLink;
509 pLastConnection->fLink = pConnection->fLink;
512 if( pConnection->Comment.Buffer != NULL)
515 AFSExFreePool( pConnection->Comment.Buffer);
518 ConnectionResult->LocalName = pConnection->LocalName;
520 AFSExFreePool( pConnection);
522 ConnectionResult->Status = WN_SUCCESS;
524 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
528 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
535 AFSGetConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
536 IN OUT WCHAR *RemoteName,
537 IN ULONG RemoteNameBufferLength,
538 IN OUT ULONG_PTR *ReturnOutputBufferLength)
541 NTSTATUS ntStatus = STATUS_SUCCESS;
542 AFSProviderConnectionCB *pConnection = NULL;
543 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
548 if( ConnectCB->LocalName != L'\0')
551 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
552 AFS_TRACE_LEVEL_VERBOSE,
553 "AFSGetConnection Local %C authentication id %I64X\n",
554 ConnectCB->LocalName,
555 ConnectCB->AuthenticationId.QuadPart);
560 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
561 AFS_TRACE_LEVEL_VERBOSE,
562 "AFSGetConnection Local (NULL) authentication id %I64X\n",
563 ConnectCB->AuthenticationId.QuadPart);
566 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
567 AFS_TRACE_LEVEL_VERBOSE,
568 "AFSGetConnection Acquiring AFSProviderListLock lock %08lX SHARED %08lX\n",
569 &pRDRDevExt->Specific.RDR.ProviderListLock,
570 PsGetCurrentThread());
572 if( ConnectCB->AuthenticationId.QuadPart == 0)
575 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
577 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
578 AFS_TRACE_LEVEL_VERBOSE,
579 "AFSGetConnection Retrieved authentication id %I64X\n",
580 ConnectCB->AuthenticationId.QuadPart);
583 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
587 // Look for the connection
590 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
592 while( pConnection != NULL)
595 if( pConnection->LocalName != L'\0')
598 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
599 AFS_TRACE_LEVEL_VERBOSE,
600 "AFSGetConnection Comparing passed in %C to %C authentication id %I64X - %I64X\n",
601 ConnectCB->LocalName,
602 pConnection->LocalName,
603 ConnectCB->AuthenticationId.QuadPart,
604 pConnection->AuthenticationId.QuadPart);
609 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
610 AFS_TRACE_LEVEL_VERBOSE,
611 "AFSGetConnection Comparing passed in %C to (NULL) authentication id %I64X - %I64X\n",
612 ConnectCB->LocalName,
613 ConnectCB->AuthenticationId.QuadPart,
614 pConnection->AuthenticationId.QuadPart);
617 if( pConnection->LocalName == ConnectCB->LocalName &&
618 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart)
624 pConnection = pConnection->fLink;
627 if( pConnection == NULL)
630 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
631 AFS_TRACE_LEVEL_VERBOSE,
632 "AFSGetConnection INVALID_PARAMETER\n");
634 try_return( ntStatus = STATUS_INVALID_PARAMETER);
637 if( RemoteNameBufferLength < pConnection->RemoteName.Length)
640 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
641 AFS_TRACE_LEVEL_VERBOSE,
642 "AFSGetConnection INSUFFICIENT_RESOURCES\n");
644 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
647 RtlCopyMemory( RemoteName,
648 pConnection->RemoteName.Buffer,
649 pConnection->RemoteName.Length);
651 *ReturnOutputBufferLength = pConnection->RemoteName.Length;
655 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
662 AFSListConnections( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
663 IN ULONG ConnectionBufferLength,
664 IN OUT ULONG_PTR *ReturnOutputBufferLength)
667 NTSTATUS ntStatus = STATUS_SUCCESS;
668 AFSProviderConnectionCB *pConnection = NULL, *pRootConnection = NULL;
669 ULONG ulCopiedLength = 0, ulRemainingLength = ConnectionBufferLength;
670 ULONG ulScope, ulType;
671 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath;
672 BOOLEAN bGlobalEnumeration = FALSE;
674 LARGE_INTEGER liAuthenticationID = {0,0};
675 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
681 // Save off some data before moving on
684 ulScope = ConnectCB->Scope;
686 ulType = ConnectCB->Type;
688 if( ConnectCB->AuthenticationId.QuadPart == 0)
691 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
693 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
694 AFS_TRACE_LEVEL_VERBOSE,
695 "AFSListConnections Retrieved authentication id %I64X\n",
696 ConnectCB->AuthenticationId.QuadPart);
699 liAuthenticationID.QuadPart = ConnectCB->AuthenticationId.QuadPart;
701 uniRemoteName.Length = 0;
702 uniRemoteName.MaximumLength = 0;
703 uniRemoteName.Buffer = NULL;
705 uniServerName.Length = 0;
706 uniServerName.MaximumLength = 0;
707 uniServerName.Buffer = NULL;
709 uniShareName.Length = 0;
710 uniShareName.MaximumLength = 0;
711 uniShareName.Buffer = NULL;
713 if( ConnectCB->RemoteNameLength > 0)
716 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
717 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
719 uniRemoteName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
720 uniRemoteName.MaximumLength,
721 AFS_NETWORK_PROVIDER_1_TAG);
723 if( uniRemoteName.Buffer == NULL)
726 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
729 RtlCopyMemory( uniRemoteName.Buffer,
730 ConnectCB->RemoteName,
731 uniRemoteName.Length);
733 if( uniRemoteName.Buffer[ 0] == L'\\' &&
734 uniRemoteName.Buffer[ 1] == L'\\')
737 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
739 uniRemoteName.Length -= sizeof( WCHAR);
742 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
745 uniRemoteName.Length -= sizeof( WCHAR);
748 FsRtlDissectName( uniRemoteName,
752 uniRemoteName = uniRemainingPath;
754 if( uniRemoteName.Length > 0)
757 FsRtlDissectName( uniRemoteName,
763 // If this is an enumeration of the global share name then
764 // adjust it to be the server name itself
767 if( uniShareName.Length == 0 ||
768 RtlCompareUnicodeString( &uniShareName,
773 bGlobalEnumeration = TRUE;
777 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
778 AFS_TRACE_LEVEL_VERBOSE,
779 "AFSListConnections Acquiring AFSProviderListLock lock %08lX 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 AFSDbgLogMsg( 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,
886 AFSDbgLogMsg( 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,
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 AFSExFreePool( uniRemoteName.Buffer);
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 uniServerName, 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 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1232 ULONG ulCRC = 0, ulCopiedLength = 0;
1233 AFSDirectoryCB *pShareDirEntry = NULL;
1234 AFSDirectoryCB *pDirEntry = NULL, *pTargetDirEntry = NULL;
1236 BOOLEAN bContinueProcessing = TRUE;
1237 AFSFileInfoCB stFileInformation;
1242 if( AFSGlobalRoot == NULL)
1245 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1246 AFS_TRACE_LEVEL_ERROR,
1247 "AFSEnumerateConnection Global root not yet initialized\n");
1249 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1252 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1256 // Grab our tree lock shared
1259 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1260 AFS_TRACE_LEVEL_VERBOSE,
1261 "AFSEnumerateConnection Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX SHARED %08lX\n",
1262 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1263 PsGetCurrentThread());
1265 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1269 // Locate the dir entry for this node
1272 ntStatus = AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1276 if( pShareDirEntry == NULL ||
1277 !NT_SUCCESS( ntStatus))
1281 // Perform a case insensitive search
1284 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1287 ntStatus = AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1291 if( pShareDirEntry == NULL ||
1292 !NT_SUCCESS( ntStatus))
1295 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1297 try_return( ntStatus);
1301 InterlockedIncrement( &pShareDirEntry->OpenReferenceCount);
1303 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1304 AFS_TRACE_LEVEL_VERBOSE,
1305 "AFSEnumerateConnection1 Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1306 &pShareDirEntry->NameInformation.FileName,
1309 pShareDirEntry->OpenReferenceCount);
1311 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1314 // Setup the request to evaluate the entry
1317 ntStatus = AFSEvaluateRootEntry( pShareDirEntry,
1320 if( !NT_SUCCESS( ntStatus))
1323 try_return( ntStatus);
1326 AFSAcquireShared( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1330 // Enumerate the content
1333 pDirEntry = pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
1335 ulIndex = ConnectCB->CurrentIndex;
1337 while( pDirEntry != NULL)
1345 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1350 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1351 pDirEntry->NameInformation.FileName.Length)
1357 ConnectCB->LocalName = L'\0';
1359 ConnectCB->RemoteNameLength = pDirEntry->NameInformation.FileName.Length;
1361 RtlCopyMemory( ConnectCB->RemoteName,
1362 pDirEntry->NameInformation.FileName.Buffer,
1363 pDirEntry->NameInformation.FileName.Length);
1365 ConnectCB->Type = RESOURCETYPE_DISK;
1367 ConnectCB->Scope = RESOURCE_CONNECTED;
1369 if( BooleanFlagOn( pDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1372 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1377 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_FILE;
1380 ConnectCB->Usage = 0;
1382 ConnectCB->CommentLength = 0;
1384 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1385 pDirEntry->NameInformation.FileName.Length;
1387 BufferLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1388 pDirEntry->NameInformation.FileName.Length;
1390 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
1391 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1392 ConnectCB->RemoteNameLength);
1394 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1397 InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
1399 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1400 AFS_TRACE_LEVEL_VERBOSE,
1401 "AFSEnumerateConnection Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1402 &pTargetDirEntry->NameInformation.FileName,
1405 pTargetDirEntry->OpenReferenceCount);
1407 *CopiedLength = ulCopiedLength;
1409 AFSReleaseResource( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1413 if( pShareDirEntry != NULL)
1415 InterlockedDecrement( &pShareDirEntry->OpenReferenceCount);
1423 AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
1424 IN ULONG BufferLength,
1425 IN OUT ULONG_PTR *ReturnOutputBufferLength)
1428 NTSTATUS ntStatus = STATUS_SUCCESS;
1429 AFSProviderConnectionCB *pConnection = NULL, *pBestMatch = NULL;
1430 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath, uniFullName, uniRemainingPathLocal;
1431 USHORT usNameLen = 0, usMaxNameLen = 0;
1432 BOOLEAN bEnumerationEntry = FALSE;
1433 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1438 uniServerName.Length = 0;
1439 uniServerName.MaximumLength = 0;
1440 uniServerName.Buffer = NULL;
1442 uniShareName.Length = 0;
1443 uniShareName.MaximumLength = 0;
1444 uniShareName.Buffer = NULL;
1446 uniRemainingPathLocal.Length = 0;
1447 uniRemainingPathLocal.MaximumLength = 0;
1448 uniRemainingPathLocal.Buffer = NULL;
1450 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
1451 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
1452 uniRemoteName.Buffer = (WCHAR *)ConnectCB->RemoteName;
1454 if( ConnectCB->LocalName != L'\0')
1457 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1458 AFS_TRACE_LEVEL_VERBOSE,
1459 "AFSGetConnectionInfo remote name %wZ Local %C authentication id %I64X\n",
1461 ConnectCB->LocalName,
1462 ConnectCB->AuthenticationId.QuadPart);
1467 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1468 AFS_TRACE_LEVEL_VERBOSE,
1469 "AFSGetConnectionInfo remote name %wZ Local (NULL) authentication id %I64X\n",
1471 ConnectCB->AuthenticationId.QuadPart);
1474 if( AFSGlobalRoot == NULL)
1477 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1478 AFS_TRACE_LEVEL_ERROR,
1479 "AFSGetConnectionInfo Global root not yet initialized\n");
1481 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1484 uniFullName = uniRemoteName;
1486 if( uniRemoteName.Buffer[ 0] == L'\\' &&
1487 uniRemoteName.Buffer[ 1] == L'\\')
1490 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
1492 uniRemoteName.Length -= sizeof( WCHAR);
1495 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
1498 uniRemoteName.Length -= sizeof( WCHAR);
1500 uniFullName.Length -= sizeof( WCHAR);
1503 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1504 AFS_TRACE_LEVEL_VERBOSE,
1505 "AFSGetConnectionInfo Processing name %wZ\n", &uniFullName);
1507 FsRtlDissectName( uniRemoteName,
1511 uniRemoteName = uniRemainingPath;
1513 if( uniRemoteName.Length > 0)
1516 FsRtlDissectName( uniRemoteName,
1521 if( RtlCompareUnicodeString( &uniServerName,
1526 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1529 if ( uniRemainingPath.Length > 0 )
1533 // Add back in the leading \ since it was stripped off above
1536 uniRemainingPath.Length += sizeof( WCHAR);
1537 if( uniRemainingPath.Length > uniRemainingPath.MaximumLength)
1539 uniRemainingPath.MaximumLength += sizeof( WCHAR);
1542 uniRemainingPath.Buffer--;
1544 uniRemainingPathLocal.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1545 uniRemainingPath.Length,
1546 AFS_NETWORK_PROVIDER_5_TAG);
1548 if( uniRemainingPathLocal.Buffer == NULL)
1551 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1552 AFS_TRACE_LEVEL_VERBOSE,
1553 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n");
1555 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1558 uniRemainingPathLocal.MaximumLength = uniRemainingPath.Length;
1559 uniRemainingPathLocal.Length = uniRemainingPath.Length;
1561 RtlCopyMemory( uniRemainingPathLocal.Buffer,
1562 uniRemainingPath.Buffer,
1563 uniRemainingPath.Length);
1566 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1567 AFS_TRACE_LEVEL_VERBOSE,
1568 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %08lX SHARED %08lX\n",
1569 &pRDRDevExt->Specific.RDR.ProviderListLock,
1570 PsGetCurrentThread());
1572 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1576 // If this is the server then return information about the
1580 if( uniShareName.Length == 0 &&
1581 RtlCompareUnicodeString( &uniServerName,
1586 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
1592 // See if we can locate it on our connection list
1595 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1597 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1598 AFS_TRACE_LEVEL_VERBOSE,
1599 "AFSGetConnectionInfo Searching for full name %wZ\n", &uniFullName);
1601 while( pConnection != NULL)
1604 if( usMaxNameLen < pConnection->RemoteName.Length &&
1605 pConnection->RemoteName.Length <= uniFullName.Length)
1608 usNameLen = uniFullName.Length;
1610 uniFullName.Length = pConnection->RemoteName.Length;
1612 if( pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
1613 RtlCompareUnicodeString( &uniFullName,
1614 &pConnection->RemoteName,
1618 usMaxNameLen = pConnection->RemoteName.Length;
1620 pBestMatch = pConnection;
1622 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1623 AFS_TRACE_LEVEL_VERBOSE,
1624 "AFSGetConnectionInfo Found match for %wZ\n", &pConnection->RemoteName);
1627 uniFullName.Length = usNameLen;
1630 pConnection = pConnection->fLink;
1633 pConnection = pBestMatch;
1635 if( pConnection != NULL)
1638 bEnumerationEntry = TRUE;
1640 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1641 AFS_TRACE_LEVEL_VERBOSE,
1642 "AFSGetConnectionInfo Using best match for %wZ\n", &pConnection->RemoteName);
1645 if( pConnection == NULL)
1649 // Locate the entry for the share
1652 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1656 if( pConnection == NULL)
1658 UNICODE_STRING uniFullName;
1659 AFSDirEnumEntry *pDirEnumEntry = NULL;
1661 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1662 AFS_TRACE_LEVEL_VERBOSE,
1663 "AFSGetConnectionInfo No connection for full name %wZ\n", &uniFullName);
1666 // Drop the lock, we will pick it up again later
1669 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1672 // OK, ask the CM about this component name
1675 ntStatus = AFSEvaluateTargetByName( NULL,
1676 &AFSGlobalRoot->ObjectInformation,
1680 if( !NT_SUCCESS( ntStatus))
1683 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1684 AFS_TRACE_LEVEL_VERBOSE,
1685 "AFSGetConnectionInfo Evaluation Failed share name %wZ\n",
1688 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1696 AFSExFreePool( pDirEnumEntry);
1699 // The share name is valid
1700 // Allocate a new node and add it to our list
1702 uniFullName.MaximumLength = PAGE_SIZE;
1703 uniFullName.Length = 0;
1705 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1706 uniFullName.MaximumLength,
1707 AFS_NETWORK_PROVIDER_6_TAG);
1709 if( uniFullName.Buffer == NULL)
1712 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1713 AFS_TRACE_LEVEL_VERBOSE,
1714 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n");
1716 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1719 uniFullName.Buffer[ 0] = L'\\';
1720 uniFullName.Buffer[ 1] = L'\\';
1722 uniFullName.Length = 2 * sizeof( WCHAR);
1724 RtlCopyMemory( &uniFullName.Buffer[ 2],
1725 AFSServerName.Buffer,
1726 AFSServerName.Length);
1728 uniFullName.Length += AFSServerName.Length;
1730 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
1732 uniFullName.Length += sizeof( WCHAR);
1734 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
1735 uniShareName.Buffer,
1736 uniShareName.Length);
1738 uniFullName.Length += uniShareName.Length;
1740 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1743 ntStatus = AFSAddConnectionEx( &uniFullName,
1744 RESOURCEDISPLAYTYPE_SHARE,
1747 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1749 AFSExFreePool( uniFullName.Buffer);
1751 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1752 AFS_TRACE_LEVEL_VERBOSE,
1753 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %08lX SHARED %08lX\n",
1754 &pRDRDevExt->Specific.RDR.ProviderListLock,
1755 PsGetCurrentThread());
1757 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1760 if ( NT_SUCCESS( ntStatus) )
1763 // Once again, locate the entry for the share we just created
1766 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1771 if( pConnection == NULL)
1774 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1775 AFS_TRACE_LEVEL_ERROR,
1776 "AFSGetConnectionInfo Failed to locate entry for full name %wZ\n", &uniFullName);
1778 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1780 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1784 // Fill in the returned connection info block
1787 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1788 pConnection->RemoteName.Length +
1789 pConnection->Comment.Length +
1790 uniRemainingPath.Length)
1793 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1794 AFS_TRACE_LEVEL_VERBOSE,
1795 "AFSGetConnectionInfo Buffer too small for full name %wZ\n",
1798 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1800 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
1803 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1804 AFS_TRACE_LEVEL_VERBOSE,
1805 "AFSGetConnectionInfo Returning entry Scope %08lX partial name %wZ full name %wZ\n",
1806 pConnection->Scope, &pConnection->RemoteName, &uniFullName);
1808 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
1810 if( !bEnumerationEntry)
1813 RtlCopyMemory( ConnectCB->RemoteName,
1815 pConnection->RemoteName.Length);
1820 RtlCopyMemory( ConnectCB->RemoteName,
1821 pConnection->RemoteName.Buffer,
1822 pConnection->RemoteName.Length);
1825 ConnectCB->LocalName = pConnection->LocalName;
1827 ConnectCB->Type = pConnection->Type;
1829 ConnectCB->Scope = pConnection->Scope;
1831 ConnectCB->DisplayType = pConnection->DisplayType;
1833 ConnectCB->Usage = pConnection->Usage;
1835 ConnectCB->CommentLength = pConnection->Comment.Length;
1837 ConnectCB->RemainingPathLength = uniRemainingPathLocal.Length;
1839 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1840 AFS_TRACE_LEVEL_VERBOSE,
1841 "AFSGetConnectionInfo Returning lengths: remote %u comment %u remaining %u\n",
1842 ConnectCB->RemoteNameLength,
1843 ConnectCB->CommentLength,
1844 ConnectCB->RemainingPathLength);
1846 if( ConnectCB->CommentLength > 0)
1849 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1850 ConnectCB->RemoteNameLength);
1852 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
1853 pConnection->Comment.Buffer,
1854 ConnectCB->CommentLength);
1857 if ( ConnectCB->RemainingPathLength > 0 )
1860 ConnectCB->RemainingPathOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1861 ConnectCB->RemoteNameLength +
1862 ConnectCB->CommentLength);
1864 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->RemainingPathOffset),
1865 uniRemainingPathLocal.Buffer,
1866 uniRemainingPathLocal.Length);
1869 *ReturnOutputBufferLength = FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1870 ConnectCB->RemoteNameLength +
1871 ConnectCB->CommentLength +
1872 ConnectCB->RemainingPathLength;
1874 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1878 if ( uniRemainingPathLocal.Buffer )
1881 AFSExFreePool( uniRemainingPathLocal.Buffer);
1889 AFSIsDriveMapped( IN WCHAR DriveMapping)
1892 BOOLEAN bDriveMapped = FALSE;
1893 AFSProviderConnectionCB *pConnection = NULL;
1894 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1899 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1902 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1904 while( pConnection != NULL)
1907 if( pConnection->LocalName != L'\0' &&
1908 RtlUpcaseUnicodeChar( pConnection->LocalName) == RtlUpcaseUnicodeChar( DriveMapping))
1911 bDriveMapped = TRUE;
1916 pConnection = pConnection->fLink;
1919 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1922 return bDriveMapped;