2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSNetworkProviderSupport.cpp
39 #include "AFSCommon.h"
42 AFSAddConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
43 IN OUT PULONG ResultStatus,
44 IN OUT ULONG_PTR *ReturnOutputBufferLength)
47 NTSTATUS ntStatus = STATUS_SUCCESS;
48 AFSProviderConnectionCB *pConnection = NULL, *pLastConnection = NULL;
49 UNICODE_STRING uniRemoteName;
50 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
55 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
56 AFS_TRACE_LEVEL_VERBOSE,
57 "AFSAddConnection Acquiring AFSProviderListLock lock %p EXCL %08lX\n",
58 &pRDRDevExt->Specific.RDR.ProviderListLock,
59 PsGetCurrentThread()));
61 if( ConnectCB->AuthenticationId.QuadPart == 0)
64 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
66 if ( ConnectCB->AuthenticationId.QuadPart == 0)
69 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
70 AFS_TRACE_LEVEL_ERROR,
71 "AFSAddConnection Unable to retrieve authentication id\n"));
73 return STATUS_ACCESS_DENIED;
76 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
77 AFS_TRACE_LEVEL_VERBOSE,
78 "AFSAddConnection Retrieved authentication id %I64X\n",
79 ConnectCB->AuthenticationId.QuadPart));
82 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
86 // Look for the connection
89 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
90 uniRemoteName.MaximumLength = uniRemoteName.Length;
92 uniRemoteName.Buffer = ConnectCB->RemoteName;
95 // Strip off any trailing slashes
98 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
101 uniRemoteName.Length -= sizeof( WCHAR);
104 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
106 while( pConnection != NULL)
109 if( pConnection->LocalName == ConnectCB->LocalName &&
110 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
111 RtlCompareUnicodeString( &uniRemoteName,
112 &pConnection->RemoteName,
119 pConnection = pConnection->fLink;
122 if( pConnection != NULL)
125 if( ConnectCB->LocalName != L'\0')
128 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
129 AFS_TRACE_LEVEL_VERBOSE,
130 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local %C authentication id %I64X\n",
132 ConnectCB->LocalName,
133 ConnectCB->AuthenticationId.QuadPart));
135 *ResultStatus = WN_ALREADY_CONNECTED;
140 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
141 AFS_TRACE_LEVEL_VERBOSE,
142 "AFSAddConnection ALREADY_CONNECTED remote name %wZ Local (NULL) authentication id %I64X\n",
144 ConnectCB->AuthenticationId.QuadPart));
146 *ResultStatus = WN_SUCCESS;
149 *ReturnOutputBufferLength = sizeof( ULONG);
151 try_return( ntStatus = STATUS_SUCCESS);
155 // Validate the remote name
158 if( uniRemoteName.Length > 2 * sizeof( WCHAR) &&
159 uniRemoteName.Buffer[ 0] == L'\\' &&
160 uniRemoteName.Buffer[ 1] == L'\\')
163 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 2];
165 uniRemoteName.Length -= (2 * sizeof( WCHAR));
168 if( uniRemoteName.Length >= AFSServerName.Length)
171 USHORT usLength = uniRemoteName.Length;
173 if (uniRemoteName.Buffer[AFSServerName.Length/sizeof( WCHAR)] != L'\\')
176 if( ConnectCB->LocalName != L'\0')
179 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
180 AFS_TRACE_LEVEL_VERBOSE,
181 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local %C authentication id %I64X\n",
183 ConnectCB->LocalName,
184 ConnectCB->AuthenticationId.QuadPart));
189 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
190 AFS_TRACE_LEVEL_VERBOSE,
191 "AFSAddConnection BAD_NETNAME 1 remote name %wZ Local (NULL) authentication id %I64X\n",
193 ConnectCB->AuthenticationId.QuadPart));
196 *ResultStatus = WN_BAD_NETNAME;
198 *ReturnOutputBufferLength = sizeof( ULONG);
200 try_return( ntStatus = STATUS_SUCCESS);
203 uniRemoteName.Length = AFSServerName.Length;
205 if( RtlCompareUnicodeString( &AFSServerName,
210 if( ConnectCB->LocalName != L'\0')
213 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
214 AFS_TRACE_LEVEL_VERBOSE,
215 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local %C authentication id %I64X\n",
217 ConnectCB->LocalName,
218 ConnectCB->AuthenticationId.QuadPart));
223 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
224 AFS_TRACE_LEVEL_VERBOSE,
225 "AFSAddConnection BAD_NETNAME 2 remote name %wZ Local (NULL) authentication id %I64X\n",
227 ConnectCB->AuthenticationId.QuadPart));
230 *ResultStatus = WN_BAD_NETNAME;
232 *ReturnOutputBufferLength = sizeof( ULONG);
234 try_return( ntStatus = STATUS_SUCCESS);
237 uniRemoteName.Length = usLength;
242 if( ConnectCB->LocalName != L'\0')
245 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
246 AFS_TRACE_LEVEL_VERBOSE,
247 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local %C authentication id %I64X\n",
249 ConnectCB->LocalName,
250 ConnectCB->AuthenticationId.QuadPart));
255 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
256 AFS_TRACE_LEVEL_VERBOSE,
257 "AFSAddConnection BAD_NETNAME 3 remote name %wZ Local (NULL) authentication id %I64X\n",
259 ConnectCB->AuthenticationId.QuadPart));
262 *ResultStatus = WN_BAD_NETNAME;
264 *ReturnOutputBufferLength = sizeof( ULONG);
266 try_return( ntStatus = STATUS_SUCCESS);
269 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
270 uniRemoteName.MaximumLength = uniRemoteName.Length;
272 uniRemoteName.Buffer = ConnectCB->RemoteName;
275 // Strip off any trailing slashes
278 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
281 uniRemoteName.Length -= sizeof( WCHAR);
285 // Allocate a new node and add it to our list
288 pConnection = (AFSProviderConnectionCB *)AFSExAllocatePoolWithTag( PagedPool,
289 sizeof( AFSProviderConnectionCB) +
290 uniRemoteName.Length,
293 if( pConnection == NULL)
296 *ResultStatus = WN_OUT_OF_MEMORY;
298 *ReturnOutputBufferLength = sizeof( ULONG);
300 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
303 RtlZeroMemory( pConnection,
304 sizeof( AFSProviderConnectionCB) + uniRemoteName.Length);
306 pConnection->LocalName = ConnectCB->LocalName;
308 pConnection->RemoteName.Length = uniRemoteName.Length;
309 pConnection->RemoteName.MaximumLength = pConnection->RemoteName.Length;
311 pConnection->RemoteName.Buffer = (WCHAR *)((char *)pConnection + sizeof( AFSProviderConnectionCB));
313 RtlCopyMemory( pConnection->RemoteName.Buffer,
314 uniRemoteName.Buffer,
315 pConnection->RemoteName.Length);
317 pConnection->Type = ConnectCB->Type;
319 pConnection->AuthenticationId = ConnectCB->AuthenticationId;
321 if( ConnectCB->LocalName != L'\0')
324 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
325 AFS_TRACE_LEVEL_VERBOSE,
326 "AFSAddConnection Adding connection remote name %wZ Local %C authentication id %I64X\n",
328 ConnectCB->LocalName,
329 ConnectCB->AuthenticationId.QuadPart));
334 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
335 AFS_TRACE_LEVEL_VERBOSE,
336 "AFSAddConnection Adding connection remote name %wZ Local (NULL) authentication id %I64X\n",
338 ConnectCB->AuthenticationId.QuadPart));
342 // Point to the component portion of the name
345 pConnection->ComponentName.Length = 0;
346 pConnection->ComponentName.MaximumLength = 0;
348 pConnection->ComponentName.Buffer = &pConnection->RemoteName.Buffer[ (pConnection->RemoteName.Length/sizeof( WCHAR)) - 1];
350 while( pConnection->ComponentName.Length <= pConnection->RemoteName.Length)
353 if( pConnection->ComponentName.Buffer[ 0] == L'\\')
356 pConnection->ComponentName.Buffer++;
361 pConnection->ComponentName.Length += sizeof( WCHAR);
362 pConnection->ComponentName.MaximumLength += sizeof( WCHAR);
364 pConnection->ComponentName.Buffer--;
368 // Go initialize the information about the connection
371 AFSInitializeConnectionInfo( pConnection,
375 // Insert the entry into our list
378 if( pRDRDevExt->Specific.RDR.ProviderConnectionList == NULL)
381 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection;
387 // Get the end of the list
390 pLastConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
392 while( pLastConnection->fLink != NULL)
395 pLastConnection = pLastConnection->fLink;
398 pLastConnection->fLink = pConnection;
401 *ResultStatus = WN_SUCCESS;
403 *ReturnOutputBufferLength = sizeof( ULONG);
407 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
415 AFSCancelConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
416 IN OUT AFSCancelConnectionResultCB *ConnectionResult,
417 IN OUT ULONG_PTR *ReturnOutputBufferLength)
420 NTSTATUS ntStatus = STATUS_SUCCESS;
421 AFSProviderConnectionCB *pConnection = NULL, *pLastConnection = NULL;
422 UNICODE_STRING uniRemoteName;
423 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
428 ConnectionResult->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
430 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
431 AFS_TRACE_LEVEL_VERBOSE,
432 "AFSCancelConnection Acquiring AFSProviderListLock lock %p EXCL %08lX\n",
433 &pRDRDevExt->Specific.RDR.ProviderListLock,
434 PsGetCurrentThread()));
436 if( ConnectCB->AuthenticationId.QuadPart == 0)
439 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
441 if ( ConnectCB->AuthenticationId.QuadPart == 0)
444 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
445 AFS_TRACE_LEVEL_ERROR,
446 "AFSCancelConnection Unable to retrieve authentication id\n"));
448 return STATUS_ACCESS_DENIED;
451 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
452 AFS_TRACE_LEVEL_VERBOSE,
453 "AFSCancelConnection Retrieved authentication id %I64X\n",
454 ConnectCB->AuthenticationId.QuadPart));
457 AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock,
461 // Look for the connection
464 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
465 uniRemoteName.MaximumLength = uniRemoteName.Length;
467 uniRemoteName.Buffer = NULL;
469 if( uniRemoteName.Length > 0)
472 uniRemoteName.Buffer = ConnectCB->RemoteName;
475 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
477 while( pConnection != NULL)
480 if( ( ConnectCB->LocalName != L'\0' &&
481 pConnection->LocalName == ConnectCB->LocalName)
483 ( ConnectCB->LocalName == L'\0' &&
484 pConnection->LocalName == L'\0' &&
485 RtlCompareUnicodeString( &uniRemoteName,
486 &pConnection->RemoteName,
490 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
491 AFS_TRACE_LEVEL_VERBOSE,
492 "AFSCancelConnection Checking remote name %wZ to stored %wZ authentication id %I64X - %I64X\n",
494 &pConnection->RemoteName,
495 ConnectCB->AuthenticationId.QuadPart,
496 pConnection->AuthenticationId.QuadPart));
498 if( ConnectCB->AuthenticationId.QuadPart == pConnection->AuthenticationId.QuadPart &&
499 ( ConnectCB->LocalName == L'\0' ||
500 RtlCompareUnicodeString( &uniRemoteName,
501 &pConnection->RemoteName,
509 pLastConnection = pConnection;
511 pConnection = pConnection->fLink;
514 if( pConnection == NULL)
517 ConnectionResult->Status = WN_NOT_CONNECTED;
519 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
521 try_return( ntStatus);
524 if( pLastConnection == NULL)
527 pRDRDevExt->Specific.RDR.ProviderConnectionList = pConnection->fLink;
532 pLastConnection->fLink = pConnection->fLink;
535 if( pConnection->Comment.Buffer != NULL)
538 AFSExFreePoolWithTag( pConnection->Comment.Buffer, 0);
541 ConnectionResult->LocalName = pConnection->LocalName;
543 AFSExFreePoolWithTag( pConnection, AFS_PROVIDER_CB);
545 ConnectionResult->Status = WN_SUCCESS;
547 *ReturnOutputBufferLength = sizeof( AFSCancelConnectionResultCB);
551 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
558 AFSGetConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
559 IN OUT WCHAR *RemoteName,
560 IN ULONG RemoteNameBufferLength,
561 IN OUT ULONG_PTR *ReturnOutputBufferLength)
564 NTSTATUS ntStatus = STATUS_SUCCESS;
565 AFSProviderConnectionCB *pConnection = NULL;
566 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
571 if( ConnectCB->AuthenticationId.QuadPart == 0)
574 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
576 if ( ConnectCB->AuthenticationId.QuadPart == 0)
579 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
580 AFS_TRACE_LEVEL_ERROR,
581 "AFSGetConnection Unable to retrieve authentication id\n"));
583 return STATUS_ACCESS_DENIED;
586 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
587 AFS_TRACE_LEVEL_VERBOSE,
588 "AFSGetConnection Retrieved authentication id %I64X\n",
589 ConnectCB->AuthenticationId.QuadPart));
592 if( ConnectCB->LocalName != L'\0')
595 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
596 AFS_TRACE_LEVEL_VERBOSE,
597 "AFSGetConnection Local %C authentication id %I64X\n",
598 ConnectCB->LocalName,
599 ConnectCB->AuthenticationId.QuadPart));
604 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
605 AFS_TRACE_LEVEL_VERBOSE,
606 "AFSGetConnection Local (NULL) authentication id %I64X\n",
607 ConnectCB->AuthenticationId.QuadPart));
610 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
611 AFS_TRACE_LEVEL_VERBOSE,
612 "AFSGetConnection Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
613 &pRDRDevExt->Specific.RDR.ProviderListLock,
614 PsGetCurrentThread()));
616 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
620 // Look for the connection
623 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
625 while( pConnection != NULL)
628 if( pConnection->LocalName != L'\0')
631 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
632 AFS_TRACE_LEVEL_VERBOSE,
633 "AFSGetConnection Comparing passed in %C to %C authentication id %I64X - %I64X\n",
634 ConnectCB->LocalName,
635 pConnection->LocalName,
636 ConnectCB->AuthenticationId.QuadPart,
637 pConnection->AuthenticationId.QuadPart));
642 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
643 AFS_TRACE_LEVEL_VERBOSE,
644 "AFSGetConnection Comparing passed in %C to (NULL) authentication id %I64X - %I64X\n",
645 ConnectCB->LocalName,
646 ConnectCB->AuthenticationId.QuadPart,
647 pConnection->AuthenticationId.QuadPart));
650 if( pConnection->LocalName == ConnectCB->LocalName &&
651 pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart)
657 pConnection = pConnection->fLink;
660 if( pConnection == NULL)
663 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
664 AFS_TRACE_LEVEL_VERBOSE,
665 "AFSGetConnection INVALID_PARAMETER\n"));
667 try_return( ntStatus = STATUS_INVALID_PARAMETER);
670 if( RemoteNameBufferLength < pConnection->RemoteName.Length)
673 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
674 AFS_TRACE_LEVEL_VERBOSE,
675 "AFSGetConnection INSUFFICIENT_RESOURCES\n"));
677 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
680 RtlCopyMemory( RemoteName,
681 pConnection->RemoteName.Buffer,
682 pConnection->RemoteName.Length);
684 *ReturnOutputBufferLength = pConnection->RemoteName.Length;
688 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
695 AFSListConnections( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
696 IN ULONG ConnectionBufferLength,
697 IN OUT ULONG_PTR *ReturnOutputBufferLength)
700 NTSTATUS ntStatus = STATUS_SUCCESS;
701 AFSProviderConnectionCB *pConnection = NULL, *pRootConnection = NULL;
702 ULONG ulCopiedLength = 0, ulRemainingLength = ConnectionBufferLength;
703 ULONG ulScope, ulType;
704 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath;
705 BOOLEAN bGlobalEnumeration = FALSE;
707 LARGE_INTEGER liAuthenticationID = {0,0};
708 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
714 // Save off some data before moving on
717 ulScope = ConnectCB->Scope;
719 ulType = ConnectCB->Type;
721 if( ConnectCB->AuthenticationId.QuadPart == 0)
724 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
726 if ( ConnectCB->AuthenticationId.QuadPart == 0)
729 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
730 AFS_TRACE_LEVEL_ERROR,
731 "AFSListConnections Unable to retrieve authentication id\n"));
733 return STATUS_ACCESS_DENIED;
736 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
737 AFS_TRACE_LEVEL_VERBOSE,
738 "AFSListConnections Retrieved authentication id %I64X\n",
739 ConnectCB->AuthenticationId.QuadPart));
742 liAuthenticationID.QuadPart = ConnectCB->AuthenticationId.QuadPart;
744 uniRemoteName.Length = 0;
745 uniRemoteName.MaximumLength = 0;
746 uniRemoteName.Buffer = NULL;
748 uniServerName.Length = 0;
749 uniServerName.MaximumLength = 0;
750 uniServerName.Buffer = NULL;
752 uniShareName.Length = 0;
753 uniShareName.MaximumLength = 0;
754 uniShareName.Buffer = NULL;
756 if( ConnectCB->RemoteNameLength > 0)
759 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
760 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
762 uniRemoteName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
763 uniRemoteName.MaximumLength,
764 AFS_NETWORK_PROVIDER_1_TAG);
766 if( uniRemoteName.Buffer == NULL)
769 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
772 RtlCopyMemory( uniRemoteName.Buffer,
773 ConnectCB->RemoteName,
774 uniRemoteName.Length);
776 if( uniRemoteName.Buffer[ 0] == L'\\' &&
777 uniRemoteName.Buffer[ 1] == L'\\')
780 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
782 uniRemoteName.Length -= sizeof( WCHAR);
785 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
788 uniRemoteName.Length -= sizeof( WCHAR);
791 FsRtlDissectName( uniRemoteName,
795 uniRemoteName = uniRemainingPath;
797 if( uniRemoteName.Length > 0)
800 FsRtlDissectName( uniRemoteName,
806 // If this is an enumeration of the global share name then
807 // adjust it to be the server name itself
810 if( uniShareName.Length == 0)
813 bGlobalEnumeration = TRUE;
817 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
818 AFS_TRACE_LEVEL_VERBOSE,
819 "AFSListConnections Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
820 &pRDRDevExt->Specific.RDR.ProviderListLock,
821 PsGetCurrentThread()));
823 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
827 // If this is a globalnet enumeration with no name then enumerate the server list
830 if( ulScope == RESOURCE_GLOBALNET)
833 if( uniServerName.Buffer == NULL)
836 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
842 // Go locate the root entry for the name passed in
845 if( bGlobalEnumeration)
848 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
851 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
853 try_return( ntStatus);
856 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
861 pRootConnection = AFSLocateEnumRootEntry( &uniShareName);
863 if( pRootConnection == NULL)
866 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
868 try_return( ntStatus);
872 // Need to handle these enumerations from the directory listing
875 ntStatus = AFSEnumerateConnection( ConnectCB,
877 ConnectionBufferLength,
885 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
888 ulIndex = ConnectCB->CurrentIndex;
890 while( pConnection != NULL)
893 if( bGlobalEnumeration &&
894 BooleanFlagOn( pConnection->Flags, AFS_CONNECTION_FLAG_GLOBAL_SHARE))
897 pConnection = pConnection->fLink;
902 if( ulScope != RESOURCE_GLOBALNET &&
903 !BooleanFlagOn( pConnection->Usage, RESOURCEUSAGE_ATTACHED))
906 pConnection = pConnection->fLink;
911 if( pConnection->LocalName != L'\0')
914 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
915 AFS_TRACE_LEVEL_VERBOSE,
916 "AFSListConnections Processing entry %wZ %C authentication id %I64X - %I64X Scope %08lX\n",
917 &pConnection->RemoteName,
918 pConnection->LocalName,
919 liAuthenticationID.QuadPart,
920 pConnection->AuthenticationId.QuadPart,
921 pConnection->Scope));
926 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
927 AFS_TRACE_LEVEL_VERBOSE,
928 "AFSListConnections Processing entry %wZ NULL LocalName authentication id %I64X - %I64X Scope %08lX\n",
929 &pConnection->RemoteName,
930 liAuthenticationID.QuadPart,
931 pConnection->AuthenticationId.QuadPart,
932 pConnection->Scope));
935 if( ulScope != RESOURCE_GLOBALNET &&
936 pConnection->AuthenticationId.QuadPart != liAuthenticationID.QuadPart)
939 pConnection = pConnection->fLink;
949 pConnection = pConnection->fLink;
954 if( ulRemainingLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
955 pConnection->RemoteName.Length +
956 pConnection->Comment.Length)
962 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
964 RtlCopyMemory( ConnectCB->RemoteName,
965 pConnection->RemoteName.Buffer,
966 pConnection->RemoteName.Length);
968 ConnectCB->LocalName = pConnection->LocalName;
970 ConnectCB->Type = pConnection->Type;
972 ConnectCB->Scope = pConnection->Scope;
974 if( !bGlobalEnumeration)
977 ConnectCB->Scope = RESOURCE_CONNECTED;
980 ConnectCB->DisplayType = pConnection->DisplayType;
982 ConnectCB->Usage = pConnection->Usage;
984 ConnectCB->CommentLength = pConnection->Comment.Length;
986 if( pConnection->Comment.Length > 0)
989 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
990 ConnectCB->RemoteNameLength);
992 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
993 pConnection->Comment.Buffer,
994 ConnectCB->CommentLength);
997 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
998 ConnectCB->RemoteNameLength +
999 ConnectCB->CommentLength;
1001 ulRemainingLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1002 ConnectCB->RemoteNameLength +
1003 ConnectCB->CommentLength;
1005 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
1006 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1007 ConnectCB->RemoteNameLength +
1008 ConnectCB->CommentLength);
1010 pConnection = pConnection->fLink;
1013 if( NT_SUCCESS( ntStatus))
1016 *ReturnOutputBufferLength = ulCopiedLength;
1019 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1023 if( uniRemoteName.Buffer != NULL)
1026 AFSExFreePoolWithTag( uniRemoteName.Buffer, 0);
1034 AFSInitializeConnectionInfo( IN AFSProviderConnectionCB *Connection,
1035 IN ULONG DisplayType)
1038 NTSTATUS ntStatus = STATUS_SUCCESS;
1039 UNICODE_STRING uniName, uniComponentName, uniRemainingName;
1044 uniName = Connection->RemoteName;
1047 // Strip of the double leading slash if there is one
1050 if( uniName.Buffer[ 0] == L'\\' &&
1051 uniName.Buffer[ 1] == L'\\')
1054 uniName.Buffer = &uniName.Buffer[ 1];
1056 uniName.Length -= sizeof( WCHAR);
1060 FsRtlDissectName( uniName,
1065 // Initialize the information for the connection
1066 // First, if this is the server only then mark it accordingly
1069 if( uniRemainingName.Length == 0 ||
1070 DisplayType == RESOURCEDISPLAYTYPE_SERVER)
1073 Connection->Type = RESOURCETYPE_DISK;
1075 Connection->Scope = 0;
1077 Connection->DisplayType = RESOURCEDISPLAYTYPE_SERVER;
1079 Connection->Usage = RESOURCEUSAGE_CONTAINER;
1081 Connection->Comment.Length = 20;
1082 Connection->Comment.MaximumLength = 22;
1084 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1085 Connection->Comment.MaximumLength,
1086 AFS_NETWORK_PROVIDER_2_TAG);
1088 if( Connection->Comment.Buffer != NULL)
1091 RtlZeroMemory( Connection->Comment.Buffer,
1092 Connection->Comment.MaximumLength);
1094 RtlCopyMemory( Connection->Comment.Buffer,
1101 Connection->Comment.Length = 0;
1102 Connection->Comment.MaximumLength = 0;
1105 try_return( ntStatus);
1108 uniName = uniRemainingName;
1110 FsRtlDissectName( uniName,
1114 if( uniRemainingName.Length == 0 ||
1115 uniRemainingName.Buffer == NULL ||
1116 DisplayType == RESOURCEDISPLAYTYPE_SHARE)
1119 Connection->Type = RESOURCETYPE_DISK;
1121 Connection->DisplayType = RESOURCEDISPLAYTYPE_SHARE;
1123 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1125 if( Connection->LocalName != L'\0')
1128 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1130 Connection->Scope = RESOURCE_CONNECTED;
1135 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1137 Connection->Scope = RESOURCE_GLOBALNET;
1140 Connection->Comment.Length = 18;
1141 Connection->Comment.MaximumLength = 20;
1143 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1144 Connection->Comment.MaximumLength,
1145 AFS_NETWORK_PROVIDER_3_TAG);
1147 if( Connection->Comment.Buffer != NULL)
1150 RtlZeroMemory( Connection->Comment.Buffer,
1151 Connection->Comment.MaximumLength);
1153 RtlCopyMemory( Connection->Comment.Buffer,
1160 Connection->Comment.Length = 0;
1161 Connection->Comment.MaximumLength = 0;
1164 try_return( ntStatus);
1168 // This is a sub directory within a share
1171 Connection->Type = RESOURCETYPE_DISK;
1173 Connection->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1175 Connection->Usage = RESOURCEUSAGE_CONNECTABLE;
1177 if( Connection->LocalName != L'\0')
1180 Connection->Usage |= RESOURCEUSAGE_ATTACHED;
1185 Connection->Usage |= RESOURCEUSAGE_NOLOCALDEVICE;
1188 Connection->Scope = RESOURCE_CONNECTED;
1190 Connection->Comment.Length = 26;
1191 Connection->Comment.MaximumLength = 28;
1193 Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1194 Connection->Comment.MaximumLength,
1195 AFS_NETWORK_PROVIDER_4_TAG);
1197 if( Connection->Comment.Buffer != NULL)
1200 RtlZeroMemory( Connection->Comment.Buffer,
1201 Connection->Comment.MaximumLength);
1203 RtlCopyMemory( Connection->Comment.Buffer,
1210 Connection->Comment.Length = 0;
1211 Connection->Comment.MaximumLength = 0;
1222 AFSProviderConnectionCB *
1223 AFSLocateEnumRootEntry( IN UNICODE_STRING *RemoteName)
1226 AFSProviderConnectionCB *pConnection = NULL;
1227 UNICODE_STRING uniRemoteName = *RemoteName;
1228 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1233 if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL)
1236 try_return( pConnection);
1239 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList->EnumerationList;
1241 while( pConnection != NULL)
1244 if( RtlCompareUnicodeString( &uniRemoteName,
1245 &pConnection->ComponentName,
1252 pConnection = pConnection->fLink;
1264 AFSEnumerateConnection( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
1265 IN AFSProviderConnectionCB *RootConnection,
1266 IN ULONG BufferLength,
1267 OUT PULONG CopiedLength)
1270 NTSTATUS ntStatus = STATUS_SUCCESS;
1271 ULONG ulCRC = 0, ulCopiedLength = 0;
1272 AFSDirectoryCB *pShareDirEntry = NULL;
1273 AFSDirectoryCB *pDirEntry = NULL, *pTargetDirEntry = NULL;
1280 if( AFSGlobalRoot == NULL)
1283 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1284 AFS_TRACE_LEVEL_ERROR,
1285 "AFSEnumerateConnection Global root not yet initialized\n"));
1287 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1290 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1294 // Grab our tree lock shared
1297 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1298 AFS_TRACE_LEVEL_VERBOSE,
1299 "AFSEnumerateConnection Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p SHARED %08lX\n",
1300 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1301 PsGetCurrentThread()));
1303 AFSAcquireShared( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1307 // Locate the dir entry for this node
1310 ntStatus = AFSLocateCaseSensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1314 if( pShareDirEntry == NULL ||
1315 !NT_SUCCESS( ntStatus))
1319 // Perform a case insensitive search
1322 ulCRC = AFSGenerateCRC( &RootConnection->ComponentName,
1325 ntStatus = AFSLocateCaseInsensitiveDirEntry( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1329 if( pShareDirEntry == NULL ||
1330 !NT_SUCCESS( ntStatus))
1333 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1335 try_return( ntStatus);
1339 lCount = InterlockedIncrement( &pShareDirEntry->DirOpenReferenceCount);
1341 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1342 AFS_TRACE_LEVEL_VERBOSE,
1343 "AFSEnumerateConnection1 Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1344 &pShareDirEntry->NameInformation.FileName,
1349 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1352 // Setup the request to evaluate the entry
1353 // On success, pTargetDirEntry has the DirOpenReferenceCount held
1356 ntStatus = AFSEvaluateRootEntry( pShareDirEntry,
1359 if( !NT_SUCCESS( ntStatus))
1362 try_return( ntStatus);
1365 AFSAcquireShared( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1369 // Enumerate the content
1372 pDirEntry = pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
1374 ulIndex = ConnectCB->CurrentIndex;
1376 while( pDirEntry != NULL)
1384 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1389 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1390 pDirEntry->NameInformation.FileName.Length)
1396 ConnectCB->LocalName = L'\0';
1398 ConnectCB->RemoteNameLength = pDirEntry->NameInformation.FileName.Length;
1400 RtlCopyMemory( ConnectCB->RemoteName,
1401 pDirEntry->NameInformation.FileName.Buffer,
1402 pDirEntry->NameInformation.FileName.Length);
1404 ConnectCB->Type = RESOURCETYPE_DISK;
1406 ConnectCB->Scope = RESOURCE_CONNECTED;
1408 if( BooleanFlagOn( pDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1411 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY;
1416 ConnectCB->DisplayType = RESOURCEDISPLAYTYPE_FILE;
1419 ConnectCB->Usage = 0;
1421 ConnectCB->CommentLength = 0;
1423 ulCopiedLength += FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1424 pDirEntry->NameInformation.FileName.Length;
1426 BufferLength -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1427 pDirEntry->NameInformation.FileName.Length;
1429 ConnectCB = (AFSNetworkProviderConnectionCB *)((char *)ConnectCB +
1430 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1431 ConnectCB->RemoteNameLength);
1433 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
1437 // Release the DirOpenReferenceCount obtained from AFSEvaluateRootEntry
1440 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
1442 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1443 AFS_TRACE_LEVEL_VERBOSE,
1444 "AFSEnumerateConnection Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1445 &pTargetDirEntry->NameInformation.FileName,
1450 ASSERT( lCount >= 0);
1452 *CopiedLength = ulCopiedLength;
1454 AFSReleaseResource( pTargetDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1458 if( pShareDirEntry != NULL)
1460 lCount = InterlockedDecrement( &pShareDirEntry->DirOpenReferenceCount);
1462 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1463 AFS_TRACE_LEVEL_VERBOSE,
1464 "AFSEnumerateConnection1 Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1465 &pShareDirEntry->NameInformation.FileName,
1470 ASSERT( lCount >= 0);
1478 AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
1479 IN ULONG BufferLength,
1480 IN OUT ULONG_PTR *ReturnOutputBufferLength)
1483 NTSTATUS ntStatus = STATUS_SUCCESS;
1484 AFSProviderConnectionCB *pConnection = NULL, *pBestMatch = NULL;
1485 UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath, uniFullName, uniRemainingPathLocal;
1486 USHORT usNameLen = 0, usMaxNameLen = 0;
1487 BOOLEAN bEnumerationEntry = FALSE;
1488 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1493 uniServerName.Length = 0;
1494 uniServerName.MaximumLength = 0;
1495 uniServerName.Buffer = NULL;
1497 uniShareName.Length = 0;
1498 uniShareName.MaximumLength = 0;
1499 uniShareName.Buffer = NULL;
1501 uniRemainingPathLocal.Length = 0;
1502 uniRemainingPathLocal.MaximumLength = 0;
1503 uniRemainingPathLocal.Buffer = NULL;
1505 uniRemoteName.Length = (USHORT)ConnectCB->RemoteNameLength;
1506 uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
1507 uniRemoteName.Buffer = (WCHAR *)ConnectCB->RemoteName;
1509 if( ConnectCB->AuthenticationId.QuadPart == 0)
1512 ConnectCB->AuthenticationId = AFSGetAuthenticationId();
1514 if ( ConnectCB->AuthenticationId.QuadPart == 0)
1517 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1518 AFS_TRACE_LEVEL_ERROR,
1519 "AFSGetConnectionInfo Unable to retrieve authentication id\n"));
1521 return STATUS_ACCESS_DENIED;
1524 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1525 AFS_TRACE_LEVEL_VERBOSE,
1526 "AFSGetConnectionInfo Retrieved authentication id %I64X\n",
1527 ConnectCB->AuthenticationId.QuadPart));
1530 if( ConnectCB->LocalName != L'\0')
1533 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1534 AFS_TRACE_LEVEL_VERBOSE,
1535 "AFSGetConnectionInfo remote name %wZ Local %C authentication id %I64X\n",
1537 ConnectCB->LocalName,
1538 ConnectCB->AuthenticationId.QuadPart));
1543 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1544 AFS_TRACE_LEVEL_VERBOSE,
1545 "AFSGetConnectionInfo remote name %wZ Local (NULL) authentication id %I64X\n",
1547 ConnectCB->AuthenticationId.QuadPart));
1550 if( AFSGlobalRoot == NULL)
1553 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1554 AFS_TRACE_LEVEL_ERROR,
1555 "AFSGetConnectionInfo Global root not yet initialized\n"));
1557 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
1560 uniFullName = uniRemoteName;
1562 if( uniRemoteName.Buffer[ 0] == L'\\' &&
1563 uniRemoteName.Buffer[ 1] == L'\\')
1566 uniRemoteName.Buffer = &uniRemoteName.Buffer[ 1];
1568 uniRemoteName.Length -= sizeof( WCHAR);
1571 if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\')
1574 uniRemoteName.Length -= sizeof( WCHAR);
1576 uniFullName.Length -= sizeof( WCHAR);
1579 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1580 AFS_TRACE_LEVEL_VERBOSE,
1581 "AFSGetConnectionInfo Processing name %wZ\n",
1584 FsRtlDissectName( uniRemoteName,
1588 uniRemoteName = uniRemainingPath;
1590 if( uniRemoteName.Length > 0)
1593 FsRtlDissectName( uniRemoteName,
1598 if( RtlCompareUnicodeString( &uniServerName,
1603 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1606 if ( uniRemainingPath.Length > 0 )
1610 // Add back in the leading \ since it was stripped off above
1613 uniRemainingPath.Length += sizeof( WCHAR);
1614 if( uniRemainingPath.Length > uniRemainingPath.MaximumLength)
1616 uniRemainingPath.MaximumLength += sizeof( WCHAR);
1619 uniRemainingPath.Buffer--;
1621 uniRemainingPathLocal.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1622 uniRemainingPath.Length,
1623 AFS_NETWORK_PROVIDER_5_TAG);
1625 if( uniRemainingPathLocal.Buffer == NULL)
1628 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1629 AFS_TRACE_LEVEL_VERBOSE,
1630 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1632 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1635 uniRemainingPathLocal.MaximumLength = uniRemainingPath.Length;
1636 uniRemainingPathLocal.Length = uniRemainingPath.Length;
1638 RtlCopyMemory( uniRemainingPathLocal.Buffer,
1639 uniRemainingPath.Buffer,
1640 uniRemainingPath.Length);
1643 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1644 AFS_TRACE_LEVEL_VERBOSE,
1645 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1646 &pRDRDevExt->Specific.RDR.ProviderListLock,
1647 PsGetCurrentThread()));
1649 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1653 // If this is the server then return information about the
1657 if( uniShareName.Length == 0 &&
1658 RtlCompareUnicodeString( &uniServerName,
1663 pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList;
1669 // See if we can locate it on our connection list
1672 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1674 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1675 AFS_TRACE_LEVEL_VERBOSE,
1676 "AFSGetConnectionInfo Searching for full name %wZ\n",
1679 while( pConnection != NULL)
1682 if( usMaxNameLen < pConnection->RemoteName.Length &&
1683 pConnection->RemoteName.Length <= uniFullName.Length)
1686 usNameLen = uniFullName.Length;
1688 uniFullName.Length = pConnection->RemoteName.Length;
1690 if( pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
1691 RtlCompareUnicodeString( &uniFullName,
1692 &pConnection->RemoteName,
1696 usMaxNameLen = pConnection->RemoteName.Length;
1698 pBestMatch = pConnection;
1700 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1701 AFS_TRACE_LEVEL_VERBOSE,
1702 "AFSGetConnectionInfo Found match for %wZ\n",
1703 &pConnection->RemoteName));
1706 uniFullName.Length = usNameLen;
1709 pConnection = pConnection->fLink;
1712 pConnection = pBestMatch;
1714 if( pConnection != NULL)
1717 bEnumerationEntry = TRUE;
1719 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1720 AFS_TRACE_LEVEL_VERBOSE,
1721 "AFSGetConnectionInfo Using best match for %wZ\n",
1722 &pConnection->RemoteName));
1725 if( pConnection == NULL)
1729 // Locate the entry for the share
1732 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1736 if( pConnection == NULL)
1738 UNICODE_STRING uniFullName;
1739 AFSDirEnumEntry *pDirEnumEntry = NULL;
1741 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1742 AFS_TRACE_LEVEL_VERBOSE,
1743 "AFSGetConnectionInfo No connection for full name %wZ\n",
1747 // Drop the lock, we will pick it up again later
1750 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1753 // OK, ask the CM about this component name
1756 ntStatus = AFSEvaluateTargetByName( NULL,
1757 &AFSGlobalRoot->ObjectInformation,
1762 if( !NT_SUCCESS( ntStatus))
1765 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1766 AFS_TRACE_LEVEL_VERBOSE,
1767 "AFSGetConnectionInfo Evaluation Failed share name %wZ\n",
1770 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1778 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_3_TAG);
1781 // The share name is valid
1782 // Allocate a new node and add it to our list
1784 uniFullName.MaximumLength = PAGE_SIZE;
1785 uniFullName.Length = 0;
1787 uniFullName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
1788 uniFullName.MaximumLength,
1789 AFS_NETWORK_PROVIDER_6_TAG);
1791 if( uniFullName.Buffer == NULL)
1794 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1795 AFS_TRACE_LEVEL_VERBOSE,
1796 "AFSGetConnectionInfo INSUFFICIENT_RESOURCES\n"));
1798 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1801 uniFullName.Buffer[ 0] = L'\\';
1802 uniFullName.Buffer[ 1] = L'\\';
1804 uniFullName.Length = 2 * sizeof( WCHAR);
1806 RtlCopyMemory( &uniFullName.Buffer[ 2],
1807 AFSServerName.Buffer,
1808 AFSServerName.Length);
1810 uniFullName.Length += AFSServerName.Length;
1812 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
1814 uniFullName.Length += sizeof( WCHAR);
1816 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
1817 uniShareName.Buffer,
1818 uniShareName.Length);
1820 uniFullName.Length += uniShareName.Length;
1822 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1825 ntStatus = AFSAddConnectionEx( &uniFullName,
1826 RESOURCEDISPLAYTYPE_SHARE,
1829 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1831 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
1833 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1834 AFS_TRACE_LEVEL_VERBOSE,
1835 "AFSGetConnectionInfo Acquiring AFSProviderListLock lock %p SHARED %08lX\n",
1836 &pRDRDevExt->Specific.RDR.ProviderListLock,
1837 PsGetCurrentThread()));
1839 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1842 if ( NT_SUCCESS( ntStatus) )
1845 // Once again, locate the entry for the share we just created
1848 pConnection = AFSLocateEnumRootEntry( &uniShareName);
1853 if( pConnection == NULL)
1856 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1857 AFS_TRACE_LEVEL_ERROR,
1858 "AFSGetConnectionInfo Failed to locate entry for full name %wZ\n",
1861 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1863 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1867 // Fill in the returned connection info block
1870 if( BufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1871 pConnection->RemoteName.Length +
1872 pConnection->Comment.Length +
1873 uniRemainingPath.Length)
1876 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1877 AFS_TRACE_LEVEL_VERBOSE,
1878 "AFSGetConnectionInfo Buffer too small for full name %wZ\n",
1881 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1883 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
1886 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1887 AFS_TRACE_LEVEL_VERBOSE,
1888 "AFSGetConnectionInfo Returning entry Scope %08lX partial name %wZ full name %wZ\n",
1889 pConnection->Scope, &pConnection->RemoteName, &uniFullName));
1891 ConnectCB->RemoteNameLength = pConnection->RemoteName.Length;
1893 if( !bEnumerationEntry)
1896 RtlCopyMemory( ConnectCB->RemoteName,
1898 pConnection->RemoteName.Length);
1903 RtlCopyMemory( ConnectCB->RemoteName,
1904 pConnection->RemoteName.Buffer,
1905 pConnection->RemoteName.Length);
1908 ConnectCB->LocalName = pConnection->LocalName;
1910 ConnectCB->Type = pConnection->Type;
1912 ConnectCB->Scope = pConnection->Scope;
1914 ConnectCB->DisplayType = pConnection->DisplayType;
1916 ConnectCB->Usage = pConnection->Usage;
1918 ConnectCB->CommentLength = pConnection->Comment.Length;
1920 ConnectCB->RemainingPathLength = uniRemainingPathLocal.Length;
1922 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
1923 AFS_TRACE_LEVEL_VERBOSE,
1924 "AFSGetConnectionInfo Returning lengths: remote %u comment %u remaining %u\n",
1925 ConnectCB->RemoteNameLength,
1926 ConnectCB->CommentLength,
1927 ConnectCB->RemainingPathLength));
1929 if( ConnectCB->CommentLength > 0)
1932 ConnectCB->CommentOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1933 ConnectCB->RemoteNameLength);
1935 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->CommentOffset),
1936 pConnection->Comment.Buffer,
1937 ConnectCB->CommentLength);
1940 if ( ConnectCB->RemainingPathLength > 0 )
1943 ConnectCB->RemainingPathOffset = (ULONG)(FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1944 ConnectCB->RemoteNameLength +
1945 ConnectCB->CommentLength);
1947 RtlCopyMemory( (void *)((char *)ConnectCB + ConnectCB->RemainingPathOffset),
1948 uniRemainingPathLocal.Buffer,
1949 uniRemainingPathLocal.Length);
1952 *ReturnOutputBufferLength = FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
1953 ConnectCB->RemoteNameLength +
1954 ConnectCB->CommentLength +
1955 ConnectCB->RemainingPathLength;
1957 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
1961 if ( uniRemainingPathLocal.Buffer )
1964 AFSExFreePoolWithTag( uniRemainingPathLocal.Buffer, 0);
1972 AFSIsDriveMapped( IN WCHAR DriveMapping)
1975 BOOLEAN bDriveMapped = FALSE;
1976 AFSProviderConnectionCB *pConnection = NULL;
1977 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1982 AFSAcquireShared( &pRDRDevExt->Specific.RDR.ProviderListLock,
1985 pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
1987 while( pConnection != NULL)
1990 if( pConnection->LocalName != L'\0' &&
1991 RtlUpcaseUnicodeChar( pConnection->LocalName) == RtlUpcaseUnicodeChar( DriveMapping))
1994 bDriveMapped = TRUE;
1999 pConnection = pConnection->fLink;
2002 AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock);
2005 return bDriveMapped;