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 lCount = InterlockedIncrement( &pShareDirEntry->DirOpenReferenceCount);
1340 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1341 AFS_TRACE_LEVEL_VERBOSE,
1342 "AFSEnumerateConnection1 Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1343 &pShareDirEntry->NameInformation.FileName,
1348 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1351 // Setup the request to evaluate the entry
1352 // On success, pTargetDirEntry has the DirOpenReferenceCount held
1355 ntStatus = AFSEvaluateRootEntry( pShareDirEntry,
1358 if( !NT_SUCCESS( ntStatus))
1361 try_return( ntStatus);
1364 AFSAcquireShared( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1368 // Enumerate the content
1371 pDirEntry = pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
1373 ulIndex = ConnectCB->CurrentIndex;
1375 while( pDirEntry != NULL)
1383 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1388 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1389 pDirEntry->NameInformation.FileName.Length)
1395 ConnectCB->LocalName = L'\0';
1397 ConnectCB->RemoteNameLength = pDirEntry->NameInformation.FileName.Length;
1399 RtlCopyMemory( ConnectCB->RemoteName,
1400 pDirEntry->NameInformation.FileName.Buffer,
1401 pDirEntry->NameInformation.FileName.Length);
1403 ConnectCB->Type = RESOURCETYPE_DISK;
1405 ConnectCB->Scope = RESOURCE_CONNECTED;
1407 if( BooleanFlagOn( pDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1410 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1415 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_FILE;
1418 ConnectCB->Usage = 0;
1420 ConnectCB->CommentLength = 0;
1422 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1423 pDirEntry->NameInformation.FileName.Length;
1425 BufferLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1426 pDirEntry->NameInformation.FileName.Length;
1428 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
1429 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1430 ConnectCB->RemoteNameLength);
1432 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1436 // Release the DirOpenReferenceCount obtained from AFSEvaluateRootEntry
1439 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
1441 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1442 AFS_TRACE_LEVEL_VERBOSE,
1443 "AFSEnumerateConnection Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1444 &pTargetDirEntry->NameInformation.FileName,
1449 ASSERT( lCount >= 0);
1451 *CopiedLength = ulCopiedLength;
1453 AFSReleaseResource( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1457 if( pShareDirEntry != NULL)
1459 lCount = InterlockedDecrement( &pShareDirEntry->DirOpenReferenceCount);
1461 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1462 AFS_TRACE_LEVEL_VERBOSE,
1463 "AFSEnumerateConnection1 Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1464 &pShareDirEntry->NameInformation.FileName,
1469 ASSERT( lCount >= 0);
1477 AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
1478 IN ULONG BufferLength,
1479 IN OUT ULONG_PTR *ReturnOutputBufferLength)
1482 NTSTATUS ntStatus = STATUS_SUCCESS;
1483 AFSProviderConnectionCB *pConnection = NULL, *pBestMatch = NULL;
1484 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath, uniFullName, uniRemainingPathLocal;
1485 BOOLEAN bEnumerationEntry = FALSE;
1486 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1491 uniServerName.Length = 0;
1492 uniServerName.MaximumLength = 0;
1493 uniServerName.Buffer = NULL;
1495 uniShareName.Length = 0;
1496 uniShareName.MaximumLength = 0;
1497 uniShareName.Buffer = NULL;
1499 uniRemainingPathLocal.Length = 0;
1500 uniRemainingPathLocal.MaximumLength = 0;
1501 uniRemainingPathLocal.Buffer = NULL;
1503 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
1504 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
1505 uniRemoteName.Buffer = (WCHAR *)ConnectCB->RemoteName;
1507 ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
1509 if ( !NT_SUCCESS( ntStatus))
1512 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1513 AFS_TRACE_LEVEL_ERROR,
1514 "AFSGetConnectionInfo Unable to retrieve authentication id %08lX\n",
1520 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1521 AFS_TRACE_LEVEL_VERBOSE,
1522 "AFSGetConnectionInfo Retrieved authentication id %I64X\n",
1523 ConnectCB->AuthenticationId.QuadPart));
1525 if( ConnectCB->LocalName != L'\0')
1528 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1529 AFS_TRACE_LEVEL_VERBOSE,
1530 "AFSGetConnectionInfo remote name %wZ Local %C authentication id %I64X\n",
1532 ConnectCB->LocalName,
1533 ConnectCB->AuthenticationId.QuadPart));
1538 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1539 AFS_TRACE_LEVEL_VERBOSE,
1540 "AFSGetConnectionInfo remote name %wZ Local (NULL) authentication id %I64X\n",
1542 ConnectCB->AuthenticationId.QuadPart));
1545 if( AFSGlobalRoot == NULL)
1548 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1549 AFS_TRACE_LEVEL_ERROR,
1550 "AFSGetConnectionInfo Global root not yet initialized\n"));
1552 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1555 uniFullName = uniRemoteName;
1557 if( uniRemoteName.Length >= 2 * sizeof( WCHAR)
1558 && uniRemoteName.Buffer[ 0] == L'\\'
1559 && uniRemoteName.Buffer[ 1] == L'\\')
1562 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
1564 uniRemoteName.Length -= sizeof( WCHAR);
1567 if( uniRemoteName.Length >= sizeof( WCHAR)
1568 && uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
1571 uniRemoteName.Length -= sizeof( WCHAR);
1573 uniFullName.Length -= sizeof( WCHAR);
1576 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1577 AFS_TRACE_LEVEL_VERBOSE,
1578 "AFSGetConnectionInfo Processing name %wZ\n",
1581 FsRtlDissectName( uniRemoteName,
1585 uniRemoteName = uniRemainingPath;
1587 if( uniRemoteName.Length > 0)
1590 FsRtlDissectName( uniRemoteName,
1595 if( RtlCompareUnicodeString( &uniServerName,
1600 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
1603 if ( uniRemainingPath.Length > 0 )
1607 // Add back in the leading \ since it was stripped off above
1610 uniRemainingPath.Length += sizeof( WCHAR);
1611 if( uniRemainingPath.Length > uniRemainingPath.MaximumLength)
1613 uniRemainingPath.MaximumLength += sizeof( WCHAR);
1616 uniRemainingPath.Buffer--;
1618 uniRemainingPathLocal.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1619 uniRemainingPath.Length,
1620 AFS_NETWORK_PROVIDER_5_TAG);
1622 if( uniRemainingPathLocal.Buffer == NULL)
1625 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1626 AFS_TRACE_LEVEL_VERBOSE,
1627 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1629 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1632 uniRemainingPathLocal.MaximumLength = uniRemainingPath.Length;
1633 uniRemainingPathLocal.Length = uniRemainingPath.Length;
1635 RtlCopyMemory( uniRemainingPathLocal.Buffer,
1636 uniRemainingPath.Buffer,
1637 uniRemainingPath.Length);
1640 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1641 AFS_TRACE_LEVEL_VERBOSE,
1642 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1643 &pRDRDevExt->Specific.RDR.ProviderListLock,
1644 PsGetCurrentThread()));
1646 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1650 // If this is the server then return information about the
1654 if( uniShareName.Length == 0 &&
1655 RtlCompareUnicodeString( &uniServerName,
1660 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
1665 USHORT usNameLen = 0, usMaxNameLen = 0;
1668 // AFSGetConnectionInfo() is called to generate responses for
1669 // NPGetResourceInformation and NPGetConnectionPerformance.
1670 // The former can be called with a Connection->RemoteName that
1671 // consists of \\server\share\dir1\dir2\...\dirN where one or
1672 // all of the directories do not have to be processed by the
1673 // network provider. For example, one of the directories might
1674 // be a reparse point that redirects to another network provider.
1675 // It might also be the case that a directory might be in the
1676 // \\afs file namespace but not be accessible with the current
1677 // credentials. That doesn't make the connection invalid.
1678 // As such the network provider is not required to validate the
1679 // entire RemoteName. This can result in false positives.
1682 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1684 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1685 AFS_TRACE_LEVEL_VERBOSE,
1686 "AFSGetConnectionInfo Searching for full name %wZ\n",
1689 while (pConnection != NULL)
1693 // A partial match can be valid but it must occur on a
1694 // component boundary.
1697 if (pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
1698 usMaxNameLen < pConnection->RemoteName.Length &&
1699 (pConnection->RemoteName.Length == uniFullName.Length ||
1700 pConnection->RemoteName.Length < uniFullName.Length &&
1701 (uniFullName.Buffer[pConnection->RemoteName.Length/sizeof(WCHAR)] == L'\\' ||
1702 uniFullName.Buffer[pConnection->RemoteName.Length/sizeof(WCHAR)] == L'/')))
1705 usNameLen = uniFullName.Length;
1707 uniFullName.Length = pConnection->RemoteName.Length;
1709 if (RtlCompareUnicodeString( &uniFullName,
1710 &pConnection->RemoteName,
1714 usMaxNameLen = pConnection->RemoteName.Length;
1716 pBestMatch = pConnection;
1718 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1719 AFS_TRACE_LEVEL_VERBOSE,
1720 "AFSGetConnectionInfo Found match for %wZ\n",
1721 &pConnection->RemoteName));
1724 uniFullName.Length = usNameLen;
1727 pConnection = pConnection->fLink;
1730 pConnection = pBestMatch;
1732 if( pConnection != NULL)
1735 bEnumerationEntry = TRUE;
1737 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1738 AFS_TRACE_LEVEL_VERBOSE,
1739 "AFSGetConnectionInfo Using best match for %wZ\n",
1740 &pConnection->RemoteName));
1746 // Locate the entry for the share
1749 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1751 if (pConnection != NULL)
1754 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1755 AFS_TRACE_LEVEL_VERBOSE,
1756 "AFSGetConnectionInfo Using share connection %wZ\n",
1757 &pConnection->RemoteName));
1762 if( pConnection == NULL)
1764 UNICODE_STRING uniFullName;
1765 AFSDirEnumEntry *pDirEnumEntry = NULL;
1767 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1768 AFS_TRACE_LEVEL_VERBOSE,
1769 "AFSGetConnectionInfo No connection for full name %wZ\n",
1773 // Drop the lock, we will pick it up again later
1776 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1779 // OK, ask the CM about this component name
1782 ntStatus = AFSEvaluateTargetByName( NULL,
1783 &AFSGlobalRoot->ObjectInformation,
1788 if( !NT_SUCCESS( ntStatus))
1791 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1792 AFS_TRACE_LEVEL_VERBOSE,
1793 "AFSGetConnectionInfo Evaluation Failed share name %wZ\n",
1796 try_return( ntStatus = STATUS_BAD_NETWORK_NAME);
1804 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_3_TAG);
1807 // The share name is valid
1808 // Allocate a new node and add it to our list
1810 uniFullName.MaximumLength = PAGE_SIZE;
1811 uniFullName.Length = 0;
1813 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1814 uniFullName.MaximumLength,
1815 AFS_NETWORK_PROVIDER_6_TAG);
1817 if( uniFullName.Buffer == NULL)
1820 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1821 AFS_TRACE_LEVEL_VERBOSE,
1822 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1824 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1827 uniFullName.Buffer[ 0] = L'\\';
1828 uniFullName.Buffer[ 1] = L'\\';
1830 uniFullName.Length = 2 * sizeof( WCHAR);
1832 RtlCopyMemory( &uniFullName.Buffer[ 2],
1833 AFSServerName.Buffer,
1834 AFSServerName.Length);
1836 uniFullName.Length += AFSServerName.Length;
1838 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
1840 uniFullName.Length += sizeof( WCHAR);
1842 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
1843 uniShareName.Buffer,
1844 uniShareName.Length);
1846 uniFullName.Length += uniShareName.Length;
1848 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1851 ntStatus = AFSAddConnectionEx( &uniFullName,
1852 RESOURCEDISPLAYTYPE_SHARE,
1855 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1857 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
1859 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1860 AFS_TRACE_LEVEL_VERBOSE,
1861 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1862 &pRDRDevExt->Specific.RDR.ProviderListLock,
1863 PsGetCurrentThread()));
1865 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1868 if ( NT_SUCCESS( ntStatus) )
1871 // Once again, locate the entry for the share we just created
1874 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1879 if( pConnection == NULL)
1882 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1883 AFS_TRACE_LEVEL_ERROR,
1884 "AFSGetConnectionInfo Failed to locate entry for full name %wZ\n",
1887 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1889 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1893 // Fill in the returned connection info block
1896 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1897 pConnection->RemoteName.Length +
1898 pConnection->Comment.Length +
1899 uniRemainingPath.Length)
1902 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1903 AFS_TRACE_LEVEL_VERBOSE,
1904 "AFSGetConnectionInfo Buffer too small for full name %wZ\n",
1907 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1909 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
1912 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1913 AFS_TRACE_LEVEL_VERBOSE,
1914 "AFSGetConnectionInfo Returning entry Scope %08lX partial name %wZ full name %wZ\n",
1915 pConnection->Scope, &pConnection->RemoteName, &uniFullName));
1917 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
1919 if( !bEnumerationEntry)
1922 RtlCopyMemory( ConnectCB->RemoteName,
1924 pConnection->RemoteName.Length);
1929 RtlCopyMemory( ConnectCB->RemoteName,
1930 pConnection->RemoteName.Buffer,
1931 pConnection->RemoteName.Length);
1934 ConnectCB->LocalName = pConnection->LocalName;
1936 ConnectCB->Type = pConnection->Type;
1938 ConnectCB->Scope = pConnection->Scope;
1940 ConnectCB->DisplayType = pConnection->DisplayType;
1942 ConnectCB->Usage = pConnection->Usage;
1944 ConnectCB->CommentLength = pConnection->Comment.Length;
1946 ConnectCB->RemainingPathLength = uniRemainingPathLocal.Length;
1948 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1949 AFS_TRACE_LEVEL_VERBOSE,
1950 "AFSGetConnectionInfo Returning lengths: remote %u comment %u remaining %u\n",
1951 ConnectCB->RemoteNameLength,
1952 ConnectCB->CommentLength,
1953 ConnectCB->RemainingPathLength));
1955 if( ConnectCB->CommentLength > 0)
1958 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1959 ConnectCB->RemoteNameLength);
1961 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
1962 pConnection->Comment.Buffer,
1963 ConnectCB->CommentLength);
1966 if ( ConnectCB->RemainingPathLength > 0 )
1969 ConnectCB->RemainingPathOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1970 ConnectCB->RemoteNameLength +
1971 ConnectCB->CommentLength);
1973 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->RemainingPathOffset),
1974 uniRemainingPathLocal.Buffer,
1975 uniRemainingPathLocal.Length);
1978 *ReturnOutputBufferLength = FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1979 ConnectCB->RemoteNameLength +
1980 ConnectCB->CommentLength +
1981 ConnectCB->RemainingPathLength;
1983 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1987 if ( uniRemainingPathLocal.Buffer )
1990 AFSExFreePoolWithTag( uniRemainingPathLocal.Buffer, 0);
1998 AFSIsDriveMapped( IN WCHAR DriveMapping)
2001 BOOLEAN bDriveMapped = FALSE;
2002 AFSProviderConnectionCB *pConnection = NULL;
2003 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2008 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
2011 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
2013 while( pConnection != NULL)
2016 if( pConnection->LocalName != L'\0' &&
2017 RtlUpcaseUnicodeChar( pConnection->LocalName) == RtlUpcaseUnicodeChar( DriveMapping))
2020 bDriveMapped = TRUE;
2025 pConnection = pConnection->fLink;
2028 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
2031 return bDriveMapped;