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, uniServerName, uniShareName, uniRemainingPath;
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 uniServerName.Length = 0;
80 uniServerName.MaximumLength = 0;
81 uniServerName.Buffer = NULL;
83 uniShareName.Length = 0;
84 uniShareName.MaximumLength = 0;
85 uniShareName.Buffer = NULL;
87 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
91 // Look for the connection
94 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
95 uniRemoteName.MaximumLength = uniRemoteName.Length;
97 uniRemoteName.Buffer = ConnectCB->RemoteName;
100 // Strip off any trailing slashes
103 if( uniRemoteName.Length >= sizeof( WCHAR)
104 && uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
107 uniRemoteName.Length -= sizeof( WCHAR);
110 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
112 while( pConnection != NULL)
115 if( pConnection->LocalName != L'\0')
118 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
119 AFS_TRACE_LEVEL_VERBOSE,
120 "AFSAddConnection Comparing passed in %C to %C authentication id %I64X - %I64X\n",
121 ConnectCB->LocalName,
122 pConnection->LocalName,
123 ConnectCB->AuthenticationId.QuadPart,
124 pConnection->AuthenticationId.QuadPart));
129 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
130 AFS_TRACE_LEVEL_VERBOSE,
131 "AFSAddConnection Comparing passed in %C to (NULL) authentication id %I64X - %I64X\n",
132 ConnectCB->LocalName,
133 ConnectCB->AuthenticationId.QuadPart,
134 pConnection->AuthenticationId.QuadPart));
137 if( pConnection->LocalName == ConnectCB->LocalName &&
138 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
139 RtlCompareUnicodeString( &uniRemoteName,
140 &pConnection->RemoteName,
147 pConnection = pConnection->fLink;
150 if( pConnection != NULL)
153 if( ConnectCB->LocalName != L'\0')
156 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
157 AFS_TRACE_LEVEL_VERBOSE,
158 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local %C authentication id %I64X\n",
160 ConnectCB->LocalName,
161 ConnectCB->AuthenticationId.QuadPart));
163 *ResultStatus = WN_ALREADY_CONNECTED;
168 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
169 AFS_TRACE_LEVEL_VERBOSE,
170 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local (NULL) authentication id %I64X\n",
172 ConnectCB->AuthenticationId.QuadPart));
174 *ResultStatus = WN_SUCCESS;
177 *ReturnOutputBufferLength = sizeof( ULONG);
179 try_return( ntStatus = STATUS_SUCCESS);
183 // Validate the remote name
186 if( uniRemoteName.Length > 2 * sizeof( WCHAR) &&
187 uniRemoteName.Buffer[ 0] == L'\\' &&
188 uniRemoteName.Buffer[ 1] == L'\\')
191 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 2];
193 uniRemoteName.Length -= (2 * sizeof( WCHAR));
196 FsRtlDissectName( uniRemoteName,
200 if( RtlCompareUnicodeString( &uniServerName,
205 if( ConnectCB->LocalName != L'\0')
208 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
209 AFS_TRACE_LEVEL_VERBOSE,
210 "AFSAddConnection Bad Server Name remote name %wZ Local %C authentication id %I64X\n",
212 ConnectCB->LocalName,
213 ConnectCB->AuthenticationId.QuadPart));
218 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
219 AFS_TRACE_LEVEL_VERBOSE,
220 "AFSAddConnection Bad Server Name remote name %wZ Local (NULL) authentication id %I64X\n",
222 ConnectCB->AuthenticationId.QuadPart));
225 *ResultStatus = WN_BAD_NETNAME;
227 *ReturnOutputBufferLength = sizeof( ULONG);
229 try_return( ntStatus = STATUS_SUCCESS);
232 if (uniRemainingPath.Length > 0)
235 AFSProviderConnectionCB *pConnection;
237 FsRtlDissectName( uniRemainingPath,
241 pConnection = AFSLocateEnumRootEntry( &uniShareName);
243 if ( pConnection == NULL) {
245 if( ConnectCB->LocalName != L'\0')
248 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
249 AFS_TRACE_LEVEL_VERBOSE,
250 "AFSAddConnection Bad Share Name remote name %wZ Local %C authentication id %I64X\n",
252 ConnectCB->LocalName,
253 ConnectCB->AuthenticationId.QuadPart));
258 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
259 AFS_TRACE_LEVEL_VERBOSE,
260 "AFSAddConnection Bad Share Name remote name %wZ Local (NULL) authentication id %I64X\n",
262 ConnectCB->AuthenticationId.QuadPart));
265 *ResultStatus = WN_BAD_NETNAME;
267 *ReturnOutputBufferLength = sizeof( ULONG);
269 try_return( ntStatus = STATUS_SUCCESS);
273 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
274 uniRemoteName.MaximumLength = uniRemoteName.Length;
276 uniRemoteName.Buffer = ConnectCB->RemoteName;
279 // Strip off any trailing slashes
282 if( uniRemoteName.Length >= sizeof( WCHAR)
283 && uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
286 uniRemoteName.Length -= sizeof( WCHAR);
290 // Allocate a new node and add it to our list
293 pConnection = (AFSProviderConnectionCB *)AFSExAllocatePoolWithTag( PagedPool,
294 sizeof( AFSProviderConnectionCB) +
295 uniRemoteName.Length,
298 if( pConnection == NULL)
301 *ResultStatus = WN_OUT_OF_MEMORY;
303 *ReturnOutputBufferLength = sizeof( ULONG);
305 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
308 RtlZeroMemory( pConnection,
309 sizeof( AFSProviderConnectionCB) + uniRemoteName.Length);
311 pConnection->LocalName = ConnectCB->LocalName;
313 pConnection->RemoteName.Length = uniRemoteName.Length;
314 pConnection->RemoteName.MaximumLength = pConnection->RemoteName.Length;
316 pConnection->RemoteName.Buffer = (WCHAR *)((char *)pConnection + sizeof( AFSProviderConnectionCB));
318 RtlCopyMemory( pConnection->RemoteName.Buffer,
319 uniRemoteName.Buffer,
320 pConnection->RemoteName.Length);
322 pConnection->Type = ConnectCB->Type;
324 pConnection->AuthenticationId = ConnectCB->AuthenticationId;
326 if( ConnectCB->LocalName != L'\0')
329 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
330 AFS_TRACE_LEVEL_VERBOSE,
331 "AFSAddConnection Adding connection remote name %wZ Local %C authentication id %I64X\n",
333 ConnectCB->LocalName,
334 ConnectCB->AuthenticationId.QuadPart));
339 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
340 AFS_TRACE_LEVEL_VERBOSE,
341 "AFSAddConnection Adding connection remote name %wZ Local (NULL) authentication id %I64X\n",
343 ConnectCB->AuthenticationId.QuadPart));
347 // Point to the component portion of the name
350 pConnection->ComponentName.Length = 0;
351 pConnection->ComponentName.MaximumLength = 0;
353 pConnection->ComponentName.Buffer = &pConnection->RemoteName.Buffer[ (pConnection->RemoteName.Length/sizeof( WCHAR)) - 1];
355 while( pConnection->ComponentName.Length <= pConnection->RemoteName.Length)
358 if( pConnection->ComponentName.Buffer[ 0] == L'\\')
361 pConnection->ComponentName.Buffer++;
366 pConnection->ComponentName.Length += sizeof( WCHAR);
367 pConnection->ComponentName.MaximumLength += sizeof( WCHAR);
369 pConnection->ComponentName.Buffer--;
373 // Go initialize the information about the connection
376 AFSInitializeConnectionInfo( pConnection,
380 // Insert the entry into our list
383 if( pRDRDevExt->Specific.RDR.ProviderConnectionList == NULL)
386 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection;
392 // Get the end of the list
395 pLastConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
397 while( pLastConnection->fLink != NULL)
400 pLastConnection = pLastConnection->fLink;
403 pLastConnection->fLink = pConnection;
406 *ResultStatus = WN_SUCCESS;
408 *ReturnOutputBufferLength = sizeof( ULONG);
412 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
420 AFSCancelConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
421 IN OUT AFSCancelConnectionResultCB *ConnectionResult,
422 IN OUT ULONG_PTR *ReturnOutputBufferLength)
425 NTSTATUS ntStatus = STATUS_SUCCESS;
426 AFSProviderConnectionCB *pConnection = NULL, *pLastConnection = NULL;
427 UNICODE_STRING uniRemoteName;
428 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
433 ConnectionResult->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
435 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
436 AFS_TRACE_LEVEL_VERBOSE,
437 "AFSCancelConnection Acquiring AFSProviderListLock lock %p EXCL %08lX\n",
438 &pRDRDevExt->Specific.RDR.ProviderListLock,
439 PsGetCurrentThread()));
441 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
443 if ( !NT_SUCCESS( ntStatus))
446 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
447 AFS_TRACE_LEVEL_ERROR,
448 "AFSCancelConnection Unable to retrieve authentication id %08lX\n",
454 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
455 AFS_TRACE_LEVEL_VERBOSE,
456 "AFSCancelConnection Retrieved authentication id %I64X\n",
457 ConnectCB->AuthenticationId.QuadPart));
459 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
463 // Look for the connection
466 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
467 uniRemoteName.MaximumLength = uniRemoteName.Length;
469 uniRemoteName.Buffer = NULL;
471 if( uniRemoteName.Length > 0)
474 uniRemoteName.Buffer = ConnectCB->RemoteName;
477 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
479 while( pConnection != NULL)
482 if( ( ConnectCB->LocalName != L'\0' &&
483 pConnection->LocalName == ConnectCB->LocalName)
485 ( ConnectCB->LocalName == L'\0' &&
486 pConnection->LocalName == L'\0' &&
487 RtlCompareUnicodeString( &uniRemoteName,
488 &pConnection->RemoteName,
492 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
493 AFS_TRACE_LEVEL_VERBOSE,
494 "AFSCancelConnection Checking remote name %wZ to stored %wZ authentication id %I64X - %I64X\n",
496 &pConnection->RemoteName,
497 ConnectCB->AuthenticationId.QuadPart,
498 pConnection->AuthenticationId.QuadPart));
500 if( ConnectCB->AuthenticationId.QuadPart == pConnection->AuthenticationId.QuadPart &&
501 ( ConnectCB->LocalName == L'\0' ||
502 RtlCompareUnicodeString( &uniRemoteName,
503 &pConnection->RemoteName,
511 pLastConnection = pConnection;
513 pConnection = pConnection->fLink;
516 if( pConnection == NULL)
519 ConnectionResult->Status = WN_NOT_CONNECTED;
521 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
523 try_return( ntStatus);
526 if( pLastConnection == NULL)
529 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection->fLink;
534 pLastConnection->fLink = pConnection->fLink;
537 if( pConnection->Comment.Buffer != NULL)
540 AFSExFreePoolWithTag( pConnection->Comment.Buffer, 0);
543 ConnectionResult->LocalName = pConnection->LocalName;
545 AFSExFreePoolWithTag( pConnection, AFS_PROVIDER_CB);
547 ConnectionResult->Status = WN_SUCCESS;
549 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
553 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
560 AFSGetConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
561 IN OUT WCHAR *RemoteName,
562 IN ULONG RemoteNameBufferLength,
563 IN OUT ULONG_PTR *ReturnOutputBufferLength)
566 NTSTATUS ntStatus = STATUS_SUCCESS;
567 AFSProviderConnectionCB *pConnection = NULL;
568 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
573 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
575 if ( !NT_SUCCESS( ntStatus))
578 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
579 AFS_TRACE_LEVEL_ERROR,
580 "AFSGetConnection Unable to retrieve authentication id %08lX\n",
586 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
587 AFS_TRACE_LEVEL_VERBOSE,
588 "AFSGetConnection Retrieved authentication id %I64X\n",
589 ConnectCB->AuthenticationId.QuadPart));
591 if( ConnectCB->LocalName != L'\0')
594 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
595 AFS_TRACE_LEVEL_VERBOSE,
596 "AFSGetConnection Local %C authentication id %I64X\n",
597 ConnectCB->LocalName,
598 ConnectCB->AuthenticationId.QuadPart));
603 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
604 AFS_TRACE_LEVEL_VERBOSE,
605 "AFSGetConnection Local (NULL) authentication id %I64X\n",
606 ConnectCB->AuthenticationId.QuadPart));
609 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
610 AFS_TRACE_LEVEL_VERBOSE,
611 "AFSGetConnection Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
612 &pRDRDevExt->Specific.RDR.ProviderListLock,
613 PsGetCurrentThread()));
615 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
619 // Look for the connection
622 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
624 while( pConnection != NULL)
627 if( pConnection->LocalName != L'\0')
630 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
631 AFS_TRACE_LEVEL_VERBOSE,
632 "AFSGetConnection Comparing passed in %C to %C authentication id %I64X - %I64X\n",
633 ConnectCB->LocalName,
634 pConnection->LocalName,
635 ConnectCB->AuthenticationId.QuadPart,
636 pConnection->AuthenticationId.QuadPart));
641 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
642 AFS_TRACE_LEVEL_VERBOSE,
643 "AFSGetConnection Comparing passed in %C to (NULL) authentication id %I64X - %I64X\n",
644 ConnectCB->LocalName,
645 ConnectCB->AuthenticationId.QuadPart,
646 pConnection->AuthenticationId.QuadPart));
649 if( pConnection->LocalName == ConnectCB->LocalName &&
650 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart)
656 pConnection = pConnection->fLink;
659 if( pConnection == NULL)
662 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
663 AFS_TRACE_LEVEL_VERBOSE,
664 "AFSGetConnection INVALID_PARAMETER\n"));
666 try_return( ntStatus = STATUS_INVALID_PARAMETER);
669 if( RemoteNameBufferLength < pConnection->RemoteName.Length)
672 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
673 AFS_TRACE_LEVEL_VERBOSE,
674 "AFSGetConnection INSUFFICIENT_RESOURCES\n"));
676 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
679 RtlCopyMemory( RemoteName,
680 pConnection->RemoteName.Buffer,
681 pConnection->RemoteName.Length);
683 *ReturnOutputBufferLength = pConnection->RemoteName.Length;
687 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
694 AFSListConnections( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
695 IN ULONG ConnectionBufferLength,
696 IN OUT ULONG_PTR *ReturnOutputBufferLength)
699 NTSTATUS ntStatus = STATUS_SUCCESS;
700 AFSProviderConnectionCB *pConnection = NULL, *pRootConnection = NULL;
701 ULONG ulCopiedLength = 0, ulRemainingLength = ConnectionBufferLength;
702 ULONG ulScope, ulType;
703 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath;
704 BOOLEAN bGlobalEnumeration = FALSE;
706 LARGE_INTEGER liAuthenticationID = {0,0};
707 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
713 // Save off some data before moving on
716 ulScope = ConnectCB->Scope;
718 ulType = ConnectCB->Type;
720 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
722 if ( !NT_SUCCESS( ntStatus))
725 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
726 AFS_TRACE_LEVEL_ERROR,
727 "AFSListConnection Unable to retrieve authentication id %08lX\n",
733 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
734 AFS_TRACE_LEVEL_VERBOSE,
735 "AFSListConnections Retrieved authentication id %I64X\n",
736 ConnectCB->AuthenticationId.QuadPart));
738 liAuthenticationID.QuadPart = ConnectCB->AuthenticationId.QuadPart;
740 uniRemoteName.Length = 0;
741 uniRemoteName.MaximumLength = 0;
742 uniRemoteName.Buffer = NULL;
744 uniServerName.Length = 0;
745 uniServerName.MaximumLength = 0;
746 uniServerName.Buffer = NULL;
748 uniShareName.Length = 0;
749 uniShareName.MaximumLength = 0;
750 uniShareName.Buffer = NULL;
752 if( ConnectCB->RemoteNameLength > 0)
755 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
756 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
758 uniRemoteName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
759 uniRemoteName.MaximumLength,
760 AFS_NETWORK_PROVIDER_1_TAG);
762 if( uniRemoteName.Buffer == NULL)
765 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
768 RtlCopyMemory( uniRemoteName.Buffer,
769 ConnectCB->RemoteName,
770 uniRemoteName.Length);
772 if( uniRemoteName.Length >= 2 * sizeof( WCHAR)
773 && uniRemoteName.Buffer[ 0] == L'\\'
774 && uniRemoteName.Buffer[ 1] == L'\\')
777 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
779 uniRemoteName.Length -= sizeof( WCHAR);
782 if( uniRemoteName.Length >= sizeof( WCHAR)
783 && uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
786 uniRemoteName.Length -= sizeof( WCHAR);
789 FsRtlDissectName( uniRemoteName,
793 uniRemoteName = uniRemainingPath;
795 if( uniRemoteName.Length > 0)
798 FsRtlDissectName( uniRemoteName,
804 // If this is an enumeration of the global share name then
805 // adjust it to be the server name itself
808 if( uniShareName.Length == 0)
811 bGlobalEnumeration = TRUE;
815 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
816 AFS_TRACE_LEVEL_VERBOSE,
817 "AFSListConnections Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
818 &pRDRDevExt->Specific.RDR.ProviderListLock,
819 PsGetCurrentThread()));
821 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
825 // If this is a globalnet enumeration with no name then enumerate the server list
828 if( ulScope == RESOURCE_GLOBALNET)
831 if( uniServerName.Buffer == NULL)
834 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
840 // Go locate the root entry for the name passed in
843 if( bGlobalEnumeration)
846 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
849 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
851 try_return( ntStatus);
854 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
859 pRootConnection = AFSLocateEnumRootEntry( &uniShareName);
861 if( pRootConnection == NULL)
864 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
866 try_return( ntStatus);
870 // Need to handle these enumerations from the directory listing
873 ntStatus = AFSEnumerateConnection( ConnectCB,
875 ConnectionBufferLength,
883 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
886 ulIndex = ConnectCB->CurrentIndex;
888 while( pConnection != NULL)
891 if( bGlobalEnumeration &&
892 BooleanFlagOn( pConnection->Flags, AFS_CONNECTION_FLAG_GLOBAL_SHARE))
895 pConnection = pConnection->fLink;
900 if( ulScope != RESOURCE_GLOBALNET &&
901 !BooleanFlagOn( pConnection->Usage, RESOURCEUSAGE_ATTACHED))
904 pConnection = pConnection->fLink;
909 if( pConnection->LocalName != L'\0')
912 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
913 AFS_TRACE_LEVEL_VERBOSE,
914 "AFSListConnections Processing entry %wZ %C authentication id %I64X - %I64X Scope %08lX\n",
915 &pConnection->RemoteName,
916 pConnection->LocalName,
917 liAuthenticationID.QuadPart,
918 pConnection->AuthenticationId.QuadPart,
919 pConnection->Scope));
924 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
925 AFS_TRACE_LEVEL_VERBOSE,
926 "AFSListConnections Processing entry %wZ NULL LocalName authentication id %I64X - %I64X Scope %08lX\n",
927 &pConnection->RemoteName,
928 liAuthenticationID.QuadPart,
929 pConnection->AuthenticationId.QuadPart,
930 pConnection->Scope));
933 if( ulScope != RESOURCE_GLOBALNET &&
934 pConnection->AuthenticationId.QuadPart != liAuthenticationID.QuadPart)
937 pConnection = pConnection->fLink;
947 pConnection = pConnection->fLink;
952 if( ulRemainingLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
953 pConnection->RemoteName.Length +
954 pConnection->Comment.Length)
960 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
962 RtlCopyMemory( ConnectCB->RemoteName,
963 pConnection->RemoteName.Buffer,
964 pConnection->RemoteName.Length);
966 ConnectCB->LocalName = pConnection->LocalName;
968 ConnectCB->Type = pConnection->Type;
970 ConnectCB->Scope = pConnection->Scope;
972 if( !bGlobalEnumeration)
975 ConnectCB->Scope = RESOURCE_CONNECTED;
978 ConnectCB->DisplayType = pConnection->DisplayType;
980 ConnectCB->Usage = pConnection->Usage;
982 ConnectCB->CommentLength = pConnection->Comment.Length;
984 if( pConnection->Comment.Length > 0)
987 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
988 ConnectCB->RemoteNameLength);
990 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
991 pConnection->Comment.Buffer,
992 ConnectCB->CommentLength);
995 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
996 ConnectCB->RemoteNameLength +
997 ConnectCB->CommentLength;
999 ulRemainingLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1000 ConnectCB->RemoteNameLength +
1001 ConnectCB->CommentLength;
1003 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
1004 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1005 ConnectCB->RemoteNameLength +
1006 ConnectCB->CommentLength);
1008 pConnection = pConnection->fLink;
1011 if( NT_SUCCESS( ntStatus))
1014 *ReturnOutputBufferLength = ulCopiedLength;
1017 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1021 if( uniRemoteName.Buffer != NULL)
1024 AFSExFreePoolWithTag( uniRemoteName.Buffer, 0);
1032 AFSInitializeConnectionInfo( IN AFSProviderConnectionCB *Connection,
1033 IN ULONG DisplayType)
1036 NTSTATUS ntStatus = STATUS_SUCCESS;
1037 UNICODE_STRING uniName, uniComponentName, uniRemainingName;
1042 uniName = Connection->RemoteName;
1045 // Strip off the double leading slash if there is one
1048 if( uniName.Length >= 2 * sizeof( WCHAR)
1049 && uniName.Buffer[ 0] == L'\\'
1050 && uniName.Buffer[ 1] == L'\\')
1053 uniName.Buffer = &uniName.Buffer[ 1];
1055 uniName.Length -= sizeof( WCHAR);
1059 FsRtlDissectName( uniName,
1064 // Initialize the information for the connection
1065 // First, if this is the server only then mark it accordingly
1068 if( uniRemainingName.Length == 0 ||
1069 DisplayType == RESOURCEDISPLAYTYPE_SERVER)
1072 Connection->Type = RESOURCETYPE_DISK;
1074 Connection->Scope = 0;
1076 Connection->DisplayType = RESOURCEDISPLAYTYPE_SERVER;
1078 Connection->Usage = RESOURCEUSAGE_CONTAINER;
1080 Connection->Comment.Length = 20;
1081 Connection->Comment.MaximumLength = 22;
1083 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1084 Connection->Comment.MaximumLength,
1085 AFS_NETWORK_PROVIDER_2_TAG);
1087 if( Connection->Comment.Buffer != NULL)
1090 RtlZeroMemory( Connection->Comment.Buffer,
1091 Connection->Comment.MaximumLength);
1093 RtlCopyMemory( Connection->Comment.Buffer,
1100 Connection->Comment.Length = 0;
1101 Connection->Comment.MaximumLength = 0;
1104 try_return( ntStatus);
1107 uniName = uniRemainingName;
1109 FsRtlDissectName( uniName,
1113 if( uniRemainingName.Length == 0 ||
1114 uniRemainingName.Buffer == NULL ||
1115 DisplayType == RESOURCEDISPLAYTYPE_SHARE)
1118 Connection->Type = RESOURCETYPE_DISK;
1120 Connection->DisplayType = RESOURCEDISPLAYTYPE_SHARE;
1122 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1124 if( Connection->LocalName != L'\0')
1127 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1129 Connection->Scope = RESOURCE_CONNECTED;
1134 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1136 Connection->Scope = RESOURCE_GLOBALNET;
1139 Connection->Comment.Length = 18;
1140 Connection->Comment.MaximumLength = 20;
1142 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1143 Connection->Comment.MaximumLength,
1144 AFS_NETWORK_PROVIDER_3_TAG);
1146 if( Connection->Comment.Buffer != NULL)
1149 RtlZeroMemory( Connection->Comment.Buffer,
1150 Connection->Comment.MaximumLength);
1152 RtlCopyMemory( Connection->Comment.Buffer,
1159 Connection->Comment.Length = 0;
1160 Connection->Comment.MaximumLength = 0;
1163 try_return( ntStatus);
1167 // This is a sub directory within a share
1170 Connection->Type = RESOURCETYPE_DISK;
1172 Connection->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1174 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1176 if( Connection->LocalName != L'\0')
1179 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1184 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1187 Connection->Scope = RESOURCE_CONNECTED;
1189 Connection->Comment.Length = 26;
1190 Connection->Comment.MaximumLength = 28;
1192 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1193 Connection->Comment.MaximumLength,
1194 AFS_NETWORK_PROVIDER_4_TAG);
1196 if( Connection->Comment.Buffer != NULL)
1199 RtlZeroMemory( Connection->Comment.Buffer,
1200 Connection->Comment.MaximumLength);
1202 RtlCopyMemory( Connection->Comment.Buffer,
1209 Connection->Comment.Length = 0;
1210 Connection->Comment.MaximumLength = 0;
1221 AFSProviderConnectionCB *
1222 AFSLocateEnumRootEntry( IN UNICODE_STRING *RemoteName)
1225 AFSProviderConnectionCB *pConnection = NULL;
1226 UNICODE_STRING uniRemoteName = *RemoteName;
1227 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1232 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
1235 try_return( pConnection);
1238 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
1240 while( pConnection != NULL)
1243 if( RtlCompareUnicodeString( &uniRemoteName,
1244 &pConnection->ComponentName,
1251 pConnection = pConnection->fLink;
1263 AFSEnumerateConnection( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
1264 IN AFSProviderConnectionCB *RootConnection,
1265 IN ULONG BufferLength,
1266 OUT PULONG CopiedLength)
1269 NTSTATUS ntStatus = STATUS_SUCCESS;
1270 ULONG ulCRC = 0, ulCopiedLength = 0;
1271 AFSDirectoryCB *pShareDirEntry = NULL;
1272 AFSDirectoryCB *pDirEntry = NULL, *pTargetDirEntry = NULL;
1279 if( AFSGlobalRoot == NULL)
1282 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1283 AFS_TRACE_LEVEL_ERROR,
1284 "AFSEnumerateConnection Global root not yet initialized\n"));
1286 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1289 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1293 // Grab our tree lock shared
1296 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1297 AFS_TRACE_LEVEL_VERBOSE,
1298 "AFSEnumerateConnection Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p SHARED %08lX\n",
1299 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1300 PsGetCurrentThread()));
1302 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1306 // Locate the dir entry for this node
1309 ntStatus = AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1313 if( pShareDirEntry == NULL ||
1314 !NT_SUCCESS( ntStatus))
1318 // Perform a case insensitive search
1321 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1324 ntStatus = AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1328 if( pShareDirEntry == NULL ||
1329 !NT_SUCCESS( ntStatus))
1332 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1334 try_return( ntStatus);
1338 // Here we have a match on the case insensitive lookup for the name. If there
1339 // Is more than one link entry for this node then fail the lookup request
1342 if( !BooleanFlagOn( pShareDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
1343 pShareDirEntry->CaseInsensitiveList.fLink != NULL)
1346 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1348 pShareDirEntry = NULL;
1350 try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION);
1354 lCount = InterlockedIncrement( &pShareDirEntry->DirOpenReferenceCount);
1356 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1357 AFS_TRACE_LEVEL_VERBOSE,
1358 "AFSEnumerateConnection1 Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1359 &pShareDirEntry->NameInformation.FileName,
1364 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1367 // Setup the request to evaluate the entry
1368 // On success, pTargetDirEntry has the DirOpenReferenceCount held
1371 ntStatus = AFSEvaluateRootEntry( pShareDirEntry,
1374 if( !NT_SUCCESS( ntStatus))
1377 try_return( ntStatus);
1380 AFSAcquireShared( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1384 // Enumerate the content
1387 pDirEntry = pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
1389 ulIndex = ConnectCB->CurrentIndex;
1391 while( pDirEntry != NULL)
1399 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1404 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1405 pDirEntry->NameInformation.FileName.Length)
1411 ConnectCB->LocalName = L'\0';
1413 ConnectCB->RemoteNameLength = pDirEntry->NameInformation.FileName.Length;
1415 RtlCopyMemory( ConnectCB->RemoteName,
1416 pDirEntry->NameInformation.FileName.Buffer,
1417 pDirEntry->NameInformation.FileName.Length);
1419 ConnectCB->Type = RESOURCETYPE_DISK;
1421 ConnectCB->Scope = RESOURCE_CONNECTED;
1423 if( BooleanFlagOn( pDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1426 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1431 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_FILE;
1434 ConnectCB->Usage = 0;
1436 ConnectCB->CommentLength = 0;
1438 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1439 pDirEntry->NameInformation.FileName.Length;
1441 BufferLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1442 pDirEntry->NameInformation.FileName.Length;
1444 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
1445 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1446 ConnectCB->RemoteNameLength);
1448 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1452 // Release the DirOpenReferenceCount obtained from AFSEvaluateRootEntry
1455 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
1457 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1458 AFS_TRACE_LEVEL_VERBOSE,
1459 "AFSEnumerateConnection Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1460 &pTargetDirEntry->NameInformation.FileName,
1465 ASSERT( lCount >= 0);
1467 *CopiedLength = ulCopiedLength;
1469 AFSReleaseResource( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1473 if( pShareDirEntry != NULL)
1475 lCount = InterlockedDecrement( &pShareDirEntry->DirOpenReferenceCount);
1477 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1478 AFS_TRACE_LEVEL_VERBOSE,
1479 "AFSEnumerateConnection1 Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1480 &pShareDirEntry->NameInformation.FileName,
1485 ASSERT( lCount >= 0);
1493 AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
1494 IN ULONG BufferLength,
1495 IN OUT ULONG_PTR *ReturnOutputBufferLength)
1498 NTSTATUS ntStatus = STATUS_SUCCESS;
1499 AFSProviderConnectionCB *pConnection = NULL, *pBestMatch = NULL;
1500 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath, uniFullName, uniRemainingPathLocal;
1501 BOOLEAN bEnumerationEntry = FALSE;
1502 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1507 uniServerName.Length = 0;
1508 uniServerName.MaximumLength = 0;
1509 uniServerName.Buffer = NULL;
1511 uniShareName.Length = 0;
1512 uniShareName.MaximumLength = 0;
1513 uniShareName.Buffer = NULL;
1515 uniRemainingPathLocal.Length = 0;
1516 uniRemainingPathLocal.MaximumLength = 0;
1517 uniRemainingPathLocal.Buffer = NULL;
1519 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
1520 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
1521 uniRemoteName.Buffer = (WCHAR *)ConnectCB->RemoteName;
1523 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
1525 if ( !NT_SUCCESS( ntStatus))
1528 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1529 AFS_TRACE_LEVEL_ERROR,
1530 "AFSGetConnectionInfo Unable to retrieve authentication id %08lX\n",
1536 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1537 AFS_TRACE_LEVEL_VERBOSE,
1538 "AFSGetConnectionInfo Retrieved authentication id %I64X\n",
1539 ConnectCB->AuthenticationId.QuadPart));
1541 if( ConnectCB->LocalName != L'\0')
1544 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1545 AFS_TRACE_LEVEL_VERBOSE,
1546 "AFSGetConnectionInfo remote name %wZ Local %C authentication id %I64X\n",
1548 ConnectCB->LocalName,
1549 ConnectCB->AuthenticationId.QuadPart));
1554 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1555 AFS_TRACE_LEVEL_VERBOSE,
1556 "AFSGetConnectionInfo remote name %wZ Local (NULL) authentication id %I64X\n",
1558 ConnectCB->AuthenticationId.QuadPart));
1561 if( AFSGlobalRoot == NULL)
1564 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1565 AFS_TRACE_LEVEL_ERROR,
1566 "AFSGetConnectionInfo Global root not yet initialized\n"));
1568 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1571 uniFullName = uniRemoteName;
1573 if( uniRemoteName.Length >= 2 * sizeof( WCHAR)
1574 && uniRemoteName.Buffer[ 0] == L'\\'
1575 && uniRemoteName.Buffer[ 1] == L'\\')
1578 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
1580 uniRemoteName.Length -= sizeof( WCHAR);
1583 if( uniRemoteName.Length >= sizeof( WCHAR)
1584 && uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
1587 uniRemoteName.Length -= sizeof( WCHAR);
1589 uniFullName.Length -= sizeof( WCHAR);
1592 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1593 AFS_TRACE_LEVEL_VERBOSE,
1594 "AFSGetConnectionInfo Processing name %wZ\n",
1597 FsRtlDissectName( uniRemoteName,
1601 uniRemoteName = uniRemainingPath;
1603 if( uniRemoteName.Length > 0)
1606 FsRtlDissectName( uniRemoteName,
1611 if( RtlCompareUnicodeString( &uniServerName,
1616 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
1619 if ( uniRemainingPath.Length > 0 )
1623 // Add back in the leading \ since it was stripped off above
1626 uniRemainingPath.Length += sizeof( WCHAR);
1627 if( uniRemainingPath.Length > uniRemainingPath.MaximumLength)
1629 uniRemainingPath.MaximumLength += sizeof( WCHAR);
1632 uniRemainingPath.Buffer--;
1634 uniRemainingPathLocal.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1635 uniRemainingPath.Length,
1636 AFS_NETWORK_PROVIDER_5_TAG);
1638 if( uniRemainingPathLocal.Buffer == NULL)
1641 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1642 AFS_TRACE_LEVEL_VERBOSE,
1643 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1645 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1648 uniRemainingPathLocal.MaximumLength = uniRemainingPath.Length;
1649 uniRemainingPathLocal.Length = uniRemainingPath.Length;
1651 RtlCopyMemory( uniRemainingPathLocal.Buffer,
1652 uniRemainingPath.Buffer,
1653 uniRemainingPath.Length);
1656 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1657 AFS_TRACE_LEVEL_VERBOSE,
1658 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1659 &pRDRDevExt->Specific.RDR.ProviderListLock,
1660 PsGetCurrentThread()));
1662 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1666 // If this is the server then return information about the
1670 if( uniShareName.Length == 0 &&
1671 RtlCompareUnicodeString( &uniServerName,
1676 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
1681 USHORT usNameLen = 0, usMaxNameLen = 0;
1684 // AFSGetConnectionInfo() is called to generate responses for
1685 // NPGetResourceInformation and NPGetConnectionPerformance.
1686 // The former can be called with a Connection->RemoteName that
1687 // consists of \\server\share\dir1\dir2\...\dirN where one or
1688 // all of the directories do not have to be processed by the
1689 // network provider. For example, one of the directories might
1690 // be a reparse point that redirects to another network provider.
1691 // It might also be the case that a directory might be in the
1692 // \\afs file namespace but not be accessible with the current
1693 // credentials. That doesn't make the connection invalid.
1694 // As such the network provider is not required to validate the
1695 // entire RemoteName. This can result in false positives.
1698 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1700 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1701 AFS_TRACE_LEVEL_VERBOSE,
1702 "AFSGetConnectionInfo Searching for full name %wZ\n",
1705 while (pConnection != NULL)
1709 // A partial match can be valid but it must occur on a
1710 // component boundary.
1713 if (pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
1714 usMaxNameLen < pConnection->RemoteName.Length &&
1715 (pConnection->RemoteName.Length == uniFullName.Length ||
1716 pConnection->RemoteName.Length < uniFullName.Length &&
1717 (uniFullName.Buffer[pConnection->RemoteName.Length/sizeof(WCHAR)] == L'\\' ||
1718 uniFullName.Buffer[pConnection->RemoteName.Length/sizeof(WCHAR)] == L'/')))
1721 usNameLen = uniFullName.Length;
1723 uniFullName.Length = pConnection->RemoteName.Length;
1725 if (RtlCompareUnicodeString( &uniFullName,
1726 &pConnection->RemoteName,
1730 usMaxNameLen = pConnection->RemoteName.Length;
1732 pBestMatch = pConnection;
1734 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1735 AFS_TRACE_LEVEL_VERBOSE,
1736 "AFSGetConnectionInfo Found match for %wZ\n",
1737 &pConnection->RemoteName));
1740 uniFullName.Length = usNameLen;
1743 pConnection = pConnection->fLink;
1746 pConnection = pBestMatch;
1748 if( pConnection != NULL)
1751 bEnumerationEntry = TRUE;
1753 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1754 AFS_TRACE_LEVEL_VERBOSE,
1755 "AFSGetConnectionInfo Using best match for %wZ\n",
1756 &pConnection->RemoteName));
1762 // Locate the entry for the share
1765 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1767 if (pConnection != NULL)
1770 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1771 AFS_TRACE_LEVEL_VERBOSE,
1772 "AFSGetConnectionInfo Using share connection %wZ\n",
1773 &pConnection->RemoteName));
1778 if( pConnection == NULL)
1780 UNICODE_STRING uniFullName;
1781 AFSDirEnumEntry *pDirEnumEntry = NULL;
1783 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1784 AFS_TRACE_LEVEL_VERBOSE,
1785 "AFSGetConnectionInfo No connection for full name %wZ\n",
1789 // Drop the lock, we will pick it up again later
1792 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1795 // OK, ask the CM about this component name
1798 ntStatus = AFSEvaluateTargetByName( NULL,
1799 &AFSGlobalRoot->ObjectInformation,
1804 if( !NT_SUCCESS( ntStatus))
1807 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1808 AFS_TRACE_LEVEL_VERBOSE,
1809 "AFSGetConnectionInfo Evaluation Failed share name %wZ\n",
1812 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
1820 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_3_TAG);
1823 // The share name is valid
1824 // Allocate a new node and add it to our list
1826 uniFullName.MaximumLength = PAGE_SIZE;
1827 uniFullName.Length = 0;
1829 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1830 uniFullName.MaximumLength,
1831 AFS_NETWORK_PROVIDER_6_TAG);
1833 if( uniFullName.Buffer == NULL)
1836 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1837 AFS_TRACE_LEVEL_VERBOSE,
1838 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1840 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1843 uniFullName.Buffer[ 0] = L'\\';
1844 uniFullName.Buffer[ 1] = L'\\';
1846 uniFullName.Length = 2 * sizeof( WCHAR);
1848 RtlCopyMemory( &uniFullName.Buffer[ 2],
1849 AFSServerName.Buffer,
1850 AFSServerName.Length);
1852 uniFullName.Length += AFSServerName.Length;
1854 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
1856 uniFullName.Length += sizeof( WCHAR);
1858 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
1859 uniShareName.Buffer,
1860 uniShareName.Length);
1862 uniFullName.Length += uniShareName.Length;
1864 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1867 ntStatus = AFSAddConnectionEx( &uniFullName,
1868 RESOURCEDISPLAYTYPE_SHARE,
1871 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1873 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
1875 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1876 AFS_TRACE_LEVEL_VERBOSE,
1877 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1878 &pRDRDevExt->Specific.RDR.ProviderListLock,
1879 PsGetCurrentThread()));
1881 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1884 if ( NT_SUCCESS( ntStatus) )
1887 // Once again, locate the entry for the share we just created
1890 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1895 if( pConnection == NULL)
1898 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1899 AFS_TRACE_LEVEL_ERROR,
1900 "AFSGetConnectionInfo Failed to locate entry for full name %wZ\n",
1903 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1905 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1909 // Fill in the returned connection info block
1912 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1913 pConnection->RemoteName.Length +
1914 pConnection->Comment.Length +
1915 uniRemainingPath.Length)
1918 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1919 AFS_TRACE_LEVEL_VERBOSE,
1920 "AFSGetConnectionInfo Buffer too small for full name %wZ\n",
1923 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1925 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
1928 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1929 AFS_TRACE_LEVEL_VERBOSE,
1930 "AFSGetConnectionInfo Returning entry Scope %08lX partial name %wZ full name %wZ\n",
1931 pConnection->Scope, &pConnection->RemoteName, &uniFullName));
1933 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
1935 if( !bEnumerationEntry)
1938 RtlCopyMemory( ConnectCB->RemoteName,
1940 pConnection->RemoteName.Length);
1945 RtlCopyMemory( ConnectCB->RemoteName,
1946 pConnection->RemoteName.Buffer,
1947 pConnection->RemoteName.Length);
1950 ConnectCB->LocalName = pConnection->LocalName;
1952 ConnectCB->Type = pConnection->Type;
1954 ConnectCB->Scope = pConnection->Scope;
1956 ConnectCB->DisplayType = pConnection->DisplayType;
1958 ConnectCB->Usage = pConnection->Usage;
1960 ConnectCB->CommentLength = pConnection->Comment.Length;
1962 ConnectCB->RemainingPathLength = uniRemainingPathLocal.Length;
1964 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1965 AFS_TRACE_LEVEL_VERBOSE,
1966 "AFSGetConnectionInfo Returning lengths: remote %u comment %u remaining %u\n",
1967 ConnectCB->RemoteNameLength,
1968 ConnectCB->CommentLength,
1969 ConnectCB->RemainingPathLength));
1971 if( ConnectCB->CommentLength > 0)
1974 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1975 ConnectCB->RemoteNameLength);
1977 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
1978 pConnection->Comment.Buffer,
1979 ConnectCB->CommentLength);
1982 if ( ConnectCB->RemainingPathLength > 0 )
1985 ConnectCB->RemainingPathOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1986 ConnectCB->RemoteNameLength +
1987 ConnectCB->CommentLength);
1989 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->RemainingPathOffset),
1990 uniRemainingPathLocal.Buffer,
1991 uniRemainingPathLocal.Length);
1994 *ReturnOutputBufferLength = FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1995 ConnectCB->RemoteNameLength +
1996 ConnectCB->CommentLength +
1997 ConnectCB->RemainingPathLength;
1999 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
2003 if ( uniRemainingPathLocal.Buffer )
2006 AFSExFreePoolWithTag( uniRemainingPathLocal.Buffer, 0);
2014 AFSIsDriveMapped( IN WCHAR DriveMapping)
2017 BOOLEAN bDriveMapped = FALSE;
2018 AFSProviderConnectionCB *pConnection = NULL;
2019 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2024 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
2027 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
2029 while( pConnection != NULL)
2032 if( pConnection->LocalName != L'\0' &&
2033 RtlUpcaseUnicodeChar( pConnection->LocalName) == RtlUpcaseUnicodeChar( DriveMapping))
2036 bDriveMapped = TRUE;
2041 pConnection = pConnection->fLink;
2044 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
2047 return bDriveMapped;