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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 ( RtlCompareUnicodeString( &uniRemoteName,
462 &pConnection->RemoteName,
466 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
467 AFS_TRACE_LEVEL_VERBOSE,
468 "AFSCancelConnection Checking remote name %wZ to stored %wZ authentication id %I64X - %I64X\n",
470 &pConnection->RemoteName,
471 ConnectCB->AuthenticationId.QuadPart,
472 pConnection->AuthenticationId.QuadPart);
474 if( ConnectCB->AuthenticationId.QuadPart == pConnection->AuthenticationId.QuadPart &&
475 ( ConnectCB->LocalName == L'\0' ||
476 RtlCompareUnicodeString( &uniRemoteName,
477 &pConnection->RemoteName,
485 pLastConnection = pConnection;
487 pConnection = pConnection->fLink;
490 if( pConnection == NULL)
493 ConnectionResult->Status = WN_NOT_CONNECTED;
495 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
497 try_return( ntStatus);
500 if( pLastConnection == NULL)
503 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection->fLink;
508 pLastConnection->fLink = pConnection->fLink;
511 if( pConnection->Comment.Buffer != NULL)
514 AFSExFreePoolWithTag( pConnection->Comment.Buffer, 0);
517 ConnectionResult->LocalName = pConnection->LocalName;
519 AFSExFreePoolWithTag( pConnection, AFS_PROVIDER_CB);
521 ConnectionResult->Status = WN_SUCCESS;
523 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
527 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
534 AFSGetConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
535 IN OUT WCHAR *RemoteName,
536 IN ULONG RemoteNameBufferLength,
537 IN OUT ULONG_PTR *ReturnOutputBufferLength)
540 NTSTATUS ntStatus = STATUS_SUCCESS;
541 AFSProviderConnectionCB *pConnection = NULL;
542 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
547 if( ConnectCB->LocalName != L'\0')
550 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
551 AFS_TRACE_LEVEL_VERBOSE,
552 "AFSGetConnection Local %C authentication id %I64X\n",
553 ConnectCB->LocalName,
554 ConnectCB->AuthenticationId.QuadPart);
559 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
560 AFS_TRACE_LEVEL_VERBOSE,
561 "AFSGetConnection Local (NULL) authentication id %I64X\n",
562 ConnectCB->AuthenticationId.QuadPart);
565 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
566 AFS_TRACE_LEVEL_VERBOSE,
567 "AFSGetConnection Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
568 &pRDRDevExt->Specific.RDR.ProviderListLock,
569 PsGetCurrentThread());
571 if( ConnectCB->AuthenticationId.QuadPart == 0)
574 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
576 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
577 AFS_TRACE_LEVEL_VERBOSE,
578 "AFSGetConnection Retrieved authentication id %I64X\n",
579 ConnectCB->AuthenticationId.QuadPart);
582 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
586 // Look for the connection
589 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
591 while( pConnection != NULL)
594 if( pConnection->LocalName != L'\0')
597 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
598 AFS_TRACE_LEVEL_VERBOSE,
599 "AFSGetConnection Comparing passed in %C to %C authentication id %I64X - %I64X\n",
600 ConnectCB->LocalName,
601 pConnection->LocalName,
602 ConnectCB->AuthenticationId.QuadPart,
603 pConnection->AuthenticationId.QuadPart);
608 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
609 AFS_TRACE_LEVEL_VERBOSE,
610 "AFSGetConnection Comparing passed in %C to (NULL) authentication id %I64X - %I64X\n",
611 ConnectCB->LocalName,
612 ConnectCB->AuthenticationId.QuadPart,
613 pConnection->AuthenticationId.QuadPart);
616 if( pConnection->LocalName == ConnectCB->LocalName &&
617 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart)
623 pConnection = pConnection->fLink;
626 if( pConnection == NULL)
629 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
630 AFS_TRACE_LEVEL_VERBOSE,
631 "AFSGetConnection INVALID_PARAMETER\n");
633 try_return( ntStatus = STATUS_INVALID_PARAMETER);
636 if( RemoteNameBufferLength < pConnection->RemoteName.Length)
639 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
640 AFS_TRACE_LEVEL_VERBOSE,
641 "AFSGetConnection INSUFFICIENT_RESOURCES\n");
643 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
646 RtlCopyMemory( RemoteName,
647 pConnection->RemoteName.Buffer,
648 pConnection->RemoteName.Length);
650 *ReturnOutputBufferLength = pConnection->RemoteName.Length;
654 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
661 AFSListConnections( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
662 IN ULONG ConnectionBufferLength,
663 IN OUT ULONG_PTR *ReturnOutputBufferLength)
666 NTSTATUS ntStatus = STATUS_SUCCESS;
667 AFSProviderConnectionCB *pConnection = NULL, *pRootConnection = NULL;
668 ULONG ulCopiedLength = 0, ulRemainingLength = ConnectionBufferLength;
669 ULONG ulScope, ulType;
670 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath;
671 BOOLEAN bGlobalEnumeration = FALSE;
673 LARGE_INTEGER liAuthenticationID = {0,0};
674 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
680 // Save off some data before moving on
683 ulScope = ConnectCB->Scope;
685 ulType = ConnectCB->Type;
687 if( ConnectCB->AuthenticationId.QuadPart == 0)
690 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
692 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
693 AFS_TRACE_LEVEL_VERBOSE,
694 "AFSListConnections Retrieved authentication id %I64X\n",
695 ConnectCB->AuthenticationId.QuadPart);
698 liAuthenticationID.QuadPart = ConnectCB->AuthenticationId.QuadPart;
700 uniRemoteName.Length = 0;
701 uniRemoteName.MaximumLength = 0;
702 uniRemoteName.Buffer = NULL;
704 uniServerName.Length = 0;
705 uniServerName.MaximumLength = 0;
706 uniServerName.Buffer = NULL;
708 uniShareName.Length = 0;
709 uniShareName.MaximumLength = 0;
710 uniShareName.Buffer = NULL;
712 if( ConnectCB->RemoteNameLength > 0)
715 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
716 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
718 uniRemoteName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
719 uniRemoteName.MaximumLength,
720 AFS_NETWORK_PROVIDER_1_TAG);
722 if( uniRemoteName.Buffer == NULL)
725 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
728 RtlCopyMemory( uniRemoteName.Buffer,
729 ConnectCB->RemoteName,
730 uniRemoteName.Length);
732 if( uniRemoteName.Buffer[ 0] == L'\\' &&
733 uniRemoteName.Buffer[ 1] == L'\\')
736 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
738 uniRemoteName.Length -= sizeof( WCHAR);
741 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
744 uniRemoteName.Length -= sizeof( WCHAR);
747 FsRtlDissectName( uniRemoteName,
751 uniRemoteName = uniRemainingPath;
753 if( uniRemoteName.Length > 0)
756 FsRtlDissectName( uniRemoteName,
762 // If this is an enumeration of the global share name then
763 // adjust it to be the server name itself
766 if( uniShareName.Length == 0 ||
767 RtlCompareUnicodeString( &uniShareName,
772 bGlobalEnumeration = TRUE;
776 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
777 AFS_TRACE_LEVEL_VERBOSE,
778 "AFSListConnections Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
779 &pRDRDevExt->Specific.RDR.ProviderListLock,
780 PsGetCurrentThread());
782 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
786 // If this is a globalnet enumeration with no name then enumerate the server list
789 if( ulScope == RESOURCE_GLOBALNET)
792 if( uniServerName.Buffer == NULL)
795 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
801 // Go locate the root entry for the name passed in
804 if( bGlobalEnumeration)
807 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
810 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
812 try_return( ntStatus);
815 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
820 pRootConnection = AFSLocateEnumRootEntry( &uniShareName);
822 if( pRootConnection == NULL)
825 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
827 try_return( ntStatus);
831 // Need to handle these enumerations from the directory listing
834 ntStatus = AFSEnumerateConnection( ConnectCB,
836 ConnectionBufferLength,
844 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
847 ulIndex = ConnectCB->CurrentIndex;
849 while( pConnection != NULL)
852 if( bGlobalEnumeration &&
853 BooleanFlagOn( pConnection->Flags, AFS_CONNECTION_FLAG_GLOBAL_SHARE))
856 pConnection = pConnection->fLink;
861 if( ulScope != RESOURCE_GLOBALNET &&
862 !BooleanFlagOn( pConnection->Usage, RESOURCEUSAGE_ATTACHED))
865 pConnection = pConnection->fLink;
870 if( pConnection->LocalName != L'\0')
873 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
874 AFS_TRACE_LEVEL_VERBOSE,
875 "AFSListConnections Processing entry %wZ %C authentication id %I64X - %I64X Scope %08lX\n",
876 &pConnection->RemoteName,
877 pConnection->LocalName,
878 liAuthenticationID.QuadPart,
879 pConnection->AuthenticationId.QuadPart,
885 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
886 AFS_TRACE_LEVEL_VERBOSE,
887 "AFSListConnections Processing entry %wZ NULL LocalName authentication id %I64X - %I64X Scope %08lX\n",
888 &pConnection->RemoteName,
889 liAuthenticationID.QuadPart,
890 pConnection->AuthenticationId.QuadPart,
894 if( ulScope != RESOURCE_GLOBALNET &&
895 pConnection->AuthenticationId.QuadPart != liAuthenticationID.QuadPart)
898 pConnection = pConnection->fLink;
908 pConnection = pConnection->fLink;
913 if( ulRemainingLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
914 pConnection->RemoteName.Length +
915 pConnection->Comment.Length)
921 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
923 RtlCopyMemory( ConnectCB->RemoteName,
924 pConnection->RemoteName.Buffer,
925 pConnection->RemoteName.Length);
927 ConnectCB->LocalName = pConnection->LocalName;
929 ConnectCB->Type = pConnection->Type;
931 ConnectCB->Scope = pConnection->Scope;
933 if( !bGlobalEnumeration)
936 ConnectCB->Scope = RESOURCE_CONNECTED;
939 ConnectCB->DisplayType = pConnection->DisplayType;
941 ConnectCB->Usage = pConnection->Usage;
943 ConnectCB->CommentLength = pConnection->Comment.Length;
945 if( pConnection->Comment.Length > 0)
948 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
949 ConnectCB->RemoteNameLength);
951 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
952 pConnection->Comment.Buffer,
953 ConnectCB->CommentLength);
956 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
957 ConnectCB->RemoteNameLength +
958 ConnectCB->CommentLength;
960 ulRemainingLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
961 ConnectCB->RemoteNameLength +
962 ConnectCB->CommentLength;
964 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
965 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
966 ConnectCB->RemoteNameLength +
967 ConnectCB->CommentLength);
969 pConnection = pConnection->fLink;
972 if( NT_SUCCESS( ntStatus))
975 *ReturnOutputBufferLength = ulCopiedLength;
978 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
982 if( uniRemoteName.Buffer != NULL)
985 AFSExFreePoolWithTag( uniRemoteName.Buffer, 0);
993 AFSInitializeConnectionInfo( IN AFSProviderConnectionCB *Connection,
994 IN ULONG DisplayType)
997 NTSTATUS ntStatus = STATUS_SUCCESS;
998 UNICODE_STRING uniName, uniComponentName, uniRemainingName;
1003 uniName = Connection->RemoteName;
1006 // Strip of the double leading slash if there is one
1009 if( uniName.Buffer[ 0] == L'\\' &&
1010 uniName.Buffer[ 1] == L'\\')
1013 uniName.Buffer = &uniName.Buffer[ 1];
1015 uniName.Length -= sizeof( WCHAR);
1019 FsRtlDissectName( uniName,
1024 // Initialize the information for the connection
1025 // First, if this is the server only then mark it accordingly
1028 if( uniRemainingName.Length == 0 ||
1029 DisplayType == RESOURCEDISPLAYTYPE_SERVER)
1032 Connection->Type = RESOURCETYPE_DISK;
1034 Connection->Scope = 0;
1036 Connection->DisplayType = RESOURCEDISPLAYTYPE_SERVER;
1038 Connection->Usage = RESOURCEUSAGE_CONTAINER;
1040 Connection->Comment.Length = 20;
1041 Connection->Comment.MaximumLength = 22;
1043 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1044 Connection->Comment.MaximumLength,
1045 AFS_NETWORK_PROVIDER_2_TAG);
1047 if( Connection->Comment.Buffer != NULL)
1050 RtlZeroMemory( Connection->Comment.Buffer,
1051 Connection->Comment.MaximumLength);
1053 RtlCopyMemory( Connection->Comment.Buffer,
1060 Connection->Comment.Length = 0;
1061 Connection->Comment.MaximumLength = 0;
1064 try_return( ntStatus);
1067 uniName = uniRemainingName;
1069 FsRtlDissectName( uniName,
1073 if( uniRemainingName.Length == 0 ||
1074 uniRemainingName.Buffer == NULL ||
1075 DisplayType == RESOURCEDISPLAYTYPE_SHARE)
1078 Connection->Type = RESOURCETYPE_DISK;
1080 Connection->DisplayType = RESOURCEDISPLAYTYPE_SHARE;
1082 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1084 if( Connection->LocalName != L'\0')
1087 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1089 Connection->Scope = RESOURCE_CONNECTED;
1094 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1096 Connection->Scope = RESOURCE_GLOBALNET;
1099 Connection->Comment.Length = 18;
1100 Connection->Comment.MaximumLength = 20;
1102 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1103 Connection->Comment.MaximumLength,
1104 AFS_NETWORK_PROVIDER_3_TAG);
1106 if( Connection->Comment.Buffer != NULL)
1109 RtlZeroMemory( Connection->Comment.Buffer,
1110 Connection->Comment.MaximumLength);
1112 RtlCopyMemory( Connection->Comment.Buffer,
1119 Connection->Comment.Length = 0;
1120 Connection->Comment.MaximumLength = 0;
1123 try_return( ntStatus);
1127 // This is a sub directory within a share
1130 Connection->Type = RESOURCETYPE_DISK;
1132 Connection->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1134 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1136 if( Connection->LocalName != L'\0')
1139 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1144 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1147 Connection->Scope = RESOURCE_CONNECTED;
1149 Connection->Comment.Length = 26;
1150 Connection->Comment.MaximumLength = 28;
1152 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1153 Connection->Comment.MaximumLength,
1154 AFS_NETWORK_PROVIDER_4_TAG);
1156 if( Connection->Comment.Buffer != NULL)
1159 RtlZeroMemory( Connection->Comment.Buffer,
1160 Connection->Comment.MaximumLength);
1162 RtlCopyMemory( Connection->Comment.Buffer,
1169 Connection->Comment.Length = 0;
1170 Connection->Comment.MaximumLength = 0;
1181 AFSProviderConnectionCB *
1182 AFSLocateEnumRootEntry( IN UNICODE_STRING *RemoteName)
1185 AFSProviderConnectionCB *pConnection = NULL;
1186 UNICODE_STRING uniRemoteName = *RemoteName;
1187 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1192 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
1195 try_return( pConnection);
1198 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
1200 while( pConnection != NULL)
1203 if( RtlCompareUnicodeString( &uniRemoteName,
1204 &pConnection->ComponentName,
1211 pConnection = pConnection->fLink;
1223 AFSEnumerateConnection( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
1224 IN AFSProviderConnectionCB *RootConnection,
1225 IN ULONG BufferLength,
1226 OUT PULONG CopiedLength)
1229 NTSTATUS ntStatus = STATUS_SUCCESS;
1230 ULONG ulCRC = 0, ulCopiedLength = 0;
1231 AFSDirectoryCB *pShareDirEntry = NULL;
1232 AFSDirectoryCB *pDirEntry = NULL, *pTargetDirEntry = NULL;
1239 if( AFSGlobalRoot == NULL)
1242 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1243 AFS_TRACE_LEVEL_ERROR,
1244 "AFSEnumerateConnection Global root not yet initialized\n");
1246 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1249 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1253 // Grab our tree lock shared
1256 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1257 AFS_TRACE_LEVEL_VERBOSE,
1258 "AFSEnumerateConnection Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p SHARED %08lX\n",
1259 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1260 PsGetCurrentThread());
1262 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1266 // Locate the dir entry for this node
1269 ntStatus = AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1273 if( pShareDirEntry == NULL ||
1274 !NT_SUCCESS( ntStatus))
1278 // Perform a case insensitive search
1281 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1284 ntStatus = AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1288 if( pShareDirEntry == NULL ||
1289 !NT_SUCCESS( ntStatus))
1292 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1294 try_return( ntStatus);
1298 lCount = InterlockedIncrement( &pShareDirEntry->DirOpenReferenceCount);
1300 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1301 AFS_TRACE_LEVEL_VERBOSE,
1302 "AFSEnumerateConnection1 Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1303 &pShareDirEntry->NameInformation.FileName,
1308 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1311 // Setup the request to evaluate the entry
1312 // On success, pTargetDirEntry has the DirOpenReferenceCount held
1315 ntStatus = AFSEvaluateRootEntry( pShareDirEntry,
1318 if( !NT_SUCCESS( ntStatus))
1321 try_return( ntStatus);
1324 AFSAcquireShared( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1328 // Enumerate the content
1331 pDirEntry = pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
1333 ulIndex = ConnectCB->CurrentIndex;
1335 while( pDirEntry != NULL)
1343 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1348 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1349 pDirEntry->NameInformation.FileName.Length)
1355 ConnectCB->LocalName = L'\0';
1357 ConnectCB->RemoteNameLength = pDirEntry->NameInformation.FileName.Length;
1359 RtlCopyMemory( ConnectCB->RemoteName,
1360 pDirEntry->NameInformation.FileName.Buffer,
1361 pDirEntry->NameInformation.FileName.Length);
1363 ConnectCB->Type = RESOURCETYPE_DISK;
1365 ConnectCB->Scope = RESOURCE_CONNECTED;
1367 if( BooleanFlagOn( pDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1370 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1375 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_FILE;
1378 ConnectCB->Usage = 0;
1380 ConnectCB->CommentLength = 0;
1382 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1383 pDirEntry->NameInformation.FileName.Length;
1385 BufferLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1386 pDirEntry->NameInformation.FileName.Length;
1388 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
1389 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1390 ConnectCB->RemoteNameLength);
1392 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1396 // Release the DirOpenReferenceCount obtained from AFSEvaluateRootEntry
1399 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
1401 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1402 AFS_TRACE_LEVEL_VERBOSE,
1403 "AFSEnumerateConnection Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1404 &pTargetDirEntry->NameInformation.FileName,
1409 ASSERT( lCount >= 0);
1411 *CopiedLength = ulCopiedLength;
1413 AFSReleaseResource( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1417 if( pShareDirEntry != NULL)
1419 lCount = InterlockedDecrement( &pShareDirEntry->DirOpenReferenceCount);
1421 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1422 AFS_TRACE_LEVEL_VERBOSE,
1423 "AFSEnumerateConnection1 Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1424 &pShareDirEntry->NameInformation.FileName,
1429 ASSERT( lCount >= 0);
1437 AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
1438 IN ULONG BufferLength,
1439 IN OUT ULONG_PTR *ReturnOutputBufferLength)
1442 NTSTATUS ntStatus = STATUS_SUCCESS;
1443 AFSProviderConnectionCB *pConnection = NULL, *pBestMatch = NULL;
1444 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath, uniFullName, uniRemainingPathLocal;
1445 USHORT usNameLen = 0, usMaxNameLen = 0;
1446 BOOLEAN bEnumerationEntry = FALSE;
1447 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1452 uniServerName.Length = 0;
1453 uniServerName.MaximumLength = 0;
1454 uniServerName.Buffer = NULL;
1456 uniShareName.Length = 0;
1457 uniShareName.MaximumLength = 0;
1458 uniShareName.Buffer = NULL;
1460 uniRemainingPathLocal.Length = 0;
1461 uniRemainingPathLocal.MaximumLength = 0;
1462 uniRemainingPathLocal.Buffer = NULL;
1464 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
1465 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
1466 uniRemoteName.Buffer = (WCHAR *)ConnectCB->RemoteName;
1468 if( ConnectCB->LocalName != L'\0')
1471 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1472 AFS_TRACE_LEVEL_VERBOSE,
1473 "AFSGetConnectionInfo remote name %wZ Local %C authentication id %I64X\n",
1475 ConnectCB->LocalName,
1476 ConnectCB->AuthenticationId.QuadPart);
1481 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1482 AFS_TRACE_LEVEL_VERBOSE,
1483 "AFSGetConnectionInfo remote name %wZ Local (NULL) authentication id %I64X\n",
1485 ConnectCB->AuthenticationId.QuadPart);
1488 if( AFSGlobalRoot == NULL)
1491 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1492 AFS_TRACE_LEVEL_ERROR,
1493 "AFSGetConnectionInfo Global root not yet initialized\n");
1495 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1498 uniFullName = uniRemoteName;
1500 if( uniRemoteName.Buffer[ 0] == L'\\' &&
1501 uniRemoteName.Buffer[ 1] == L'\\')
1504 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
1506 uniRemoteName.Length -= sizeof( WCHAR);
1509 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
1512 uniRemoteName.Length -= sizeof( WCHAR);
1514 uniFullName.Length -= sizeof( WCHAR);
1517 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1518 AFS_TRACE_LEVEL_VERBOSE,
1519 "AFSGetConnectionInfo Processing name %wZ\n", &uniFullName);
1521 FsRtlDissectName( uniRemoteName,
1525 uniRemoteName = uniRemainingPath;
1527 if( uniRemoteName.Length > 0)
1530 FsRtlDissectName( uniRemoteName,
1535 if( RtlCompareUnicodeString( &uniServerName,
1540 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1543 if ( uniRemainingPath.Length > 0 )
1547 // Add back in the leading \ since it was stripped off above
1550 uniRemainingPath.Length += sizeof( WCHAR);
1551 if( uniRemainingPath.Length > uniRemainingPath.MaximumLength)
1553 uniRemainingPath.MaximumLength += sizeof( WCHAR);
1556 uniRemainingPath.Buffer--;
1558 uniRemainingPathLocal.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1559 uniRemainingPath.Length,
1560 AFS_NETWORK_PROVIDER_5_TAG);
1562 if( uniRemainingPathLocal.Buffer == NULL)
1565 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1566 AFS_TRACE_LEVEL_VERBOSE,
1567 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n");
1569 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1572 uniRemainingPathLocal.MaximumLength = uniRemainingPath.Length;
1573 uniRemainingPathLocal.Length = uniRemainingPath.Length;
1575 RtlCopyMemory( uniRemainingPathLocal.Buffer,
1576 uniRemainingPath.Buffer,
1577 uniRemainingPath.Length);
1580 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1581 AFS_TRACE_LEVEL_VERBOSE,
1582 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1583 &pRDRDevExt->Specific.RDR.ProviderListLock,
1584 PsGetCurrentThread());
1586 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1590 // If this is the server then return information about the
1594 if( uniShareName.Length == 0 &&
1595 RtlCompareUnicodeString( &uniServerName,
1600 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
1606 // See if we can locate it on our connection list
1609 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1611 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1612 AFS_TRACE_LEVEL_VERBOSE,
1613 "AFSGetConnectionInfo Searching for full name %wZ\n", &uniFullName);
1615 while( pConnection != NULL)
1618 if( usMaxNameLen < pConnection->RemoteName.Length &&
1619 pConnection->RemoteName.Length <= uniFullName.Length)
1622 usNameLen = uniFullName.Length;
1624 uniFullName.Length = pConnection->RemoteName.Length;
1626 if( pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
1627 RtlCompareUnicodeString( &uniFullName,
1628 &pConnection->RemoteName,
1632 usMaxNameLen = pConnection->RemoteName.Length;
1634 pBestMatch = pConnection;
1636 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1637 AFS_TRACE_LEVEL_VERBOSE,
1638 "AFSGetConnectionInfo Found match for %wZ\n", &pConnection->RemoteName);
1641 uniFullName.Length = usNameLen;
1644 pConnection = pConnection->fLink;
1647 pConnection = pBestMatch;
1649 if( pConnection != NULL)
1652 bEnumerationEntry = TRUE;
1654 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1655 AFS_TRACE_LEVEL_VERBOSE,
1656 "AFSGetConnectionInfo Using best match for %wZ\n", &pConnection->RemoteName);
1659 if( pConnection == NULL)
1663 // Locate the entry for the share
1666 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1670 if( pConnection == NULL)
1672 UNICODE_STRING uniFullName;
1673 AFSDirEnumEntry *pDirEnumEntry = NULL;
1675 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1676 AFS_TRACE_LEVEL_VERBOSE,
1677 "AFSGetConnectionInfo No connection for full name %wZ\n", &uniFullName);
1680 // Drop the lock, we will pick it up again later
1683 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1686 // OK, ask the CM about this component name
1689 ntStatus = AFSEvaluateTargetByName( NULL,
1690 &AFSGlobalRoot->ObjectInformation,
1695 if( !NT_SUCCESS( ntStatus))
1698 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1699 AFS_TRACE_LEVEL_VERBOSE,
1700 "AFSGetConnectionInfo Evaluation Failed share name %wZ\n",
1703 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1711 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_3_TAG);
1714 // The share name is valid
1715 // Allocate a new node and add it to our list
1717 uniFullName.MaximumLength = PAGE_SIZE;
1718 uniFullName.Length = 0;
1720 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1721 uniFullName.MaximumLength,
1722 AFS_NETWORK_PROVIDER_6_TAG);
1724 if( uniFullName.Buffer == NULL)
1727 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1728 AFS_TRACE_LEVEL_VERBOSE,
1729 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n");
1731 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1734 uniFullName.Buffer[ 0] = L'\\';
1735 uniFullName.Buffer[ 1] = L'\\';
1737 uniFullName.Length = 2 * sizeof( WCHAR);
1739 RtlCopyMemory( &uniFullName.Buffer[ 2],
1740 AFSServerName.Buffer,
1741 AFSServerName.Length);
1743 uniFullName.Length += AFSServerName.Length;
1745 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
1747 uniFullName.Length += sizeof( WCHAR);
1749 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
1750 uniShareName.Buffer,
1751 uniShareName.Length);
1753 uniFullName.Length += uniShareName.Length;
1755 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1758 ntStatus = AFSAddConnectionEx( &uniFullName,
1759 RESOURCEDISPLAYTYPE_SHARE,
1762 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1764 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
1766 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1767 AFS_TRACE_LEVEL_VERBOSE,
1768 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1769 &pRDRDevExt->Specific.RDR.ProviderListLock,
1770 PsGetCurrentThread());
1772 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1775 if ( NT_SUCCESS( ntStatus) )
1778 // Once again, locate the entry for the share we just created
1781 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1786 if( pConnection == NULL)
1789 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1790 AFS_TRACE_LEVEL_ERROR,
1791 "AFSGetConnectionInfo Failed to locate entry for full name %wZ\n", &uniFullName);
1793 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1795 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1799 // Fill in the returned connection info block
1802 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1803 pConnection->RemoteName.Length +
1804 pConnection->Comment.Length +
1805 uniRemainingPath.Length)
1808 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1809 AFS_TRACE_LEVEL_VERBOSE,
1810 "AFSGetConnectionInfo Buffer too small for full name %wZ\n",
1813 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1815 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
1818 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1819 AFS_TRACE_LEVEL_VERBOSE,
1820 "AFSGetConnectionInfo Returning entry Scope %08lX partial name %wZ full name %wZ\n",
1821 pConnection->Scope, &pConnection->RemoteName, &uniFullName);
1823 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
1825 if( !bEnumerationEntry)
1828 RtlCopyMemory( ConnectCB->RemoteName,
1830 pConnection->RemoteName.Length);
1835 RtlCopyMemory( ConnectCB->RemoteName,
1836 pConnection->RemoteName.Buffer,
1837 pConnection->RemoteName.Length);
1840 ConnectCB->LocalName = pConnection->LocalName;
1842 ConnectCB->Type = pConnection->Type;
1844 ConnectCB->Scope = pConnection->Scope;
1846 ConnectCB->DisplayType = pConnection->DisplayType;
1848 ConnectCB->Usage = pConnection->Usage;
1850 ConnectCB->CommentLength = pConnection->Comment.Length;
1852 ConnectCB->RemainingPathLength = uniRemainingPathLocal.Length;
1854 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1855 AFS_TRACE_LEVEL_VERBOSE,
1856 "AFSGetConnectionInfo Returning lengths: remote %u comment %u remaining %u\n",
1857 ConnectCB->RemoteNameLength,
1858 ConnectCB->CommentLength,
1859 ConnectCB->RemainingPathLength);
1861 if( ConnectCB->CommentLength > 0)
1864 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1865 ConnectCB->RemoteNameLength);
1867 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
1868 pConnection->Comment.Buffer,
1869 ConnectCB->CommentLength);
1872 if ( ConnectCB->RemainingPathLength > 0 )
1875 ConnectCB->RemainingPathOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1876 ConnectCB->RemoteNameLength +
1877 ConnectCB->CommentLength);
1879 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->RemainingPathOffset),
1880 uniRemainingPathLocal.Buffer,
1881 uniRemainingPathLocal.Length);
1884 *ReturnOutputBufferLength = FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1885 ConnectCB->RemoteNameLength +
1886 ConnectCB->CommentLength +
1887 ConnectCB->RemainingPathLength;
1889 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1893 if ( uniRemainingPathLocal.Buffer )
1896 AFSExFreePoolWithTag( uniRemainingPathLocal.Buffer, 0);
1904 AFSIsDriveMapped( IN WCHAR DriveMapping)
1907 BOOLEAN bDriveMapped = FALSE;
1908 AFSProviderConnectionCB *pConnection = NULL;
1909 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1914 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1917 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1919 while( pConnection != NULL)
1922 if( pConnection->LocalName != L'\0' &&
1923 RtlUpcaseUnicodeChar( pConnection->LocalName) == RtlUpcaseUnicodeChar( DriveMapping))
1926 bDriveMapped = TRUE;
1931 pConnection = pConnection->fLink;
1934 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1937 return bDriveMapped;