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));
128 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
129 AFS_TRACE_LEVEL_VERBOSE,
130 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local (NULL) authentication id %I64X\n",
132 ConnectCB->AuthenticationId.QuadPart));
135 *ResultStatus = WN_ALREADY_CONNECTED;
137 *ReturnOutputBufferLength = sizeof( ULONG);
139 try_return( ntStatus);
143 // Validate the remote name
146 if( uniRemoteName.Length > 2 * sizeof( WCHAR) &&
147 uniRemoteName.Buffer[ 0] == L'\\' &&
148 uniRemoteName.Buffer[ 1] == L'\\')
151 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 2];
153 uniRemoteName.Length -= (2 * sizeof( WCHAR));
156 if( uniRemoteName.Length >= AFSServerName.Length)
159 USHORT usLength = uniRemoteName.Length;
161 if (uniRemoteName.Buffer[AFSServerName.Length/sizeof( WCHAR)] != L'\\')
164 if( ConnectCB->LocalName != L'\0')
167 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
168 AFS_TRACE_LEVEL_VERBOSE,
169 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local %C authentication id %I64X\n",
171 ConnectCB->LocalName,
172 ConnectCB->AuthenticationId.QuadPart));
177 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
178 AFS_TRACE_LEVEL_VERBOSE,
179 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local (NULL) authentication id %I64X\n",
181 ConnectCB->AuthenticationId.QuadPart));
184 *ResultStatus = WN_BAD_NETNAME;
186 *ReturnOutputBufferLength = sizeof( ULONG);
188 try_return( ntStatus = STATUS_SUCCESS);
191 uniRemoteName.Length = AFSServerName.Length;
193 if( RtlCompareUnicodeString( &AFSServerName,
198 if( ConnectCB->LocalName != L'\0')
201 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
202 AFS_TRACE_LEVEL_VERBOSE,
203 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local %C authentication id %I64X\n",
205 ConnectCB->LocalName,
206 ConnectCB->AuthenticationId.QuadPart));
211 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
212 AFS_TRACE_LEVEL_VERBOSE,
213 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local (NULL) authentication id %I64X\n",
215 ConnectCB->AuthenticationId.QuadPart));
218 *ResultStatus = WN_BAD_NETNAME;
220 *ReturnOutputBufferLength = sizeof( ULONG);
222 try_return( ntStatus = STATUS_SUCCESS);
225 uniRemoteName.Length = usLength;
230 if( ConnectCB->LocalName != L'\0')
233 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
234 AFS_TRACE_LEVEL_VERBOSE,
235 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local %C authentication id %I64X\n",
237 ConnectCB->LocalName,
238 ConnectCB->AuthenticationId.QuadPart));
243 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
244 AFS_TRACE_LEVEL_VERBOSE,
245 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local (NULL) authentication id %I64X\n",
247 ConnectCB->AuthenticationId.QuadPart));
250 *ResultStatus = WN_BAD_NETNAME;
252 *ReturnOutputBufferLength = sizeof( ULONG);
254 try_return( ntStatus = STATUS_SUCCESS);
257 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
258 uniRemoteName.MaximumLength = uniRemoteName.Length;
260 uniRemoteName.Buffer = ConnectCB->RemoteName;
263 // Strip off any trailing slashes
266 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
269 uniRemoteName.Length -= sizeof( WCHAR);
273 // Allocate a new node and add it to our list
276 pConnection = (AFSProviderConnectionCB *)AFSExAllocatePoolWithTag( PagedPool,
277 sizeof( AFSProviderConnectionCB) +
278 uniRemoteName.Length,
281 if( pConnection == NULL)
284 *ResultStatus = WN_OUT_OF_MEMORY;
286 *ReturnOutputBufferLength = sizeof( ULONG);
288 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
291 RtlZeroMemory( pConnection,
292 sizeof( AFSProviderConnectionCB) + uniRemoteName.Length);
294 pConnection->LocalName = ConnectCB->LocalName;
296 pConnection->RemoteName.Length = uniRemoteName.Length;
297 pConnection->RemoteName.MaximumLength = pConnection->RemoteName.Length;
299 pConnection->RemoteName.Buffer = (WCHAR *)((char *)pConnection + sizeof( AFSProviderConnectionCB));
301 RtlCopyMemory( pConnection->RemoteName.Buffer,
302 uniRemoteName.Buffer,
303 pConnection->RemoteName.Length);
305 pConnection->Type = ConnectCB->Type;
307 pConnection->AuthenticationId = ConnectCB->AuthenticationId;
309 if( ConnectCB->LocalName != L'\0')
312 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
313 AFS_TRACE_LEVEL_VERBOSE,
314 "AFSAddConnection Adding connection remote name %wZ Local %C authentication id %I64X\n",
316 ConnectCB->LocalName,
317 ConnectCB->AuthenticationId.QuadPart));
322 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
323 AFS_TRACE_LEVEL_VERBOSE,
324 "AFSAddConnection Adding connection remote name %wZ Local (NULL) authentication id %I64X\n",
326 ConnectCB->AuthenticationId.QuadPart));
330 // Point to the component portion of the name
333 pConnection->ComponentName.Length = 0;
334 pConnection->ComponentName.MaximumLength = 0;
336 pConnection->ComponentName.Buffer = &pConnection->RemoteName.Buffer[ (pConnection->RemoteName.Length/sizeof( WCHAR)) - 1];
338 while( pConnection->ComponentName.Length <= pConnection->RemoteName.Length)
341 if( pConnection->ComponentName.Buffer[ 0] == L'\\')
344 pConnection->ComponentName.Buffer++;
349 pConnection->ComponentName.Length += sizeof( WCHAR);
350 pConnection->ComponentName.MaximumLength += sizeof( WCHAR);
352 pConnection->ComponentName.Buffer--;
356 // Go initialize the information about the connection
359 AFSInitializeConnectionInfo( pConnection,
363 // Insert the entry into our list
366 if( pRDRDevExt->Specific.RDR.ProviderConnectionList == NULL)
369 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection;
375 // Get the end of the list
378 pLastConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
380 while( pLastConnection->fLink != NULL)
383 pLastConnection = pLastConnection->fLink;
386 pLastConnection->fLink = pConnection;
389 *ResultStatus = WN_SUCCESS;
391 *ReturnOutputBufferLength = sizeof( ULONG);
395 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
403 AFSCancelConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
404 IN OUT AFSCancelConnectionResultCB *ConnectionResult,
405 IN OUT ULONG_PTR *ReturnOutputBufferLength)
408 NTSTATUS ntStatus = STATUS_SUCCESS;
409 AFSProviderConnectionCB *pConnection = NULL, *pLastConnection = NULL;
410 UNICODE_STRING uniRemoteName;
411 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
416 ConnectionResult->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
418 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
419 AFS_TRACE_LEVEL_VERBOSE,
420 "AFSCancelConnection Acquiring AFSProviderListLock lock %p EXCL %08lX\n",
421 &pRDRDevExt->Specific.RDR.ProviderListLock,
422 PsGetCurrentThread()));
424 if( ConnectCB->AuthenticationId.QuadPart == 0)
427 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
429 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
430 AFS_TRACE_LEVEL_VERBOSE,
431 "AFSCancelConnection Retrieved authentication id %I64X\n",
432 ConnectCB->AuthenticationId.QuadPart));
435 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
439 // Look for the connection
442 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
443 uniRemoteName.MaximumLength = uniRemoteName.Length;
445 uniRemoteName.Buffer = NULL;
447 if( uniRemoteName.Length > 0)
450 uniRemoteName.Buffer = ConnectCB->RemoteName;
453 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
455 while( pConnection != NULL)
458 if( ( ConnectCB->LocalName != L'\0' &&
459 pConnection->LocalName == ConnectCB->LocalName)
461 ( ConnectCB->LocalName == L'\0' &&
462 pConnection->LocalName == L'\0' &&
463 RtlCompareUnicodeString( &uniRemoteName,
464 &pConnection->RemoteName,
468 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
469 AFS_TRACE_LEVEL_VERBOSE,
470 "AFSCancelConnection Checking remote name %wZ to stored %wZ authentication id %I64X - %I64X\n",
472 &pConnection->RemoteName,
473 ConnectCB->AuthenticationId.QuadPart,
474 pConnection->AuthenticationId.QuadPart));
476 if( ConnectCB->AuthenticationId.QuadPart == pConnection->AuthenticationId.QuadPart &&
477 ( ConnectCB->LocalName == L'\0' ||
478 RtlCompareUnicodeString( &uniRemoteName,
479 &pConnection->RemoteName,
487 pLastConnection = pConnection;
489 pConnection = pConnection->fLink;
492 if( pConnection == NULL)
495 ConnectionResult->Status = WN_NOT_CONNECTED;
497 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
499 try_return( ntStatus);
502 if( pLastConnection == NULL)
505 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection->fLink;
510 pLastConnection->fLink = pConnection->fLink;
513 if( pConnection->Comment.Buffer != NULL)
516 AFSExFreePoolWithTag( pConnection->Comment.Buffer, 0);
519 ConnectionResult->LocalName = pConnection->LocalName;
521 AFSExFreePoolWithTag( pConnection, AFS_PROVIDER_CB);
523 ConnectionResult->Status = WN_SUCCESS;
525 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
529 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
536 AFSGetConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
537 IN OUT WCHAR *RemoteName,
538 IN ULONG RemoteNameBufferLength,
539 IN OUT ULONG_PTR *ReturnOutputBufferLength)
542 NTSTATUS ntStatus = STATUS_SUCCESS;
543 AFSProviderConnectionCB *pConnection = NULL;
544 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
549 if( ConnectCB->LocalName != L'\0')
552 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
553 AFS_TRACE_LEVEL_VERBOSE,
554 "AFSGetConnection Local %C authentication id %I64X\n",
555 ConnectCB->LocalName,
556 ConnectCB->AuthenticationId.QuadPart));
561 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
562 AFS_TRACE_LEVEL_VERBOSE,
563 "AFSGetConnection Local (NULL) authentication id %I64X\n",
564 ConnectCB->AuthenticationId.QuadPart));
567 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
568 AFS_TRACE_LEVEL_VERBOSE,
569 "AFSGetConnection Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
570 &pRDRDevExt->Specific.RDR.ProviderListLock,
571 PsGetCurrentThread()));
573 if( ConnectCB->AuthenticationId.QuadPart == 0)
576 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
578 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
579 AFS_TRACE_LEVEL_VERBOSE,
580 "AFSGetConnection Retrieved authentication id %I64X\n",
581 ConnectCB->AuthenticationId.QuadPart));
584 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
588 // Look for the connection
591 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
593 while( pConnection != NULL)
596 if( pConnection->LocalName != L'\0')
599 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
600 AFS_TRACE_LEVEL_VERBOSE,
601 "AFSGetConnection Comparing passed in %C to %C authentication id %I64X - %I64X\n",
602 ConnectCB->LocalName,
603 pConnection->LocalName,
604 ConnectCB->AuthenticationId.QuadPart,
605 pConnection->AuthenticationId.QuadPart));
610 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
611 AFS_TRACE_LEVEL_VERBOSE,
612 "AFSGetConnection Comparing passed in %C to (NULL) authentication id %I64X - %I64X\n",
613 ConnectCB->LocalName,
614 ConnectCB->AuthenticationId.QuadPart,
615 pConnection->AuthenticationId.QuadPart));
618 if( pConnection->LocalName == ConnectCB->LocalName &&
619 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart)
625 pConnection = pConnection->fLink;
628 if( pConnection == NULL)
631 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
632 AFS_TRACE_LEVEL_VERBOSE,
633 "AFSGetConnection INVALID_PARAMETER\n"));
635 try_return( ntStatus = STATUS_INVALID_PARAMETER);
638 if( RemoteNameBufferLength < pConnection->RemoteName.Length)
641 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
642 AFS_TRACE_LEVEL_VERBOSE,
643 "AFSGetConnection INSUFFICIENT_RESOURCES\n"));
645 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
648 RtlCopyMemory( RemoteName,
649 pConnection->RemoteName.Buffer,
650 pConnection->RemoteName.Length);
652 *ReturnOutputBufferLength = pConnection->RemoteName.Length;
656 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
663 AFSListConnections( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
664 IN ULONG ConnectionBufferLength,
665 IN OUT ULONG_PTR *ReturnOutputBufferLength)
668 NTSTATUS ntStatus = STATUS_SUCCESS;
669 AFSProviderConnectionCB *pConnection = NULL, *pRootConnection = NULL;
670 ULONG ulCopiedLength = 0, ulRemainingLength = ConnectionBufferLength;
671 ULONG ulScope, ulType;
672 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath;
673 BOOLEAN bGlobalEnumeration = FALSE;
675 LARGE_INTEGER liAuthenticationID = {0,0};
676 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
682 // Save off some data before moving on
685 ulScope = ConnectCB->Scope;
687 ulType = ConnectCB->Type;
689 if( ConnectCB->AuthenticationId.QuadPart == 0)
692 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
694 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
695 AFS_TRACE_LEVEL_VERBOSE,
696 "AFSListConnections Retrieved authentication id %I64X\n",
697 ConnectCB->AuthenticationId.QuadPart));
700 liAuthenticationID.QuadPart = ConnectCB->AuthenticationId.QuadPart;
702 uniRemoteName.Length = 0;
703 uniRemoteName.MaximumLength = 0;
704 uniRemoteName.Buffer = NULL;
706 uniServerName.Length = 0;
707 uniServerName.MaximumLength = 0;
708 uniServerName.Buffer = NULL;
710 uniShareName.Length = 0;
711 uniShareName.MaximumLength = 0;
712 uniShareName.Buffer = NULL;
714 if( ConnectCB->RemoteNameLength > 0)
717 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
718 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
720 uniRemoteName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
721 uniRemoteName.MaximumLength,
722 AFS_NETWORK_PROVIDER_1_TAG);
724 if( uniRemoteName.Buffer == NULL)
727 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
730 RtlCopyMemory( uniRemoteName.Buffer,
731 ConnectCB->RemoteName,
732 uniRemoteName.Length);
734 if( uniRemoteName.Buffer[ 0] == L'\\' &&
735 uniRemoteName.Buffer[ 1] == L'\\')
738 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
740 uniRemoteName.Length -= sizeof( WCHAR);
743 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
746 uniRemoteName.Length -= sizeof( WCHAR);
749 FsRtlDissectName( uniRemoteName,
753 uniRemoteName = uniRemainingPath;
755 if( uniRemoteName.Length > 0)
758 FsRtlDissectName( uniRemoteName,
764 // If this is an enumeration of the global share name then
765 // adjust it to be the server name itself
768 if( uniShareName.Length == 0 ||
769 RtlCompareUnicodeString( &uniShareName,
774 bGlobalEnumeration = TRUE;
778 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
779 AFS_TRACE_LEVEL_VERBOSE,
780 "AFSListConnections Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
781 &pRDRDevExt->Specific.RDR.ProviderListLock,
782 PsGetCurrentThread()));
784 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
788 // If this is a globalnet enumeration with no name then enumerate the server list
791 if( ulScope == RESOURCE_GLOBALNET)
794 if( uniServerName.Buffer == NULL)
797 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
803 // Go locate the root entry for the name passed in
806 if( bGlobalEnumeration)
809 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
812 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
814 try_return( ntStatus);
817 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
822 pRootConnection = AFSLocateEnumRootEntry( &uniShareName);
824 if( pRootConnection == NULL)
827 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
829 try_return( ntStatus);
833 // Need to handle these enumerations from the directory listing
836 ntStatus = AFSEnumerateConnection( ConnectCB,
838 ConnectionBufferLength,
846 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
849 ulIndex = ConnectCB->CurrentIndex;
851 while( pConnection != NULL)
854 if( bGlobalEnumeration &&
855 BooleanFlagOn( pConnection->Flags, AFS_CONNECTION_FLAG_GLOBAL_SHARE))
858 pConnection = pConnection->fLink;
863 if( ulScope != RESOURCE_GLOBALNET &&
864 !BooleanFlagOn( pConnection->Usage, RESOURCEUSAGE_ATTACHED))
867 pConnection = pConnection->fLink;
872 if( pConnection->LocalName != L'\0')
875 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
876 AFS_TRACE_LEVEL_VERBOSE,
877 "AFSListConnections Processing entry %wZ %C authentication id %I64X - %I64X Scope %08lX\n",
878 &pConnection->RemoteName,
879 pConnection->LocalName,
880 liAuthenticationID.QuadPart,
881 pConnection->AuthenticationId.QuadPart,
882 pConnection->Scope));
887 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
888 AFS_TRACE_LEVEL_VERBOSE,
889 "AFSListConnections Processing entry %wZ NULL LocalName authentication id %I64X - %I64X Scope %08lX\n",
890 &pConnection->RemoteName,
891 liAuthenticationID.QuadPart,
892 pConnection->AuthenticationId.QuadPart,
893 pConnection->Scope));
896 if( ulScope != RESOURCE_GLOBALNET &&
897 pConnection->AuthenticationId.QuadPart != liAuthenticationID.QuadPart)
900 pConnection = pConnection->fLink;
910 pConnection = pConnection->fLink;
915 if( ulRemainingLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
916 pConnection->RemoteName.Length +
917 pConnection->Comment.Length)
923 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
925 RtlCopyMemory( ConnectCB->RemoteName,
926 pConnection->RemoteName.Buffer,
927 pConnection->RemoteName.Length);
929 ConnectCB->LocalName = pConnection->LocalName;
931 ConnectCB->Type = pConnection->Type;
933 ConnectCB->Scope = pConnection->Scope;
935 if( !bGlobalEnumeration)
938 ConnectCB->Scope = RESOURCE_CONNECTED;
941 ConnectCB->DisplayType = pConnection->DisplayType;
943 ConnectCB->Usage = pConnection->Usage;
945 ConnectCB->CommentLength = pConnection->Comment.Length;
947 if( pConnection->Comment.Length > 0)
950 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
951 ConnectCB->RemoteNameLength);
953 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
954 pConnection->Comment.Buffer,
955 ConnectCB->CommentLength);
958 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
959 ConnectCB->RemoteNameLength +
960 ConnectCB->CommentLength;
962 ulRemainingLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
963 ConnectCB->RemoteNameLength +
964 ConnectCB->CommentLength;
966 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
967 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
968 ConnectCB->RemoteNameLength +
969 ConnectCB->CommentLength);
971 pConnection = pConnection->fLink;
974 if( NT_SUCCESS( ntStatus))
977 *ReturnOutputBufferLength = ulCopiedLength;
980 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
984 if( uniRemoteName.Buffer != NULL)
987 AFSExFreePoolWithTag( uniRemoteName.Buffer, 0);
995 AFSInitializeConnectionInfo( IN AFSProviderConnectionCB *Connection,
996 IN ULONG DisplayType)
999 NTSTATUS ntStatus = STATUS_SUCCESS;
1000 UNICODE_STRING uniName, uniComponentName, uniRemainingName;
1005 uniName = Connection->RemoteName;
1008 // Strip of the double leading slash if there is one
1011 if( uniName.Buffer[ 0] == L'\\' &&
1012 uniName.Buffer[ 1] == L'\\')
1015 uniName.Buffer = &uniName.Buffer[ 1];
1017 uniName.Length -= sizeof( WCHAR);
1021 FsRtlDissectName( uniName,
1026 // Initialize the information for the connection
1027 // First, if this is the server only then mark it accordingly
1030 if( uniRemainingName.Length == 0 ||
1031 DisplayType == RESOURCEDISPLAYTYPE_SERVER)
1034 Connection->Type = RESOURCETYPE_DISK;
1036 Connection->Scope = 0;
1038 Connection->DisplayType = RESOURCEDISPLAYTYPE_SERVER;
1040 Connection->Usage = RESOURCEUSAGE_CONTAINER;
1042 Connection->Comment.Length = 20;
1043 Connection->Comment.MaximumLength = 22;
1045 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1046 Connection->Comment.MaximumLength,
1047 AFS_NETWORK_PROVIDER_2_TAG);
1049 if( Connection->Comment.Buffer != NULL)
1052 RtlZeroMemory( Connection->Comment.Buffer,
1053 Connection->Comment.MaximumLength);
1055 RtlCopyMemory( Connection->Comment.Buffer,
1062 Connection->Comment.Length = 0;
1063 Connection->Comment.MaximumLength = 0;
1066 try_return( ntStatus);
1069 uniName = uniRemainingName;
1071 FsRtlDissectName( uniName,
1075 if( uniRemainingName.Length == 0 ||
1076 uniRemainingName.Buffer == NULL ||
1077 DisplayType == RESOURCEDISPLAYTYPE_SHARE)
1080 Connection->Type = RESOURCETYPE_DISK;
1082 Connection->DisplayType = RESOURCEDISPLAYTYPE_SHARE;
1084 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1086 if( Connection->LocalName != L'\0')
1089 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1091 Connection->Scope = RESOURCE_CONNECTED;
1096 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1098 Connection->Scope = RESOURCE_GLOBALNET;
1101 Connection->Comment.Length = 18;
1102 Connection->Comment.MaximumLength = 20;
1104 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1105 Connection->Comment.MaximumLength,
1106 AFS_NETWORK_PROVIDER_3_TAG);
1108 if( Connection->Comment.Buffer != NULL)
1111 RtlZeroMemory( Connection->Comment.Buffer,
1112 Connection->Comment.MaximumLength);
1114 RtlCopyMemory( Connection->Comment.Buffer,
1121 Connection->Comment.Length = 0;
1122 Connection->Comment.MaximumLength = 0;
1125 try_return( ntStatus);
1129 // This is a sub directory within a share
1132 Connection->Type = RESOURCETYPE_DISK;
1134 Connection->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1136 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1138 if( Connection->LocalName != L'\0')
1141 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1146 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1149 Connection->Scope = RESOURCE_CONNECTED;
1151 Connection->Comment.Length = 26;
1152 Connection->Comment.MaximumLength = 28;
1154 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1155 Connection->Comment.MaximumLength,
1156 AFS_NETWORK_PROVIDER_4_TAG);
1158 if( Connection->Comment.Buffer != NULL)
1161 RtlZeroMemory( Connection->Comment.Buffer,
1162 Connection->Comment.MaximumLength);
1164 RtlCopyMemory( Connection->Comment.Buffer,
1171 Connection->Comment.Length = 0;
1172 Connection->Comment.MaximumLength = 0;
1183 AFSProviderConnectionCB *
1184 AFSLocateEnumRootEntry( IN UNICODE_STRING *RemoteName)
1187 AFSProviderConnectionCB *pConnection = NULL;
1188 UNICODE_STRING uniRemoteName = *RemoteName;
1189 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1194 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
1197 try_return( pConnection);
1200 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
1202 while( pConnection != NULL)
1205 if( RtlCompareUnicodeString( &uniRemoteName,
1206 &pConnection->ComponentName,
1213 pConnection = pConnection->fLink;
1225 AFSEnumerateConnection( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
1226 IN AFSProviderConnectionCB *RootConnection,
1227 IN ULONG BufferLength,
1228 OUT PULONG CopiedLength)
1231 NTSTATUS ntStatus = STATUS_SUCCESS;
1232 ULONG ulCRC = 0, ulCopiedLength = 0;
1233 AFSDirectoryCB *pShareDirEntry = NULL;
1234 AFSDirectoryCB *pDirEntry = NULL, *pTargetDirEntry = NULL;
1241 if( AFSGlobalRoot == NULL)
1244 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1245 AFS_TRACE_LEVEL_ERROR,
1246 "AFSEnumerateConnection Global root not yet initialized\n"));
1248 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1251 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1255 // Grab our tree lock shared
1258 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1259 AFS_TRACE_LEVEL_VERBOSE,
1260 "AFSEnumerateConnection Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p SHARED %08lX\n",
1261 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1262 PsGetCurrentThread()));
1264 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1268 // Locate the dir entry for this node
1271 ntStatus = AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1275 if( pShareDirEntry == NULL ||
1276 !NT_SUCCESS( ntStatus))
1280 // Perform a case insensitive search
1283 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1286 ntStatus = AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1290 if( pShareDirEntry == NULL ||
1291 !NT_SUCCESS( ntStatus))
1294 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1296 try_return( ntStatus);
1300 lCount = InterlockedIncrement( &pShareDirEntry->DirOpenReferenceCount);
1302 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1303 AFS_TRACE_LEVEL_VERBOSE,
1304 "AFSEnumerateConnection1 Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1305 &pShareDirEntry->NameInformation.FileName,
1310 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1313 // Setup the request to evaluate the entry
1314 // On success, pTargetDirEntry has the DirOpenReferenceCount held
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;
1398 // Release the DirOpenReferenceCount obtained from AFSEvaluateRootEntry
1401 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
1403 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1404 AFS_TRACE_LEVEL_VERBOSE,
1405 "AFSEnumerateConnection Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1406 &pTargetDirEntry->NameInformation.FileName,
1411 ASSERT( lCount >= 0);
1413 *CopiedLength = ulCopiedLength;
1415 AFSReleaseResource( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1419 if( pShareDirEntry != NULL)
1421 lCount = InterlockedDecrement( &pShareDirEntry->DirOpenReferenceCount);
1423 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1424 AFS_TRACE_LEVEL_VERBOSE,
1425 "AFSEnumerateConnection1 Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1426 &pShareDirEntry->NameInformation.FileName,
1431 ASSERT( lCount >= 0);
1439 AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
1440 IN ULONG BufferLength,
1441 IN OUT ULONG_PTR *ReturnOutputBufferLength)
1444 NTSTATUS ntStatus = STATUS_SUCCESS;
1445 AFSProviderConnectionCB *pConnection = NULL, *pBestMatch = NULL;
1446 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath, uniFullName, uniRemainingPathLocal;
1447 USHORT usNameLen = 0, usMaxNameLen = 0;
1448 BOOLEAN bEnumerationEntry = FALSE;
1449 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1454 uniServerName.Length = 0;
1455 uniServerName.MaximumLength = 0;
1456 uniServerName.Buffer = NULL;
1458 uniShareName.Length = 0;
1459 uniShareName.MaximumLength = 0;
1460 uniShareName.Buffer = NULL;
1462 uniRemainingPathLocal.Length = 0;
1463 uniRemainingPathLocal.MaximumLength = 0;
1464 uniRemainingPathLocal.Buffer = NULL;
1466 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
1467 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
1468 uniRemoteName.Buffer = (WCHAR *)ConnectCB->RemoteName;
1470 if( ConnectCB->LocalName != L'\0')
1473 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1474 AFS_TRACE_LEVEL_VERBOSE,
1475 "AFSGetConnectionInfo remote name %wZ Local %C authentication id %I64X\n",
1477 ConnectCB->LocalName,
1478 ConnectCB->AuthenticationId.QuadPart));
1483 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1484 AFS_TRACE_LEVEL_VERBOSE,
1485 "AFSGetConnectionInfo remote name %wZ Local (NULL) authentication id %I64X\n",
1487 ConnectCB->AuthenticationId.QuadPart));
1490 if( AFSGlobalRoot == NULL)
1493 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1494 AFS_TRACE_LEVEL_ERROR,
1495 "AFSGetConnectionInfo Global root not yet initialized\n"));
1497 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1500 uniFullName = uniRemoteName;
1502 if( uniRemoteName.Buffer[ 0] == L'\\' &&
1503 uniRemoteName.Buffer[ 1] == L'\\')
1506 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
1508 uniRemoteName.Length -= sizeof( WCHAR);
1511 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
1514 uniRemoteName.Length -= sizeof( WCHAR);
1516 uniFullName.Length -= sizeof( WCHAR);
1519 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1520 AFS_TRACE_LEVEL_VERBOSE,
1521 "AFSGetConnectionInfo Processing name %wZ\n",
1524 FsRtlDissectName( uniRemoteName,
1528 uniRemoteName = uniRemainingPath;
1530 if( uniRemoteName.Length > 0)
1533 FsRtlDissectName( uniRemoteName,
1538 if( RtlCompareUnicodeString( &uniServerName,
1543 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1546 if ( uniRemainingPath.Length > 0 )
1550 // Add back in the leading \ since it was stripped off above
1553 uniRemainingPath.Length += sizeof( WCHAR);
1554 if( uniRemainingPath.Length > uniRemainingPath.MaximumLength)
1556 uniRemainingPath.MaximumLength += sizeof( WCHAR);
1559 uniRemainingPath.Buffer--;
1561 uniRemainingPathLocal.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1562 uniRemainingPath.Length,
1563 AFS_NETWORK_PROVIDER_5_TAG);
1565 if( uniRemainingPathLocal.Buffer == NULL)
1568 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1569 AFS_TRACE_LEVEL_VERBOSE,
1570 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1572 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1575 uniRemainingPathLocal.MaximumLength = uniRemainingPath.Length;
1576 uniRemainingPathLocal.Length = uniRemainingPath.Length;
1578 RtlCopyMemory( uniRemainingPathLocal.Buffer,
1579 uniRemainingPath.Buffer,
1580 uniRemainingPath.Length);
1583 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1584 AFS_TRACE_LEVEL_VERBOSE,
1585 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1586 &pRDRDevExt->Specific.RDR.ProviderListLock,
1587 PsGetCurrentThread()));
1589 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1593 // If this is the server then return information about the
1597 if( uniShareName.Length == 0 &&
1598 RtlCompareUnicodeString( &uniServerName,
1603 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
1609 // See if we can locate it on our connection list
1612 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1614 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1615 AFS_TRACE_LEVEL_VERBOSE,
1616 "AFSGetConnectionInfo Searching for full name %wZ\n",
1619 while( pConnection != NULL)
1622 if( usMaxNameLen < pConnection->RemoteName.Length &&
1623 pConnection->RemoteName.Length <= uniFullName.Length)
1626 usNameLen = uniFullName.Length;
1628 uniFullName.Length = pConnection->RemoteName.Length;
1630 if( pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
1631 RtlCompareUnicodeString( &uniFullName,
1632 &pConnection->RemoteName,
1636 usMaxNameLen = pConnection->RemoteName.Length;
1638 pBestMatch = pConnection;
1640 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1641 AFS_TRACE_LEVEL_VERBOSE,
1642 "AFSGetConnectionInfo Found match for %wZ\n",
1643 &pConnection->RemoteName));
1646 uniFullName.Length = usNameLen;
1649 pConnection = pConnection->fLink;
1652 pConnection = pBestMatch;
1654 if( pConnection != NULL)
1657 bEnumerationEntry = TRUE;
1659 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1660 AFS_TRACE_LEVEL_VERBOSE,
1661 "AFSGetConnectionInfo Using best match for %wZ\n",
1662 &pConnection->RemoteName));
1665 if( pConnection == NULL)
1669 // Locate the entry for the share
1672 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1676 if( pConnection == NULL)
1678 UNICODE_STRING uniFullName;
1679 AFSDirEnumEntry *pDirEnumEntry = NULL;
1681 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1682 AFS_TRACE_LEVEL_VERBOSE,
1683 "AFSGetConnectionInfo No connection for full name %wZ\n",
1687 // Drop the lock, we will pick it up again later
1690 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1693 // OK, ask the CM about this component name
1696 ntStatus = AFSEvaluateTargetByName( NULL,
1697 &AFSGlobalRoot->ObjectInformation,
1702 if( !NT_SUCCESS( ntStatus))
1705 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1706 AFS_TRACE_LEVEL_VERBOSE,
1707 "AFSGetConnectionInfo Evaluation Failed share name %wZ\n",
1710 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1718 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_3_TAG);
1721 // The share name is valid
1722 // Allocate a new node and add it to our list
1724 uniFullName.MaximumLength = PAGE_SIZE;
1725 uniFullName.Length = 0;
1727 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1728 uniFullName.MaximumLength,
1729 AFS_NETWORK_PROVIDER_6_TAG);
1731 if( uniFullName.Buffer == NULL)
1734 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1735 AFS_TRACE_LEVEL_VERBOSE,
1736 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1738 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1741 uniFullName.Buffer[ 0] = L'\\';
1742 uniFullName.Buffer[ 1] = L'\\';
1744 uniFullName.Length = 2 * sizeof( WCHAR);
1746 RtlCopyMemory( &uniFullName.Buffer[ 2],
1747 AFSServerName.Buffer,
1748 AFSServerName.Length);
1750 uniFullName.Length += AFSServerName.Length;
1752 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
1754 uniFullName.Length += sizeof( WCHAR);
1756 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
1757 uniShareName.Buffer,
1758 uniShareName.Length);
1760 uniFullName.Length += uniShareName.Length;
1762 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1765 ntStatus = AFSAddConnectionEx( &uniFullName,
1766 RESOURCEDISPLAYTYPE_SHARE,
1769 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1771 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
1773 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1774 AFS_TRACE_LEVEL_VERBOSE,
1775 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1776 &pRDRDevExt->Specific.RDR.ProviderListLock,
1777 PsGetCurrentThread()));
1779 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1782 if ( NT_SUCCESS( ntStatus) )
1785 // Once again, locate the entry for the share we just created
1788 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1793 if( pConnection == NULL)
1796 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1797 AFS_TRACE_LEVEL_ERROR,
1798 "AFSGetConnectionInfo Failed to locate entry for full name %wZ\n",
1801 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1803 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1807 // Fill in the returned connection info block
1810 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1811 pConnection->RemoteName.Length +
1812 pConnection->Comment.Length +
1813 uniRemainingPath.Length)
1816 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1817 AFS_TRACE_LEVEL_VERBOSE,
1818 "AFSGetConnectionInfo Buffer too small for full name %wZ\n",
1821 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1823 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
1826 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1827 AFS_TRACE_LEVEL_VERBOSE,
1828 "AFSGetConnectionInfo Returning entry Scope %08lX partial name %wZ full name %wZ\n",
1829 pConnection->Scope, &pConnection->RemoteName, &uniFullName));
1831 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
1833 if( !bEnumerationEntry)
1836 RtlCopyMemory( ConnectCB->RemoteName,
1838 pConnection->RemoteName.Length);
1843 RtlCopyMemory( ConnectCB->RemoteName,
1844 pConnection->RemoteName.Buffer,
1845 pConnection->RemoteName.Length);
1848 ConnectCB->LocalName = pConnection->LocalName;
1850 ConnectCB->Type = pConnection->Type;
1852 ConnectCB->Scope = pConnection->Scope;
1854 ConnectCB->DisplayType = pConnection->DisplayType;
1856 ConnectCB->Usage = pConnection->Usage;
1858 ConnectCB->CommentLength = pConnection->Comment.Length;
1860 ConnectCB->RemainingPathLength = uniRemainingPathLocal.Length;
1862 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1863 AFS_TRACE_LEVEL_VERBOSE,
1864 "AFSGetConnectionInfo Returning lengths: remote %u comment %u remaining %u\n",
1865 ConnectCB->RemoteNameLength,
1866 ConnectCB->CommentLength,
1867 ConnectCB->RemainingPathLength));
1869 if( ConnectCB->CommentLength > 0)
1872 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1873 ConnectCB->RemoteNameLength);
1875 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
1876 pConnection->Comment.Buffer,
1877 ConnectCB->CommentLength);
1880 if ( ConnectCB->RemainingPathLength > 0 )
1883 ConnectCB->RemainingPathOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1884 ConnectCB->RemoteNameLength +
1885 ConnectCB->CommentLength);
1887 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->RemainingPathOffset),
1888 uniRemainingPathLocal.Buffer,
1889 uniRemainingPathLocal.Length);
1892 *ReturnOutputBufferLength = FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1893 ConnectCB->RemoteNameLength +
1894 ConnectCB->CommentLength +
1895 ConnectCB->RemainingPathLength;
1897 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1901 if ( uniRemainingPathLocal.Buffer )
1904 AFSExFreePoolWithTag( uniRemainingPathLocal.Buffer, 0);
1912 AFSIsDriveMapped( IN WCHAR DriveMapping)
1915 BOOLEAN bDriveMapped = FALSE;
1916 AFSProviderConnectionCB *pConnection = NULL;
1917 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1922 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1925 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1927 while( pConnection != NULL)
1930 if( pConnection->LocalName != L'\0' &&
1931 RtlUpcaseUnicodeChar( pConnection->LocalName) == RtlUpcaseUnicodeChar( DriveMapping))
1934 bDriveMapped = TRUE;
1939 pConnection = pConnection->fLink;
1942 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1945 return bDriveMapped;