2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2015 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSNetworkProviderSupport.cpp
39 #include "AFSCommon.h"
42 AFSAddConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
43 IN OUT PULONG ResultStatus,
44 IN OUT ULONG_PTR *ReturnOutputBufferLength)
47 NTSTATUS ntStatus = STATUS_SUCCESS;
48 AFSProviderConnectionCB *pConnection = NULL, *pLastConnection = NULL;
49 UNICODE_STRING uniRemoteName;
50 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
55 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
56 AFS_TRACE_LEVEL_VERBOSE,
57 "AFSAddConnection Acquiring AFSProviderListLock lock %p EXCL %08lX\n",
58 &pRDRDevExt->Specific.RDR.ProviderListLock,
59 PsGetCurrentThread()));
61 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
63 if ( !NT_SUCCESS( ntStatus))
66 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
67 AFS_TRACE_LEVEL_ERROR,
68 "AFSAddConnection Unable to retrieve authentication id %08lX\n",
74 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
75 AFS_TRACE_LEVEL_VERBOSE,
76 "AFSAddConnection Retrieved authentication id %I64X\n",
77 ConnectCB->AuthenticationId.QuadPart));
79 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
83 // Look for the connection
86 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
87 uniRemoteName.MaximumLength = uniRemoteName.Length;
89 uniRemoteName.Buffer = ConnectCB->RemoteName;
92 // Strip off any trailing slashes
95 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
98 uniRemoteName.Length -= sizeof( WCHAR);
101 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
103 while( pConnection != NULL)
106 if( pConnection->LocalName == ConnectCB->LocalName &&
107 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
108 RtlCompareUnicodeString( &uniRemoteName,
109 &pConnection->RemoteName,
116 pConnection = pConnection->fLink;
119 if( pConnection != NULL)
122 if( ConnectCB->LocalName != L'\0')
125 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
126 AFS_TRACE_LEVEL_VERBOSE,
127 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local %C authentication id %I64X\n",
129 ConnectCB->LocalName,
130 ConnectCB->AuthenticationId.QuadPart));
132 *ResultStatus = WN_ALREADY_CONNECTED;
137 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
138 AFS_TRACE_LEVEL_VERBOSE,
139 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local (NULL) authentication id %I64X\n",
141 ConnectCB->AuthenticationId.QuadPart));
143 *ResultStatus = WN_SUCCESS;
146 *ReturnOutputBufferLength = sizeof( ULONG);
148 try_return( ntStatus = STATUS_SUCCESS);
152 // Validate the remote name
155 if( uniRemoteName.Length > 2 * sizeof( WCHAR) &&
156 uniRemoteName.Buffer[ 0] == L'\\' &&
157 uniRemoteName.Buffer[ 1] == L'\\')
160 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 2];
162 uniRemoteName.Length -= (2 * sizeof( WCHAR));
165 if( uniRemoteName.Length >= AFSServerName.Length)
168 USHORT usLength = uniRemoteName.Length;
170 if (uniRemoteName.Buffer[AFSServerName.Length/sizeof( WCHAR)] != L'\\')
173 if( ConnectCB->LocalName != L'\0')
176 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
177 AFS_TRACE_LEVEL_VERBOSE,
178 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local %C authentication id %I64X\n",
180 ConnectCB->LocalName,
181 ConnectCB->AuthenticationId.QuadPart));
186 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
187 AFS_TRACE_LEVEL_VERBOSE,
188 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local (NULL) authentication id %I64X\n",
190 ConnectCB->AuthenticationId.QuadPart));
193 *ResultStatus = WN_BAD_NETNAME;
195 *ReturnOutputBufferLength = sizeof( ULONG);
197 try_return( ntStatus = STATUS_SUCCESS);
200 uniRemoteName.Length = AFSServerName.Length;
202 if( RtlCompareUnicodeString( &AFSServerName,
207 if( ConnectCB->LocalName != L'\0')
210 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
211 AFS_TRACE_LEVEL_VERBOSE,
212 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local %C authentication id %I64X\n",
214 ConnectCB->LocalName,
215 ConnectCB->AuthenticationId.QuadPart));
220 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
221 AFS_TRACE_LEVEL_VERBOSE,
222 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local (NULL) authentication id %I64X\n",
224 ConnectCB->AuthenticationId.QuadPart));
227 *ResultStatus = WN_BAD_NETNAME;
229 *ReturnOutputBufferLength = sizeof( ULONG);
231 try_return( ntStatus = STATUS_SUCCESS);
234 uniRemoteName.Length = usLength;
239 if( ConnectCB->LocalName != L'\0')
242 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
243 AFS_TRACE_LEVEL_VERBOSE,
244 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local %C authentication id %I64X\n",
246 ConnectCB->LocalName,
247 ConnectCB->AuthenticationId.QuadPart));
252 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
253 AFS_TRACE_LEVEL_VERBOSE,
254 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local (NULL) authentication id %I64X\n",
256 ConnectCB->AuthenticationId.QuadPart));
259 *ResultStatus = WN_BAD_NETNAME;
261 *ReturnOutputBufferLength = sizeof( ULONG);
263 try_return( ntStatus = STATUS_SUCCESS);
266 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
267 uniRemoteName.MaximumLength = uniRemoteName.Length;
269 uniRemoteName.Buffer = ConnectCB->RemoteName;
272 // Strip off any trailing slashes
275 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
278 uniRemoteName.Length -= sizeof( WCHAR);
282 // Allocate a new node and add it to our list
285 pConnection = (AFSProviderConnectionCB *)AFSExAllocatePoolWithTag( PagedPool,
286 sizeof( AFSProviderConnectionCB) +
287 uniRemoteName.Length,
290 if( pConnection == NULL)
293 *ResultStatus = WN_OUT_OF_MEMORY;
295 *ReturnOutputBufferLength = sizeof( ULONG);
297 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
300 RtlZeroMemory( pConnection,
301 sizeof( AFSProviderConnectionCB) + uniRemoteName.Length);
303 pConnection->LocalName = ConnectCB->LocalName;
305 pConnection->RemoteName.Length = uniRemoteName.Length;
306 pConnection->RemoteName.MaximumLength = pConnection->RemoteName.Length;
308 pConnection->RemoteName.Buffer = (WCHAR *)((char *)pConnection + sizeof( AFSProviderConnectionCB));
310 RtlCopyMemory( pConnection->RemoteName.Buffer,
311 uniRemoteName.Buffer,
312 pConnection->RemoteName.Length);
314 pConnection->Type = ConnectCB->Type;
316 pConnection->AuthenticationId = ConnectCB->AuthenticationId;
318 if( ConnectCB->LocalName != L'\0')
321 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
322 AFS_TRACE_LEVEL_VERBOSE,
323 "AFSAddConnection Adding connection remote name %wZ Local %C authentication id %I64X\n",
325 ConnectCB->LocalName,
326 ConnectCB->AuthenticationId.QuadPart));
331 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
332 AFS_TRACE_LEVEL_VERBOSE,
333 "AFSAddConnection Adding connection remote name %wZ Local (NULL) authentication id %I64X\n",
335 ConnectCB->AuthenticationId.QuadPart));
339 // Point to the component portion of the name
342 pConnection->ComponentName.Length = 0;
343 pConnection->ComponentName.MaximumLength = 0;
345 pConnection->ComponentName.Buffer = &pConnection->RemoteName.Buffer[ (pConnection->RemoteName.Length/sizeof( WCHAR)) - 1];
347 while( pConnection->ComponentName.Length <= pConnection->RemoteName.Length)
350 if( pConnection->ComponentName.Buffer[ 0] == L'\\')
353 pConnection->ComponentName.Buffer++;
358 pConnection->ComponentName.Length += sizeof( WCHAR);
359 pConnection->ComponentName.MaximumLength += sizeof( WCHAR);
361 pConnection->ComponentName.Buffer--;
365 // Go initialize the information about the connection
368 AFSInitializeConnectionInfo( pConnection,
372 // Insert the entry into our list
375 if( pRDRDevExt->Specific.RDR.ProviderConnectionList == NULL)
378 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection;
384 // Get the end of the list
387 pLastConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
389 while( pLastConnection->fLink != NULL)
392 pLastConnection = pLastConnection->fLink;
395 pLastConnection->fLink = pConnection;
398 *ResultStatus = WN_SUCCESS;
400 *ReturnOutputBufferLength = sizeof( ULONG);
404 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
412 AFSCancelConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
413 IN OUT AFSCancelConnectionResultCB *ConnectionResult,
414 IN OUT ULONG_PTR *ReturnOutputBufferLength)
417 NTSTATUS ntStatus = STATUS_SUCCESS;
418 AFSProviderConnectionCB *pConnection = NULL, *pLastConnection = NULL;
419 UNICODE_STRING uniRemoteName;
420 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
425 ConnectionResult->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
427 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
428 AFS_TRACE_LEVEL_VERBOSE,
429 "AFSCancelConnection Acquiring AFSProviderListLock lock %p EXCL %08lX\n",
430 &pRDRDevExt->Specific.RDR.ProviderListLock,
431 PsGetCurrentThread()));
433 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
435 if ( !NT_SUCCESS( ntStatus))
438 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
439 AFS_TRACE_LEVEL_ERROR,
440 "AFSCancelConnection Unable to retrieve authentication id %08lX\n",
446 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
447 AFS_TRACE_LEVEL_VERBOSE,
448 "AFSCancelConnection Retrieved authentication id %I64X\n",
449 ConnectCB->AuthenticationId.QuadPart));
451 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
455 // Look for the connection
458 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
459 uniRemoteName.MaximumLength = uniRemoteName.Length;
461 uniRemoteName.Buffer = NULL;
463 if( uniRemoteName.Length > 0)
466 uniRemoteName.Buffer = ConnectCB->RemoteName;
469 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
471 while( pConnection != NULL)
474 if( ( ConnectCB->LocalName != L'\0' &&
475 pConnection->LocalName == ConnectCB->LocalName)
477 ( ConnectCB->LocalName == L'\0' &&
478 pConnection->LocalName == L'\0' &&
479 RtlCompareUnicodeString( &uniRemoteName,
480 &pConnection->RemoteName,
484 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
485 AFS_TRACE_LEVEL_VERBOSE,
486 "AFSCancelConnection Checking remote name %wZ to stored %wZ authentication id %I64X - %I64X\n",
488 &pConnection->RemoteName,
489 ConnectCB->AuthenticationId.QuadPart,
490 pConnection->AuthenticationId.QuadPart));
492 if( ConnectCB->AuthenticationId.QuadPart == pConnection->AuthenticationId.QuadPart &&
493 ( ConnectCB->LocalName == L'\0' ||
494 RtlCompareUnicodeString( &uniRemoteName,
495 &pConnection->RemoteName,
503 pLastConnection = pConnection;
505 pConnection = pConnection->fLink;
508 if( pConnection == NULL)
511 ConnectionResult->Status = WN_NOT_CONNECTED;
513 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
515 try_return( ntStatus);
518 if( pLastConnection == NULL)
521 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection->fLink;
526 pLastConnection->fLink = pConnection->fLink;
529 if( pConnection->Comment.Buffer != NULL)
532 AFSExFreePoolWithTag( pConnection->Comment.Buffer, 0);
535 ConnectionResult->LocalName = pConnection->LocalName;
537 AFSExFreePoolWithTag( pConnection, AFS_PROVIDER_CB);
539 ConnectionResult->Status = WN_SUCCESS;
541 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
545 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
552 AFSGetConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
553 IN OUT WCHAR *RemoteName,
554 IN ULONG RemoteNameBufferLength,
555 IN OUT ULONG_PTR *ReturnOutputBufferLength)
558 NTSTATUS ntStatus = STATUS_SUCCESS;
559 AFSProviderConnectionCB *pConnection = NULL;
560 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
565 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
567 if ( !NT_SUCCESS( ntStatus))
570 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
571 AFS_TRACE_LEVEL_ERROR,
572 "AFSGetConnection Unable to retrieve authentication id %08lX\n",
578 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
579 AFS_TRACE_LEVEL_VERBOSE,
580 "AFSGetConnection Retrieved authentication id %I64X\n",
581 ConnectCB->AuthenticationId.QuadPart));
583 if( ConnectCB->LocalName != L'\0')
586 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
587 AFS_TRACE_LEVEL_VERBOSE,
588 "AFSGetConnection Local %C authentication id %I64X\n",
589 ConnectCB->LocalName,
590 ConnectCB->AuthenticationId.QuadPart));
595 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
596 AFS_TRACE_LEVEL_VERBOSE,
597 "AFSGetConnection Local (NULL) authentication id %I64X\n",
598 ConnectCB->AuthenticationId.QuadPart));
601 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
602 AFS_TRACE_LEVEL_VERBOSE,
603 "AFSGetConnection Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
604 &pRDRDevExt->Specific.RDR.ProviderListLock,
605 PsGetCurrentThread()));
607 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
611 // Look for the connection
614 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
616 while( pConnection != NULL)
619 if( pConnection->LocalName != L'\0')
622 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
623 AFS_TRACE_LEVEL_VERBOSE,
624 "AFSGetConnection Comparing passed in %C to %C authentication id %I64X - %I64X\n",
625 ConnectCB->LocalName,
626 pConnection->LocalName,
627 ConnectCB->AuthenticationId.QuadPart,
628 pConnection->AuthenticationId.QuadPart));
633 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
634 AFS_TRACE_LEVEL_VERBOSE,
635 "AFSGetConnection Comparing passed in %C to (NULL) authentication id %I64X - %I64X\n",
636 ConnectCB->LocalName,
637 ConnectCB->AuthenticationId.QuadPart,
638 pConnection->AuthenticationId.QuadPart));
641 if( pConnection->LocalName == ConnectCB->LocalName &&
642 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart)
648 pConnection = pConnection->fLink;
651 if( pConnection == NULL)
654 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
655 AFS_TRACE_LEVEL_VERBOSE,
656 "AFSGetConnection INVALID_PARAMETER\n"));
658 try_return( ntStatus = STATUS_INVALID_PARAMETER);
661 if( RemoteNameBufferLength < pConnection->RemoteName.Length)
664 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
665 AFS_TRACE_LEVEL_VERBOSE,
666 "AFSGetConnection INSUFFICIENT_RESOURCES\n"));
668 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
671 RtlCopyMemory( RemoteName,
672 pConnection->RemoteName.Buffer,
673 pConnection->RemoteName.Length);
675 *ReturnOutputBufferLength = pConnection->RemoteName.Length;
679 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
686 AFSListConnections( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
687 IN ULONG ConnectionBufferLength,
688 IN OUT ULONG_PTR *ReturnOutputBufferLength)
691 NTSTATUS ntStatus = STATUS_SUCCESS;
692 AFSProviderConnectionCB *pConnection = NULL, *pRootConnection = NULL;
693 ULONG ulCopiedLength = 0, ulRemainingLength = ConnectionBufferLength;
694 ULONG ulScope, ulType;
695 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath;
696 BOOLEAN bGlobalEnumeration = FALSE;
698 LARGE_INTEGER liAuthenticationID = {0,0};
699 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
705 // Save off some data before moving on
708 ulScope = ConnectCB->Scope;
710 ulType = ConnectCB->Type;
712 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
714 if ( !NT_SUCCESS( ntStatus))
717 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
718 AFS_TRACE_LEVEL_ERROR,
719 "AFSListConnection Unable to retrieve authentication id %08lX\n",
725 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
726 AFS_TRACE_LEVEL_VERBOSE,
727 "AFSListConnections Retrieved authentication id %I64X\n",
728 ConnectCB->AuthenticationId.QuadPart));
730 liAuthenticationID.QuadPart = ConnectCB->AuthenticationId.QuadPart;
732 uniRemoteName.Length = 0;
733 uniRemoteName.MaximumLength = 0;
734 uniRemoteName.Buffer = NULL;
736 uniServerName.Length = 0;
737 uniServerName.MaximumLength = 0;
738 uniServerName.Buffer = NULL;
740 uniShareName.Length = 0;
741 uniShareName.MaximumLength = 0;
742 uniShareName.Buffer = NULL;
744 if( ConnectCB->RemoteNameLength > 0)
747 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
748 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
750 uniRemoteName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
751 uniRemoteName.MaximumLength,
752 AFS_NETWORK_PROVIDER_1_TAG);
754 if( uniRemoteName.Buffer == NULL)
757 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
760 RtlCopyMemory( uniRemoteName.Buffer,
761 ConnectCB->RemoteName,
762 uniRemoteName.Length);
764 if( uniRemoteName.Buffer[ 0] == L'\\' &&
765 uniRemoteName.Buffer[ 1] == L'\\')
768 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
770 uniRemoteName.Length -= sizeof( WCHAR);
773 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
776 uniRemoteName.Length -= sizeof( WCHAR);
779 FsRtlDissectName( uniRemoteName,
783 uniRemoteName = uniRemainingPath;
785 if( uniRemoteName.Length > 0)
788 FsRtlDissectName( uniRemoteName,
794 // If this is an enumeration of the global share name then
795 // adjust it to be the server name itself
798 if( uniShareName.Length == 0)
801 bGlobalEnumeration = TRUE;
805 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
806 AFS_TRACE_LEVEL_VERBOSE,
807 "AFSListConnections Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
808 &pRDRDevExt->Specific.RDR.ProviderListLock,
809 PsGetCurrentThread()));
811 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
815 // If this is a globalnet enumeration with no name then enumerate the server list
818 if( ulScope == RESOURCE_GLOBALNET)
821 if( uniServerName.Buffer == NULL)
824 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
830 // Go locate the root entry for the name passed in
833 if( bGlobalEnumeration)
836 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
839 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
841 try_return( ntStatus);
844 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
849 pRootConnection = AFSLocateEnumRootEntry( &uniShareName);
851 if( pRootConnection == NULL)
854 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
856 try_return( ntStatus);
860 // Need to handle these enumerations from the directory listing
863 ntStatus = AFSEnumerateConnection( ConnectCB,
865 ConnectionBufferLength,
873 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
876 ulIndex = ConnectCB->CurrentIndex;
878 while( pConnection != NULL)
881 if( bGlobalEnumeration &&
882 BooleanFlagOn( pConnection->Flags, AFS_CONNECTION_FLAG_GLOBAL_SHARE))
885 pConnection = pConnection->fLink;
890 if( ulScope != RESOURCE_GLOBALNET &&
891 !BooleanFlagOn( pConnection->Usage, RESOURCEUSAGE_ATTACHED))
894 pConnection = pConnection->fLink;
899 if( pConnection->LocalName != L'\0')
902 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
903 AFS_TRACE_LEVEL_VERBOSE,
904 "AFSListConnections Processing entry %wZ %C authentication id %I64X - %I64X Scope %08lX\n",
905 &pConnection->RemoteName,
906 pConnection->LocalName,
907 liAuthenticationID.QuadPart,
908 pConnection->AuthenticationId.QuadPart,
909 pConnection->Scope));
914 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
915 AFS_TRACE_LEVEL_VERBOSE,
916 "AFSListConnections Processing entry %wZ NULL LocalName authentication id %I64X - %I64X Scope %08lX\n",
917 &pConnection->RemoteName,
918 liAuthenticationID.QuadPart,
919 pConnection->AuthenticationId.QuadPart,
920 pConnection->Scope));
923 if( ulScope != RESOURCE_GLOBALNET &&
924 pConnection->AuthenticationId.QuadPart != liAuthenticationID.QuadPart)
927 pConnection = pConnection->fLink;
937 pConnection = pConnection->fLink;
942 if( ulRemainingLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
943 pConnection->RemoteName.Length +
944 pConnection->Comment.Length)
950 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
952 RtlCopyMemory( ConnectCB->RemoteName,
953 pConnection->RemoteName.Buffer,
954 pConnection->RemoteName.Length);
956 ConnectCB->LocalName = pConnection->LocalName;
958 ConnectCB->Type = pConnection->Type;
960 ConnectCB->Scope = pConnection->Scope;
962 if( !bGlobalEnumeration)
965 ConnectCB->Scope = RESOURCE_CONNECTED;
968 ConnectCB->DisplayType = pConnection->DisplayType;
970 ConnectCB->Usage = pConnection->Usage;
972 ConnectCB->CommentLength = pConnection->Comment.Length;
974 if( pConnection->Comment.Length > 0)
977 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
978 ConnectCB->RemoteNameLength);
980 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
981 pConnection->Comment.Buffer,
982 ConnectCB->CommentLength);
985 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
986 ConnectCB->RemoteNameLength +
987 ConnectCB->CommentLength;
989 ulRemainingLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
990 ConnectCB->RemoteNameLength +
991 ConnectCB->CommentLength;
993 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
994 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
995 ConnectCB->RemoteNameLength +
996 ConnectCB->CommentLength);
998 pConnection = pConnection->fLink;
1001 if( NT_SUCCESS( ntStatus))
1004 *ReturnOutputBufferLength = ulCopiedLength;
1007 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1011 if( uniRemoteName.Buffer != NULL)
1014 AFSExFreePoolWithTag( uniRemoteName.Buffer, 0);
1022 AFSInitializeConnectionInfo( IN AFSProviderConnectionCB *Connection,
1023 IN ULONG DisplayType)
1026 NTSTATUS ntStatus = STATUS_SUCCESS;
1027 UNICODE_STRING uniName, uniComponentName, uniRemainingName;
1032 uniName = Connection->RemoteName;
1035 // Strip of the double leading slash if there is one
1038 if( uniName.Buffer[ 0] == L'\\' &&
1039 uniName.Buffer[ 1] == L'\\')
1042 uniName.Buffer = &uniName.Buffer[ 1];
1044 uniName.Length -= sizeof( WCHAR);
1048 FsRtlDissectName( uniName,
1053 // Initialize the information for the connection
1054 // First, if this is the server only then mark it accordingly
1057 if( uniRemainingName.Length == 0 ||
1058 DisplayType == RESOURCEDISPLAYTYPE_SERVER)
1061 Connection->Type = RESOURCETYPE_DISK;
1063 Connection->Scope = 0;
1065 Connection->DisplayType = RESOURCEDISPLAYTYPE_SERVER;
1067 Connection->Usage = RESOURCEUSAGE_CONTAINER;
1069 Connection->Comment.Length = 20;
1070 Connection->Comment.MaximumLength = 22;
1072 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1073 Connection->Comment.MaximumLength,
1074 AFS_NETWORK_PROVIDER_2_TAG);
1076 if( Connection->Comment.Buffer != NULL)
1079 RtlZeroMemory( Connection->Comment.Buffer,
1080 Connection->Comment.MaximumLength);
1082 RtlCopyMemory( Connection->Comment.Buffer,
1089 Connection->Comment.Length = 0;
1090 Connection->Comment.MaximumLength = 0;
1093 try_return( ntStatus);
1096 uniName = uniRemainingName;
1098 FsRtlDissectName( uniName,
1102 if( uniRemainingName.Length == 0 ||
1103 uniRemainingName.Buffer == NULL ||
1104 DisplayType == RESOURCEDISPLAYTYPE_SHARE)
1107 Connection->Type = RESOURCETYPE_DISK;
1109 Connection->DisplayType = RESOURCEDISPLAYTYPE_SHARE;
1111 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1113 if( Connection->LocalName != L'\0')
1116 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1118 Connection->Scope = RESOURCE_CONNECTED;
1123 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1125 Connection->Scope = RESOURCE_GLOBALNET;
1128 Connection->Comment.Length = 18;
1129 Connection->Comment.MaximumLength = 20;
1131 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1132 Connection->Comment.MaximumLength,
1133 AFS_NETWORK_PROVIDER_3_TAG);
1135 if( Connection->Comment.Buffer != NULL)
1138 RtlZeroMemory( Connection->Comment.Buffer,
1139 Connection->Comment.MaximumLength);
1141 RtlCopyMemory( Connection->Comment.Buffer,
1148 Connection->Comment.Length = 0;
1149 Connection->Comment.MaximumLength = 0;
1152 try_return( ntStatus);
1156 // This is a sub directory within a share
1159 Connection->Type = RESOURCETYPE_DISK;
1161 Connection->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1163 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1165 if( Connection->LocalName != L'\0')
1168 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1173 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1176 Connection->Scope = RESOURCE_CONNECTED;
1178 Connection->Comment.Length = 26;
1179 Connection->Comment.MaximumLength = 28;
1181 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1182 Connection->Comment.MaximumLength,
1183 AFS_NETWORK_PROVIDER_4_TAG);
1185 if( Connection->Comment.Buffer != NULL)
1188 RtlZeroMemory( Connection->Comment.Buffer,
1189 Connection->Comment.MaximumLength);
1191 RtlCopyMemory( Connection->Comment.Buffer,
1198 Connection->Comment.Length = 0;
1199 Connection->Comment.MaximumLength = 0;
1210 AFSProviderConnectionCB *
1211 AFSLocateEnumRootEntry( IN UNICODE_STRING *RemoteName)
1214 AFSProviderConnectionCB *pConnection = NULL;
1215 UNICODE_STRING uniRemoteName = *RemoteName;
1216 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1221 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
1224 try_return( pConnection);
1227 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
1229 while( pConnection != NULL)
1232 if( RtlCompareUnicodeString( &uniRemoteName,
1233 &pConnection->ComponentName,
1240 pConnection = pConnection->fLink;
1252 AFSEnumerateConnection( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
1253 IN AFSProviderConnectionCB *RootConnection,
1254 IN ULONG BufferLength,
1255 OUT PULONG CopiedLength)
1258 NTSTATUS ntStatus = STATUS_SUCCESS;
1259 ULONG ulCRC = 0, ulCopiedLength = 0;
1260 AFSDirectoryCB *pShareDirEntry = NULL;
1261 AFSDirectoryCB *pDirEntry = NULL, *pTargetDirEntry = NULL;
1268 if( AFSGlobalRoot == NULL)
1271 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1272 AFS_TRACE_LEVEL_ERROR,
1273 "AFSEnumerateConnection Global root not yet initialized\n"));
1275 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1278 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1282 // Grab our tree lock shared
1285 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1286 AFS_TRACE_LEVEL_VERBOSE,
1287 "AFSEnumerateConnection Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p SHARED %08lX\n",
1288 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1289 PsGetCurrentThread()));
1291 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1295 // Locate the dir entry for this node
1298 ntStatus = AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1302 if( pShareDirEntry == NULL ||
1303 !NT_SUCCESS( ntStatus))
1307 // Perform a case insensitive search
1310 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1313 ntStatus = AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1317 if( pShareDirEntry == NULL ||
1318 !NT_SUCCESS( ntStatus))
1321 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1323 try_return( ntStatus);
1327 lCount = InterlockedIncrement( &pShareDirEntry->DirOpenReferenceCount);
1329 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1330 AFS_TRACE_LEVEL_VERBOSE,
1331 "AFSEnumerateConnection1 Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1332 &pShareDirEntry->NameInformation.FileName,
1337 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1340 // Setup the request to evaluate the entry
1341 // On success, pTargetDirEntry has the DirOpenReferenceCount held
1344 ntStatus = AFSEvaluateRootEntry( pShareDirEntry,
1347 if( !NT_SUCCESS( ntStatus))
1350 try_return( ntStatus);
1353 AFSAcquireShared( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1357 // Enumerate the content
1360 pDirEntry = pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
1362 ulIndex = ConnectCB->CurrentIndex;
1364 while( pDirEntry != NULL)
1372 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1377 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1378 pDirEntry->NameInformation.FileName.Length)
1384 ConnectCB->LocalName = L'\0';
1386 ConnectCB->RemoteNameLength = pDirEntry->NameInformation.FileName.Length;
1388 RtlCopyMemory( ConnectCB->RemoteName,
1389 pDirEntry->NameInformation.FileName.Buffer,
1390 pDirEntry->NameInformation.FileName.Length);
1392 ConnectCB->Type = RESOURCETYPE_DISK;
1394 ConnectCB->Scope = RESOURCE_CONNECTED;
1396 if( BooleanFlagOn( pDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1399 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1404 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_FILE;
1407 ConnectCB->Usage = 0;
1409 ConnectCB->CommentLength = 0;
1411 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1412 pDirEntry->NameInformation.FileName.Length;
1414 BufferLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1415 pDirEntry->NameInformation.FileName.Length;
1417 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
1418 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1419 ConnectCB->RemoteNameLength);
1421 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1425 // Release the DirOpenReferenceCount obtained from AFSEvaluateRootEntry
1428 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
1430 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1431 AFS_TRACE_LEVEL_VERBOSE,
1432 "AFSEnumerateConnection Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1433 &pTargetDirEntry->NameInformation.FileName,
1438 ASSERT( lCount >= 0);
1440 *CopiedLength = ulCopiedLength;
1442 AFSReleaseResource( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1446 if( pShareDirEntry != NULL)
1448 lCount = InterlockedDecrement( &pShareDirEntry->DirOpenReferenceCount);
1450 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1451 AFS_TRACE_LEVEL_VERBOSE,
1452 "AFSEnumerateConnection1 Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1453 &pShareDirEntry->NameInformation.FileName,
1458 ASSERT( lCount >= 0);
1466 AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
1467 IN ULONG BufferLength,
1468 IN OUT ULONG_PTR *ReturnOutputBufferLength)
1471 NTSTATUS ntStatus = STATUS_SUCCESS;
1472 AFSProviderConnectionCB *pConnection = NULL, *pBestMatch = NULL;
1473 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath, uniFullName, uniRemainingPathLocal;
1474 BOOLEAN bEnumerationEntry = FALSE;
1475 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1480 uniServerName.Length = 0;
1481 uniServerName.MaximumLength = 0;
1482 uniServerName.Buffer = NULL;
1484 uniShareName.Length = 0;
1485 uniShareName.MaximumLength = 0;
1486 uniShareName.Buffer = NULL;
1488 uniRemainingPathLocal.Length = 0;
1489 uniRemainingPathLocal.MaximumLength = 0;
1490 uniRemainingPathLocal.Buffer = NULL;
1492 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
1493 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
1494 uniRemoteName.Buffer = (WCHAR *)ConnectCB->RemoteName;
1496 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
1498 if ( !NT_SUCCESS( ntStatus))
1501 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1502 AFS_TRACE_LEVEL_ERROR,
1503 "AFSGetConnectionInfo Unable to retrieve authentication id %08lX\n",
1509 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1510 AFS_TRACE_LEVEL_VERBOSE,
1511 "AFSGetConnectionInfo Retrieved authentication id %I64X\n",
1512 ConnectCB->AuthenticationId.QuadPart));
1514 if( ConnectCB->LocalName != L'\0')
1517 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1518 AFS_TRACE_LEVEL_VERBOSE,
1519 "AFSGetConnectionInfo remote name %wZ Local %C authentication id %I64X\n",
1521 ConnectCB->LocalName,
1522 ConnectCB->AuthenticationId.QuadPart));
1527 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1528 AFS_TRACE_LEVEL_VERBOSE,
1529 "AFSGetConnectionInfo remote name %wZ Local (NULL) authentication id %I64X\n",
1531 ConnectCB->AuthenticationId.QuadPart));
1534 if( AFSGlobalRoot == NULL)
1537 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1538 AFS_TRACE_LEVEL_ERROR,
1539 "AFSGetConnectionInfo Global root not yet initialized\n"));
1541 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1544 uniFullName = uniRemoteName;
1546 if( uniRemoteName.Buffer[ 0] == L'\\' &&
1547 uniRemoteName.Buffer[ 1] == L'\\')
1550 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
1552 uniRemoteName.Length -= sizeof( WCHAR);
1555 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
1558 uniRemoteName.Length -= sizeof( WCHAR);
1560 uniFullName.Length -= sizeof( WCHAR);
1563 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1564 AFS_TRACE_LEVEL_VERBOSE,
1565 "AFSGetConnectionInfo Processing name %wZ\n",
1568 FsRtlDissectName( uniRemoteName,
1572 uniRemoteName = uniRemainingPath;
1574 if( uniRemoteName.Length > 0)
1577 FsRtlDissectName( uniRemoteName,
1582 if( RtlCompareUnicodeString( &uniServerName,
1587 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1590 if ( uniRemainingPath.Length > 0 )
1594 // Add back in the leading \ since it was stripped off above
1597 uniRemainingPath.Length += sizeof( WCHAR);
1598 if( uniRemainingPath.Length > uniRemainingPath.MaximumLength)
1600 uniRemainingPath.MaximumLength += sizeof( WCHAR);
1603 uniRemainingPath.Buffer--;
1605 uniRemainingPathLocal.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1606 uniRemainingPath.Length,
1607 AFS_NETWORK_PROVIDER_5_TAG);
1609 if( uniRemainingPathLocal.Buffer == NULL)
1612 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1613 AFS_TRACE_LEVEL_VERBOSE,
1614 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1616 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1619 uniRemainingPathLocal.MaximumLength = uniRemainingPath.Length;
1620 uniRemainingPathLocal.Length = uniRemainingPath.Length;
1622 RtlCopyMemory( uniRemainingPathLocal.Buffer,
1623 uniRemainingPath.Buffer,
1624 uniRemainingPath.Length);
1627 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1628 AFS_TRACE_LEVEL_VERBOSE,
1629 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1630 &pRDRDevExt->Specific.RDR.ProviderListLock,
1631 PsGetCurrentThread()));
1633 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1637 // If this is the server then return information about the
1641 if( uniShareName.Length == 0 &&
1642 RtlCompareUnicodeString( &uniServerName,
1647 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
1652 USHORT usNameLen = 0, usMaxNameLen = 0;
1655 // AFSGetConnectionInfo() is called to generate responses for
1656 // NPGetResourceInformation and NPGetConnectionPerformance.
1657 // The former can be called with a Connection->RemoteName that
1658 // consists of \\server\share\dir1\dir2\...\dirN where one or
1659 // all of the directories do not have to be processed by the
1660 // network provider. For example, one of the directories might
1661 // be a reparse point that redirects to another network provider.
1662 // It might also be the case that a directory might be in the
1663 // \\afs file namespace but not be accessible with the current
1664 // credentials. That doesn't make the connection invalid.
1665 // As such the network provider is not required to validate the
1666 // entire RemoteName. This can result in false positives.
1669 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1671 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1672 AFS_TRACE_LEVEL_VERBOSE,
1673 "AFSGetConnectionInfo Searching for full name %wZ\n",
1676 while (pConnection != NULL)
1680 // A partial match can be valid but it must occur on a
1681 // component boundary.
1684 if (pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
1685 usMaxNameLen < pConnection->RemoteName.Length &&
1686 (pConnection->RemoteName.Length == uniFullName.Length ||
1687 pConnection->RemoteName.Length < uniFullName.Length &&
1688 (uniFullName.Buffer[pConnection->RemoteName.Length/sizeof(WCHAR)] == L'\\' ||
1689 uniFullName.Buffer[pConnection->RemoteName.Length/sizeof(WCHAR)] == L'/')))
1692 usNameLen = uniFullName.Length;
1694 uniFullName.Length = pConnection->RemoteName.Length;
1696 if (RtlCompareUnicodeString( &uniFullName,
1697 &pConnection->RemoteName,
1701 usMaxNameLen = pConnection->RemoteName.Length;
1703 pBestMatch = pConnection;
1705 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1706 AFS_TRACE_LEVEL_VERBOSE,
1707 "AFSGetConnectionInfo Found match for %wZ\n",
1708 &pConnection->RemoteName));
1711 uniFullName.Length = usNameLen;
1714 pConnection = pConnection->fLink;
1717 pConnection = pBestMatch;
1719 if( pConnection != NULL)
1722 bEnumerationEntry = TRUE;
1724 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1725 AFS_TRACE_LEVEL_VERBOSE,
1726 "AFSGetConnectionInfo Using best match for %wZ\n",
1727 &pConnection->RemoteName));
1733 // Locate the entry for the share
1736 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1738 if (pConnection != NULL)
1741 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1742 AFS_TRACE_LEVEL_VERBOSE,
1743 "AFSGetConnectionInfo Using share connection %wZ\n",
1744 &pConnection->RemoteName));
1749 if( pConnection == NULL)
1751 UNICODE_STRING uniFullName;
1752 AFSDirEnumEntry *pDirEnumEntry = NULL;
1754 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1755 AFS_TRACE_LEVEL_VERBOSE,
1756 "AFSGetConnectionInfo No connection for full name %wZ\n",
1760 // Drop the lock, we will pick it up again later
1763 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1766 // OK, ask the CM about this component name
1769 ntStatus = AFSEvaluateTargetByName( NULL,
1770 &AFSGlobalRoot->ObjectInformation,
1775 if( !NT_SUCCESS( ntStatus))
1778 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1779 AFS_TRACE_LEVEL_VERBOSE,
1780 "AFSGetConnectionInfo Evaluation Failed share name %wZ\n",
1783 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1791 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_3_TAG);
1794 // The share name is valid
1795 // Allocate a new node and add it to our list
1797 uniFullName.MaximumLength = PAGE_SIZE;
1798 uniFullName.Length = 0;
1800 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1801 uniFullName.MaximumLength,
1802 AFS_NETWORK_PROVIDER_6_TAG);
1804 if( uniFullName.Buffer == NULL)
1807 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1808 AFS_TRACE_LEVEL_VERBOSE,
1809 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1811 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1814 uniFullName.Buffer[ 0] = L'\\';
1815 uniFullName.Buffer[ 1] = L'\\';
1817 uniFullName.Length = 2 * sizeof( WCHAR);
1819 RtlCopyMemory( &uniFullName.Buffer[ 2],
1820 AFSServerName.Buffer,
1821 AFSServerName.Length);
1823 uniFullName.Length += AFSServerName.Length;
1825 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
1827 uniFullName.Length += sizeof( WCHAR);
1829 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
1830 uniShareName.Buffer,
1831 uniShareName.Length);
1833 uniFullName.Length += uniShareName.Length;
1835 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1838 ntStatus = AFSAddConnectionEx( &uniFullName,
1839 RESOURCEDISPLAYTYPE_SHARE,
1842 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1844 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
1846 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1847 AFS_TRACE_LEVEL_VERBOSE,
1848 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1849 &pRDRDevExt->Specific.RDR.ProviderListLock,
1850 PsGetCurrentThread()));
1852 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1855 if ( NT_SUCCESS( ntStatus) )
1858 // Once again, locate the entry for the share we just created
1861 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1866 if( pConnection == NULL)
1869 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1870 AFS_TRACE_LEVEL_ERROR,
1871 "AFSGetConnectionInfo Failed to locate entry for full name %wZ\n",
1874 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1876 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1880 // Fill in the returned connection info block
1883 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1884 pConnection->RemoteName.Length +
1885 pConnection->Comment.Length +
1886 uniRemainingPath.Length)
1889 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1890 AFS_TRACE_LEVEL_VERBOSE,
1891 "AFSGetConnectionInfo Buffer too small for full name %wZ\n",
1894 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1896 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
1899 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1900 AFS_TRACE_LEVEL_VERBOSE,
1901 "AFSGetConnectionInfo Returning entry Scope %08lX partial name %wZ full name %wZ\n",
1902 pConnection->Scope, &pConnection->RemoteName, &uniFullName));
1904 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
1906 if( !bEnumerationEntry)
1909 RtlCopyMemory( ConnectCB->RemoteName,
1911 pConnection->RemoteName.Length);
1916 RtlCopyMemory( ConnectCB->RemoteName,
1917 pConnection->RemoteName.Buffer,
1918 pConnection->RemoteName.Length);
1921 ConnectCB->LocalName = pConnection->LocalName;
1923 ConnectCB->Type = pConnection->Type;
1925 ConnectCB->Scope = pConnection->Scope;
1927 ConnectCB->DisplayType = pConnection->DisplayType;
1929 ConnectCB->Usage = pConnection->Usage;
1931 ConnectCB->CommentLength = pConnection->Comment.Length;
1933 ConnectCB->RemainingPathLength = uniRemainingPathLocal.Length;
1935 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1936 AFS_TRACE_LEVEL_VERBOSE,
1937 "AFSGetConnectionInfo Returning lengths: remote %u comment %u remaining %u\n",
1938 ConnectCB->RemoteNameLength,
1939 ConnectCB->CommentLength,
1940 ConnectCB->RemainingPathLength));
1942 if( ConnectCB->CommentLength > 0)
1945 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1946 ConnectCB->RemoteNameLength);
1948 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
1949 pConnection->Comment.Buffer,
1950 ConnectCB->CommentLength);
1953 if ( ConnectCB->RemainingPathLength > 0 )
1956 ConnectCB->RemainingPathOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1957 ConnectCB->RemoteNameLength +
1958 ConnectCB->CommentLength);
1960 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->RemainingPathOffset),
1961 uniRemainingPathLocal.Buffer,
1962 uniRemainingPathLocal.Length);
1965 *ReturnOutputBufferLength = FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1966 ConnectCB->RemoteNameLength +
1967 ConnectCB->CommentLength +
1968 ConnectCB->RemainingPathLength;
1970 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1974 if ( uniRemainingPathLocal.Buffer )
1977 AFSExFreePoolWithTag( uniRemainingPathLocal.Buffer, 0);
1985 AFSIsDriveMapped( IN WCHAR DriveMapping)
1988 BOOLEAN bDriveMapped = FALSE;
1989 AFSProviderConnectionCB *pConnection = NULL;
1990 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1995 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1998 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
2000 while( pConnection != NULL)
2003 if( pConnection->LocalName != L'\0' &&
2004 RtlUpcaseUnicodeChar( pConnection->LocalName) == RtlUpcaseUnicodeChar( DriveMapping))
2007 bDriveMapped = TRUE;
2012 pConnection = pConnection->fLink;
2015 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
2018 return bDriveMapped;