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_NET_ERROR);
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;
2249 HANDLE hControlDevice = NULL;
2251 #ifdef AFS_DEBUG_TRACE
2252 if ( lpNetResource == NULL)
2254 AFSDbgPrint( L"NPOpenEnum Scope %s Type %s Usage %s NetResource: (Null)\n",
2255 GetScopeString(dwScope), GetTypeString(dwType), GetUsageString(dwUsage));
2259 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",
2260 GetScopeString(dwScope),
2261 GetTypeString(dwType),
2262 GetUsageString(dwUsage),
2264 GetScopeString(lpNetResource->dwScope),
2265 GetTypeString(lpNetResource->dwType),
2266 GetDisplayString(lpNetResource->dwDisplayType),
2267 GetUsageString(lpNetResource->dwUsage),
2268 lpNetResource->lpLocalName,
2269 lpNetResource->lpRemoteName,
2270 lpNetResource->lpComment);
2276 dwUsage = RESOURCEUSAGE_ALL;
2280 if ( dwType == 0 || dwType == RESOURCEUSAGE_ATTACHED)
2282 dwType |= RESOURCETYPE_DISK | RESOURCETYPE_PRINT;
2286 hControlDevice = OpenRedirector();
2288 if( hControlDevice == NULL)
2291 #ifdef AFS_DEBUG_TRACE
2292 AFSDbgPrint( L"NPOpenEnum OpenRedirector failure, returning WN_NET_ERROR\n");
2295 return WN_NO_NETWORK;
2298 CloseHandle( hControlDevice);
2301 *lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( AFSEnumerationCB));
2303 if( *lphEnum == NULL)
2306 return WN_OUT_OF_MEMORY;
2309 pEnumCB = (AFSEnumerationCB *)*lphEnum;
2311 pEnumCB->CurrentIndex = 0;
2313 pEnumCB->Type = dwType;
2317 case RESOURCE_CONNECTED:
2320 pEnumCB->Scope = RESOURCE_CONNECTED;
2325 case RESOURCE_CONTEXT:
2328 pEnumCB->Scope = RESOURCE_CONTEXT;
2333 case RESOURCE_GLOBALNET:
2336 if( lpNetResource != NULL &&
2337 lpNetResource->lpRemoteName != NULL)
2340 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2342 if( pEnumCB->RemoteName == NULL)
2345 dwStatus = WN_OUT_OF_MEMORY;
2346 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2352 StringCbCopy( pEnumCB->RemoteName,
2354 lpNetResource->lpRemoteName);
2359 pEnumCB->Scope = RESOURCE_GLOBALNET;
2366 #ifdef AFS_DEBUG_TRACE
2367 AFSDbgPrint( L"NPOpenEnum Processing (Scope %s 0x%x) Type %s Usage %s, returning WN_NOT_SUPPORTED\n",
2368 GetScopeString(dwScope), dwScope, GetTypeString(dwType), GetUsageString(dwUsage));
2371 dwStatus = WN_NOT_SUPPORTED;
2372 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2384 NPEnumResource( HANDLE hEnum,
2387 LPDWORD lpBufferSize)
2390 DWORD dwStatus = WN_NO_MORE_ENTRIES; //WN_SUCCESS;
2392 ULONG EntriesCopied;
2393 ULONG EntriesRequested;
2395 LPNETRESOURCE pNetResource;
2397 ULONG SpaceAvailable;
2399 AFSNetworkProviderConnectionCB *pConnectionCB = NULL;
2400 void *pConnectionCBBase = NULL;
2402 UNICODE_STRING uniRemoteName;
2403 HANDLE hControlDevice = NULL;
2404 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2409 if ( lpBufferSize == NULL)
2411 #ifdef AFS_DEBUG_TRACE
2412 AFSDbgPrint( L"NPEnumResource No output size, returning WN_BAD_VALUE\n");
2414 try_return( dwStatus = WN_BAD_VALUE);
2417 ReadProviderNameString();
2419 pNetResource = (LPNETRESOURCE) lpBuffer;
2420 SpaceAvailable = *lpBufferSize;
2421 EntriesRequested = *lpcCount;
2422 *lpcCount = EntriesCopied = 0;
2423 StringZone = (PWCHAR) ((char *)lpBuffer + *lpBufferSize);
2425 #ifdef AFS_DEBUG_TRACE
2426 AFSDbgPrint( L"NPEnumResource Processing Remote name %s Scope %s Type %s Usage %s Index %d SpaceAvailable 0x%lX RequestedEntries %lu\n",
2427 pEnumCB->RemoteName ? pEnumCB->RemoteName : L"(Null)",
2428 GetScopeString(pEnumCB->Scope),
2429 GetTypeString(pEnumCB->Type),
2430 GetUsageString(pEnumCB->Type),
2431 pEnumCB->CurrentIndex,
2436 if ( NPIsFSDisabled())
2439 #ifdef AFS_DEBUG_TRACE
2440 AFSDbgPrint( L"NPEnumResource AFSRDFS is disabled, returning WN_NO_MORE_ENTRIES\n");
2443 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2446 pConnectionCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 0x1000);
2448 if( pConnectionCB == NULL)
2451 #ifdef AFS_DEBUG_TRACE
2452 AFSDbgPrint( L"NPEnumResource Out of Memory\n");
2455 try_return( dwStatus = WN_OUT_OF_MEMORY);
2458 pConnectionCBBase = (void *)pConnectionCB;
2460 hControlDevice = OpenRedirector();
2462 if( hControlDevice == NULL)
2465 #ifdef AFS_DEBUG_TRACE
2466 AFSDbgPrint( L"NPEnumResource OpenRedirector failure, returning WN_NET_ERROR\n");
2469 try_return( dwStatus = WN_NET_ERROR);
2472 if( pEnumCB->Type != RESOURCETYPE_ANY && pEnumCB->Type != RESOURCETYPE_DISK)
2475 #ifdef AFS_DEBUG_TRACE
2476 AFSDbgPrint( L"NPEnumResource Non-DISK queries are not supported, returning WN_NO_MORE_ENTRIES\n");
2478 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2482 // Handle the special cases here
2483 // 0. Provider Network Root
2488 if ( pEnumCB->Scope == RESOURCE_GLOBALNET)
2491 ReadServerNameString();
2493 if ( pEnumCB->CurrentIndex == 0 &&
2494 pEnumCB->RemoteName == NULL)
2497 // Determine the space needed for this entry...
2499 SpaceNeeded = 2 * ( cbProviderNameLength + sizeof( WCHAR));
2501 uniRemoteName.Length = (USHORT)cbProviderNameLength;
2502 uniRemoteName.MaximumLength = uniRemoteName.Length;
2503 uniRemoteName.Buffer = wszProviderName;
2505 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2508 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2510 #ifdef AFS_DEBUG_TRACE
2511 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2515 try_return( dwStatus = WN_MORE_DATA);
2518 #ifdef AFS_DEBUG_TRACE
2519 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2523 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2525 pNetResource->dwScope = RESOURCE_GLOBALNET;
2526 pNetResource->dwType = RESOURCETYPE_ANY;
2527 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_NETWORK;
2528 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_RESERVED;
2530 // setup string area at opposite end of buffer
2531 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2533 pNetResource->lpLocalName = NULL;
2536 pNetResource->lpRemoteName = StringZone;
2538 StringCbCopy( StringZone,
2539 cbProviderNameLength + sizeof( WCHAR),
2542 StringZone += cbProviderNameLength / sizeof(WCHAR) + 1;
2544 pNetResource->lpComment = NULL;
2546 // copy provider name
2547 pNetResource->lpProvider = StringZone;
2548 StringCbCopy( StringZone,
2549 cbProviderNameLength + sizeof( WCHAR),
2552 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2554 #ifdef AFS_DEBUG_TRACE
2555 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2557 GetScopeString(pNetResource->dwScope),
2558 GetTypeString(pNetResource->dwType),
2559 GetDisplayString(pNetResource->dwDisplayType),
2560 GetUsageString(pNetResource->dwUsage),
2561 pNetResource->lpLocalName,
2562 pNetResource->lpRemoteName,
2563 pNetResource->lpComment);
2566 // setup the new end of buffer
2567 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2573 // do not change the index since we did not query the redirector
2574 pEnumCB->CurrentIndex = 0;
2576 // remember that we returned the provider name
2577 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2579 if( pEnumCB->RemoteName == NULL)
2582 try_return( dwStatus = WN_OUT_OF_MEMORY);
2587 StringCbCopy( pEnumCB->RemoteName,
2593 if ( pEnumCB->CurrentIndex == 0 &&
2594 lstrlen( pEnumCB->RemoteName) == cbProviderNameLength / sizeof( WCHAR) &&
2595 _wcsnicmp( pEnumCB->RemoteName, wszProviderName, cbProviderNameLength / sizeof( WCHAR)) == 0 &&
2596 EntriesCopied < EntriesRequested)
2600 // After the network provider entry comes the server entry
2603 // Determine the space needed for this entry...
2605 SpaceNeeded = cbProviderNameLength + cbServerNameUNCLength + cbServerCommentLength + 3 * sizeof( WCHAR);
2607 uniRemoteName.Length = (USHORT)cbServerNameUNCLength;
2608 uniRemoteName.MaximumLength = uniRemoteName.Length;
2609 uniRemoteName.Buffer = wszServerNameUNC;
2611 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2614 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2616 #ifdef AFS_DEBUG_TRACE
2617 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2621 try_return( dwStatus = WN_MORE_DATA);
2624 #ifdef AFS_DEBUG_TRACE
2625 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2629 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2631 pNetResource->dwScope = 0;
2632 pNetResource->dwType = RESOURCETYPE_ANY;
2633 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
2634 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
2636 // setup string area at opposite end of buffer
2637 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2639 pNetResource->lpLocalName = NULL;
2642 pNetResource->lpRemoteName = StringZone;
2644 StringCbCopy( StringZone,
2645 cbServerNameUNCLength + sizeof( WCHAR),
2648 StringZone += cbServerNameUNCLength / sizeof(WCHAR) + 1;
2651 pNetResource->lpComment = StringZone;
2653 StringCbCopy( StringZone,
2654 cbServerCommentLength + sizeof( WCHAR),
2657 StringZone += cbServerCommentLength / sizeof( WCHAR) + 1;
2659 // copy provider name
2660 pNetResource->lpProvider = StringZone;
2661 StringCbCopy( StringZone,
2662 cbProviderNameLength + sizeof( WCHAR),
2665 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2667 #ifdef AFS_DEBUG_TRACE
2668 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2670 GetScopeString(pNetResource->dwScope),
2671 GetTypeString(pNetResource->dwType),
2672 GetDisplayString(pNetResource->dwDisplayType),
2673 GetUsageString(pNetResource->dwUsage),
2674 pNetResource->lpLocalName,
2675 pNetResource->lpRemoteName,
2676 pNetResource->lpComment);
2679 // setup the new end of buffer
2680 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2686 // do not update the index because we did not query the redirector
2687 pEnumCB->CurrentIndex = 0;
2689 // remember that we returned the server
2690 StringCbCopy( pEnumCB->RemoteName,
2698 // Setup what we are going to ask for
2701 pConnectionCB->Scope = pEnumCB->Scope;
2703 pConnectionCB->Type = pEnumCB->Type;
2705 pConnectionCB->CurrentIndex = pEnumCB->CurrentIndex;
2707 pConnectionCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
2710 // If this is a RESOURCE_GLOBALNET enumeration then pass down the remote name if
2714 pConnectionCB->RemoteNameLength = 0;
2716 if( pEnumCB->Scope == RESOURCE_GLOBALNET &&
2717 pEnumCB->RemoteName != NULL)
2720 pConnectionCB->RemoteNameLength = wcslen( pEnumCB->RemoteName) * sizeof( WCHAR);
2722 StringCbCopy( pConnectionCB->RemoteName,
2723 (0x1000 - sizeof(AFSNetworkProviderConnectionCB)) + sizeof(WCHAR),
2724 pEnumCB->RemoteName);
2727 pConnectionCB->AuthenticationId = AFSRetrieveAuthId();
2729 #ifdef AFS_DEBUG_TRACE
2730 AFSDbgPrint( L"NPEnumResource Retrieved authentication id %08lX-%08lX\n",
2731 pConnectionCB->AuthenticationId.HighPart,
2732 pConnectionCB->AuthenticationId.LowPart);
2735 dwError = DeviceIoControl( hControlDevice,
2736 IOCTL_AFS_LIST_CONNECTIONS,
2746 #ifdef AFS_DEBUG_TRACE
2747 DWORD gle = GetLastError();
2749 AFSDbgPrint( L"NPEnumResource Failed to list connections from file system - gle 0x%x\n",
2752 try_return( dwStatus = WN_NOT_CONNECTED);
2755 if( dwCopyBytes == 0)
2758 #ifdef AFS_DEBUG_TRACE
2759 AFSDbgPrint( L"NPEnumResource No More Entries\n");
2761 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2764 dwIndex = pEnumCB->CurrentIndex;
2766 while( EntriesCopied < EntriesRequested)
2769 uniRemoteName.Length = (USHORT)pConnectionCB->RemoteNameLength;
2770 uniRemoteName.MaximumLength = uniRemoteName.Length;
2771 uniRemoteName.Buffer = pConnectionCB->RemoteName;
2773 // Determine the space needed for this entry...
2777 if( pConnectionCB->LocalName != 0)
2780 SpaceNeeded += 3 * sizeof(WCHAR); // local name
2783 SpaceNeeded += pConnectionCB->RemoteNameLength + sizeof( WCHAR); // remote name
2785 if( pConnectionCB->CommentLength > 0)
2788 SpaceNeeded += pConnectionCB->CommentLength + sizeof( WCHAR); // comment
2791 SpaceNeeded += cbProviderNameLength + sizeof( WCHAR); // provider name
2793 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2796 if (EntriesCopied == 0) {
2798 dwStatus = WN_MORE_DATA;
2800 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2802 #ifdef AFS_DEBUG_TRACE
2803 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2810 #ifdef AFS_DEBUG_TRACE
2811 AFSDbgPrint( L"NPEnumResource Return SUCCESS but more entries Index %d\n",
2815 dwStatus = WN_SUCCESS;
2821 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2823 pNetResource->dwScope = pConnectionCB->Scope;
2824 pNetResource->dwType = pConnectionCB->Type;
2826 pNetResource->dwDisplayType = pConnectionCB->DisplayType;
2828 if ( pNetResource->dwType == RESOURCETYPE_ANY &&
2829 pNetResource->dwDisplayType == RESOURCEDISPLAYTYPE_SHARE)
2832 pNetResource->dwType = RESOURCETYPE_DISK;
2835 if ( pEnumCB->Scope == RESOURCE_CONNECTED)
2838 pNetResource->dwUsage = 0;
2843 pNetResource->dwUsage = pConnectionCB->Usage;
2846 // setup string area at opposite end of buffer
2847 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2850 if( pConnectionCB->LocalName != 0)
2853 pNetResource->lpLocalName = StringZone;
2854 *StringZone++ = towupper(pConnectionCB->LocalName);
2855 *StringZone++ = L':';
2856 *StringZone++ = L'\0';
2861 pNetResource->lpLocalName = NULL;
2864 #ifdef AFS_DEBUG_TRACE
2865 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2870 pNetResource->lpRemoteName = StringZone;
2872 CopyMemory( StringZone,
2873 pConnectionCB->RemoteName,
2874 pConnectionCB->RemoteNameLength);
2876 StringZone += (pConnectionCB->RemoteNameLength / sizeof(WCHAR));
2878 *StringZone++ = L'\0';
2881 if( pConnectionCB->CommentLength > 0)
2884 pNetResource->lpComment = StringZone;
2886 CopyMemory( StringZone,
2887 (void *)((char *)pConnectionCB + pConnectionCB->CommentOffset),
2888 pConnectionCB->CommentLength);
2890 StringZone += (pConnectionCB->CommentLength / sizeof(WCHAR));
2892 *StringZone++ = L'\0';
2897 pNetResource->lpComment = NULL;
2900 // copy provider name
2901 pNetResource->lpProvider = StringZone;
2902 StringCbCopy( StringZone,
2903 cbProviderNameLength + sizeof( WCHAR),
2906 StringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
2908 #ifdef AFS_DEBUG_TRACE
2909 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2911 GetScopeString(pNetResource->dwScope),
2912 GetTypeString(pNetResource->dwType),
2913 GetDisplayString(pNetResource->dwDisplayType),
2914 GetUsageString(pNetResource->dwUsage),
2915 pNetResource->lpLocalName,
2916 pNetResource->lpRemoteName,
2917 pNetResource->lpComment);
2920 // setup the new end of buffer
2921 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2929 dwCopyBytes -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2930 pConnectionCB->RemoteNameLength +
2931 pConnectionCB->CommentLength;
2933 if( dwCopyBytes == 0)
2936 dwStatus = WN_SUCCESS;
2941 pConnectionCB = (AFSNetworkProviderConnectionCB *)((char *)pConnectionCB +
2942 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2943 pConnectionCB->RemoteNameLength +
2944 pConnectionCB->CommentLength);
2947 *lpcCount = EntriesCopied;
2949 // update entry index
2950 pEnumCB->CurrentIndex = dwIndex;
2952 #ifdef AFS_DEBUG_TRACE
2953 AFSDbgPrint( L"NPEnumResource Completed Count %d Index %d\n",
2960 if ( hControlDevice != NULL)
2963 CloseHandle( hControlDevice);
2966 if( pConnectionCBBase != NULL)
2969 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectionCBBase);
2978 Routine Description:
2980 This routine closes the handle for enumeration of resources.
2984 hEnum - the enumeration handle
2988 WN_SUCCESS if successful, otherwise the appropriate error
2992 The sample only supports the notion of enumerating connected shares
2997 NPCloseEnum( HANDLE hEnum )
3000 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
3002 #ifdef AFS_DEBUG_TRACE
3003 AFSDbgPrint( L"NPCloseEnum\n");
3006 if( pEnumCB->RemoteName != NULL)
3009 HeapFree( GetProcessHeap( ), 0, (PVOID) pEnumCB->RemoteName);
3012 HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum );
3018 NPGetResourceParent( LPNETRESOURCE lpNetResource,
3020 LPDWORD lpBufferSize )
3023 DWORD dwStatus = WN_ACCESS_DENIED;
3024 WCHAR *pwchRemoteName = NULL, *pwchSearch = NULL, *pwchSystem = NULL;
3025 LPNETRESOURCE lpOutResource = (LPNETRESOURCE) lpBuffer;
3027 if ( NPIsFSDisabled())
3030 #ifdef AFS_DEBUG_TRACE
3031 AFSDbgPrint( L"NPGetResourceParent AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
3034 return WN_BAD_NETNAME;
3037 if ( lpNetResource == NULL)
3039 #ifdef AFS_DEBUG_TRACE
3040 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
3042 return WN_MORE_DATA;
3045 if( lpNetResource->lpRemoteName == NULL)
3047 #ifdef AFS_DEBUG_TRACE
3048 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
3050 return WN_BAD_NETNAME;
3053 if ( lpNetResource->dwType != 0 &&
3054 lpNetResource->dwType != RESOURCETYPE_DISK)
3056 #ifdef AFS_DEBUG_TRACE
3057 AFSDbgPrint( L"NPGetResourceParent Bad dwType\n");
3059 return WN_BAD_VALUE;
3062 if ( lpBufferSize == NULL )
3065 #ifdef AFS_DEBUG_TRACE
3066 AFSDbgPrint( L"NPGetResourceParent Null lpBufferSize\n");
3068 return WN_BAD_VALUE;
3071 #ifdef AFS_DEBUG_TRACE
3072 AFSDbgPrint( L"NPGetResourceParent For remote name %s\n",
3073 lpNetResource->lpRemoteName);
3076 pwchRemoteName = lpNetResource->lpRemoteName;
3079 // The input will be of the form \\AFS\CELL\path.
3080 // \\AFS has no parent and by definition returns an empty NETRESOURCE.
3083 pwchSearch = pwchRemoteName + (wcslen( pwchRemoteName) - 1);
3085 while( pwchSearch != pwchRemoteName)
3088 if( *pwchSearch == L'\\')
3091 *pwchSearch = L'\0';
3099 if( pwchSearch != pwchRemoteName &&
3100 pwchSearch != pwchRemoteName + 1)
3103 #ifdef AFS_DEBUG_TRACE
3104 AFSDbgPrint( L"NPGetResourceParent Processing parent %s\n",
3105 lpNetResource->lpRemoteName);
3108 dwStatus = NPGetResourceInformation( lpNetResource,
3115 if ( lpOutResource == NULL ||
3116 *lpBufferSize < sizeof( NETRESOURCE) )
3118 *lpBufferSize = sizeof( NETRESOURCE);
3120 return WN_MORE_DATA;
3123 memset( lpOutResource, 0, sizeof( NETRESOURCE));
3133 NPGetResourceInformation( LPNETRESOURCE lpNetResource,
3135 LPDWORD lpBufferSize,
3136 LPWSTR *lplpSystem )
3139 DWORD dwStatus = WN_NOT_CONNECTED;
3140 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3142 DWORD dwBufferSize = 0;
3143 HANDLE hControlDevice = NULL;
3144 NETRESOURCE *pNetResource = (NETRESOURCE *)lpBuffer;
3145 PWCHAR pStringZone = NULL;
3146 UNICODE_STRING uniRemoteName;
3147 DWORD ulRequiredLen = 0;
3158 ReadProviderNameString();
3160 if ( NPIsFSDisabled())
3163 #ifdef AFS_DEBUG_TRACE
3164 AFSDbgPrint( L"NPGetResourceInformation AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
3167 try_return( dwStatus = WN_BAD_NETNAME);
3170 if ( lpNetResource == NULL ||
3171 lpBufferSize == NULL )
3174 #ifdef AFS_DEBUG_TRACE
3175 AFSDbgPrint( L"NPGetResourceInformaton Null lpNetResource or lpBufferSize\n");
3177 return WN_BAD_VALUE;
3180 if( lpNetResource->lpRemoteName == NULL)
3182 #ifdef AFS_DEBUG_TRACE
3183 AFSDbgPrint( L"NPGetResourceInformation No resource name\n");
3186 try_return( dwStatus = WN_NOT_CONNECTED);
3189 dwPassedSize = *lpBufferSize;
3191 dwBufferSize = 0x1000;
3193 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
3195 if( pConnectCB == NULL)
3198 try_return( dwStatus = WN_OUT_OF_MEMORY);
3201 pConnectCB->RemoteNameLength = wcslen( lpNetResource->lpRemoteName) * sizeof( WCHAR);
3203 StringCbCopy( pConnectCB->RemoteName,
3204 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
3205 lpNetResource->lpRemoteName);
3207 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3209 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
3211 #ifdef AFS_DEBUG_TRACE
3212 AFSDbgPrint( L"NPGetResourceInformation Retrieved authentication id %08lX-%08lX\n",
3213 pConnectCB->AuthenticationId.HighPart,
3214 pConnectCB->AuthenticationId.LowPart);
3217 hControlDevice = OpenRedirector();
3219 if( hControlDevice == NULL)
3222 #ifdef AFS_DEBUG_TRACE
3223 AFSDbgPrint( L"NPGetResourceInformation OpenRedirector failure, returning WN_NET_ERROR\n");
3226 try_return( dwStatus = WN_NET_ERROR);
3229 uniRemoteName.Length = (USHORT)pConnectCB->RemoteNameLength;
3230 uniRemoteName.MaximumLength = uniRemoteName.Length;
3231 uniRemoteName.Buffer = pConnectCB->RemoteName;
3233 #ifdef AFS_DEBUG_TRACE
3234 AFSDbgPrint( L"NPGetResourceInformation For remote name %wZ Scope %08lX Type %08lX Usage %08lX\n",
3241 dwError = DeviceIoControl( hControlDevice,
3242 IOCTL_AFS_GET_CONNECTION_INFORMATION,
3252 #ifdef AFS_DEBUG_TRACE
3253 DWORD gle = GetLastError();
3255 AFSDbgPrint( L"NPGetResourceInformation Failed to get connection info from file system for local %s gle 0x%x\n",
3256 lpNetResource->lpRemoteName, gle);
3258 try_return( dwStatus = WN_BAD_NETNAME);
3261 // Determine the space needed for this entry...
3263 ulRequiredLen = sizeof( NETRESOURCE);
3265 ulRequiredLen += pConnectCB->RemoteNameLength + sizeof( WCHAR);
3267 ulRequiredLen += pConnectCB->CommentLength + sizeof( WCHAR);
3269 ulRequiredLen += cbProviderNameLength + sizeof( WCHAR);
3271 ulRequiredLen += pConnectCB->RemainingPathLength + sizeof( WCHAR);
3273 if( pNetResource == NULL ||
3274 ulRequiredLen > dwPassedSize)
3277 *lpBufferSize = ulRequiredLen;
3279 try_return( dwStatus = WN_MORE_DATA);
3282 pStringZone = (PWCHAR) ((char *)lpBuffer + sizeof( NETRESOURCE));
3284 pNetResource->dwScope = 0 /* pConnectCB->Scope*/;
3285 pNetResource->dwType = 0 /* pConnectCB->Type */;
3287 pNetResource->dwDisplayType = pConnectCB->DisplayType;
3289 pNetResource->dwUsage = pConnectCB->Usage;
3291 pNetResource->lpLocalName = NULL;
3294 pNetResource->lpRemoteName = pStringZone;
3296 CopyMemory( pStringZone,
3297 pConnectCB->RemoteName,
3298 pConnectCB->RemoteNameLength);
3300 pStringZone += (pConnectCB->RemoteNameLength / sizeof(WCHAR));
3302 *pStringZone++ = L'\0';
3305 pNetResource->lpComment = pStringZone;
3307 CopyMemory( pStringZone,
3308 (void *)((char *)pConnectCB + pConnectCB->CommentOffset),
3309 pConnectCB->CommentLength);
3311 pStringZone += (pConnectCB->CommentLength / sizeof(WCHAR));
3313 *pStringZone++ = L'\0';
3315 // copy remaining path
3316 if (pConnectCB->RemainingPathLength > 0)
3318 *lplpSystem = pStringZone;
3320 CopyMemory( pStringZone,
3321 (void *)((char *)pConnectCB + pConnectCB->RemainingPathOffset),
3322 pConnectCB->RemainingPathLength);
3324 pStringZone += (pConnectCB->RemainingPathLength / sizeof(WCHAR));
3326 *pStringZone++ = L'\0';
3328 #ifdef AFS_DEBUG_TRACE
3329 AFSDbgPrint( L"NPGetResourceInformation For remote name %s returning remaining path %s\n",
3330 pNetResource->lpRemoteName,
3335 // copy provider name
3336 pNetResource->lpProvider = pStringZone;
3338 StringCbCopy( pStringZone,
3339 cbProviderNameLength + sizeof( WCHAR),
3342 pStringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
3344 *lpBufferSize = ulRequiredLen;
3346 dwStatus = WN_SUCCESS;
3350 if ( hControlDevice != NULL)
3353 CloseHandle( hControlDevice);
3356 if( pConnectCB != NULL)
3359 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3367 SeparateRemainingPath( WCHAR * lpConnectionName, WCHAR **lppRemainingPath)
3374 // at this point the lpConnectionName contains the full name. We need to
3375 // truncate it to \\server\share and move the remaining path back one position.
3378 for ( pwch = lpConnectionName, dwCount = 0; *pwch; pwch++)
3380 if ( *pwch == L'\\')
3394 // Found the remaining path that must be moved
3397 *lppRemainingPath = pwch + 1;
3404 for ( ; *pwch; pwch++);
3407 // and work backwards moving the string
3408 // and then make sure that there is at least
3409 // a path separator.
3414 for ( ;pwch > *lppRemainingPath; pwch--)
3416 *pwch = *(pwch - 1);
3424 NPGetUniversalName( LPCWSTR lpLocalPath,
3427 LPDWORD lpBufferSize)
3430 DWORD dwBufferSize = *lpBufferSize;
3433 dwStatus = NPGetUniversalNameCommon( lpLocalPath,
3439 if ( dwStatus == WN_NOT_CONNECTED)
3442 dwStatus = NPGetUniversalNameCommon( lpLocalPath,
3451 *lpBufferSize = dwBufferSize;
3457 static DWORD APIENTRY
3458 NPGetUniversalNameCommon( LPCWSTR lpLocalPath,
3461 LPDWORD lpBufferSize,
3464 DWORD dwStatus = WN_NOT_CONNECTED;
3465 WCHAR wchLocalName[3];
3466 WCHAR *pwchSubstName = NULL;
3467 DWORD dwSubstNameLength = 0;
3468 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3470 DWORD dwBufferSize = 0;
3471 DWORD dwPassedSize = *lpBufferSize;
3472 DWORD dwRemainingLength = *lpBufferSize;
3473 HANDLE hControlDevice = NULL;
3474 DWORD dwLocalPathLength = 0;
3475 DWORD dwRemainingPathLength = 0;
3481 #ifdef AFS_DEBUG_TRACE
3482 AFSDbgPrint( L"NPGetUniversalName local path %s level 0x%X\n",
3483 lpLocalPath ? lpLocalPath : L"(Null)",
3487 if ( NPIsFSDisabled())
3490 #ifdef AFS_DEBUG_TRACE
3491 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
3494 try_return( dwStatus = WN_NOT_CONNECTED);
3497 dwLocalPathLength = lstrlen( lpLocalPath);
3499 dwRemainingPathLength = dwLocalPathLength - 2; // no drive letter
3501 if( dwLocalPathLength == 0)
3504 #ifdef AFS_DEBUG_TRACE
3505 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_BAD_LOCALNAME\n");
3508 try_return( dwStatus = WN_BAD_LOCALNAME);
3511 if( lpBuffer == NULL ||
3512 lpBufferSize == NULL)
3514 #ifdef AFS_DEBUG_TRACE
3515 AFSDbgPrint( L"NPGetUniversalName No output buffer or size\n");
3517 try_return( dwStatus = WN_BAD_VALUE);
3520 dwSubstNameLength = 4096;
3522 pwchSubstName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSubstNameLength);
3524 if ( pwchSubstName == NULL)
3526 #ifdef AFS_DEBUG_TRACE
3527 AFSDbgPrint( L"NPGetUniversalName unable to allocate substitution name buffer.\n");
3529 try_return( dwStatus = WN_OUT_OF_MEMORY);
3532 memset(lpBuffer, 0, dwPassedSize);
3534 if ( !bDriveSubstOk ||
3535 !DriveSubstitution( lpLocalPath, pwchSubstName, dwSubstNameLength, &dwStatus))
3537 wchLocalName[0] = towupper(lpLocalPath[0]);
3538 wchLocalName[1] = L':';
3539 wchLocalName[2] = L'\0';
3541 #ifdef AFS_DEBUG_TRACE
3542 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for %s level 0x%X\n",
3550 ReadServerNameString();
3552 if ( pwchSubstName[0] != L'\\' &&
3553 pwchSubstName[1] == L':')
3556 wchLocalName[0] = towupper(pwchSubstName[0]);
3557 wchLocalName[1] = L':';
3558 wchLocalName[2] = L'\0';
3560 #ifdef AFS_DEBUG_TRACE
3561 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for drive substitution %s -> %s\n",
3566 else if ( _wcsnicmp( pwchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
3567 ( pwchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
3568 pwchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
3572 #ifdef AFS_DEBUG_TRACE
3573 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is AFS; Level 0x%x BufferSize 0x%x\n",
3579 dwBufferSize = (wcslen( pwchSubstName) + 1) * sizeof( WCHAR);
3581 switch( dwInfoLevel)
3584 case UNIVERSAL_NAME_INFO_LEVEL:
3587 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3589 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize;
3591 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3594 #ifdef AFS_DEBUG_TRACE
3595 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3598 try_return( dwStatus = WN_MORE_DATA);
3601 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3603 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3605 memcpy( pUniversalInfo->lpUniversalName,
3607 min( dwBufferSize, dwRemainingLength));
3609 dwRemainingLength -= min( dwBufferSize, dwRemainingLength);
3611 #ifdef AFS_DEBUG_TRACE
3612 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3614 pUniversalInfo->lpUniversalName,
3615 pUniversalInfo->lpUniversalName);
3618 if ( dwPassedSize < *lpBufferSize)
3621 try_return( dwStatus = WN_MORE_DATA);
3624 try_return( dwStatus = WN_SUCCESS);
3627 case REMOTE_NAME_INFO_LEVEL:
3630 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3632 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + 2 * dwBufferSize + sizeof( WCHAR);
3634 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3637 #ifdef AFS_DEBUG_TRACE
3638 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3641 try_return( dwStatus = WN_MORE_DATA);
3644 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3646 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3648 memcpy( pRemoteInfo->lpUniversalName,
3650 min( dwRemainingLength, dwBufferSize));
3652 dwRemainingLength -= min( dwRemainingLength, dwBufferSize);
3654 #ifdef AFS_DEBUG_TRACE
3655 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3657 pRemoteInfo->lpUniversalName,
3658 pRemoteInfo->lpUniversalName);
3661 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3663 pRemoteInfo->lpConnectionName = (LPTSTR)((char *)pRemoteInfo->lpUniversalName + dwBufferSize);
3665 memcpy( pRemoteInfo->lpConnectionName,
3667 min( dwRemainingLength, dwBufferSize));
3669 dwRemainingLength -= min( dwRemainingLength, dwBufferSize) - sizeof( WCHAR);
3671 SeparateRemainingPath( pRemoteInfo->lpConnectionName,
3672 &pRemoteInfo->lpRemainingPath);
3675 #ifdef AFS_DEBUG_TRACE
3676 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3678 pRemoteInfo->lpConnectionName,
3679 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3681 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3683 pRemoteInfo->lpRemainingPath,
3684 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3687 if ( dwPassedSize < *lpBufferSize)
3690 try_return( dwStatus = WN_MORE_DATA);
3693 try_return( dwStatus = WN_SUCCESS);
3697 #ifdef AFS_DEBUG_TRACE
3698 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3701 try_return( dwStatus = WN_BAD_VALUE);
3707 #ifdef AFS_DEBUG_TRACE
3708 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is not AFS\n",
3711 try_return( dwStatus = WN_NOT_CONNECTED);
3715 dwBufferSize = 0x1000;
3717 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
3719 if( pConnectCB == NULL)
3721 try_return( dwStatus = WN_OUT_OF_MEMORY);
3724 pConnectCB->LocalName = towupper(wchLocalName[0]);
3726 pConnectCB->RemoteNameLength = 0;
3728 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3730 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
3732 #ifdef AFS_DEBUG_TRACE
3733 AFSDbgPrint( L"NPGetUniversalName Retrieved authentication id %08lX-%08lX\n",
3734 pConnectCB->AuthenticationId.HighPart,
3735 pConnectCB->AuthenticationId.LowPart);
3738 hControlDevice = OpenRedirector();
3740 if( hControlDevice == NULL)
3743 try_return( dwStatus = WN_NET_ERROR);
3746 dwError = DeviceIoControl( hControlDevice,
3747 IOCTL_AFS_GET_CONNECTION,
3757 #ifdef AFS_DEBUG_TRACE
3758 DWORD gle = GetLastError();
3760 AFSDbgPrint( L"NPGetUniversalName Failed to get connection from file system for local %s gle 0x%x\n",
3763 try_return( dwStatus = WN_NOT_CONNECTED);
3766 switch( dwInfoLevel)
3769 case UNIVERSAL_NAME_INFO_LEVEL:
3772 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3774 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize + sizeof( WCHAR);
3776 *lpBufferSize += dwRemainingPathLength * sizeof( WCHAR);
3778 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3781 #ifdef AFS_DEBUG_TRACE
3782 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3785 try_return( dwStatus = WN_MORE_DATA);
3788 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3790 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3792 pch = (char *)pUniversalInfo->lpUniversalName;
3796 min( dwBufferSize, dwRemainingLength));
3798 pch += min( dwBufferSize, dwRemainingLength);
3800 dwRemainingLength -= min( dwBufferSize + sizeof(WCHAR), dwRemainingLength);
3804 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3806 pch += min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3808 dwRemainingLength -= min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3810 #ifdef AFS_DEBUG_TRACE
3811 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3813 pUniversalInfo->lpUniversalName,
3814 pUniversalInfo->lpUniversalName);
3817 if ( dwPassedSize < *lpBufferSize)
3820 try_return( dwStatus = WN_MORE_DATA);
3823 try_return( dwStatus = WN_SUCCESS);
3826 case REMOTE_NAME_INFO_LEVEL:
3829 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3831 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + (2 * dwBufferSize + sizeof( WCHAR)) + 2 * sizeof( WCHAR);
3833 *lpBufferSize += 2 * dwRemainingPathLength * sizeof( WCHAR);
3835 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3838 #ifdef AFS_DEBUG_TRACE
3839 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3842 try_return( dwStatus = WN_MORE_DATA);
3845 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3847 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3849 pch = (char *)pRemoteInfo->lpUniversalName;
3853 min( dwBufferSize, dwRemainingLength));
3855 pch += min( dwBufferSize, dwRemainingLength);
3857 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3861 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3863 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3865 dwRemainingLength -= min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3867 #ifdef AFS_DEBUG_TRACE
3868 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3870 pRemoteInfo->lpUniversalName,
3871 pRemoteInfo->lpUniversalName);
3874 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3876 pRemoteInfo->lpConnectionName = (LPWSTR)pch;
3880 min( dwBufferSize, dwRemainingLength));
3882 pch += min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3884 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3888 if ( dwRemainingLength > dwRemainingPathLength + sizeof( WCHAR))
3890 pRemoteInfo->lpRemainingPath = (LPWSTR)pch;
3894 min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength));
3896 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3898 dwRemainingLength -= min((dwLocalPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3901 #ifdef AFS_DEBUG_TRACE
3902 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3904 pRemoteInfo->lpConnectionName,
3905 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3907 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3909 pRemoteInfo->lpRemainingPath,
3910 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3913 if ( dwPassedSize < *lpBufferSize)
3916 try_return( dwStatus = WN_MORE_DATA);
3919 try_return( dwStatus = WN_SUCCESS);
3923 #ifdef AFS_DEBUG_TRACE
3924 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3927 try_return( dwStatus = WN_BAD_VALUE);
3932 #ifdef AFS_DEBUG_TRACE
3933 AFSDbgPrint( L"NPGetUniversalName BufferSize 0x%X\n",
3936 if ( hControlDevice != NULL)
3939 CloseHandle( hControlDevice);
3945 HeapFree( GetProcessHeap(), 0, (PVOID) pwchSubstName);
3948 if( pConnectCB != NULL)
3951 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3960 GetFormatFlags( DWORD dwFlags)
3962 static WCHAR Buffer[128] = L"";
3965 // WNFMT_MULTILINE 0x01
3966 // WNFMT_ABBREVIATED 0x02
3967 // WNFMT_INENUM 0x10
3968 // WNFMT_CONNECTION 0x20
3978 if ( dwFlags & WNFMT_MULTILINE )
3980 StringCbCat( Buffer, sizeof(Buffer), L"MULTILINE|");
3983 if ( dwFlags & WNFMT_INENUM )
3985 StringCbCat( Buffer, sizeof(Buffer), L"ABBREVIATED|");
3988 if ( dwFlags & WNFMT_INENUM )
3990 StringCbCat( Buffer, sizeof(Buffer), L"INENUM|");
3993 if ( dwFlags & WNFMT_CONNECTION )
3995 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTION|");
3998 if ( dwFlags & ~(WNFMT_MULTILINE|WNFMT_ABBREVIATED|WNFMT_INENUM|WNFMT_CONNECTION) )
4000 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
4003 Buffer[lstrlen(Buffer)-1] = L'\0';
4009 NPFormatNetworkName( LPTSTR lpRemoteName,
4010 LPTSTR lpFormattedName,
4013 DWORD dwAveCharPerLine)
4016 DWORD dwLen = 0, dwCurrentLen = 0;
4017 LPTSTR pCurrentName = lpRemoteName;
4019 #ifdef AFS_DEBUG_TRACE
4020 AFSDbgPrint( L"NPFormatNetworkName Remote %s Flags %s (0x%x) CharsPerLine %u\n",
4022 GetFormatFlags( dwFlags),
4029 // Walk back in the name until we hit a \
4032 dwLen = wcslen( lpRemoteName);
4034 pCurrentName += (dwLen - 1);
4036 if ( pCurrentName[ 0] != L'\\')
4042 if( pCurrentName[ 0] == L'\\')
4058 if( *lpnLength < dwCurrentLen * sizeof( WCHAR))
4061 *lpnLength = dwCurrentLen * sizeof( WCHAR);
4063 #ifdef AFS_DEBUG_TRACE
4064 AFSDbgPrint( L"NPFormatNetworkName remote name %s WN_MORE_DATA\n",
4068 return WN_MORE_DATA;
4071 StringCbCopy( lpFormattedName,
4075 *lpnLength = dwCurrentLen * sizeof( WCHAR);
4077 #ifdef AFS_DEBUG_TRACE
4078 AFSDbgPrint( L"NPFormatNetworkName remote name %s as %s\n",
4086 /************************************************************
4087 / Unsupported entry points
4088 /************************************************************/
4091 // AuthGroup processing is implemented in src/WINNT/afsd/afslogon.c
4096 LPCWSTR lpAuthentInfoType,
4097 LPVOID lpAuthentInfo,
4098 LPCWSTR lpPreviousAuthentInfoType,
4099 LPVOID lpPreviousAuthentInfo,
4100 LPWSTR lpStationName,
4101 LPVOID StationHandle,
4102 LPWSTR *lpLogonScript)
4105 #ifdef AFS_DEBUG_TRACE
4106 AFSDbgPrint( L"NPLogonNotify, returning WN_NOT_SUPPORTED\n");
4109 return WN_NOT_SUPPORTED;
4113 NPPasswordChangeNotify (
4114 LPCWSTR lpAuthentInfoType,
4115 LPVOID lpAuthentInfo,
4116 LPCWSTR lpPreviousAuthentInfoType,
4117 LPVOID lpPreviousAuthentInfo,
4118 LPWSTR lpStationName,
4119 LPVOID StationHandle,
4120 DWORD dwChangeInfo )
4123 #ifdef AFS_DEBUG_TRACE
4124 AFSDbgPrint( L"NPPasswordChangeNotify, returning WN_NOT_SUPPORTED\n");
4127 SetLastError( WN_NOT_SUPPORTED );
4129 return WN_NOT_SUPPORTED;
4133 NPGetUser( LPTSTR lpName,
4135 LPDWORD lpBufferSize)
4138 DWORD rc = WN_NOT_SUPPORTED;
4140 AFSDbgPrint( L"NPGetUser Entry Name %s\n", lpName);
4148 NPGetReconnectFlags( LPWSTR lpRemoteName,
4149 unsigned char *Parameter2)
4152 DWORD dwStatus = WN_NOT_SUPPORTED;
4154 AFSDbgPrint( L"NPGetReconnectFlags RemoteName %s\n",
4163 I_SystemFocusDialog( VOID)
4166 DWORD dwStatus = WN_NOT_SUPPORTED;
4168 AFSDbgPrint( L"I_SystemFocusDialog\n");
4173 /************************************************************
4174 / END Unsupported entry points
4175 /************************************************************/
4182 HANDLE hControlDevice = NULL;
4184 hControlDevice = CreateFile( AFS_SYMLINK_W,
4185 GENERIC_READ | GENERIC_WRITE,
4186 FILE_SHARE_READ | FILE_SHARE_WRITE,
4192 if( hControlDevice == INVALID_HANDLE_VALUE)
4195 hControlDevice = NULL;
4196 #ifdef AFS_DEBUG_TRACE
4197 AFSDbgPrint( L"Failed to open control device error: %d\n",
4203 // only do this if you want network shares to fail to mount
4204 // when the file system is not yet ready
4208 AFSDriverStatusRespCB respCB;
4211 memset( &respCB, '\0', sizeof( AFSDriverStatusRespCB));
4213 if ( !DeviceIoControl( hControlDevice,
4214 IOCTL_AFS_STATUS_REQUEST,
4218 sizeof( AFSDriverStatusRespCB),
4221 dwBytes != sizeof(AFSDriverStatusRespCB) ||
4222 respCB.Status != AFS_DRIVER_STATUS_READY )
4225 CloseHandle( hControlDevice);
4227 hControlDevice = NULL;
4232 return hControlDevice;
4239 LARGE_INTEGER liAuthId = {0,0};
4240 HANDLE hToken = NULL;
4241 TOKEN_STATISTICS stTokenInfo;
4242 DWORD dwCopyBytes = 0;
4244 if ( !OpenThreadToken( GetCurrentThread(),
4246 FALSE, // Impersonation
4249 if( !OpenProcessToken( GetCurrentProcess(),
4254 #ifdef AFS_DEBUG_TRACE
4255 AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve Thread and Process tokens 0x%X\n",
4262 #ifdef AFS_DEBUG_TRACE
4263 AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Process Token\n");
4270 #ifdef AFS_DEBUG_TRACE
4271 AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Thread Token\n");
4275 if ( hToken != NULL)
4278 if( !GetTokenInformation( hToken,
4281 sizeof( TOKEN_STATISTICS),
4285 #ifdef AFS_DEBUG_TRACE
4286 AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve token information 0x%X\n",
4293 liAuthId.HighPart = stTokenInfo.AuthenticationId.HighPart;
4294 liAuthId.LowPart = stTokenInfo.AuthenticationId.LowPart;
4297 CloseHandle( hToken);
4306 static int init = 0;
4307 static DWORD debug = 0;
4312 if (RegOpenKey (HKEY_LOCAL_MACHINE,
4313 TEXT("SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider"), &hk) == 0)
4315 DWORD dwSize = sizeof(BOOL);
4316 DWORD dwType = REG_DWORD;
4317 RegQueryValueEx (hk, TEXT("Debug"), NULL, &dwType, (PBYTE)&debug, &dwSize);
4327 cm_Utf16ToUtf8Alloc(const WCHAR * s, int cch_src, int *pcch_dest)
4332 if (s == NULL || cch_src == 0 || *s == L'\0') {
4334 *pcch_dest = ((cch_src != 0)?1:0);
4338 cch_dest = WideCharToMultiByte(CP_UTF8, 0, s, cch_src, NULL, 0, NULL, FALSE);
4340 if (cch_dest == 0) {
4342 *pcch_dest = cch_dest;
4346 dest = HeapAlloc( GetProcessHeap(), 0, (cch_dest + 1) * sizeof(char));
4348 WideCharToMultiByte(CP_UTF8, 0, s, cch_src, dest, cch_dest, NULL, FALSE);
4352 *pcch_dest = cch_dest;
4358 AppendDebugStringToLogFile(WCHAR *wszbuffer)
4366 if ( !wszbuffer || !wszbuffer[0] )
4369 len = (int)wcslen(wszbuffer);
4371 buffer = cm_Utf16ToUtf8Alloc(wszbuffer, len, &len);
4376 hFile = CreateFileW( L"C:\\TEMP\\AFSRDFSProvider.log",
4381 FILE_ATTRIBUTE_NORMAL,
4384 if ( hFile == INVALID_HANDLE_VALUE ) {
4385 OutputDebugString(L"C:\\AFSRDFSProvider.log cannot be opened.\n");
4389 bRet = WriteFile( hFile, buffer, len, &dwWritten, NULL);
4391 bRet = CloseHandle(hFile);
4393 HeapFree(GetProcessHeap(), 0, buffer);
4404 WCHAR wszbuffer[512];
4406 DWORD debug = Debug();
4411 va_start( marker, Format );
4413 StringCbPrintf( wszbuffer, sizeof(wszbuffer), L"[%d-%08X] ",
4419 GetCurrentThreadId());
4421 rc = StringCbVPrintfW( &wszbuffer[ 14], sizeof(wszbuffer) - 14 * sizeof(WCHAR), Format, marker);
4423 if (SUCCEEDED(rc)) {
4425 OutputDebugString( wszbuffer );
4427 AppendDebugStringToLogFile(wszbuffer);
4429 OutputDebugString(L"AFSDbgPrint Failed to create string\n");
4432 return SUCCEEDED(rc) ? 1 : 0;