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 #define _WIN32_WINNT 0x0500
49 #define AFS_DEBUG_TRACE 1
51 #ifndef WNNC_NET_OPENAFS
52 #define WNNC_NET_OPENAFS 0x00390000
55 #include "AFSUserDefines.h"
56 #include "AFSUserIoctl.h"
57 #include "AFSUserStructs.h"
58 #include "AFSProvider.h"
59 #include "AFS_Npdll.h"
67 #define SCRATCHSZ 1024
73 ULONG _cdecl AFSDbgPrint( PWCHAR Format, ... );
76 NPGetConnectionCommon( LPWSTR lpLocalName,
82 NPGetConnection3Common( LPCWSTR lpLocalName,
89 NPGetUniversalNameCommon( LPCWSTR lpLocalPath,
96 DriveSubstitution( LPCWSTR drivestr,
101 #define WNNC_DRIVER( major, minor ) ( major * 0x00010000 + minor )
103 #define OPENAFS_PROVIDER_NAME L"OpenAFS Network"
104 #define OPENAFS_PROVIDER_NAME_LENGTH 30
106 #define MAX_PROVIDER_NAME_LENGTH 256
108 static ULONG cbProviderNameLength = OPENAFS_PROVIDER_NAME_LENGTH;
110 static wchar_t wszProviderName[MAX_PROVIDER_NAME_LENGTH+1] = OPENAFS_PROVIDER_NAME;
112 static BOOL bProviderNameRead = FALSE;
114 #define OPENAFS_SERVER_NAME L"AFS"
115 #define OPENAFS_SERVER_NAME_LENGTH 6
117 #define OPENAFS_SERVER_COMMENT L"AFS Root"
118 #define OPENAFS_SERVER_COMMENT_LENGTH 16
120 #define MAX_SERVER_NAME_LENGTH 30
122 static ULONG cbServerNameLength = 0;
124 static ULONG cbServerNameUNCLength = 0;
126 static ULONG cbServerCommentLength = OPENAFS_SERVER_COMMENT_LENGTH;
128 static wchar_t wszServerName[MAX_SERVER_NAME_LENGTH+1];
130 static wchar_t wszServerNameUNC[MAX_SERVER_NAME_LENGTH+3];
132 static wchar_t wszServerComment[] = OPENAFS_SERVER_COMMENT;
134 static BOOL bServerNameRead = FALSE;
137 AFSRetrieveAuthId( void);
140 ReadProviderNameString( void)
146 if ( bProviderNameRead )
149 code = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
150 L"SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider",
151 0, KEY_QUERY_VALUE, &hk);
153 if ( code == ERROR_SUCCESS) {
155 dwLen = sizeof(wszProviderName);
157 code = RegQueryValueExW( hk, L"Name", NULL, NULL,
158 (LPBYTE) wszProviderName, &dwLen);
160 if ( code == ERROR_SUCCESS)
163 wszProviderName[MAX_PROVIDER_NAME_LENGTH] = '\0';
165 cbProviderNameLength = wcslen( wszProviderName) * sizeof( WCHAR);
171 bProviderNameRead = TRUE;
175 ReadServerNameString( void)
181 if ( bServerNameRead )
184 code = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
185 L"SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters",
186 0, KEY_QUERY_VALUE, &hk);
188 if ( code == ERROR_SUCCESS) {
190 dwLen = sizeof(wszProviderName);
192 code = RegQueryValueExW( hk, L"NetbiosName", NULL, NULL,
193 (LPBYTE) wszServerName, &dwLen);
195 if ( code == ERROR_SUCCESS)
198 wszServerName[MAX_SERVER_NAME_LENGTH] = '\0';
200 cbServerNameLength = wcslen( wszServerName) * sizeof( WCHAR);
202 wszServerNameUNC[0] = wszServerNameUNC[1] = L'\\';
204 memcpy(&wszServerNameUNC[2], wszServerName, (cbServerNameLength + 1) * sizeof( WCHAR));
206 cbServerNameUNCLength = cbServerNameLength + 2 * sizeof( WCHAR);
212 bServerNameRead = TRUE;
217 /* returns TRUE if the file system is disabled or not installed */
219 NPIsFSDisabled( void)
224 DWORD dwStart = SERVICE_DISABLED;
226 code = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
227 L"SYSTEM\\CurrentControlSet\\Services\\AFSRedirector",
228 0, KEY_QUERY_VALUE, &hk);
230 if ( code != ERROR_SUCCESS)
235 dwLen = sizeof(dwStart);
237 code = RegQueryValueExW( hk, L"Start", NULL, NULL,
238 (LPBYTE) &dwStart, &dwLen);
242 return ( dwStart == SERVICE_DISABLED);
246 #define try_return(S) { S; goto try_exit; }
252 typedef struct _UNICODE_STRING {
254 USHORT MaximumLength;
256 } UNICODE_STRING, *PUNICODE_STRING;
259 OpenRedirector( void);
261 typedef struct _AFS_ENUM_CB
276 // Recursively evaluate drivestr to find the final
277 // dos drive letter to which the source is mapped.
280 DriveSubstitution(LPCWSTR drivestr, LPWSTR subststr, size_t substlen, DWORD * pStatus)
283 WCHAR device[MAX_PATH + 26];
286 *pStatus = WN_SUCCESS;
288 memset( subststr, 0, substlen);
289 drive[0] = drivestr[0];
290 drive[1] = drivestr[1];
293 if ( substlen < 3 * sizeof( WCHAR))
296 // Cannot represent "D:"
301 if ( QueryDosDevice(drive, device, MAX_PATH + 26) )
303 #ifdef AFS_DEBUG_TRACE
304 AFSDbgPrint( L"DriveSubstitution QueryDosDevice %s [%s -> %s]\n",
309 if ( device[0] == L'\\' &&
312 device[3] == L'\\' &&
313 iswalpha(device[4]) &&
316 drive[0] = device[4];
320 if ( !DriveSubstitution(drive, subststr, substlen, pStatus) )
323 subststr[0] = drive[0];
332 hr = StringCbCat( subststr, substlen, &device[6]);
334 if ( SUCCEEDED(hr) && drivestr[2] )
336 hr = StringCbCat( subststr, substlen, &drivestr[2]);
339 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
342 if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER )
343 *pStatus = WN_MORE_DATA;
345 #ifdef AFS_DEBUG_TRACE
346 AFSDbgPrint( L"DriveSubstitution (hr = %X) %s -> %s\n",
354 else if ( device[0] == L'\\' &&
357 device[3] == L'\\' &&
366 hr = StringCbCopyN(&subststr[1], substlen - sizeof(WCHAR), &device[7], sizeof(device) - 7 * sizeof(WCHAR));
368 if ( SUCCEEDED(hr) && drivestr[2] )
370 hr = StringCbCat( subststr, substlen, &drivestr[2]);
373 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
376 if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER )
377 *pStatus = WN_MORE_DATA;
379 #ifdef AFS_DEBUG_TRACE
380 AFSDbgPrint( L"DriveSubstitution (hr = %X) %s -> %s\n",
388 #ifdef AFS_DEBUG_TRACE
389 AFSDbgPrint( L"DriveSubstitution StringCbCopyN 1 hr 0x%X\n",
393 else if ( _wcsnicmp( AFS_RDR_DEVICE_NAME, device, sizeof( AFS_RDR_DEVICE_NAME) / sizeof( WCHAR) - 1) == 0)
396 // \Device\AFSRedirector\;X:\\afs\cellname
399 hr = StringCbCopy( subststr, substlen,
400 &device[3 + sizeof( AFS_RDR_DEVICE_NAME) / sizeof( WCHAR)]);
402 if ( SUCCEEDED(hr) && drivestr[2] )
404 hr = StringCbCat( subststr, substlen, &drivestr[2]);
407 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
410 if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER )
411 *pStatus = WN_MORE_DATA;
413 #ifdef AFS_DEBUG_TRACE
414 AFSDbgPrint( L"DriveSubstitution (hr = %X) %s -> %s\n",
422 #ifdef AFS_DEBUG_TRACE
423 AFSDbgPrint( L"DriveSubstitution StringCbCopyN 2 hr 0x%X\n",
428 #ifdef AFS_DEBUG_TRACE
429 AFSDbgPrint( L"DriveSubstitution no substitution or match %s !! %s\n",
436 #ifdef AFS_DEBUG_TRACE
437 AFSDbgPrint( L"DriveSubstitution QueryDosDevice failed %s gle 0x%X\n",
448 NPGetCapsQueryString( DWORD nIndex)
451 case WNNC_SPEC_VERSION:
452 return L"WNNC_SPEC_VERSION";
455 return L"WNNC_NET_TYPE";
457 case WNNC_DRIVER_VERSION:
458 return L"WNNC_DRIVER_VERSION";
463 case WNNC_CONNECTION:
464 return L"WNNC_CONNECTION";
467 return L"WNNC_DIALOG";
470 return L"WNNC_ADMIN";
472 case WNNC_ENUMERATION:
473 return L"WNNC_ENUMERATION";
476 return L"WNNC_START";
478 case WNNC_CONNECTION_FLAGS:
479 return L"WNNC_CONNECTION_FLAGS";
487 // This is the only function which must be exported, everything else is optional
492 NPGetCaps( DWORD nIndex )
497 #ifdef AFS_DEBUG_TRACE
498 AFSDbgPrint( L"NPGetCaps Index %u %s\n", nIndex,
499 NPGetCapsQueryString( nIndex));
503 case WNNC_SPEC_VERSION:
506 rc = WNNC_SPEC_VERSION51;
512 rc = WNNC_NET_OPENAFS;
516 case WNNC_DRIVER_VERSION:
519 rc = WNNC_DRIVER(1, 0);
523 case WNNC_CONNECTION:
531 rc = WNNC_CON_GETCONNECTIONS |
532 WNNC_CON_CANCELCONNECTION |
533 WNNC_CON_ADDCONNECTION |
534 WNNC_CON_ADDCONNECTION3 |
535 WNNC_CON_GETPERFORMANCE;
540 case WNNC_ENUMERATION:
542 rc = WNNC_ENUM_LOCAL |
552 rc = WNNC_WAIT_FOR_START;
562 // WNNC_DLG_DEVICEMODE
563 // WNNC_DLG_PROPERTYDIALOG
564 // WNNC_DLG_SEARCHDIALOG
565 // WNNC_DLG_PERMISSIONEDITOR
568 rc = WNNC_DLG_FORMATNETWORKNAME |
569 WNNC_DLG_GETRESOURCEINFORMATION |
570 WNNC_DLG_GETRESOURCEPARENT;
589 // WNNC_ADM_GETDIRECTORYTYPE
590 // WNNC_ADM_DIRECTORYNOTIFY
591 // used by the old File Manager
602 NPAddConnection( LPNETRESOURCE lpNetResource,
607 #ifdef AFS_DEBUG_TRACE
608 AFSDbgPrint( L"NPAddConnection forwarding to NPAddConnection3\n");
610 return NPAddConnection3( NULL, lpNetResource, lpPassword, lpUserName, 0 );
614 Add3FlagsToString( DWORD dwFlags, WCHAR *wszBuffer, size_t wch)
621 if (dwFlags & CONNECT_TEMPORARY) {
623 hr = StringCbCat( wszBuffer, wch, L"TEMPORARY");
633 if (dwFlags & CONNECT_INTERACTIVE) {
637 hr = StringCbCat( wszBuffer, wch, L"|");
645 hr = StringCbCat( wszBuffer, wch, L"INTERACTIVE");
655 if (dwFlags & CONNECT_PROMPT) {
659 hr = StringCbCat( wszBuffer, wch, L"|");
667 hr = StringCbCat( wszBuffer, wch, L"PROMPT");
677 if (dwFlags & CONNECT_INTERACTIVE) {
681 hr = StringCbCat( wszBuffer, wch, L"|");
689 hr = StringCbCat( wszBuffer, wch, L"DEFERRED");
702 NPAddConnection3( HWND hwndOwner,
703 LPNETRESOURCE lpNetResource,
709 DWORD dwStatus = WN_SUCCESS;
710 WCHAR wchRemoteName[MAX_PATH+1];
711 WCHAR wchLocalName[3];
712 DWORD dwCopyBytes = 0;
713 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
715 DWORD dwBufferSize = 0;
716 HANDLE hControlDevice = NULL;
717 HANDLE hToken = NULL;
718 LARGE_INTEGER liAuthId = {0,0};
720 WCHAR wszFlagsString[1024]=L"";
724 if ( NPIsFSDisabled())
727 #ifdef AFS_DEBUG_TRACE
728 AFSDbgPrint( L"NPAddConnection3 AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
731 return WN_BAD_NETNAME;
734 if ((lpNetResource->lpRemoteName == NULL) ||
735 (lpNetResource->lpRemoteName[0] != L'\\') ||
736 (lpNetResource->lpRemoteName[1] != L'\\') ||
737 ((lpNetResource->dwType != RESOURCETYPE_DISK) &&
738 (lpNetResource->dwType != RESOURCETYPE_ANY)))
741 #ifdef AFS_DEBUG_TRACE
742 AFSDbgPrint( L"NPAddConnection3 invalid input, returning WN_BAD_NETNAME\n");
744 return WN_BAD_NETNAME;
747 #ifdef AFS_DEBUG_TRACE
748 Add3FlagsToString( dwFlags, wszFlagsString, 1024);
750 AFSDbgPrint( L"NPAddConnection3 processing Remote %s User %s Pass %s Flags %s\n",
751 lpNetResource->lpRemoteName,
752 lpUserName == NULL? L"use-default": lpUserName[0] ? lpUserName : L"no-username",
753 lpPassword == NULL? L"use-default": lpPassword[0] ? L"provided" : L"no-password",
756 if( lpNetResource->lpLocalName != NULL)
759 wchLocalName[0] = towupper(lpNetResource->lpLocalName[0]);
760 wchLocalName[1] = L':';
761 wchLocalName[2] = L'\0';
764 hr = StringCbCopy(wchRemoteName, sizeof( wchRemoteName), lpNetResource->lpRemoteName);
768 #ifdef AFS_DEBUG_TRACE
769 AFSDbgPrint( L"NPAddConnection3 lpRemoteName longer than MAX_PATH, returning WN_BAD_NETNAME\n");
771 return WN_BAD_NETNAME;
775 // Allocate our buffer to pass to the redirector filter
778 dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + (wcslen( wchRemoteName) * sizeof( WCHAR));
780 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
782 if( pConnectCB == NULL)
785 try_return( dwStatus = WN_OUT_OF_MEMORY);
788 if( lpNetResource->lpLocalName != NULL)
791 pConnectCB->LocalName = towupper(wchLocalName[0]);
793 #ifdef AFS_DEBUG_TRACE
794 AFSDbgPrint( L"NPAddConnection3 Adding mapping for drive %s remote name %s\n",
802 pConnectCB->LocalName = L'\0';
804 #ifdef AFS_DEBUG_TRACE
805 AFSDbgPrint( L"NPAddConnection3 Adding mapping for NO drive remote name %s\n",
810 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
812 pConnectCB->RemoteNameLength = wcslen( wchRemoteName) * sizeof( WCHAR);
814 memcpy( pConnectCB->RemoteName,
816 pConnectCB->RemoteNameLength);
818 pConnectCB->Type = lpNetResource->dwType;
820 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
822 #ifdef AFS_DEBUG_TRACE
823 AFSDbgPrint( L"NPAddConnection3 Retrieved authentication id %08lX-%08lX\n",
824 pConnectCB->AuthenticationId.HighPart,
825 pConnectCB->AuthenticationId.LowPart);
828 hControlDevice = OpenRedirector();
830 if( hControlDevice == NULL)
833 #ifdef AFS_DEBUG_TRACE
834 AFSDbgPrint( L"NPAddConnection3 OpenRedirector failure, returning WN_NET_ERROR\n");
837 try_return( dwStatus = WN_NET_ERROR);
840 dwError = DeviceIoControl( hControlDevice,
841 IOCTL_AFS_ADD_CONNECTION,
851 #ifdef AFS_DEBUG_TRACE
852 AFSDbgPrint( L"NPAddConnection3 Failed to add connection to file system %d\n", GetLastError());
854 try_return( dwStatus = WN_OUT_OF_MEMORY);
858 // The status returned from the driver will indicate how it was handled
861 if( dwStatus == WN_SUCCESS &&
862 lpNetResource->lpLocalName != NULL)
865 WCHAR TempBuf[MAX_PATH+26];
867 if( !QueryDosDeviceW( wchLocalName,
872 if( GetLastError() != ERROR_FILE_NOT_FOUND)
875 #ifdef AFS_DEBUG_TRACE
876 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW failed with file not found\n");
878 NPCancelConnection( wchLocalName, TRUE);
880 dwStatus = ERROR_ALREADY_ASSIGNED;
885 UNICODE_STRING uniConnectionName;
888 // Create a symbolic link object to the device we are redirecting
891 uniConnectionName.MaximumLength = (USHORT)( wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR) +
892 pConnectCB->RemoteNameLength +
893 8 + // Local name and \;
894 sizeof(WCHAR)); // Space for NULL-termination.
897 // Don't include NULL-termination.
900 uniConnectionName.Length = uniConnectionName.MaximumLength - sizeof(WCHAR);
902 uniConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
903 uniConnectionName.MaximumLength);
905 if( uniConnectionName.Buffer == NULL)
908 try_return( dwStatus = GetLastError());
911 hr = StringCbCopyW( uniConnectionName.Buffer,
912 uniConnectionName.MaximumLength,
913 AFS_RDR_DEVICE_NAME);
916 #ifdef AFS_DEBUG_TRACE
917 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
919 try_return( dwStatus = WN_OUT_OF_MEMORY);
922 hr = StringCbCatW( uniConnectionName.Buffer,
923 uniConnectionName.MaximumLength,
927 #ifdef AFS_DEBUG_TRACE
928 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
930 try_return( dwStatus = WN_OUT_OF_MEMORY);
933 hr = StringCbCatW( uniConnectionName.Buffer,
934 uniConnectionName.MaximumLength,
938 #ifdef AFS_DEBUG_TRACE
939 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
941 try_return( dwStatus = WN_OUT_OF_MEMORY);
944 hr = StringCbCatW( uniConnectionName.Buffer,
945 uniConnectionName.MaximumLength,
949 #ifdef AFS_DEBUG_TRACE
950 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
952 try_return( dwStatus = WN_OUT_OF_MEMORY);
955 #ifdef AFS_DEBUG_TRACE
956 AFSDbgPrint( L"NPAddConnection3 DefineDosDevice Local %s connection name %s\n",
958 uniConnectionName.Buffer);
961 if( !DefineDosDeviceW( DDD_RAW_TARGET_PATH |
962 DDD_NO_BROADCAST_SYSTEM,
964 uniConnectionName.Buffer))
966 #ifdef AFS_DEBUG_TRACE
967 AFSDbgPrint( L"NPAddConnection3 Failed to assign drive\n");
969 dwStatus = GetLastError();
974 #ifdef AFS_DEBUG_TRACE
975 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW assigned drive %s\n", wchLocalName);
978 dwStatus = WN_SUCCESS;
981 LocalFree( uniConnectionName.Buffer);
987 #ifdef AFS_DEBUG_TRACE
988 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW %Z already existed\n", TempBuf);
990 NPCancelConnection( wchLocalName, TRUE);
992 dwStatus = ERROR_ALREADY_ASSIGNED;
998 if ( hControlDevice != NULL)
1001 CloseHandle( hControlDevice);
1004 if( pConnectCB != NULL)
1007 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1016 NPCancelConnection( LPWSTR lpName,
1020 WCHAR wchRemoteName[MAX_PATH+1];
1021 DWORD dwRemoteNameLength = (MAX_PATH+1) * sizeof(WCHAR);
1022 DWORD dwStatus = WN_NOT_CONNECTED;
1023 DWORD dwCopyBytes = 0;
1024 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1025 AFSCancelConnectionResultCB stCancelConn;
1027 DWORD dwBufferSize = 0;
1028 BOOL bLocalName = TRUE;
1029 HANDLE hControlDevice = NULL;
1030 WCHAR wchLocalName[ 3];
1031 WCHAR *pwchLocalName = NULL;
1037 if ( NPIsFSDisabled())
1040 #ifdef AFS_DEBUG_TRACE
1041 AFSDbgPrint( L"NPCancelConnection AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1044 try_return( dwStatus = WN_NOT_CONNECTED);
1047 if( *lpName == L'\\' &&
1048 *(lpName + 1) == L'\\')
1053 wchLocalName[0] = L'\0';
1055 hr = StringCbCopyW( wchRemoteName, sizeof( wchRemoteName), lpName);
1059 #ifdef AFS_DEBUG_TRACE
1060 AFSDbgPrint( L"NPCancelConnection lpName longer than MAX_PATH\n");
1062 try_return( dwStatus = WN_OUT_OF_MEMORY);
1065 dwRemoteNameLength = (wcslen( wchRemoteName) * sizeof( WCHAR));
1070 wchLocalName[0] = towupper(lpName[0]);
1071 wchLocalName[1] = L':';
1072 wchLocalName[2] = L'\0';
1075 // Get the remote name for the connection, if we are handling it
1078 dwStatus = NPGetConnectionCommon( wchLocalName,
1080 &dwRemoteNameLength,
1083 if( dwStatus != WN_SUCCESS ||
1084 dwRemoteNameLength == 0)
1087 #ifdef AFS_DEBUG_TRACE
1088 AFSDbgPrint( L"NPCancelConnection Status 0x%x NameLength %u, returning WN_NOT_CONNECTED\n",
1089 dwStatus, dwRemoteNameLength);
1091 try_return( dwStatus = WN_NOT_CONNECTED);
1095 // NPGetConnection returns the buffer size not the length without NUL
1097 dwRemoteNameLength -= sizeof( WCHAR);
1100 wchRemoteName[ dwRemoteNameLength/sizeof( WCHAR)] = L'\0';
1102 #ifdef AFS_DEBUG_TRACE
1103 AFSDbgPrint( L"NPCancelConnection Attempting to cancel '%s' -> '%s'\n",
1104 wchLocalName, wchRemoteName);
1107 dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + dwRemoteNameLength;
1109 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1111 if( pConnectCB == NULL)
1114 try_return( dwStatus = WN_OUT_OF_MEMORY);
1120 pConnectCB->LocalName = wchLocalName[0];
1125 pConnectCB->LocalName = L'\0';
1128 pConnectCB->RemoteNameLength = (USHORT)dwRemoteNameLength;
1130 StringCbCopyW( pConnectCB->RemoteName,
1131 dwRemoteNameLength + sizeof( WCHAR),
1134 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1136 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1138 #ifdef AFS_DEBUG_TRACE
1139 AFSDbgPrint( L"NPCancelConnection Retrieved authentication id %08lX-%08lX\n",
1140 pConnectCB->AuthenticationId.HighPart,
1141 pConnectCB->AuthenticationId.LowPart);
1144 hControlDevice = OpenRedirector();
1146 if( hControlDevice == NULL)
1149 #ifdef AFS_DEBUG_TRACE
1150 AFSDbgPrint( L"NPCancelConnection OpenRedirector failure, returning WN_NET_ERROR\n");
1153 try_return( dwStatus = WN_NET_ERROR);
1156 memset( &stCancelConn,
1158 sizeof( AFSCancelConnectionResultCB));
1160 dwError = DeviceIoControl( hControlDevice,
1161 IOCTL_AFS_CANCEL_CONNECTION,
1165 sizeof( AFSCancelConnectionResultCB),
1171 #ifdef AFS_DEBUG_TRACE
1172 DWORD gle = GetLastError();
1174 AFSDbgPrint( L"NPCancelConnection DeviceIoControl failed - gle 0x%x\n", gle);
1176 try_return( dwStatus = WN_NOT_CONNECTED);
1179 dwStatus = stCancelConn.Status;
1181 #ifdef AFS_DEBUG_TRACE
1182 if ( dwStatus == WN_NOT_CONNECTED )
1185 AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status WN_NOT_CONNECTED\n",
1191 AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status %08lX\n",
1197 if( dwStatus == WN_SUCCESS &&
1199 stCancelConn.LocalName != L'\0'))
1202 UNICODE_STRING uniConnectionName;
1205 // Create a symbolic link object to the device we are redirecting
1208 uniConnectionName.MaximumLength = (USHORT)( wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR) +
1209 dwRemoteNameLength +
1210 8 + // Local name and \;
1211 sizeof(WCHAR)); // Space for NULL-termination.
1214 // Don't include NULL-termination.
1217 uniConnectionName.Length = uniConnectionName.MaximumLength - sizeof(WCHAR);
1219 uniConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
1220 uniConnectionName.MaximumLength);
1222 if( uniConnectionName.Buffer == NULL)
1225 try_return( dwStatus = GetLastError());
1228 hr = StringCbCopyW( uniConnectionName.Buffer,
1229 uniConnectionName.MaximumLength,
1230 AFS_RDR_DEVICE_NAME);
1234 #ifdef AFS_DEBUG_TRACE
1235 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (1)\n");
1237 try_return( dwStatus = WN_OUT_OF_MEMORY);
1240 hr = StringCbCatW( uniConnectionName.Buffer,
1241 uniConnectionName.MaximumLength,
1246 #ifdef AFS_DEBUG_TRACE
1247 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (2)\n");
1249 try_return( dwStatus = WN_OUT_OF_MEMORY);
1255 wchLocalName[ 0] = stCancelConn.LocalName;
1257 wchLocalName[ 1] = L':';
1259 wchLocalName[ 2] = L'\0';
1261 hr = StringCbCatW( uniConnectionName.Buffer,
1262 uniConnectionName.MaximumLength,
1267 #ifdef AFS_DEBUG_TRACE
1268 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (3)\n");
1270 try_return( dwStatus = WN_OUT_OF_MEMORY);
1273 pwchLocalName = wchLocalName;
1278 hr = StringCbCatW( uniConnectionName.Buffer,
1279 uniConnectionName.MaximumLength,
1284 #ifdef AFS_DEBUG_TRACE
1285 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (4)\n");
1287 try_return( dwStatus = WN_OUT_OF_MEMORY);
1290 pwchLocalName = lpName;
1293 hr = StringCbCatW( uniConnectionName.Buffer,
1294 uniConnectionName.MaximumLength,
1299 #ifdef AFS_DEBUG_TRACE
1300 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (5)\n");
1302 try_return( dwStatus = WN_OUT_OF_MEMORY);
1305 if( !DefineDosDevice( DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE,
1307 uniConnectionName.Buffer))
1310 #ifdef AFS_DEBUG_TRACE
1311 DWORD gle = GetLastError();
1313 AFSDbgPrint( L"NPCancelConnection Failed to cancel connection to system - gle 0x%x Name %s connection %wZ\n",
1316 &uniConnectionName);
1321 #ifdef AFS_DEBUG_TRACE
1323 AFSDbgPrint( L"NPCancelConnection Canceled connection to system - Name %s connection %wZ\n",
1325 &uniConnectionName);
1332 if ( hControlDevice != NULL)
1335 CloseHandle( hControlDevice);
1339 if( pConnectCB != NULL)
1342 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1352 NPGetConnection( LPWSTR lpLocalName,
1353 LPWSTR lpRemoteName,
1354 LPDWORD lpBufferSize)
1357 DWORD dwBufferSize = *lpBufferSize;
1360 dwStatus = NPGetConnectionCommon( lpLocalName,
1365 if ( dwStatus == WN_NOT_CONNECTED)
1368 dwStatus = NPGetConnectionCommon( lpLocalName,
1376 *lpBufferSize = dwBufferSize;
1384 NPGetConnectionCommon( LPWSTR lpLocalName,
1385 LPWSTR lpRemoteName,
1386 LPDWORD lpBufferSize,
1390 DWORD dwStatus = WN_NOT_CONNECTED;
1391 WCHAR wchLocalName[3];
1392 WCHAR wchSubstName[1024 + 26];
1393 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1395 DWORD dwBufferSize = 0;
1396 HANDLE hControlDevice = NULL;
1402 if ( NPIsFSDisabled())
1405 #ifdef AFS_DEBUG_TRACE
1406 AFSDbgPrint( L"NPGetConnection AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1409 try_return( dwStatus = WN_NOT_CONNECTED);
1412 if( lstrlen( lpLocalName) == 0)
1414 #ifdef AFS_DEBUG_TRACE
1415 AFSDbgPrint( L"NPGetConnection No local name, returning WN_BAD_LOCALNAME\n");
1417 try_return( dwStatus = WN_BAD_LOCALNAME);
1420 if ( lpBufferSize == NULL)
1422 #ifdef AFS_DEBUG_TRACE
1423 AFSDbgPrint( L"NPGetConnection No output size, returning WN_BAD_LOCALNAME\n");
1425 try_return( dwStatus = WN_BAD_VALUE);
1428 dwPassedSize = *lpBufferSize;
1430 if ( !bDriveSubstOk ||
1431 !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName), &dwStatus))
1433 wchLocalName[0] = towupper(lpLocalName[0]);
1434 wchLocalName[1] = L':';
1435 wchLocalName[2] = L'\0';
1437 #ifdef AFS_DEBUG_TRACE
1438 AFSDbgPrint( L"NPGetConnection Requesting connection for %s\n",
1444 ReadServerNameString();
1446 if ( wchSubstName[0] != L'\\' &&
1447 wchSubstName[1] == L':')
1450 wchLocalName[0] = towupper(wchSubstName[0]);
1451 wchLocalName[1] = L':';
1452 wchLocalName[2] = L'\0';
1454 #ifdef AFS_DEBUG_TRACE
1455 AFSDbgPrint( L"NPGetConnection Requesting connection for drive substitution %s -> %s\n",
1460 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
1461 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
1462 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
1467 DWORD dwRequiredSize;
1469 #ifdef AFS_DEBUG_TRACE
1470 AFSDbgPrint( L"NPGetConnection drive substitution %s is AFS\n",
1474 dwRequiredSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
1476 if ( lpRemoteName == NULL ||
1477 dwPassedSize == 0 ||
1478 dwRequiredSize > *lpBufferSize)
1481 *lpBufferSize = dwRequiredSize;
1483 try_return( dwStatus = WN_MORE_DATA);
1487 hr = StringCbCopyN(lpRemoteName, *lpBufferSize, wchSubstName, sizeof( wchSubstName));
1492 for ( dwCount = 0, pwch = lpRemoteName; *pwch && pwch < lpRemoteName + (*lpBufferSize); pwch++ )
1494 if ( *pwch == L'\\' )
1508 *lpBufferSize = wcslen( lpRemoteName) * sizeof( WCHAR) + sizeof( WCHAR);
1510 try_return( dwStatus = WN_SUCCESS);
1512 else if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER)
1515 *lpBufferSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
1517 for ( dwCount = 0, pwch = lpRemoteName; *pwch; pwch++ )
1519 if ( *pwch == L'\\' )
1527 *lpBufferSize = wcslen( lpRemoteName) * sizeof( WCHAR) + sizeof( WCHAR);
1529 try_return( dwStatus = WN_SUCCESS);
1535 try_return( dwStatus = WN_MORE_DATA);
1540 #ifdef AFS_DEBUG_TRACE
1541 AFSDbgPrint( L"NPGetConnection StringCbCopyN failure 0x%X\n",
1544 try_return( dwStatus = WN_NET_ERROR);
1550 #ifdef AFS_DEBUG_TRACE
1551 AFSDbgPrint( L"NPGetConnection drive substitution %s is not AFS\n",
1554 try_return( dwStatus = WN_NOT_CONNECTED);
1558 #ifdef AFS_DEBUG_TRACE
1559 AFSDbgPrint( L"NPGetConnection Requesting connection for %s\n",
1563 dwBufferSize = 0x1000;
1565 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1567 if( pConnectCB == NULL)
1570 try_return( dwStatus = WN_OUT_OF_MEMORY);
1573 pConnectCB->LocalName = towupper(wchLocalName[0]);
1575 pConnectCB->RemoteNameLength = 0;
1577 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1579 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1581 #ifdef AFS_DEBUG_TRACE
1582 AFSDbgPrint( L"NPGetConnection Retrieved authentication id %08lX-%08lX\n",
1583 pConnectCB->AuthenticationId.HighPart,
1584 pConnectCB->AuthenticationId.LowPart);
1587 hControlDevice = OpenRedirector();
1589 if( hControlDevice == NULL)
1592 #ifdef AFS_DEBUG_TRACE
1593 AFSDbgPrint( L"NPGetConnection OpenRedirector failure, returning WN_NET_ERROR\n");
1596 try_return( dwStatus = WN_NET_ERROR);
1599 dwError = DeviceIoControl( hControlDevice,
1600 IOCTL_AFS_GET_CONNECTION,
1610 #ifdef AFS_DEBUG_TRACE
1611 DWORD gle = GetLastError();
1613 AFSDbgPrint( L"NPGetConnection Failed to get connection from file system for local %s gle 0x%x\n",
1616 try_return( dwStatus = WN_NOT_CONNECTED);
1620 // IOCTL_AFS_GET_CONNECTION returns a counted string
1623 if( lpRemoteName == NULL ||
1624 *lpBufferSize + sizeof( WCHAR) > dwPassedSize)
1627 *lpBufferSize += sizeof( WCHAR);
1629 try_return( dwStatus = WN_MORE_DATA);
1632 memcpy( lpRemoteName,
1636 lpRemoteName[ *lpBufferSize/sizeof( WCHAR)] = L'\0';
1638 *lpBufferSize += sizeof( WCHAR);
1640 #ifdef AFS_DEBUG_TRACE
1641 AFSDbgPrint( L"NPGetConnection local %s remote %s\n",
1645 dwStatus = WN_SUCCESS;
1649 if ( hControlDevice != NULL)
1652 CloseHandle( hControlDevice);
1655 if( pConnectCB != NULL)
1658 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1666 NPGetConnection3( IN LPCWSTR lpLocalName,
1668 OUT LPVOID lpBuffer,
1669 IN OUT LPDWORD lpBufferSize)
1672 DWORD dwBufferSize = *lpBufferSize;
1675 dwStatus = NPGetConnection3Common( lpLocalName,
1681 if ( dwStatus == WN_NOT_CONNECTED)
1684 dwStatus = NPGetConnection3Common( lpLocalName,
1693 *lpBufferSize = dwBufferSize;
1700 static DWORD APIENTRY
1701 NPGetConnection3Common( IN LPCWSTR lpLocalName,
1703 OUT LPVOID lpBuffer,
1704 IN OUT LPDWORD lpBufferSize,
1705 IN BOOL bDriveSubstOk)
1708 DWORD dwStatus = WN_NOT_CONNECTED;
1709 WCHAR wchLocalName[3];
1710 WCHAR wchSubstName[1024 + 26];
1711 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1713 DWORD dwBufferSize = 0;
1714 HANDLE hControlDevice = NULL;
1716 DWORD *pConnectState =(DWORD *)lpBuffer;
1721 if ( NPIsFSDisabled())
1724 #ifdef AFS_DEBUG_TRACE
1725 AFSDbgPrint( L"NPGetConnection3 AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1728 try_return( dwStatus = WN_NOT_CONNECTED);
1731 if( lstrlen( lpLocalName) == 0)
1733 #ifdef AFS_DEBUG_TRACE
1734 AFSDbgPrint( L"NPGetConnection3 No local name, returning WN_BAD_LOCALNAME\n");
1736 try_return( dwStatus = WN_BAD_LOCALNAME);
1740 // LanMan NPGetConnection3 only responds to level 1
1743 if ( dwLevel != 0x1)
1745 #ifdef AFS_DEBUG_TRACE
1746 AFSDbgPrint( L"NPGetConnection3 Level 0x%X returning WN_BAD_LEVEL\n", dwLevel);
1748 try_return( dwStatus = WN_BAD_LEVEL);
1751 if ( lpBufferSize == NULL)
1753 #ifdef AFS_DEBUG_TRACE
1754 AFSDbgPrint( L"NPGetConnection3 No output size, returning WN_BAD_VALUE\n");
1756 try_return( dwStatus = WN_BAD_VALUE);
1759 dwPassedSize = *lpBufferSize;
1761 if ( dwPassedSize == 0 ||
1765 *lpBufferSize = sizeof( DWORD);
1767 try_return( dwStatus = WN_MORE_DATA);
1770 if ( !bDriveSubstOk ||
1771 !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName), &dwStatus))
1773 wchLocalName[0] = towupper(lpLocalName[0]);
1774 wchLocalName[1] = L':';
1775 wchLocalName[2] = L'\0';
1777 #ifdef AFS_DEBUG_TRACE
1778 AFSDbgPrint( L"NPGetConnection3 Requesting connection for %s level 0x%X\n",
1786 ReadServerNameString();
1788 if ( wchSubstName[0] != L'\\' &&
1789 wchSubstName[1] == L':')
1792 wchLocalName[0] = towupper(wchSubstName[0]);
1793 wchLocalName[1] = L':';
1794 wchLocalName[2] = L'\0';
1796 #ifdef AFS_DEBUG_TRACE
1797 AFSDbgPrint( L"NPGetConnection3 Requesting connection for drive substitution %s -> %s level 0x%x\n",
1803 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
1804 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
1805 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
1808 #ifdef AFS_DEBUG_TRACE
1809 AFSDbgPrint( L"NPGetConnection3 drive substitution %s is AFS return connected\n",
1812 *pConnectState = WNGETCON_CONNECTED;
1814 *lpBufferSize = sizeof( DWORD);
1816 try_return( dwStatus = WN_SUCCESS);
1821 #ifdef AFS_DEBUG_TRACE
1822 AFSDbgPrint( L"NPGetConnection3 drive substitution %s is not AFS return not connected\n",
1825 try_return( dwStatus = WN_NOT_CONNECTED);
1829 dwBufferSize = 0x1000;
1831 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1833 if( pConnectCB == NULL)
1836 try_return( dwStatus = WN_OUT_OF_MEMORY);
1839 pConnectCB->LocalName = towupper(wchLocalName[0]);
1841 pConnectCB->RemoteNameLength = 0;
1843 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1845 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1847 #ifdef AFS_DEBUG_TRACE
1848 AFSDbgPrint( L"NPGetConnection3 Retrieved authentication id %08lX-%08lX\n",
1849 pConnectCB->AuthenticationId.HighPart,
1850 pConnectCB->AuthenticationId.LowPart);
1853 hControlDevice = OpenRedirector();
1855 if( hControlDevice == NULL)
1858 #ifdef AFS_DEBUG_TRACE
1859 AFSDbgPrint( L"NPGetConnection3 OpenRedirector failure, returning WN_NET_ERROR\n");
1862 try_return( dwStatus = WN_NET_ERROR);
1865 dwError = DeviceIoControl( hControlDevice,
1866 IOCTL_AFS_GET_CONNECTION,
1876 #ifdef AFS_DEBUG_TRACE
1877 DWORD gle = GetLastError();
1879 AFSDbgPrint( L"NPGetConnection3 Failed to get connection from file system for local %s gle 0x%x\n",
1882 try_return( dwStatus = WN_NOT_CONNECTED);
1885 *lpBufferSize = sizeof( DWORD);
1887 if( sizeof( DWORD) > dwPassedSize)
1890 try_return( dwStatus = WN_MORE_DATA);
1893 *pConnectState = WNGETCON_CONNECTED;
1895 #ifdef AFS_DEBUG_TRACE
1896 AFSDbgPrint( L"NPGetConnection3 local %s connect-state 0x%x\n",
1900 dwStatus = WN_SUCCESS;
1904 if ( hControlDevice != NULL)
1907 CloseHandle( hControlDevice);
1910 if( pConnectCB != NULL)
1913 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1922 NPGetConnectionPerformance( LPCWSTR lpRemoteName,
1923 LPNETCONNECTINFOSTRUCT lpNetConnectInfo)
1926 DWORD dwReturn = WN_SUCCESS;
1927 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1928 DWORD dwBufferSize = 0;
1929 HANDLE hControlDevice = NULL;
1935 if ( NPIsFSDisabled())
1938 #ifdef AFS_DEBUG_TRACE
1939 AFSDbgPrint( L"NPGetConnectionPerformance AFSRDFS is disabled, returning WN_NET_ERROR\n");
1942 return WN_NET_ERROR;
1945 AFSDbgPrint( L"NPGetConnectionPerformance Entry for remote connection %S\n",
1948 dwBufferSize = 0x1000;
1950 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1952 if( pConnectCB == NULL)
1954 try_return( dwReturn = WN_OUT_OF_MEMORY);
1957 pConnectCB->RemoteNameLength = wcslen( lpRemoteName) * sizeof( WCHAR);
1959 StringCbCopy( pConnectCB->RemoteName,
1960 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
1963 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1965 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1967 hControlDevice = OpenRedirector();
1969 if( hControlDevice == NULL)
1971 AFSDbgPrint( L"NPGetConnectionPerformance OpenRedirector failure, returning WN_NET_ERROR\n");
1973 try_return( dwReturn = WN_NET_ERROR);
1976 dwError = DeviceIoControl( hControlDevice,
1977 IOCTL_AFS_GET_CONNECTION_INFORMATION,
1987 #ifdef AFS_DEBUG_TRACE
1988 DWORD gle = GetLastError();
1990 AFSDbgPrint( L"NPGetConnectionPerformance Failed to get connection info from file system for remote %S gle 0x%x\n",
1994 try_return( dwReturn = WN_NOT_CONNECTED);
1997 lpNetConnectInfo->dwFlags = 0;
1999 lpNetConnectInfo->dwSpeed = 0;
2001 lpNetConnectInfo->dwDelay = 0;
2003 lpNetConnectInfo->dwOptDataSize = 0x10000;
2005 AFSDbgPrint( L"NPGetConnectionPerformance Successfully returned information for remote connection %S\n",
2010 if ( hControlDevice != NULL)
2012 CloseHandle( hControlDevice);
2015 if( pConnectCB != NULL)
2017 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
2025 GetUsageString( DWORD dwUsage)
2027 static WCHAR Buffer[128] = L"";
2029 // RESOURCEUSAGE_CONNECTABLE 0x00000001
2030 // RESOURCEUSAGE_CONTAINER 0x00000002
2031 // RESOURCEUSAGE_NOLOCALDEVICE 0x00000004
2032 // RESOURCEUSAGE_SIBLING 0x00000008
2033 // RESOURCEUSAGE_ATTACHED 0x00000010
2034 // RESOURCEUSAGE_ALL (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED)
2035 // RESOURCEUSAGE_RESERVED 0x80000000
2040 if ( dwUsage == RESOURCEUSAGE_ALL )
2050 if ( dwUsage & RESOURCEUSAGE_CONNECTABLE )
2052 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTABLE|");
2055 if ( dwUsage & RESOURCEUSAGE_CONTAINER )
2057 StringCbCat( Buffer, sizeof(Buffer), L"CONTAINER|");
2060 if ( dwUsage & RESOURCEUSAGE_NOLOCALDEVICE )
2062 StringCbCat( Buffer, sizeof(Buffer), L"NOLOCALDEVICE|");
2065 if ( dwUsage & RESOURCEUSAGE_SIBLING )
2067 StringCbCat( Buffer, sizeof(Buffer), L"SIBLING|");
2070 if ( dwUsage & RESOURCEUSAGE_ATTACHED )
2072 StringCbCat( Buffer, sizeof(Buffer), L"ATTACHED|");
2075 if ( dwUsage & RESOURCEUSAGE_RESERVED )
2077 StringCbCat( Buffer, sizeof(Buffer), L"RESERVED|");
2080 if ( dwUsage & ~(RESOURCEUSAGE_ALL|RESOURCEUSAGE_NOLOCALDEVICE|RESOURCEUSAGE_SIBLING|RESOURCEUSAGE_RESERVED) )
2082 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
2085 Buffer[lstrlen(Buffer)-1] = L'\0';
2091 GetTypeString( DWORD dwType)
2093 static WCHAR Buffer[128] = L"";
2096 // RESOURCETYPE_ANY 0x00000000
2097 // RESOURCETYPE_DISK 0x00000001
2098 // RESOURCETYPE_PRINT 0x00000002
2099 // RESOURCETYPE_RESERVED 0x00000008
2100 // RESOURCETYPE_UNKNOWN 0xFFFFFFFF
2105 if ( dwType == RESOURCETYPE_ANY )
2110 if ( dwType == RESOURCETYPE_UNKNOWN )
2115 if ( dwType & RESOURCETYPE_DISK )
2117 StringCbCat( Buffer, sizeof(Buffer), L"DISK|");
2120 if ( dwType & RESOURCETYPE_PRINT )
2122 StringCbCat( Buffer, sizeof(Buffer), L"PRINT|");
2125 if ( dwType & RESOURCETYPE_RESERVED )
2127 StringCbCat( Buffer, sizeof(Buffer), L"RESERVED|");
2130 if ( dwType & ~(RESOURCETYPE_DISK|RESOURCETYPE_PRINT|RESOURCETYPE_RESERVED) )
2132 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
2135 Buffer[lstrlen(Buffer)-1] = L'\0';
2141 GetScopeString( DWORD dwScope)
2143 static WCHAR Buffer[128] = L"";
2146 // RESOURCE_CONNECTED 0x00000001
2147 // RESOURCE_GLOBALNET 0x00000002
2148 // RESOURCE_REMEMBERED 0x00000003
2149 // RESOURCE_RECENT 0x00000004
2150 // RESOURCE_CONTEXT 0x00000005
2155 if ( dwScope == RESOURCE_CONNECTED )
2157 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTED|");
2160 if ( dwScope == RESOURCE_GLOBALNET )
2162 StringCbCat( Buffer, sizeof(Buffer), L"GLOBALNET|");
2165 if ( dwScope == RESOURCE_REMEMBERED )
2167 StringCbCat( Buffer, sizeof(Buffer), L"REMEMBERED|");
2170 if ( dwScope == RESOURCE_RECENT )
2172 StringCbCat( Buffer, sizeof(Buffer), L"RECENT|");
2175 if ( dwScope == RESOURCE_CONTEXT )
2177 StringCbCat( Buffer, sizeof(Buffer), L"CONTEXT|");
2180 if ( dwScope & ~(RESOURCE_CONNECTED|RESOURCE_GLOBALNET|RESOURCE_REMEMBERED|RESOURCE_RECENT|RESOURCE_CONTEXT) )
2182 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
2185 Buffer[lstrlen(Buffer)-1] = L'\0';
2191 GetDisplayString( DWORD dwDisplay)
2194 // RESOURCEDISPLAYTYPE_GENERIC 0x00000000
2195 // RESOURCEDISPLAYTYPE_DOMAIN 0x00000001
2196 // RESOURCEDISPLAYTYPE_SERVER 0x00000002
2197 // RESOURCEDISPLAYTYPE_SHARE 0x00000003
2198 // RESOURCEDISPLAYTYPE_FILE 0x00000004
2199 // RESOURCEDISPLAYTYPE_GROUP 0x00000005
2200 // RESOURCEDISPLAYTYPE_NETWORK 0x00000006
2201 // RESOURCEDISPLAYTYPE_ROOT 0x00000007
2202 // RESOURCEDISPLAYTYPE_SHAREADMIN 0x00000008
2203 // RESOURCEDISPLAYTYPE_DIRECTORY 0x00000009
2204 // RESOURCEDISPLAYTYPE_TREE 0x0000000A
2205 // RESOURCEDISPLAYTYPE_NDSCONTAINER 0x0000000B
2208 switch ( dwDisplay ) {
2209 case RESOURCEDISPLAYTYPE_GENERIC:
2211 case RESOURCEDISPLAYTYPE_DOMAIN:
2213 case RESOURCEDISPLAYTYPE_SERVER:
2215 case RESOURCEDISPLAYTYPE_SHARE:
2217 case RESOURCEDISPLAYTYPE_FILE:
2219 case RESOURCEDISPLAYTYPE_GROUP:
2221 case RESOURCEDISPLAYTYPE_NETWORK:
2223 case RESOURCEDISPLAYTYPE_ROOT:
2225 case RESOURCEDISPLAYTYPE_SHAREADMIN:
2226 return L"SHAREADMIN";
2227 case RESOURCEDISPLAYTYPE_DIRECTORY:
2228 return L"DIRECTORY";
2229 case RESOURCEDISPLAYTYPE_TREE:
2231 case RESOURCEDISPLAYTYPE_NDSCONTAINER:
2232 return L"NDSCONTAINER";
2240 NPOpenEnum( DWORD dwScope,
2243 LPNETRESOURCE lpNetResource,
2247 DWORD dwStatus = WN_SUCCESS;
2248 AFSEnumerationCB *pEnumCB = NULL;
2250 #ifdef AFS_DEBUG_TRACE
2251 if ( lpNetResource == NULL)
2253 AFSDbgPrint( L"NPOpenEnum Scope %s Type %s Usage %s NetResource: (Null)\n",
2254 GetScopeString(dwScope), GetTypeString(dwType), GetUsageString(dwUsage));
2258 AFSDbgPrint( L"NPOpenEnum Scope %s Type %s Usage %s NetResource (0x%p): Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2259 GetScopeString(dwScope),
2260 GetTypeString(dwType),
2261 GetUsageString(dwUsage),
2263 GetScopeString(lpNetResource->dwScope),
2264 GetTypeString(lpNetResource->dwType),
2265 GetDisplayString(lpNetResource->dwDisplayType),
2266 GetUsageString(lpNetResource->dwUsage),
2267 lpNetResource->lpLocalName,
2268 lpNetResource->lpRemoteName,
2269 lpNetResource->lpComment);
2275 dwUsage = RESOURCEUSAGE_ALL;
2279 if ( dwType == 0 || dwType == RESOURCEUSAGE_ATTACHED)
2281 dwType |= RESOURCETYPE_DISK | RESOURCETYPE_PRINT;
2285 *lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( AFSEnumerationCB));
2287 if( *lphEnum == NULL)
2290 return WN_OUT_OF_MEMORY;
2293 pEnumCB = (AFSEnumerationCB *)*lphEnum;
2295 pEnumCB->CurrentIndex = 0;
2297 pEnumCB->Type = dwType;
2301 case RESOURCE_CONNECTED:
2304 pEnumCB->Scope = RESOURCE_CONNECTED;
2309 case RESOURCE_CONTEXT:
2312 pEnumCB->Scope = RESOURCE_CONTEXT;
2317 case RESOURCE_GLOBALNET:
2320 if( lpNetResource != NULL &&
2321 lpNetResource->lpRemoteName != NULL)
2324 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2326 if( pEnumCB->RemoteName == NULL)
2329 dwStatus = WN_OUT_OF_MEMORY;
2330 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2336 StringCbCopy( pEnumCB->RemoteName,
2338 lpNetResource->lpRemoteName);
2343 pEnumCB->Scope = RESOURCE_GLOBALNET;
2350 #ifdef AFS_DEBUG_TRACE
2351 AFSDbgPrint( L"NPOpenEnum Processing (Scope %s 0x%x) Type %s Usage %s, returning WN_NOT_SUPPORTED\n",
2352 GetScopeString(dwScope), dwScope, GetTypeString(dwType), GetUsageString(dwUsage));
2355 dwStatus = WN_NOT_SUPPORTED;
2356 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2368 NPEnumResource( HANDLE hEnum,
2371 LPDWORD lpBufferSize)
2374 DWORD dwStatus = WN_NO_MORE_ENTRIES; //WN_SUCCESS;
2376 ULONG EntriesCopied;
2377 ULONG EntriesRequested;
2379 LPNETRESOURCE pNetResource;
2381 ULONG SpaceAvailable;
2383 AFSNetworkProviderConnectionCB *pConnectionCB = NULL;
2384 void *pConnectionCBBase = NULL;
2386 UNICODE_STRING uniRemoteName;
2387 HANDLE hControlDevice = NULL;
2388 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2393 if ( lpBufferSize == NULL)
2395 #ifdef AFS_DEBUG_TRACE
2396 AFSDbgPrint( L"NPEnumResource No output size, returning WN_BAD_VALUE\n");
2398 try_return( dwStatus = WN_BAD_VALUE);
2401 ReadProviderNameString();
2403 pNetResource = (LPNETRESOURCE) lpBuffer;
2404 SpaceAvailable = *lpBufferSize;
2405 EntriesRequested = *lpcCount;
2406 *lpcCount = EntriesCopied = 0;
2407 StringZone = (PWCHAR) ((char *)lpBuffer + *lpBufferSize);
2409 #ifdef AFS_DEBUG_TRACE
2410 AFSDbgPrint( L"NPEnumResource Processing Remote name %s Scope %s Type %s Usage %s Index %d SpaceAvailable 0x%lX RequestedEntries %lu\n",
2411 pEnumCB->RemoteName ? pEnumCB->RemoteName : L"(Null)",
2412 GetScopeString(pEnumCB->Scope),
2413 GetTypeString(pEnumCB->Type),
2414 GetUsageString(pEnumCB->Type),
2415 pEnumCB->CurrentIndex,
2420 if ( NPIsFSDisabled())
2423 #ifdef AFS_DEBUG_TRACE
2424 AFSDbgPrint( L"NPEnumResource AFSRDFS is disabled, returning WN_NO_MORE_ENTRIES\n");
2427 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2430 pConnectionCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 0x1000);
2432 if( pConnectionCB == NULL)
2435 #ifdef AFS_DEBUG_TRACE
2436 AFSDbgPrint( L"NPEnumResource Out of Memory\n");
2439 try_return( dwStatus = WN_OUT_OF_MEMORY);
2442 pConnectionCBBase = (void *)pConnectionCB;
2444 hControlDevice = OpenRedirector();
2446 if( hControlDevice == NULL)
2449 #ifdef AFS_DEBUG_TRACE
2450 AFSDbgPrint( L"NPEnumResource OpenRedirector failure, returning WN_NET_ERROR\n");
2453 try_return( dwStatus = WN_NET_ERROR);
2456 if( pEnumCB->Type != RESOURCETYPE_ANY && pEnumCB->Type != RESOURCETYPE_DISK)
2459 #ifdef AFS_DEBUG_TRACE
2460 AFSDbgPrint( L"NPEnumResource Non-DISK queries are not supported, returning WN_NO_MORE_ENTRIES\n");
2462 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2466 // Handle the special cases here
2467 // 0. Provider Network Root
2472 if ( pEnumCB->Scope == RESOURCE_GLOBALNET)
2475 ReadServerNameString();
2477 if ( pEnumCB->CurrentIndex == 0 &&
2478 pEnumCB->RemoteName == NULL)
2481 // Determine the space needed for this entry...
2483 SpaceNeeded = 2 * ( cbProviderNameLength + sizeof( WCHAR));
2485 uniRemoteName.Length = (USHORT)cbProviderNameLength;
2486 uniRemoteName.MaximumLength = uniRemoteName.Length;
2487 uniRemoteName.Buffer = wszProviderName;
2489 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2492 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2494 #ifdef AFS_DEBUG_TRACE
2495 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2499 try_return( dwStatus = WN_MORE_DATA);
2502 #ifdef AFS_DEBUG_TRACE
2503 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2507 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2509 pNetResource->dwScope = RESOURCE_GLOBALNET;
2510 pNetResource->dwType = RESOURCETYPE_ANY;
2511 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_NETWORK;
2512 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_RESERVED;
2514 // setup string area at opposite end of buffer
2515 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2517 pNetResource->lpLocalName = NULL;
2520 pNetResource->lpRemoteName = StringZone;
2522 StringCbCopy( StringZone,
2523 cbProviderNameLength + sizeof( WCHAR),
2526 StringZone += cbProviderNameLength / sizeof(WCHAR) + 1;
2528 pNetResource->lpComment = NULL;
2530 // copy provider name
2531 pNetResource->lpProvider = StringZone;
2532 StringCbCopy( StringZone,
2533 cbProviderNameLength + sizeof( WCHAR),
2536 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2538 #ifdef AFS_DEBUG_TRACE
2539 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2541 GetScopeString(pNetResource->dwScope),
2542 GetTypeString(pNetResource->dwType),
2543 GetDisplayString(pNetResource->dwDisplayType),
2544 GetUsageString(pNetResource->dwUsage),
2545 pNetResource->lpLocalName,
2546 pNetResource->lpRemoteName,
2547 pNetResource->lpComment);
2550 // setup the new end of buffer
2551 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2557 // do not change the index since we did not query the redirector
2558 pEnumCB->CurrentIndex = 0;
2560 // remember that we returned the provider name
2561 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2563 if( pEnumCB->RemoteName == NULL)
2566 try_return( dwStatus = WN_OUT_OF_MEMORY);
2571 StringCbCopy( pEnumCB->RemoteName,
2577 if ( pEnumCB->CurrentIndex == 0 &&
2578 lstrlen( pEnumCB->RemoteName) == cbProviderNameLength / sizeof( WCHAR) &&
2579 _wcsnicmp( pEnumCB->RemoteName, wszProviderName, cbProviderNameLength / sizeof( WCHAR)) == 0 &&
2580 EntriesCopied < EntriesRequested)
2584 // After the network provider entry comes the server entry
2587 // Determine the space needed for this entry...
2589 SpaceNeeded = cbProviderNameLength + cbServerNameUNCLength + cbServerCommentLength + 3 * sizeof( WCHAR);
2591 uniRemoteName.Length = (USHORT)cbServerNameUNCLength;
2592 uniRemoteName.MaximumLength = uniRemoteName.Length;
2593 uniRemoteName.Buffer = wszServerNameUNC;
2595 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2598 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2600 #ifdef AFS_DEBUG_TRACE
2601 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2605 try_return( dwStatus = WN_MORE_DATA);
2608 #ifdef AFS_DEBUG_TRACE
2609 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2613 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2615 pNetResource->dwScope = 0;
2616 pNetResource->dwType = RESOURCETYPE_ANY;
2617 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
2618 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
2620 // setup string area at opposite end of buffer
2621 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2623 pNetResource->lpLocalName = NULL;
2626 pNetResource->lpRemoteName = StringZone;
2628 StringCbCopy( StringZone,
2629 cbServerNameUNCLength + sizeof( WCHAR),
2632 StringZone += cbServerNameUNCLength / sizeof(WCHAR) + 1;
2635 pNetResource->lpComment = StringZone;
2637 StringCbCopy( StringZone,
2638 cbServerCommentLength + sizeof( WCHAR),
2641 StringZone += cbServerCommentLength / sizeof( WCHAR) + 1;
2643 // copy provider name
2644 pNetResource->lpProvider = StringZone;
2645 StringCbCopy( StringZone,
2646 cbProviderNameLength + sizeof( WCHAR),
2649 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2651 #ifdef AFS_DEBUG_TRACE
2652 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2654 GetScopeString(pNetResource->dwScope),
2655 GetTypeString(pNetResource->dwType),
2656 GetDisplayString(pNetResource->dwDisplayType),
2657 GetUsageString(pNetResource->dwUsage),
2658 pNetResource->lpLocalName,
2659 pNetResource->lpRemoteName,
2660 pNetResource->lpComment);
2663 // setup the new end of buffer
2664 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2670 // do not update the index because we did not query the redirector
2671 pEnumCB->CurrentIndex = 0;
2673 // remember that we returned the server
2674 StringCbCopy( pEnumCB->RemoteName,
2682 // Setup what we are going to ask for
2685 pConnectionCB->Scope = pEnumCB->Scope;
2687 pConnectionCB->Type = pEnumCB->Type;
2689 pConnectionCB->CurrentIndex = pEnumCB->CurrentIndex;
2691 pConnectionCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
2694 // If this is a RESOURCE_GLOBALNET enumeration then pass down the remote name if
2698 pConnectionCB->RemoteNameLength = 0;
2700 if( pEnumCB->Scope == RESOURCE_GLOBALNET &&
2701 pEnumCB->RemoteName != NULL)
2704 pConnectionCB->RemoteNameLength = wcslen( pEnumCB->RemoteName) * sizeof( WCHAR);
2706 StringCbCopy( pConnectionCB->RemoteName,
2707 (0x1000 - sizeof(AFSNetworkProviderConnectionCB)) + sizeof(WCHAR),
2708 pEnumCB->RemoteName);
2711 pConnectionCB->AuthenticationId = AFSRetrieveAuthId();
2713 #ifdef AFS_DEBUG_TRACE
2714 AFSDbgPrint( L"NPEnumResource Retrieved authentication id %08lX-%08lX\n",
2715 pConnectionCB->AuthenticationId.HighPart,
2716 pConnectionCB->AuthenticationId.LowPart);
2719 dwError = DeviceIoControl( hControlDevice,
2720 IOCTL_AFS_LIST_CONNECTIONS,
2730 #ifdef AFS_DEBUG_TRACE
2731 DWORD gle = GetLastError();
2733 AFSDbgPrint( L"NPEnumResource Failed to list connections from file system - gle 0x%x\n",
2736 try_return( dwStatus = WN_NOT_CONNECTED);
2739 if( dwCopyBytes == 0)
2742 #ifdef AFS_DEBUG_TRACE
2743 AFSDbgPrint( L"NPEnumResource No More Entries\n");
2745 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2748 dwIndex = pEnumCB->CurrentIndex;
2750 while( EntriesCopied < EntriesRequested)
2753 uniRemoteName.Length = (USHORT)pConnectionCB->RemoteNameLength;
2754 uniRemoteName.MaximumLength = uniRemoteName.Length;
2755 uniRemoteName.Buffer = pConnectionCB->RemoteName;
2757 // Determine the space needed for this entry...
2761 if( pConnectionCB->LocalName != 0)
2764 SpaceNeeded += 3 * sizeof(WCHAR); // local name
2767 SpaceNeeded += pConnectionCB->RemoteNameLength + sizeof( WCHAR); // remote name
2769 if( pConnectionCB->CommentLength > 0)
2772 SpaceNeeded += pConnectionCB->CommentLength + sizeof( WCHAR); // comment
2775 SpaceNeeded += cbProviderNameLength + sizeof( WCHAR); // provider name
2777 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2780 if (EntriesCopied == 0) {
2782 dwStatus = WN_MORE_DATA;
2784 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2786 #ifdef AFS_DEBUG_TRACE
2787 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2794 #ifdef AFS_DEBUG_TRACE
2795 AFSDbgPrint( L"NPEnumResource Return SUCCESS but more entries Index %d\n",
2799 dwStatus = WN_SUCCESS;
2805 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2807 pNetResource->dwScope = pConnectionCB->Scope;
2808 pNetResource->dwType = pConnectionCB->Type;
2810 pNetResource->dwDisplayType = pConnectionCB->DisplayType;
2812 if ( pNetResource->dwType == RESOURCETYPE_ANY &&
2813 pNetResource->dwDisplayType == RESOURCEDISPLAYTYPE_SHARE)
2816 pNetResource->dwType = RESOURCETYPE_DISK;
2819 if ( pEnumCB->Scope == RESOURCE_CONNECTED)
2822 pNetResource->dwUsage = 0;
2827 pNetResource->dwUsage = pConnectionCB->Usage;
2830 // setup string area at opposite end of buffer
2831 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2834 if( pConnectionCB->LocalName != 0)
2837 pNetResource->lpLocalName = StringZone;
2838 *StringZone++ = towupper(pConnectionCB->LocalName);
2839 *StringZone++ = L':';
2840 *StringZone++ = L'\0';
2845 pNetResource->lpLocalName = NULL;
2848 #ifdef AFS_DEBUG_TRACE
2849 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2854 pNetResource->lpRemoteName = StringZone;
2856 CopyMemory( StringZone,
2857 pConnectionCB->RemoteName,
2858 pConnectionCB->RemoteNameLength);
2860 StringZone += (pConnectionCB->RemoteNameLength / sizeof(WCHAR));
2862 *StringZone++ = L'\0';
2865 if( pConnectionCB->CommentLength > 0)
2868 pNetResource->lpComment = StringZone;
2870 CopyMemory( StringZone,
2871 (void *)((char *)pConnectionCB + pConnectionCB->CommentOffset),
2872 pConnectionCB->CommentLength);
2874 StringZone += (pConnectionCB->CommentLength / sizeof(WCHAR));
2876 *StringZone++ = L'\0';
2881 pNetResource->lpComment = NULL;
2884 // copy provider name
2885 pNetResource->lpProvider = StringZone;
2886 StringCbCopy( StringZone,
2887 cbProviderNameLength + sizeof( WCHAR),
2890 StringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
2892 #ifdef AFS_DEBUG_TRACE
2893 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2895 GetScopeString(pNetResource->dwScope),
2896 GetTypeString(pNetResource->dwType),
2897 GetDisplayString(pNetResource->dwDisplayType),
2898 GetUsageString(pNetResource->dwUsage),
2899 pNetResource->lpLocalName,
2900 pNetResource->lpRemoteName,
2901 pNetResource->lpComment);
2904 // setup the new end of buffer
2905 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2913 dwCopyBytes -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2914 pConnectionCB->RemoteNameLength +
2915 pConnectionCB->CommentLength;
2917 if( dwCopyBytes == 0)
2920 dwStatus = WN_SUCCESS;
2925 pConnectionCB = (AFSNetworkProviderConnectionCB *)((char *)pConnectionCB +
2926 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2927 pConnectionCB->RemoteNameLength +
2928 pConnectionCB->CommentLength);
2931 *lpcCount = EntriesCopied;
2933 // update entry index
2934 pEnumCB->CurrentIndex = dwIndex;
2936 #ifdef AFS_DEBUG_TRACE
2937 AFSDbgPrint( L"NPEnumResource Completed Count %d Index %d\n",
2944 if ( hControlDevice != NULL)
2947 CloseHandle( hControlDevice);
2950 if( pConnectionCBBase != NULL)
2953 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectionCBBase);
2962 Routine Description:
2964 This routine closes the handle for enumeration of resources.
2968 hEnum - the enumeration handle
2972 WN_SUCCESS if successful, otherwise the appropriate error
2976 The sample only supports the notion of enumerating connected shares
2981 NPCloseEnum( HANDLE hEnum )
2984 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2986 #ifdef AFS_DEBUG_TRACE
2987 AFSDbgPrint( L"NPCloseEnum\n");
2990 if( pEnumCB->RemoteName != NULL)
2993 HeapFree( GetProcessHeap( ), 0, (PVOID) pEnumCB->RemoteName);
2996 HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum );
3002 NPGetResourceParent( LPNETRESOURCE lpNetResource,
3004 LPDWORD lpBufferSize )
3007 DWORD dwStatus = WN_ACCESS_DENIED;
3008 WCHAR *pwchRemoteName = NULL, *pwchSearch = NULL, *pwchSystem = NULL;
3009 LPNETRESOURCE lpOutResource = (LPNETRESOURCE) lpBuffer;
3011 if ( NPIsFSDisabled())
3014 #ifdef AFS_DEBUG_TRACE
3015 AFSDbgPrint( L"NPGetResourceParent AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
3018 return WN_BAD_NETNAME;
3021 if ( lpNetResource == NULL)
3023 #ifdef AFS_DEBUG_TRACE
3024 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
3026 return WN_MORE_DATA;
3029 if( lpNetResource->lpRemoteName == NULL)
3031 #ifdef AFS_DEBUG_TRACE
3032 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
3034 return WN_BAD_NETNAME;
3037 if ( lpNetResource->dwType != 0 &&
3038 lpNetResource->dwType != RESOURCETYPE_DISK)
3040 #ifdef AFS_DEBUG_TRACE
3041 AFSDbgPrint( L"NPGetResourceParent Bad dwType\n");
3043 return WN_BAD_VALUE;
3046 if ( lpBufferSize == NULL )
3049 #ifdef AFS_DEBUG_TRACE
3050 AFSDbgPrint( L"NPGetResourceParent Null lpBufferSize\n");
3052 return WN_BAD_VALUE;
3055 #ifdef AFS_DEBUG_TRACE
3056 AFSDbgPrint( L"NPGetResourceParent For remote name %s\n",
3057 lpNetResource->lpRemoteName);
3060 pwchRemoteName = lpNetResource->lpRemoteName;
3063 // The input will be of the form \\AFS\CELL\path.
3064 // \\AFS has no parent and by definition returns an empty NETRESOURCE.
3067 pwchSearch = pwchRemoteName + (wcslen( pwchRemoteName) - 1);
3069 while( pwchSearch != pwchRemoteName)
3072 if( *pwchSearch == L'\\')
3075 *pwchSearch = L'\0';
3083 if( pwchSearch != pwchRemoteName &&
3084 pwchSearch != pwchRemoteName + 1)
3087 #ifdef AFS_DEBUG_TRACE
3088 AFSDbgPrint( L"NPGetResourceParent Processing parent %s\n",
3089 lpNetResource->lpRemoteName);
3092 dwStatus = NPGetResourceInformation( lpNetResource,
3099 if ( lpOutResource == NULL ||
3100 *lpBufferSize < sizeof( NETRESOURCE) )
3102 *lpBufferSize = sizeof( NETRESOURCE);
3104 return WN_MORE_DATA;
3107 memset( lpOutResource, 0, sizeof( NETRESOURCE));
3117 NPGetResourceInformation( LPNETRESOURCE lpNetResource,
3119 LPDWORD lpBufferSize,
3120 LPWSTR *lplpSystem )
3123 DWORD dwStatus = WN_NOT_CONNECTED;
3124 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3126 DWORD dwBufferSize = 0;
3127 HANDLE hControlDevice = NULL;
3128 NETRESOURCE *pNetResource = (NETRESOURCE *)lpBuffer;
3129 PWCHAR pStringZone = NULL;
3130 UNICODE_STRING uniRemoteName;
3131 DWORD ulRequiredLen = 0;
3142 ReadProviderNameString();
3144 if ( NPIsFSDisabled())
3147 #ifdef AFS_DEBUG_TRACE
3148 AFSDbgPrint( L"NPGetResourceInformation AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
3151 try_return( dwStatus = WN_BAD_NETNAME);
3154 if ( lpNetResource == NULL ||
3155 lpBufferSize == NULL )
3158 #ifdef AFS_DEBUG_TRACE
3159 AFSDbgPrint( L"NPGetResourceInformaton Null lpNetResource or lpBufferSize\n");
3161 return WN_BAD_VALUE;
3164 if( lpNetResource->lpRemoteName == NULL)
3166 #ifdef AFS_DEBUG_TRACE
3167 AFSDbgPrint( L"NPGetResourceInformation No resource name\n");
3170 try_return( dwStatus = WN_NOT_CONNECTED);
3173 dwPassedSize = *lpBufferSize;
3175 dwBufferSize = 0x1000;
3177 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
3179 if( pConnectCB == NULL)
3182 try_return( dwStatus = WN_OUT_OF_MEMORY);
3185 pConnectCB->RemoteNameLength = wcslen( lpNetResource->lpRemoteName) * sizeof( WCHAR);
3187 StringCbCopy( pConnectCB->RemoteName,
3188 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
3189 lpNetResource->lpRemoteName);
3191 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3193 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
3195 #ifdef AFS_DEBUG_TRACE
3196 AFSDbgPrint( L"NPGetResourceInformation Retrieved authentication id %08lX-%08lX\n",
3197 pConnectCB->AuthenticationId.HighPart,
3198 pConnectCB->AuthenticationId.LowPart);
3201 hControlDevice = OpenRedirector();
3203 if( hControlDevice == NULL)
3206 #ifdef AFS_DEBUG_TRACE
3207 AFSDbgPrint( L"NPGetResourceInformation OpenRedirector failure, returning WN_NET_ERROR\n");
3210 try_return( dwStatus = WN_NET_ERROR);
3213 uniRemoteName.Length = (USHORT)pConnectCB->RemoteNameLength;
3214 uniRemoteName.MaximumLength = uniRemoteName.Length;
3215 uniRemoteName.Buffer = pConnectCB->RemoteName;
3217 #ifdef AFS_DEBUG_TRACE
3218 AFSDbgPrint( L"NPGetResourceInformation For remote name %wZ Scope %08lX Type %08lX Usage %08lX\n",
3225 dwError = DeviceIoControl( hControlDevice,
3226 IOCTL_AFS_GET_CONNECTION_INFORMATION,
3236 #ifdef AFS_DEBUG_TRACE
3237 DWORD gle = GetLastError();
3239 AFSDbgPrint( L"NPGetResourceInformation Failed to get connection info from file system for local %s gle 0x%x\n",
3240 lpNetResource->lpRemoteName, gle);
3242 try_return( dwStatus = WN_BAD_NETNAME);
3245 // Determine the space needed for this entry...
3247 ulRequiredLen = sizeof( NETRESOURCE);
3249 ulRequiredLen += pConnectCB->RemoteNameLength + sizeof( WCHAR);
3251 ulRequiredLen += pConnectCB->CommentLength + sizeof( WCHAR);
3253 ulRequiredLen += cbProviderNameLength + sizeof( WCHAR);
3255 ulRequiredLen += pConnectCB->RemainingPathLength + sizeof( WCHAR);
3257 if( pNetResource == NULL ||
3258 ulRequiredLen > dwPassedSize)
3261 *lpBufferSize = ulRequiredLen;
3263 try_return( dwStatus = WN_MORE_DATA);
3266 pStringZone = (PWCHAR) ((char *)lpBuffer + sizeof( NETRESOURCE));
3268 pNetResource->dwScope = 0 /* pConnectCB->Scope*/;
3269 pNetResource->dwType = 0 /* pConnectCB->Type */;
3271 pNetResource->dwDisplayType = pConnectCB->DisplayType;
3273 pNetResource->dwUsage = pConnectCB->Usage;
3275 pNetResource->lpLocalName = NULL;
3278 pNetResource->lpRemoteName = pStringZone;
3280 CopyMemory( pStringZone,
3281 pConnectCB->RemoteName,
3282 pConnectCB->RemoteNameLength);
3284 pStringZone += (pConnectCB->RemoteNameLength / sizeof(WCHAR));
3286 *pStringZone++ = L'\0';
3289 pNetResource->lpComment = pStringZone;
3291 CopyMemory( pStringZone,
3292 (void *)((char *)pConnectCB + pConnectCB->CommentOffset),
3293 pConnectCB->CommentLength);
3295 pStringZone += (pConnectCB->CommentLength / sizeof(WCHAR));
3297 *pStringZone++ = L'\0';
3299 // copy remaining path
3300 if (pConnectCB->RemainingPathLength > 0)
3302 *lplpSystem = pStringZone;
3304 CopyMemory( pStringZone,
3305 (void *)((char *)pConnectCB + pConnectCB->RemainingPathOffset),
3306 pConnectCB->RemainingPathLength);
3308 pStringZone += (pConnectCB->RemainingPathLength / sizeof(WCHAR));
3310 *pStringZone++ = L'\0';
3312 #ifdef AFS_DEBUG_TRACE
3313 AFSDbgPrint( L"NPGetResourceInformation For remote name %s returning remaining path %s\n",
3314 pNetResource->lpRemoteName,
3319 // copy provider name
3320 pNetResource->lpProvider = pStringZone;
3322 StringCbCopy( pStringZone,
3323 cbProviderNameLength + sizeof( WCHAR),
3326 pStringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
3328 *lpBufferSize = ulRequiredLen;
3330 dwStatus = WN_SUCCESS;
3334 if ( hControlDevice != NULL)
3337 CloseHandle( hControlDevice);
3340 if( pConnectCB != NULL)
3343 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3351 SeparateRemainingPath( WCHAR * lpConnectionName, WCHAR **lppRemainingPath)
3358 // at this point the lpConnectionName contains the full name. We need to
3359 // truncate it to \\server\share and move the remaining path back one position.
3362 for ( pwch = lpConnectionName, dwCount = 0; *pwch; pwch++)
3364 if ( *pwch == L'\\')
3378 // Found the remaining path that must be moved
3381 *lppRemainingPath = pwch + 1;
3388 for ( ; *pwch; pwch++);
3391 // and work backwards moving the string
3392 // and then make sure that there is at least
3393 // a path separator.
3398 for ( ;pwch > *lppRemainingPath; pwch--)
3400 *pwch = *(pwch - 1);
3408 NPGetUniversalName( LPCWSTR lpLocalPath,
3411 LPDWORD lpBufferSize)
3414 DWORD dwBufferSize = *lpBufferSize;
3417 dwStatus = NPGetUniversalNameCommon( lpLocalPath,
3423 if ( dwStatus == WN_NOT_CONNECTED)
3426 dwStatus = NPGetUniversalNameCommon( lpLocalPath,
3435 *lpBufferSize = dwBufferSize;
3441 static DWORD APIENTRY
3442 NPGetUniversalNameCommon( LPCWSTR lpLocalPath,
3445 LPDWORD lpBufferSize,
3448 DWORD dwStatus = WN_NOT_CONNECTED;
3449 WCHAR wchLocalName[3];
3450 WCHAR *pwchSubstName = NULL;
3451 DWORD dwSubstNameLength = 0;
3452 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3454 DWORD dwBufferSize = 0;
3455 DWORD dwPassedSize = *lpBufferSize;
3456 DWORD dwRemainingLength = *lpBufferSize;
3457 HANDLE hControlDevice = NULL;
3458 DWORD dwLocalPathLength = 0;
3459 DWORD dwRemainingPathLength = 0;
3465 #ifdef AFS_DEBUG_TRACE
3466 AFSDbgPrint( L"NPGetUniversalName local path %s level 0x%X\n",
3467 lpLocalPath ? lpLocalPath : L"(Null)",
3471 if ( NPIsFSDisabled())
3474 #ifdef AFS_DEBUG_TRACE
3475 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
3478 try_return( dwStatus = WN_NOT_CONNECTED);
3481 dwLocalPathLength = lstrlen( lpLocalPath);
3483 dwRemainingPathLength = dwLocalPathLength - 2; // no drive letter
3485 if( dwLocalPathLength == 0)
3488 #ifdef AFS_DEBUG_TRACE
3489 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_BAD_LOCALNAME\n");
3492 try_return( dwStatus = WN_BAD_LOCALNAME);
3495 if( lpBuffer == NULL ||
3496 lpBufferSize == NULL)
3498 #ifdef AFS_DEBUG_TRACE