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:
528 // WNNC_CON_GETPERFORMANCE
532 rc = WNNC_CON_GETCONNECTIONS |
533 WNNC_CON_CANCELCONNECTION |
534 WNNC_CON_ADDCONNECTION |
535 WNNC_CON_ADDCONNECTION3;
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 );
615 NPAddConnection3( HWND hwndOwner,
616 LPNETRESOURCE lpNetResource,
622 DWORD dwStatus = WN_SUCCESS;
623 WCHAR wchRemoteName[MAX_PATH+1];
624 WCHAR wchLocalName[3];
625 DWORD dwCopyBytes = 0;
626 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
628 DWORD dwBufferSize = 0;
629 HANDLE hControlDevice = NULL;
630 HANDLE hToken = NULL;
631 LARGE_INTEGER liAuthId = {0,0};
636 if ( NPIsFSDisabled())
639 #ifdef AFS_DEBUG_TRACE
640 AFSDbgPrint( L"NPAddConnection3 AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
643 return WN_BAD_NETNAME;
646 if ((lpNetResource->lpRemoteName == NULL) ||
647 (lpNetResource->lpRemoteName[0] != L'\\') ||
648 (lpNetResource->lpRemoteName[1] != L'\\') ||
649 ((lpNetResource->dwType != RESOURCETYPE_DISK) &&
650 (lpNetResource->dwType != RESOURCETYPE_ANY)))
653 #ifdef AFS_DEBUG_TRACE
654 AFSDbgPrint( L"NPAddConnection3 invalid input, returning WN_BAD_NETNAME\n");
656 return WN_BAD_NETNAME;
659 #ifdef AFS_DEBUG_TRACE
660 AFSDbgPrint( L"NPAddConnection3 processing\n");
662 if( lpNetResource->lpLocalName != NULL)
665 wchLocalName[0] = towupper(lpNetResource->lpLocalName[0]);
666 wchLocalName[1] = L':';
667 wchLocalName[2] = L'\0';
670 hr = StringCbCopy(wchRemoteName, sizeof( wchRemoteName), lpNetResource->lpRemoteName);
674 #ifdef AFS_DEBUG_TRACE
675 AFSDbgPrint( L"NPAddConnection3 lpRemoteName longer than MAX_PATH, returning WN_BAD_NETNAME\n");
677 return WN_BAD_NETNAME;
681 // Allocate our buffer to pass to the redirector filter
684 dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + (wcslen( wchRemoteName) * sizeof( WCHAR));
686 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
688 if( pConnectCB == NULL)
691 try_return( dwStatus = WN_OUT_OF_MEMORY);
694 if( lpNetResource->lpLocalName != NULL)
697 pConnectCB->LocalName = towupper(wchLocalName[0]);
699 #ifdef AFS_DEBUG_TRACE
700 AFSDbgPrint( L"NPAddConnection3 Adding mapping for drive %s remote name %s\n",
708 pConnectCB->LocalName = L'\0';
710 #ifdef AFS_DEBUG_TRACE
711 AFSDbgPrint( L"NPAddConnection3 Adding mapping for NO drive remote name %s\n",
716 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
718 pConnectCB->RemoteNameLength = wcslen( wchRemoteName) * sizeof( WCHAR);
720 memcpy( pConnectCB->RemoteName,
722 pConnectCB->RemoteNameLength);
724 pConnectCB->Type = lpNetResource->dwType;
726 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
728 #ifdef AFS_DEBUG_TRACE
729 AFSDbgPrint( L"NPAddConnection3 Retrieved authentication id %08lX-%08lX\n",
730 pConnectCB->AuthenticationId.HighPart,
731 pConnectCB->AuthenticationId.LowPart);
734 hControlDevice = OpenRedirector();
736 if( hControlDevice == NULL)
739 #ifdef AFS_DEBUG_TRACE
740 AFSDbgPrint( L"NPAddConnection3 OpenRedirector failure, returning WN_NET_ERROR\n");
743 try_return( dwStatus = WN_NET_ERROR);
746 dwError = DeviceIoControl( hControlDevice,
747 IOCTL_AFS_ADD_CONNECTION,
757 #ifdef AFS_DEBUG_TRACE
758 AFSDbgPrint( L"NPAddConnection3 Failed to add connection to file system %d\n", GetLastError());
760 try_return( dwStatus = WN_OUT_OF_MEMORY);
764 // The status returned from the driver will indicate how it was handled
767 if( dwStatus == WN_SUCCESS &&
768 lpNetResource->lpLocalName != NULL)
771 WCHAR TempBuf[MAX_PATH+26];
773 if( !QueryDosDeviceW( wchLocalName,
778 if( GetLastError() != ERROR_FILE_NOT_FOUND)
781 #ifdef AFS_DEBUG_TRACE
782 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW failed with file not found\n");
784 NPCancelConnection( wchLocalName, TRUE);
786 dwStatus = ERROR_ALREADY_ASSIGNED;
791 UNICODE_STRING uniConnectionName;
794 // Create a symbolic link object to the device we are redirecting
797 uniConnectionName.MaximumLength = (USHORT)( wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR) +
798 pConnectCB->RemoteNameLength +
799 8 + // Local name and \;
800 sizeof(WCHAR)); // Space for NULL-termination.
803 // Don't include NULL-termination.
806 uniConnectionName.Length = uniConnectionName.MaximumLength - sizeof(WCHAR);
808 uniConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
809 uniConnectionName.MaximumLength);
811 if( uniConnectionName.Buffer == NULL)
814 try_return( dwStatus = GetLastError());
817 hr = StringCbCopyW( uniConnectionName.Buffer,
818 uniConnectionName.MaximumLength,
819 AFS_RDR_DEVICE_NAME);
822 #ifdef AFS_DEBUG_TRACE
823 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
825 try_return( dwStatus = WN_OUT_OF_MEMORY);
828 hr = StringCbCatW( uniConnectionName.Buffer,
829 uniConnectionName.MaximumLength,
833 #ifdef AFS_DEBUG_TRACE
834 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
836 try_return( dwStatus = WN_OUT_OF_MEMORY);
839 hr = StringCbCatW( uniConnectionName.Buffer,
840 uniConnectionName.MaximumLength,
844 #ifdef AFS_DEBUG_TRACE
845 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
847 try_return( dwStatus = WN_OUT_OF_MEMORY);
850 hr = StringCbCatW( uniConnectionName.Buffer,
851 uniConnectionName.MaximumLength,
855 #ifdef AFS_DEBUG_TRACE
856 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
858 try_return( dwStatus = WN_OUT_OF_MEMORY);
861 #ifdef AFS_DEBUG_TRACE
862 AFSDbgPrint( L"NPAddConnection3 DefineDosDevice Local %s connection name %s\n",
864 uniConnectionName.Buffer);
867 if( !DefineDosDeviceW( DDD_RAW_TARGET_PATH |
868 DDD_NO_BROADCAST_SYSTEM,
870 uniConnectionName.Buffer))
872 #ifdef AFS_DEBUG_TRACE
873 AFSDbgPrint( L"NPAddConnection3 Failed to assign drive\n");
875 dwStatus = GetLastError();
880 #ifdef AFS_DEBUG_TRACE
881 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW assigned drive %s\n", wchLocalName);
884 dwStatus = WN_SUCCESS;
887 LocalFree( uniConnectionName.Buffer);
893 #ifdef AFS_DEBUG_TRACE
894 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW %Z already existed\n", TempBuf);
896 NPCancelConnection( wchLocalName, TRUE);
898 dwStatus = ERROR_ALREADY_ASSIGNED;
904 if ( hControlDevice != NULL)
907 CloseHandle( hControlDevice);
910 if( pConnectCB != NULL)
913 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
922 NPCancelConnection( LPWSTR lpName,
926 WCHAR wchRemoteName[MAX_PATH+1];
927 DWORD dwRemoteNameLength = (MAX_PATH+1) * sizeof(WCHAR);
928 DWORD dwStatus = WN_NOT_CONNECTED;
929 DWORD dwCopyBytes = 0;
930 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
931 AFSCancelConnectionResultCB stCancelConn;
933 DWORD dwBufferSize = 0;
934 BOOL bLocalName = TRUE;
935 HANDLE hControlDevice = NULL;
936 WCHAR wchLocalName[ 3];
937 WCHAR *pwchLocalName = NULL;
943 if ( NPIsFSDisabled())
946 #ifdef AFS_DEBUG_TRACE
947 AFSDbgPrint( L"NPCancelConnection AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
950 try_return( dwStatus = WN_NOT_CONNECTED);
953 if( *lpName == L'\\' &&
954 *(lpName + 1) == L'\\')
959 wchLocalName[0] = L'\0';
961 hr = StringCbCopyW( wchRemoteName, sizeof( wchRemoteName), lpName);
965 #ifdef AFS_DEBUG_TRACE
966 AFSDbgPrint( L"NPCancelConnection lpName longer than MAX_PATH\n");
968 try_return( dwStatus = WN_OUT_OF_MEMORY);
971 dwRemoteNameLength = (wcslen( wchRemoteName) * sizeof( WCHAR));
976 wchLocalName[0] = towupper(lpName[0]);
977 wchLocalName[1] = L':';
978 wchLocalName[2] = L'\0';
981 // Get the remote name for the connection, if we are handling it
984 dwStatus = NPGetConnectionCommon( wchLocalName,
989 if( dwStatus != WN_SUCCESS ||
990 dwRemoteNameLength == 0)
993 #ifdef AFS_DEBUG_TRACE
994 AFSDbgPrint( L"NPCancelConnection Status 0x%x NameLength %u, returning WN_NOT_CONNECTED\n",
995 dwStatus, dwRemoteNameLength);
997 try_return( dwStatus = WN_NOT_CONNECTED);
1001 // NPGetConnection returns the buffer size not the length without NUL
1003 dwRemoteNameLength -= sizeof( WCHAR);
1006 wchRemoteName[ dwRemoteNameLength/sizeof( WCHAR)] = L'\0';
1008 #ifdef AFS_DEBUG_TRACE
1009 AFSDbgPrint( L"NPCancelConnection Attempting to cancel '%s' -> '%s'\n",
1010 wchLocalName, wchRemoteName);
1013 dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + dwRemoteNameLength;
1015 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1017 if( pConnectCB == NULL)
1020 try_return( dwStatus = WN_OUT_OF_MEMORY);
1026 pConnectCB->LocalName = wchLocalName[0];
1031 pConnectCB->LocalName = L'\0';
1034 pConnectCB->RemoteNameLength = (USHORT)dwRemoteNameLength;
1036 StringCbCopyW( pConnectCB->RemoteName,
1037 dwRemoteNameLength + sizeof( WCHAR),
1040 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1042 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1044 #ifdef AFS_DEBUG_TRACE
1045 AFSDbgPrint( L"NPCancelConnection Retrieved authentication id %08lX-%08lX\n",
1046 pConnectCB->AuthenticationId.HighPart,
1047 pConnectCB->AuthenticationId.LowPart);
1050 hControlDevice = OpenRedirector();
1052 if( hControlDevice == NULL)
1055 #ifdef AFS_DEBUG_TRACE
1056 AFSDbgPrint( L"NPCancelConnection OpenRedirector failure, returning WN_NET_ERROR\n");
1059 try_return( dwStatus = WN_NET_ERROR);
1062 memset( &stCancelConn,
1064 sizeof( AFSCancelConnectionResultCB));
1066 dwError = DeviceIoControl( hControlDevice,
1067 IOCTL_AFS_CANCEL_CONNECTION,
1071 sizeof( AFSCancelConnectionResultCB),
1077 #ifdef AFS_DEBUG_TRACE
1078 DWORD gle = GetLastError();
1080 AFSDbgPrint( L"NPCancelConnection DeviceIoControl failed - gle 0x%x\n", gle);
1082 try_return( dwStatus = WN_NOT_CONNECTED);
1085 dwStatus = stCancelConn.Status;
1087 #ifdef AFS_DEBUG_TRACE
1088 if ( dwStatus == WN_NOT_CONNECTED )
1091 AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status WN_NOT_CONNECTED\n",
1097 AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status %08lX\n",
1103 if( dwStatus == WN_SUCCESS &&
1105 stCancelConn.LocalName != L'\0'))
1108 UNICODE_STRING uniConnectionName;
1111 // Create a symbolic link object to the device we are redirecting
1114 uniConnectionName.MaximumLength = (USHORT)( wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR) +
1115 dwRemoteNameLength +
1116 8 + // Local name and \;
1117 sizeof(WCHAR)); // Space for NULL-termination.
1120 // Don't include NULL-termination.
1123 uniConnectionName.Length = uniConnectionName.MaximumLength - sizeof(WCHAR);
1125 uniConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
1126 uniConnectionName.MaximumLength);
1128 if( uniConnectionName.Buffer == NULL)
1131 try_return( dwStatus = GetLastError());
1134 hr = StringCbCopyW( uniConnectionName.Buffer,
1135 uniConnectionName.MaximumLength,
1136 AFS_RDR_DEVICE_NAME);
1140 #ifdef AFS_DEBUG_TRACE
1141 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (1)\n");
1143 try_return( dwStatus = WN_OUT_OF_MEMORY);
1146 hr = StringCbCatW( uniConnectionName.Buffer,
1147 uniConnectionName.MaximumLength,
1152 #ifdef AFS_DEBUG_TRACE
1153 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (2)\n");
1155 try_return( dwStatus = WN_OUT_OF_MEMORY);
1161 wchLocalName[ 0] = stCancelConn.LocalName;
1163 wchLocalName[ 1] = L':';
1165 wchLocalName[ 2] = L'\0';
1167 hr = StringCbCatW( uniConnectionName.Buffer,
1168 uniConnectionName.MaximumLength,
1173 #ifdef AFS_DEBUG_TRACE
1174 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (3)\n");
1176 try_return( dwStatus = WN_OUT_OF_MEMORY);
1179 pwchLocalName = wchLocalName;
1184 hr = StringCbCatW( uniConnectionName.Buffer,
1185 uniConnectionName.MaximumLength,
1190 #ifdef AFS_DEBUG_TRACE
1191 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (4)\n");
1193 try_return( dwStatus = WN_OUT_OF_MEMORY);
1196 pwchLocalName = lpName;
1199 hr = StringCbCatW( uniConnectionName.Buffer,
1200 uniConnectionName.MaximumLength,
1205 #ifdef AFS_DEBUG_TRACE
1206 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (5)\n");
1208 try_return( dwStatus = WN_OUT_OF_MEMORY);
1211 if( !DefineDosDevice( DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE,
1213 uniConnectionName.Buffer))
1216 #ifdef AFS_DEBUG_TRACE
1217 DWORD gle = GetLastError();
1219 AFSDbgPrint( L"NPCancelConnection Failed to cancel connection to system - gle 0x%x Name %s connection %wZ\n",
1222 &uniConnectionName);
1227 #ifdef AFS_DEBUG_TRACE
1229 AFSDbgPrint( L"NPCancelConnection Canceled connection to system - Name %s connection %wZ\n",
1231 &uniConnectionName);
1238 if ( hControlDevice != NULL)
1241 CloseHandle( hControlDevice);
1245 if( pConnectCB != NULL)
1248 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1258 NPGetConnection( LPWSTR lpLocalName,
1259 LPWSTR lpRemoteName,
1260 LPDWORD lpBufferSize)
1263 DWORD dwBufferSize = *lpBufferSize;
1266 dwStatus = NPGetConnectionCommon( lpLocalName,
1271 if ( dwStatus == WN_NOT_CONNECTED)
1274 dwStatus = NPGetConnectionCommon( lpLocalName,
1282 *lpBufferSize = dwBufferSize;
1290 NPGetConnectionCommon( LPWSTR lpLocalName,
1291 LPWSTR lpRemoteName,
1292 LPDWORD lpBufferSize,
1296 DWORD dwStatus = WN_NOT_CONNECTED;
1297 WCHAR wchLocalName[3];
1298 WCHAR wchSubstName[1024 + 26];
1299 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1301 DWORD dwBufferSize = 0;
1302 HANDLE hControlDevice = NULL;
1308 if ( NPIsFSDisabled())
1311 #ifdef AFS_DEBUG_TRACE
1312 AFSDbgPrint( L"NPGetConnection AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1315 try_return( dwStatus = WN_NOT_CONNECTED);
1318 if( lstrlen( lpLocalName) == 0)
1320 #ifdef AFS_DEBUG_TRACE
1321 AFSDbgPrint( L"NPGetConnection No local name, returning WN_BAD_LOCALNAME\n");
1323 try_return( dwStatus = WN_BAD_LOCALNAME);
1326 if ( lpBufferSize == NULL)
1328 #ifdef AFS_DEBUG_TRACE
1329 AFSDbgPrint( L"NPGetConnection No output size, returning WN_BAD_LOCALNAME\n");
1331 try_return( dwStatus = WN_BAD_VALUE);
1334 dwPassedSize = *lpBufferSize;
1336 if ( !bDriveSubstOk ||
1337 !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName), &dwStatus))
1339 wchLocalName[0] = towupper(lpLocalName[0]);
1340 wchLocalName[1] = L':';
1341 wchLocalName[2] = L'\0';
1343 #ifdef AFS_DEBUG_TRACE
1344 AFSDbgPrint( L"NPGetConnection Requesting connection for %s\n",
1350 ReadServerNameString();
1352 if ( wchSubstName[0] != L'\\' &&
1353 wchSubstName[1] == L':')
1356 wchLocalName[0] = towupper(wchSubstName[0]);
1357 wchLocalName[1] = L':';
1358 wchLocalName[2] = L'\0';
1360 #ifdef AFS_DEBUG_TRACE
1361 AFSDbgPrint( L"NPGetConnection Requesting connection for drive substitution %s -> %s\n",
1366 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
1367 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
1368 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
1373 DWORD dwRequiredSize;
1375 #ifdef AFS_DEBUG_TRACE
1376 AFSDbgPrint( L"NPGetConnection drive substitution %s is AFS\n",
1380 dwRequiredSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
1382 if ( lpRemoteName == NULL ||
1383 dwPassedSize == 0 ||
1384 dwRequiredSize > *lpBufferSize)
1387 *lpBufferSize = dwRequiredSize;
1389 try_return( dwStatus = WN_MORE_DATA);
1393 hr = StringCbCopyN(lpRemoteName, *lpBufferSize, wchSubstName, sizeof( wchSubstName));
1398 for ( dwCount = 0, pwch = lpRemoteName; *pwch && pwch < lpRemoteName + (*lpBufferSize); pwch++ )
1400 if ( *pwch == L'\\' )
1414 *lpBufferSize = wcslen( lpRemoteName) * sizeof( WCHAR) + sizeof( WCHAR);
1416 try_return( dwStatus = WN_SUCCESS);
1418 else if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER)
1421 *lpBufferSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
1423 for ( dwCount = 0, pwch = lpRemoteName; *pwch; pwch++ )
1425 if ( *pwch == L'\\' )
1433 *lpBufferSize = wcslen( lpRemoteName) * sizeof( WCHAR) + sizeof( WCHAR);
1435 try_return( dwStatus = WN_SUCCESS);
1441 try_return( dwStatus = WN_MORE_DATA);
1446 #ifdef AFS_DEBUG_TRACE
1447 AFSDbgPrint( L"NPGetConnection StringCbCopyN failure 0x%X\n",
1450 try_return( dwStatus = WN_NET_ERROR);
1456 #ifdef AFS_DEBUG_TRACE
1457 AFSDbgPrint( L"NPGetConnection drive substitution %s is not AFS\n",
1460 try_return( dwStatus = WN_NOT_CONNECTED);
1464 #ifdef AFS_DEBUG_TRACE
1465 AFSDbgPrint( L"NPGetConnection Requesting connection for %s\n",
1469 dwBufferSize = 0x1000;
1471 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1473 if( pConnectCB == NULL)
1476 try_return( dwStatus = WN_OUT_OF_MEMORY);
1479 pConnectCB->LocalName = towupper(wchLocalName[0]);
1481 pConnectCB->RemoteNameLength = 0;
1483 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1485 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1487 #ifdef AFS_DEBUG_TRACE
1488 AFSDbgPrint( L"NPGetConnection Retrieved authentication id %08lX-%08lX\n",
1489 pConnectCB->AuthenticationId.HighPart,
1490 pConnectCB->AuthenticationId.LowPart);
1493 hControlDevice = OpenRedirector();
1495 if( hControlDevice == NULL)
1498 #ifdef AFS_DEBUG_TRACE
1499 AFSDbgPrint( L"NPGetConnection OpenRedirector failure, returning WN_NET_ERROR\n");
1502 try_return( dwStatus = WN_NET_ERROR);
1505 dwError = DeviceIoControl( hControlDevice,
1506 IOCTL_AFS_GET_CONNECTION,
1516 #ifdef AFS_DEBUG_TRACE
1517 DWORD gle = GetLastError();
1519 AFSDbgPrint( L"NPGetConnection Failed to get connection from file system for local %s gle 0x%x\n",
1522 try_return( dwStatus = WN_NOT_CONNECTED);
1526 // IOCTL_AFS_GET_CONNECTION returns a counted string
1529 if( lpRemoteName == NULL ||
1530 *lpBufferSize + sizeof( WCHAR) > dwPassedSize)
1533 *lpBufferSize += sizeof( WCHAR);
1535 try_return( dwStatus = WN_MORE_DATA);
1538 memcpy( lpRemoteName,
1542 lpRemoteName[ *lpBufferSize/sizeof( WCHAR)] = L'\0';
1544 *lpBufferSize += sizeof( WCHAR);
1546 #ifdef AFS_DEBUG_TRACE
1547 AFSDbgPrint( L"NPGetConnection local %s remote %s\n",
1551 dwStatus = WN_SUCCESS;
1555 if ( hControlDevice != NULL)
1558 CloseHandle( hControlDevice);
1561 if( pConnectCB != NULL)
1564 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1572 NPGetConnection3( IN LPCWSTR lpLocalName,
1574 OUT LPVOID lpBuffer,
1575 IN OUT LPDWORD lpBufferSize)
1578 DWORD dwBufferSize = *lpBufferSize;
1581 dwStatus = NPGetConnection3Common( lpLocalName,
1587 if ( dwStatus == WN_NOT_CONNECTED)
1590 dwStatus = NPGetConnection3Common( lpLocalName,
1599 *lpBufferSize = dwBufferSize;
1606 static DWORD APIENTRY
1607 NPGetConnection3Common( IN LPCWSTR lpLocalName,
1609 OUT LPVOID lpBuffer,
1610 IN OUT LPDWORD lpBufferSize,
1611 IN BOOL bDriveSubstOk)
1614 DWORD dwStatus = WN_NOT_CONNECTED;
1615 WCHAR wchLocalName[3];
1616 WCHAR wchSubstName[1024 + 26];
1617 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1619 DWORD dwBufferSize = 0;
1620 HANDLE hControlDevice = NULL;
1622 DWORD *pConnectState =(DWORD *)lpBuffer;
1627 if ( NPIsFSDisabled())
1630 #ifdef AFS_DEBUG_TRACE
1631 AFSDbgPrint( L"NPGetConnection3 AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1634 try_return( dwStatus = WN_NOT_CONNECTED);
1637 if( lstrlen( lpLocalName) == 0)
1639 #ifdef AFS_DEBUG_TRACE
1640 AFSDbgPrint( L"NPGetConnection3 No local name, returning WN_BAD_LOCALNAME\n");
1642 try_return( dwStatus = WN_BAD_LOCALNAME);
1646 // LanMan NPGetConnection3 only responds to level 1
1649 if ( dwLevel != 0x1)
1651 #ifdef AFS_DEBUG_TRACE
1652 AFSDbgPrint( L"NPGetConnection3 Level 0x%X returning WN_BAD_LEVEL\n", dwLevel);
1654 try_return( dwStatus = WN_BAD_LEVEL);
1657 if ( lpBufferSize == NULL)
1659 #ifdef AFS_DEBUG_TRACE
1660 AFSDbgPrint( L"NPGetConnection3 No output size, returning WN_BAD_VALUE\n");
1662 try_return( dwStatus = WN_BAD_VALUE);
1665 dwPassedSize = *lpBufferSize;
1667 if ( dwPassedSize == 0 ||
1671 *lpBufferSize = sizeof( DWORD);
1673 try_return( dwStatus = WN_MORE_DATA);
1676 if ( !bDriveSubstOk ||
1677 !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName), &dwStatus))
1679 wchLocalName[0] = towupper(lpLocalName[0]);
1680 wchLocalName[1] = L':';
1681 wchLocalName[2] = L'\0';
1683 #ifdef AFS_DEBUG_TRACE
1684 AFSDbgPrint( L"NPGetConnection3 Requesting connection for %s level 0x%X\n",
1692 ReadServerNameString();
1694 if ( wchSubstName[0] != L'\\' &&
1695 wchSubstName[1] == L':')
1698 wchLocalName[0] = towupper(wchSubstName[0]);
1699 wchLocalName[1] = L':';
1700 wchLocalName[2] = L'\0';
1702 #ifdef AFS_DEBUG_TRACE
1703 AFSDbgPrint( L"NPGetConnection3 Requesting connection for drive substitution %s -> %s level 0x%x\n",
1709 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
1710 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
1711 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
1714 #ifdef AFS_DEBUG_TRACE
1715 AFSDbgPrint( L"NPGetConnection3 drive substitution %s is AFS return connected\n",
1718 *pConnectState = WNGETCON_CONNECTED;
1720 *lpBufferSize = sizeof( DWORD);
1722 try_return( dwStatus = WN_SUCCESS);
1727 #ifdef AFS_DEBUG_TRACE
1728 AFSDbgPrint( L"NPGetConnection3 drive substitution %s is not AFS return not connected\n",
1731 try_return( dwStatus = WN_NOT_CONNECTED);
1735 dwBufferSize = 0x1000;
1737 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1739 if( pConnectCB == NULL)
1742 try_return( dwStatus = WN_OUT_OF_MEMORY);
1745 pConnectCB->LocalName = towupper(wchLocalName[0]);
1747 pConnectCB->RemoteNameLength = 0;
1749 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1751 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1753 #ifdef AFS_DEBUG_TRACE
1754 AFSDbgPrint( L"NPGetConnection3 Retrieved authentication id %08lX-%08lX\n",
1755 pConnectCB->AuthenticationId.HighPart,
1756 pConnectCB->AuthenticationId.LowPart);
1759 hControlDevice = OpenRedirector();
1761 if( hControlDevice == NULL)
1764 #ifdef AFS_DEBUG_TRACE
1765 AFSDbgPrint( L"NPGetConnection3 OpenRedirector failure, returning WN_NET_ERROR\n");
1768 try_return( dwStatus = WN_NET_ERROR);
1771 dwError = DeviceIoControl( hControlDevice,
1772 IOCTL_AFS_GET_CONNECTION,
1782 #ifdef AFS_DEBUG_TRACE
1783 DWORD gle = GetLastError();
1785 AFSDbgPrint( L"NPGetConnection3 Failed to get connection from file system for local %s gle 0x%x\n",
1788 try_return( dwStatus = WN_NOT_CONNECTED);
1791 *lpBufferSize = sizeof( DWORD);
1793 if( sizeof( DWORD) > dwPassedSize)
1796 try_return( dwStatus = WN_MORE_DATA);
1799 *pConnectState = WNGETCON_CONNECTED;
1801 #ifdef AFS_DEBUG_TRACE
1802 AFSDbgPrint( L"NPGetConnection3 local %s connect-state 0x%x\n",
1806 dwStatus = WN_SUCCESS;
1810 if ( hControlDevice != NULL)
1813 CloseHandle( hControlDevice);
1816 if( pConnectCB != NULL)
1819 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1828 NPGetConnectionPerformance( LPCWSTR lpRemoteName,
1829 LPNETCONNECTINFOSTRUCT lpNetConnectInfo)
1832 DWORD dwReturn = WN_SUCCESS;
1833 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1834 DWORD dwBufferSize = 0;
1835 HANDLE hControlDevice = NULL;
1841 if ( NPIsFSDisabled())
1844 #ifdef AFS_DEBUG_TRACE
1845 AFSDbgPrint( L"NPGetConnectionPerformance AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
1848 return WN_NO_NETWORK;
1851 AFSDbgPrint( L"NPGetConnectionPerformance Entry for remote connection %S\n",
1854 dwBufferSize = 0x1000;
1856 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1858 if( pConnectCB == NULL)
1860 try_return( dwReturn = WN_OUT_OF_MEMORY);
1863 pConnectCB->RemoteNameLength = wcslen( lpRemoteName) * sizeof( WCHAR);
1865 StringCbCopy( pConnectCB->RemoteName,
1866 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
1869 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1871 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1873 hControlDevice = OpenRedirector();
1875 if( hControlDevice == NULL)
1877 AFSDbgPrint( L"NPGetConnectionPerformance OpenRedirector failure, returning WN_NET_ERROR\n");
1879 try_return( dwReturn = WN_NET_ERROR);
1882 dwError = DeviceIoControl( hControlDevice,
1883 IOCTL_AFS_GET_CONNECTION_INFORMATION,
1893 #ifdef AFS_DEBUG_TRACE
1894 DWORD gle = GetLastError();
1896 AFSDbgPrint( L"NPGetConnectionPerformance Failed to get connection info from file system for remote %S gle 0x%x\n",
1900 try_return( dwReturn = WN_NOT_CONNECTED);
1903 lpNetConnectInfo->dwFlags = WNCON_DYNAMIC;
1905 lpNetConnectInfo->dwSpeed = 500;
1907 lpNetConnectInfo->dwDelay = 0;
1909 lpNetConnectInfo->dwOptDataSize = 0x1000;
1911 AFSDbgPrint( L"NPGetConnectionPerformance Successfully returned information for remote connection %S\n",
1916 if ( hControlDevice != NULL)
1918 CloseHandle( hControlDevice);
1921 if( pConnectCB != NULL)
1923 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1931 GetUsageString( DWORD dwUsage)
1933 static WCHAR Buffer[128] = L"";
1935 // RESOURCEUSAGE_CONNECTABLE 0x00000001
1936 // RESOURCEUSAGE_CONTAINER 0x00000002
1937 // RESOURCEUSAGE_NOLOCALDEVICE 0x00000004
1938 // RESOURCEUSAGE_SIBLING 0x00000008
1939 // RESOURCEUSAGE_ATTACHED 0x00000010
1940 // RESOURCEUSAGE_ALL (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED)
1941 // RESOURCEUSAGE_RESERVED 0x80000000
1946 if ( dwUsage == RESOURCEUSAGE_ALL )
1956 if ( dwUsage & RESOURCEUSAGE_CONNECTABLE )
1958 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTABLE|");
1961 if ( dwUsage & RESOURCEUSAGE_CONTAINER )
1963 StringCbCat( Buffer, sizeof(Buffer), L"CONTAINER|");
1966 if ( dwUsage & RESOURCEUSAGE_NOLOCALDEVICE )
1968 StringCbCat( Buffer, sizeof(Buffer), L"NOLOCALDEVICE|");
1971 if ( dwUsage & RESOURCEUSAGE_SIBLING )
1973 StringCbCat( Buffer, sizeof(Buffer), L"SIBLING|");
1976 if ( dwUsage & RESOURCEUSAGE_ATTACHED )
1978 StringCbCat( Buffer, sizeof(Buffer), L"ATTACHED|");
1981 if ( dwUsage & RESOURCEUSAGE_RESERVED )
1983 StringCbCat( Buffer, sizeof(Buffer), L"RESERVED|");
1986 if ( dwUsage & ~(RESOURCEUSAGE_ALL|RESOURCEUSAGE_NOLOCALDEVICE|RESOURCEUSAGE_SIBLING|RESOURCEUSAGE_RESERVED) )
1988 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
1991 Buffer[lstrlen(Buffer)-1] = L'\0';
1997 GetTypeString( DWORD dwType)
1999 static WCHAR Buffer[128] = L"";
2002 // RESOURCETYPE_ANY 0x00000000
2003 // RESOURCETYPE_DISK 0x00000001
2004 // RESOURCETYPE_PRINT 0x00000002
2005 // RESOURCETYPE_RESERVED 0x00000008
2006 // RESOURCETYPE_UNKNOWN 0xFFFFFFFF
2011 if ( dwType == RESOURCETYPE_ANY )
2016 if ( dwType == RESOURCETYPE_UNKNOWN )
2021 if ( dwType & RESOURCETYPE_DISK )
2023 StringCbCat( Buffer, sizeof(Buffer), L"DISK|");
2026 if ( dwType & RESOURCETYPE_PRINT )
2028 StringCbCat( Buffer, sizeof(Buffer), L"PRINT|");
2031 if ( dwType & RESOURCETYPE_RESERVED )
2033 StringCbCat( Buffer, sizeof(Buffer), L"RESERVED|");
2036 if ( dwType & ~(RESOURCETYPE_DISK|RESOURCETYPE_PRINT|RESOURCETYPE_RESERVED) )
2038 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
2041 Buffer[lstrlen(Buffer)-1] = L'\0';
2047 GetScopeString( DWORD dwScope)
2049 static WCHAR Buffer[128] = L"";
2052 // RESOURCE_CONNECTED 0x00000001
2053 // RESOURCE_GLOBALNET 0x00000002
2054 // RESOURCE_REMEMBERED 0x00000003
2055 // RESOURCE_RECENT 0x00000004
2056 // RESOURCE_CONTEXT 0x00000005
2061 if ( dwScope == RESOURCE_CONNECTED )
2063 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTED|");
2066 if ( dwScope == RESOURCE_GLOBALNET )
2068 StringCbCat( Buffer, sizeof(Buffer), L"GLOBALNET|");
2071 if ( dwScope == RESOURCE_REMEMBERED )
2073 StringCbCat( Buffer, sizeof(Buffer), L"REMEMBERED|");
2076 if ( dwScope == RESOURCE_RECENT )
2078 StringCbCat( Buffer, sizeof(Buffer), L"RECENT|");
2081 if ( dwScope == RESOURCE_CONTEXT )
2083 StringCbCat( Buffer, sizeof(Buffer), L"CONTEXT|");
2086 if ( dwScope & ~(RESOURCE_CONNECTED|RESOURCE_GLOBALNET|RESOURCE_REMEMBERED|RESOURCE_RECENT|RESOURCE_CONTEXT) )
2088 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
2091 Buffer[lstrlen(Buffer)-1] = L'\0';
2097 GetDisplayString( DWORD dwDisplay)
2100 // RESOURCEDISPLAYTYPE_GENERIC 0x00000000
2101 // RESOURCEDISPLAYTYPE_DOMAIN 0x00000001
2102 // RESOURCEDISPLAYTYPE_SERVER 0x00000002
2103 // RESOURCEDISPLAYTYPE_SHARE 0x00000003
2104 // RESOURCEDISPLAYTYPE_FILE 0x00000004
2105 // RESOURCEDISPLAYTYPE_GROUP 0x00000005
2106 // RESOURCEDISPLAYTYPE_NETWORK 0x00000006
2107 // RESOURCEDISPLAYTYPE_ROOT 0x00000007
2108 // RESOURCEDISPLAYTYPE_SHAREADMIN 0x00000008
2109 // RESOURCEDISPLAYTYPE_DIRECTORY 0x00000009
2110 // RESOURCEDISPLAYTYPE_TREE 0x0000000A
2111 // RESOURCEDISPLAYTYPE_NDSCONTAINER 0x0000000B
2114 switch ( dwDisplay ) {
2115 case RESOURCEDISPLAYTYPE_GENERIC:
2117 case RESOURCEDISPLAYTYPE_DOMAIN:
2119 case RESOURCEDISPLAYTYPE_SERVER:
2121 case RESOURCEDISPLAYTYPE_SHARE:
2123 case RESOURCEDISPLAYTYPE_FILE:
2125 case RESOURCEDISPLAYTYPE_GROUP:
2127 case RESOURCEDISPLAYTYPE_NETWORK:
2129 case RESOURCEDISPLAYTYPE_ROOT:
2131 case RESOURCEDISPLAYTYPE_SHAREADMIN:
2132 return L"SHAREADMIN";
2133 case RESOURCEDISPLAYTYPE_DIRECTORY:
2134 return L"DIRECTORY";
2135 case RESOURCEDISPLAYTYPE_TREE:
2137 case RESOURCEDISPLAYTYPE_NDSCONTAINER:
2138 return L"NDSCONTAINER";
2146 NPOpenEnum( DWORD dwScope,
2149 LPNETRESOURCE lpNetResource,
2153 DWORD dwStatus = WN_SUCCESS;
2154 AFSEnumerationCB *pEnumCB = NULL;
2156 #ifdef AFS_DEBUG_TRACE
2157 if ( lpNetResource == NULL)
2159 AFSDbgPrint( L"NPOpenEnum Scope %s Type %s Usage %s NetResource: (Null)\n",
2160 GetScopeString(dwScope), GetTypeString(dwType), GetUsageString(dwUsage));
2164 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",
2165 GetScopeString(dwScope),
2166 GetTypeString(dwType),
2167 GetUsageString(dwUsage),
2169 GetScopeString(lpNetResource->dwScope),
2170 GetTypeString(lpNetResource->dwType),
2171 GetDisplayString(lpNetResource->dwDisplayType),
2172 GetUsageString(lpNetResource->dwUsage),
2173 lpNetResource->lpLocalName,
2174 lpNetResource->lpRemoteName,
2175 lpNetResource->lpComment);
2181 dwUsage = RESOURCEUSAGE_ALL;
2185 if ( dwType == 0 || dwType == RESOURCEUSAGE_ATTACHED)
2187 dwType |= RESOURCETYPE_DISK | RESOURCETYPE_PRINT;
2191 *lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( AFSEnumerationCB));
2193 if( *lphEnum == NULL)
2196 return WN_OUT_OF_MEMORY;
2199 pEnumCB = (AFSEnumerationCB *)*lphEnum;
2201 pEnumCB->CurrentIndex = 0;
2203 pEnumCB->Type = dwType;
2207 case RESOURCE_CONNECTED:
2210 pEnumCB->Scope = RESOURCE_CONNECTED;
2215 case RESOURCE_CONTEXT:
2218 pEnumCB->Scope = RESOURCE_CONTEXT;
2223 case RESOURCE_GLOBALNET:
2226 if( lpNetResource != NULL &&
2227 lpNetResource->lpRemoteName != NULL)
2230 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2232 if( pEnumCB->RemoteName == NULL)
2235 dwStatus = WN_OUT_OF_MEMORY;
2236 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2242 StringCbCopy( pEnumCB->RemoteName,
2244 lpNetResource->lpRemoteName);
2249 pEnumCB->Scope = RESOURCE_GLOBALNET;
2256 #ifdef AFS_DEBUG_TRACE
2257 AFSDbgPrint( L"NPOpenEnum Processing (Scope %s 0x%x) Type %s Usage %s, returning WN_NOT_SUPPORTED\n",
2258 GetScopeString(dwScope), dwScope, GetTypeString(dwType), GetUsageString(dwUsage));
2261 dwStatus = WN_NOT_SUPPORTED;
2262 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2274 NPEnumResource( HANDLE hEnum,
2277 LPDWORD lpBufferSize)
2280 DWORD dwStatus = WN_NO_MORE_ENTRIES; //WN_SUCCESS;
2282 ULONG EntriesCopied;
2283 ULONG EntriesRequested;
2285 LPNETRESOURCE pNetResource;
2287 ULONG SpaceAvailable;
2289 AFSNetworkProviderConnectionCB *pConnectionCB = NULL;
2290 void *pConnectionCBBase = NULL;
2292 UNICODE_STRING uniRemoteName;
2293 HANDLE hControlDevice = NULL;
2294 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2299 if ( lpBufferSize == NULL)
2301 #ifdef AFS_DEBUG_TRACE
2302 AFSDbgPrint( L"NPEnumResource No output size, returning WN_BAD_VALUE\n");
2304 try_return( dwStatus = WN_BAD_VALUE);
2307 ReadProviderNameString();
2309 pNetResource = (LPNETRESOURCE) lpBuffer;
2310 SpaceAvailable = *lpBufferSize;
2311 EntriesRequested = *lpcCount;
2312 *lpcCount = EntriesCopied = 0;
2313 StringZone = (PWCHAR) ((char *)lpBuffer + *lpBufferSize);
2315 #ifdef AFS_DEBUG_TRACE
2316 AFSDbgPrint( L"NPEnumResource Processing Remote name %s Scope %s Type %s Usage %s Index %d SpaceAvailable 0x%lX RequestedEntries %lu\n",
2317 pEnumCB->RemoteName ? pEnumCB->RemoteName : L"(Null)",
2318 GetScopeString(pEnumCB->Scope),
2319 GetTypeString(pEnumCB->Type),
2320 GetUsageString(pEnumCB->Type),
2321 pEnumCB->CurrentIndex,
2326 if ( NPIsFSDisabled())
2329 #ifdef AFS_DEBUG_TRACE
2330 AFSDbgPrint( L"NPEnumResource AFSRDFS is disabled, returning WN_NO_MORE_ENTRIES\n");
2333 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2336 pConnectionCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 0x1000);
2338 if( pConnectionCB == NULL)
2341 #ifdef AFS_DEBUG_TRACE
2342 AFSDbgPrint( L"NPEnumResource Out of Memory\n");
2345 try_return( dwStatus = WN_OUT_OF_MEMORY);
2348 pConnectionCBBase = (void *)pConnectionCB;
2350 hControlDevice = OpenRedirector();
2352 if( hControlDevice == NULL)
2355 #ifdef AFS_DEBUG_TRACE
2356 AFSDbgPrint( L"NPEnumResource OpenRedirector failure, returning WN_NET_ERROR\n");
2359 try_return( dwStatus = WN_NET_ERROR);
2362 if( pEnumCB->Type != RESOURCETYPE_ANY && pEnumCB->Type != RESOURCETYPE_DISK)
2365 #ifdef AFS_DEBUG_TRACE
2366 AFSDbgPrint( L"NPEnumResource Non-DISK queries are not supported, returning WN_NO_MORE_ENTRIES\n");
2368 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2372 // Handle the special cases here
2373 // 0. Provider Network Root
2378 if ( pEnumCB->Scope == RESOURCE_GLOBALNET)
2381 ReadServerNameString();
2383 if ( pEnumCB->CurrentIndex == 0 &&
2384 pEnumCB->RemoteName == NULL)
2387 // Determine the space needed for this entry...
2389 SpaceNeeded = 2 * ( cbProviderNameLength + sizeof( WCHAR));
2391 uniRemoteName.Length = (USHORT)cbProviderNameLength;
2392 uniRemoteName.MaximumLength = uniRemoteName.Length;
2393 uniRemoteName.Buffer = wszProviderName;
2395 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2398 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2400 #ifdef AFS_DEBUG_TRACE
2401 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2405 try_return( dwStatus = WN_MORE_DATA);
2408 #ifdef AFS_DEBUG_TRACE
2409 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2413 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2415 pNetResource->dwScope = RESOURCE_GLOBALNET;
2416 pNetResource->dwType = RESOURCETYPE_ANY;
2417 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_NETWORK;
2418 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_RESERVED;
2420 // setup string area at opposite end of buffer
2421 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2423 pNetResource->lpLocalName = NULL;
2426 pNetResource->lpRemoteName = StringZone;
2428 StringCbCopy( StringZone,
2429 cbProviderNameLength + sizeof( WCHAR),
2432 StringZone += cbProviderNameLength / sizeof(WCHAR) + 1;
2434 pNetResource->lpComment = NULL;
2436 // copy provider name
2437 pNetResource->lpProvider = StringZone;
2438 StringCbCopy( StringZone,
2439 cbProviderNameLength + sizeof( WCHAR),
2442 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2444 #ifdef AFS_DEBUG_TRACE
2445 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2447 GetScopeString(pNetResource->dwScope),
2448 GetTypeString(pNetResource->dwType),
2449 GetDisplayString(pNetResource->dwDisplayType),
2450 GetUsageString(pNetResource->dwUsage),
2451 pNetResource->lpLocalName,
2452 pNetResource->lpRemoteName,
2453 pNetResource->lpComment);
2456 // setup the new end of buffer
2457 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2463 // do not change the index since we did not query the redirector
2464 pEnumCB->CurrentIndex = 0;
2466 // remember that we returned the provider name
2467 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2469 if( pEnumCB->RemoteName == NULL)
2472 try_return( dwStatus = WN_OUT_OF_MEMORY);
2477 StringCbCopy( pEnumCB->RemoteName,
2483 if ( pEnumCB->CurrentIndex == 0 &&
2484 lstrlen( pEnumCB->RemoteName) == cbProviderNameLength / sizeof( WCHAR) &&
2485 _wcsnicmp( pEnumCB->RemoteName, wszProviderName, cbProviderNameLength / sizeof( WCHAR)) == 0 &&
2486 EntriesCopied < EntriesRequested)
2490 // After the network provider entry comes the server entry
2493 // Determine the space needed for this entry...
2495 SpaceNeeded = cbProviderNameLength + cbServerNameUNCLength + cbServerCommentLength + 3 * sizeof( WCHAR);
2497 uniRemoteName.Length = (USHORT)cbServerNameUNCLength;
2498 uniRemoteName.MaximumLength = uniRemoteName.Length;
2499 uniRemoteName.Buffer = wszServerNameUNC;
2501 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2504 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2506 #ifdef AFS_DEBUG_TRACE
2507 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2511 try_return( dwStatus = WN_MORE_DATA);
2514 #ifdef AFS_DEBUG_TRACE
2515 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2519 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2521 pNetResource->dwScope = 0;
2522 pNetResource->dwType = RESOURCETYPE_ANY;
2523 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
2524 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
2526 // setup string area at opposite end of buffer
2527 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2529 pNetResource->lpLocalName = NULL;
2532 pNetResource->lpRemoteName = StringZone;
2534 StringCbCopy( StringZone,
2535 cbServerNameUNCLength + sizeof( WCHAR),
2538 StringZone += cbServerNameUNCLength / sizeof(WCHAR) + 1;
2541 pNetResource->lpComment = StringZone;
2543 StringCbCopy( StringZone,
2544 cbServerCommentLength + sizeof( WCHAR),
2547 StringZone += cbServerCommentLength / sizeof( WCHAR) + 1;
2549 // copy provider name
2550 pNetResource->lpProvider = StringZone;
2551 StringCbCopy( StringZone,
2552 cbProviderNameLength + sizeof( WCHAR),
2555 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2557 #ifdef AFS_DEBUG_TRACE
2558 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2560 GetScopeString(pNetResource->dwScope),
2561 GetTypeString(pNetResource->dwType),
2562 GetDisplayString(pNetResource->dwDisplayType),
2563 GetUsageString(pNetResource->dwUsage),
2564 pNetResource->lpLocalName,
2565 pNetResource->lpRemoteName,
2566 pNetResource->lpComment);
2569 // setup the new end of buffer
2570 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2576 // do not update the index because we did not query the redirector
2577 pEnumCB->CurrentIndex = 0;
2579 // remember that we returned the server
2580 StringCbCopy( pEnumCB->RemoteName,
2588 // Setup what we are going to ask for
2591 pConnectionCB->Scope = pEnumCB->Scope;
2593 pConnectionCB->Type = pEnumCB->Type;
2595 pConnectionCB->CurrentIndex = pEnumCB->CurrentIndex;
2597 pConnectionCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
2600 // If this is a RESOURCE_GLOBALNET enumeration then pass down the remote name if
2604 pConnectionCB->RemoteNameLength = 0;
2606 if( pEnumCB->Scope == RESOURCE_GLOBALNET &&
2607 pEnumCB->RemoteName != NULL)
2610 pConnectionCB->RemoteNameLength = wcslen( pEnumCB->RemoteName) * sizeof( WCHAR);
2612 StringCbCopy( pConnectionCB->RemoteName,
2613 (0x1000 - sizeof(AFSNetworkProviderConnectionCB)) + sizeof(WCHAR),
2614 pEnumCB->RemoteName);
2617 pConnectionCB->AuthenticationId = AFSRetrieveAuthId();
2619 #ifdef AFS_DEBUG_TRACE
2620 AFSDbgPrint( L"NPEnumResource Retrieved authentication id %08lX-%08lX\n",
2621 pConnectionCB->AuthenticationId.HighPart,
2622 pConnectionCB->AuthenticationId.LowPart);
2625 dwError = DeviceIoControl( hControlDevice,
2626 IOCTL_AFS_LIST_CONNECTIONS,
2636 #ifdef AFS_DEBUG_TRACE
2637 DWORD gle = GetLastError();
2639 AFSDbgPrint( L"NPEnumResource Failed to list connections from file system - gle 0x%x\n",
2642 try_return( dwStatus = WN_NOT_CONNECTED);
2645 if( dwCopyBytes == 0)
2648 #ifdef AFS_DEBUG_TRACE
2649 AFSDbgPrint( L"NPEnumResource No More Entries\n");
2651 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2654 dwIndex = pEnumCB->CurrentIndex;
2656 while( EntriesCopied < EntriesRequested)
2659 uniRemoteName.Length = (USHORT)pConnectionCB->RemoteNameLength;
2660 uniRemoteName.MaximumLength = uniRemoteName.Length;
2661 uniRemoteName.Buffer = pConnectionCB->RemoteName;
2663 // Determine the space needed for this entry...
2667 if( pConnectionCB->LocalName != 0)
2670 SpaceNeeded += 3 * sizeof(WCHAR); // local name
2673 SpaceNeeded += pConnectionCB->RemoteNameLength + sizeof( WCHAR); // remote name
2675 if( pConnectionCB->CommentLength > 0)
2678 SpaceNeeded += pConnectionCB->CommentLength + sizeof( WCHAR); // comment
2681 SpaceNeeded += cbProviderNameLength + sizeof( WCHAR); // provider name
2683 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2686 if (EntriesCopied == 0) {
2688 dwStatus = WN_MORE_DATA;
2690 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2692 #ifdef AFS_DEBUG_TRACE
2693 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2700 #ifdef AFS_DEBUG_TRACE
2701 AFSDbgPrint( L"NPEnumResource Return SUCCESS but more entries Index %d\n",
2705 dwStatus = WN_SUCCESS;
2711 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2713 pNetResource->dwScope = pConnectionCB->Scope;
2714 pNetResource->dwType = pConnectionCB->Type;
2716 pNetResource->dwDisplayType = pConnectionCB->DisplayType;
2718 if ( pNetResource->dwType == RESOURCETYPE_ANY &&
2719 pNetResource->dwDisplayType == RESOURCEDISPLAYTYPE_SHARE)
2722 pNetResource->dwType = RESOURCETYPE_DISK;
2725 if ( pEnumCB->Scope == RESOURCE_CONNECTED)
2728 pNetResource->dwUsage = 0;
2733 pNetResource->dwUsage = pConnectionCB->Usage;
2736 // setup string area at opposite end of buffer
2737 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2740 if( pConnectionCB->LocalName != 0)
2743 pNetResource->lpLocalName = StringZone;
2744 *StringZone++ = towupper(pConnectionCB->LocalName);
2745 *StringZone++ = L':';
2746 *StringZone++ = L'\0';
2751 pNetResource->lpLocalName = NULL;
2754 #ifdef AFS_DEBUG_TRACE
2755 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2760 pNetResource->lpRemoteName = StringZone;
2762 CopyMemory( StringZone,
2763 pConnectionCB->RemoteName,
2764 pConnectionCB->RemoteNameLength);
2766 StringZone += (pConnectionCB->RemoteNameLength / sizeof(WCHAR));
2768 *StringZone++ = L'\0';
2771 if( pConnectionCB->CommentLength > 0)
2774 pNetResource->lpComment = StringZone;
2776 CopyMemory( StringZone,
2777 (void *)((char *)pConnectionCB + pConnectionCB->CommentOffset),
2778 pConnectionCB->CommentLength);
2780 StringZone += (pConnectionCB->CommentLength / sizeof(WCHAR));
2782 *StringZone++ = L'\0';
2787 pNetResource->lpComment = NULL;
2790 // copy provider name
2791 pNetResource->lpProvider = StringZone;
2792 StringCbCopy( StringZone,
2793 cbProviderNameLength + sizeof( WCHAR),
2796 StringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
2798 #ifdef AFS_DEBUG_TRACE
2799 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2801 GetScopeString(pNetResource->dwScope),
2802 GetTypeString(pNetResource->dwType),
2803 GetDisplayString(pNetResource->dwDisplayType),
2804 GetUsageString(pNetResource->dwUsage),
2805 pNetResource->lpLocalName,
2806 pNetResource->lpRemoteName,
2807 pNetResource->lpComment);
2810 // setup the new end of buffer
2811 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2819 dwCopyBytes -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2820 pConnectionCB->RemoteNameLength +
2821 pConnectionCB->CommentLength;
2823 if( dwCopyBytes == 0)
2826 dwStatus = WN_SUCCESS;
2831 pConnectionCB = (AFSNetworkProviderConnectionCB *)((char *)pConnectionCB +
2832 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2833 pConnectionCB->RemoteNameLength +
2834 pConnectionCB->CommentLength);
2837 *lpcCount = EntriesCopied;
2839 // update entry index
2840 pEnumCB->CurrentIndex = dwIndex;
2842 #ifdef AFS_DEBUG_TRACE
2843 AFSDbgPrint( L"NPEnumResource Completed Count %d Index %d\n",
2850 if ( hControlDevice != NULL)
2853 CloseHandle( hControlDevice);
2856 if( pConnectionCBBase != NULL)
2859 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectionCBBase);
2868 Routine Description:
2870 This routine closes the handle for enumeration of resources.
2874 hEnum - the enumeration handle
2878 WN_SUCCESS if successful, otherwise the appropriate error
2882 The sample only supports the notion of enumerating connected shares
2887 NPCloseEnum( HANDLE hEnum )
2890 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2892 #ifdef AFS_DEBUG_TRACE
2893 AFSDbgPrint( L"NPCloseEnum\n");
2896 if( pEnumCB->RemoteName != NULL)
2899 HeapFree( GetProcessHeap( ), 0, (PVOID) pEnumCB->RemoteName);
2902 HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum );
2908 NPGetResourceParent( LPNETRESOURCE lpNetResource,
2910 LPDWORD lpBufferSize )
2913 DWORD dwStatus = WN_ACCESS_DENIED;
2914 WCHAR *pwchRemoteName = NULL, *pwchSearch = NULL, *pwchSystem = NULL;
2915 LPNETRESOURCE lpOutResource = (LPNETRESOURCE) lpBuffer;
2917 if ( lpNetResource == NULL)
2919 #ifdef AFS_DEBUG_TRACE
2920 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2922 return WN_MORE_DATA;
2925 if( lpNetResource->lpRemoteName == NULL)
2927 #ifdef AFS_DEBUG_TRACE
2928 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2930 return WN_BAD_NETNAME;
2933 if ( lpNetResource->dwType != 0 &&
2934 lpNetResource->dwType != RESOURCETYPE_DISK)
2936 #ifdef AFS_DEBUG_TRACE
2937 AFSDbgPrint( L"NPGetResourceParent Bad dwType\n");
2939 return WN_BAD_VALUE;
2942 if ( lpBufferSize == NULL )
2945 #ifdef AFS_DEBUG_TRACE
2946 AFSDbgPrint( L"NPGetResourceParent Null lpBufferSize\n");
2948 return WN_BAD_VALUE;
2951 #ifdef AFS_DEBUG_TRACE
2952 AFSDbgPrint( L"NPGetResourceParent For remote name %s\n",
2953 lpNetResource->lpRemoteName);
2956 pwchRemoteName = lpNetResource->lpRemoteName;
2958 pwchSearch = pwchRemoteName + (wcslen( pwchRemoteName) - 1);
2960 while( pwchSearch != pwchRemoteName)
2963 if( *pwchSearch == L'\\')
2966 *pwchSearch = L'\0';
2974 if( pwchSearch != pwchRemoteName)
2977 #ifdef AFS_DEBUG_TRACE
2978 AFSDbgPrint( L"NPGetResourceParent Processing parent %s\n",
2979 lpNetResource->lpRemoteName);
2982 dwStatus = NPGetResourceInformation( lpNetResource,
2989 if ( lpOutResource == NULL ||
2990 *lpBufferSize < sizeof( NETRESOURCE) )
2992 *lpBufferSize = sizeof( NETRESOURCE);
2994 return WN_MORE_DATA;
2997 memset( lpOutResource, 0, sizeof( NETRESOURCE));
3007 NPGetResourceInformation( LPNETRESOURCE lpNetResource,
3009 LPDWORD lpBufferSize,
3010 LPWSTR *lplpSystem )
3013 DWORD dwStatus = WN_NOT_CONNECTED;
3014 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3016 DWORD dwBufferSize = 0;
3017 HANDLE hControlDevice = NULL;
3018 NETRESOURCE *pNetResource = (NETRESOURCE *)lpBuffer;
3019 PWCHAR pStringZone = NULL;
3020 UNICODE_STRING uniRemoteName;
3021 DWORD ulRequiredLen = 0;
3032 ReadProviderNameString();
3034 if ( NPIsFSDisabled())
3037 #ifdef AFS_DEBUG_TRACE
3038 AFSDbgPrint( L"NPGetResourceInformation AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
3041 try_return( dwStatus = WN_BAD_NETNAME);
3044 if ( lpNetResource == NULL ||
3045 lpBufferSize == NULL )
3048 #ifdef AFS_DEBUG_TRACE
3049 AFSDbgPrint( L"NPGetResourceInformaton Null lpNetResource or lpBufferSize\n");
3051 return WN_BAD_VALUE;
3054 if( lpNetResource->lpRemoteName == NULL)
3056 #ifdef AFS_DEBUG_TRACE
3057 AFSDbgPrint( L"NPGetResourceInformation No resource name\n");
3060 try_return( dwStatus = WN_NOT_CONNECTED);
3063 dwPassedSize = *lpBufferSize;
3065 dwBufferSize = 0x1000;
3067 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
3069 if( pConnectCB == NULL)
3072 try_return( dwStatus = WN_OUT_OF_MEMORY);
3075 pConnectCB->RemoteNameLength = wcslen( lpNetResource->lpRemoteName) * sizeof( WCHAR);
3077 StringCbCopy( pConnectCB->RemoteName,
3078 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
3079 lpNetResource->lpRemoteName);
3081 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3083 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
3085 #ifdef AFS_DEBUG_TRACE
3086 AFSDbgPrint( L"NPGetResourceInformation Retrieved authentication id %08lX-%08lX\n",
3087 pConnectCB->AuthenticationId.HighPart,
3088 pConnectCB->AuthenticationId.LowPart);
3091 hControlDevice = OpenRedirector();
3093 if( hControlDevice == NULL)
3096 #ifdef AFS_DEBUG_TRACE
3097 AFSDbgPrint( L"NPGetResourceInformation OpenRedirector failure, returning WN_NET_ERROR\n");
3100 try_return( dwStatus = WN_NET_ERROR);
3103 dwError = DeviceIoControl( hControlDevice,
3104 IOCTL_AFS_GET_CONNECTION_INFORMATION,
3114 #ifdef AFS_DEBUG_TRACE
3115 DWORD gle = GetLastError();
3117 AFSDbgPrint( L"NPGetResourceInformation Failed to get connection info from file system for local %s gle 0x%x\n",
3118 lpNetResource->lpRemoteName, gle);
3120 try_return( dwStatus = WN_BAD_NETNAME);
3123 uniRemoteName.Length = (USHORT)pConnectCB->RemoteNameLength;
3124 uniRemoteName.MaximumLength = uniRemoteName.Length;
3125 uniRemoteName.Buffer = pConnectCB->RemoteName;
3127 #ifdef AFS_DEBUG_TRACE
3128 AFSDbgPrint( L"NPGetResourceInformation For remote name %wZ Scope %08lX Type %08lX Usage %08lX\n",
3135 // Determine the space needed for this entry...
3137 ulRequiredLen = sizeof( NETRESOURCE);
3139 ulRequiredLen += pConnectCB->RemoteNameLength + sizeof( WCHAR);
3141 ulRequiredLen += pConnectCB->CommentLength + sizeof( WCHAR);
3143 ulRequiredLen += cbProviderNameLength + sizeof( WCHAR);
3145 ulRequiredLen += pConnectCB->RemainingPathLength + sizeof( WCHAR);
3147 if( pNetResource == NULL ||
3148 ulRequiredLen > dwPassedSize)
3151 *lpBufferSize = ulRequiredLen;
3153 try_return( dwStatus = WN_MORE_DATA);
3156 pStringZone = (PWCHAR) ((char *)lpBuffer + sizeof( NETRESOURCE));
3158 pNetResource->dwScope = 0 /* pConnectCB->Scope*/;
3159 pNetResource->dwType = 0 /* pConnectCB->Type */;
3161 pNetResource->dwDisplayType = pConnectCB->DisplayType;
3163 pNetResource->dwUsage = pConnectCB->Usage;
3165 pNetResource->lpLocalName = NULL;
3168 pNetResource->lpRemoteName = pStringZone;
3170 CopyMemory( pStringZone,
3171 pConnectCB->RemoteName,
3172 pConnectCB->RemoteNameLength);
3174 pStringZone += (pConnectCB->RemoteNameLength / sizeof(WCHAR));
3176 *pStringZone++ = L'\0';
3179 pNetResource->lpComment = pStringZone;
3181 CopyMemory( pStringZone,
3182 (void *)((char *)pConnectCB + pConnectCB->CommentOffset),
3183 pConnectCB->CommentLength);
3185 pStringZone += (pConnectCB->CommentLength / sizeof(WCHAR));
3187 *pStringZone++ = L'\0';
3189 // copy remaining path
3190 if (pConnectCB->RemainingPathLength > 0)
3192 *lplpSystem = pStringZone;
3194 CopyMemory( pStringZone,
3195 (void *)((char *)pConnectCB + pConnectCB->RemainingPathOffset),
3196 pConnectCB->RemainingPathLength);
3198 pStringZone += (pConnectCB->RemainingPathLength / sizeof(WCHAR));
3200 *pStringZone++ = L'\0';
3202 #ifdef AFS_DEBUG_TRACE
3203 AFSDbgPrint( L"NPGetResourceInformation For remote name %s returning remaining path %s\n",
3204 pNetResource->lpRemoteName,
3209 // copy provider name
3210 pNetResource->lpProvider = pStringZone;
3212 StringCbCopy( pStringZone,
3213 cbProviderNameLength + sizeof( WCHAR),
3216 pStringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
3218 *lpBufferSize = ulRequiredLen;
3220 dwStatus = WN_SUCCESS;
3224 if ( hControlDevice != NULL)
3227 CloseHandle( hControlDevice);
3230 if( pConnectCB != NULL)
3233 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3241 SeparateRemainingPath( WCHAR * lpConnectionName, WCHAR **lppRemainingPath)
3248 // at this point the lpConnectionName contains the full name. We need to
3249 // truncate it to \\server\share and move the remaining path back one position.
3252 for ( pwch = lpConnectionName, dwCount = 0; *pwch; pwch++)
3254 if ( *pwch == L'\\')
3268 // Found the remaining path that must be moved
3271 *lppRemainingPath = pwch + 1;
3278 for ( ; *pwch; pwch++);
3281 // and work backwards moving the string
3282 // and then make sure that there is at least
3283 // a path separator.
3288 for ( ;pwch > *lppRemainingPath; pwch--)
3290 *pwch = *(pwch - 1);
3298 NPGetUniversalName( LPCWSTR lpLocalPath,
3301 LPDWORD lpBufferSize)
3304 DWORD dwBufferSize = *lpBufferSize;
3307 dwStatus = NPGetUniversalNameCommon( lpLocalPath,
3313 if ( dwStatus == WN_NOT_CONNECTED)
3316 dwStatus = NPGetUniversalNameCommon( lpLocalPath,
3325 *lpBufferSize = dwBufferSize;
3331 static DWORD APIENTRY
3332 NPGetUniversalNameCommon( LPCWSTR lpLocalPath,
3335 LPDWORD lpBufferSize,
3338 DWORD dwStatus = WN_NOT_CONNECTED;
3339 WCHAR wchLocalName[3];
3340 WCHAR *pwchSubstName = NULL;
3341 DWORD dwSubstNameLength = 0;
3342 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3344 DWORD dwBufferSize = 0;
3345 DWORD dwPassedSize = *lpBufferSize;
3346 DWORD dwRemainingLength = *lpBufferSize;
3347 HANDLE hControlDevice = NULL;
3348 DWORD dwLocalPathLength = 0;
3349 DWORD dwRemainingPathLength = 0;
3355 #ifdef AFS_DEBUG_TRACE
3356 AFSDbgPrint( L"NPGetUniversalName local path %s level 0x%X\n",
3357 lpLocalPath ? lpLocalPath : L"(Null)",
3361 if ( NPIsFSDisabled())
3364 #ifdef AFS_DEBUG_TRACE
3365 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
3368 try_return( dwStatus = WN_NOT_CONNECTED);
3371 dwLocalPathLength = lstrlen( lpLocalPath);
3373 dwRemainingPathLength = dwLocalPathLength - 2; // no drive letter
3375 if( dwLocalPathLength == 0)
3378 #ifdef AFS_DEBUG_TRACE
3379 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_BAD_LOCALNAME\n");
3382 try_return( dwStatus = WN_BAD_LOCALNAME);
3385 if( lpBuffer == NULL ||
3386 lpBufferSize == NULL)
3388 #ifdef AFS_DEBUG_TRACE
3389 AFSDbgPrint( L"NPGetUniversalName No output buffer or size\n");
3391 try_return( dwStatus = WN_BAD_VALUE);
3394 dwSubstNameLength = 4096;
3396 pwchSubstName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSubstNameLength);
3398 if ( pwchSubstName == NULL)
3400 #ifdef AFS_DEBUG_TRACE
3401 AFSDbgPrint( L"NPGetUniversalName unable to allocate substitution name buffer.\n");
3403 try_return( dwStatus = WN_OUT_OF_MEMORY);
3406 memset(lpBuffer, 0, dwPassedSize);
3408 if ( !bDriveSubstOk ||
3409 !DriveSubstitution( lpLocalPath, pwchSubstName, dwSubstNameLength, &dwStatus))
3411 wchLocalName[0] = towupper(lpLocalPath[0]);
3412 wchLocalName[1] = L':';
3413 wchLocalName[2] = L'\0';
3415 #ifdef AFS_DEBUG_TRACE
3416 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for %s level 0x%X\n",
3424 ReadServerNameString();
3426 if ( pwchSubstName[0] != L'\\' &&
3427 pwchSubstName[1] == L':')
3430 wchLocalName[0] = towupper(pwchSubstName[0]);
3431 wchLocalName[1] = L':';
3432 wchLocalName[2] = L'\0';
3434 #ifdef AFS_DEBUG_TRACE
3435 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for drive substitution %s -> %s\n",
3440 else if ( _wcsnicmp( pwchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
3441 ( pwchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
3442 pwchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
3446 #ifdef AFS_DEBUG_TRACE
3447 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is AFS; Level 0x%x BufferSize 0x%x\n",
3453 dwBufferSize = (wcslen( pwchSubstName) + 1) * sizeof( WCHAR);
3455 switch( dwInfoLevel)
3458 case UNIVERSAL_NAME_INFO_LEVEL:
3461 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3463 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize;
3465 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3468 #ifdef AFS_DEBUG_TRACE
3469 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3472 try_return( dwStatus = WN_MORE_DATA);
3475 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3477 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3479 memcpy( pUniversalInfo->lpUniversalName,
3481 min( dwBufferSize, dwRemainingLength));
3483 dwRemainingLength -= min( dwBufferSize, dwRemainingLength);
3485 #ifdef AFS_DEBUG_TRACE
3486 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3488 pUniversalInfo->lpUniversalName,
3489 pUniversalInfo->lpUniversalName);
3492 if ( dwPassedSize < *lpBufferSize)
3495 try_return( dwStatus = WN_MORE_DATA);
3498 try_return( dwStatus = WN_SUCCESS);
3501 case REMOTE_NAME_INFO_LEVEL:
3504 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3506 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + 2 * dwBufferSize + sizeof( WCHAR);
3508 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3511 #ifdef AFS_DEBUG_TRACE
3512 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3515 try_return( dwStatus = WN_MORE_DATA);
3518 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3520 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3522 memcpy( pRemoteInfo->lpUniversalName,
3524 min( dwRemainingLength, dwBufferSize));
3526 dwRemainingLength -= min( dwRemainingLength, dwBufferSize);
3528 #ifdef AFS_DEBUG_TRACE
3529 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3531 pRemoteInfo->lpUniversalName,
3532 pRemoteInfo->lpUniversalName);
3535 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3537 pRemoteInfo->lpConnectionName = (LPTSTR)((char *)pRemoteInfo->lpUniversalName + dwBufferSize);
3539 memcpy( pRemoteInfo->lpConnectionName,
3541 min( dwRemainingLength, dwBufferSize));
3543 dwRemainingLength -= min( dwRemainingLength, dwBufferSize) - sizeof( WCHAR);
3545 SeparateRemainingPath( pRemoteInfo->lpConnectionName,
3546 &pRemoteInfo->lpRemainingPath);
3549 #ifdef AFS_DEBUG_TRACE
3550 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3552 pRemoteInfo->lpConnectionName,
3553 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3555 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3557 pRemoteInfo->lpRemainingPath,
3558 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3561 if ( dwPassedSize < *lpBufferSize)
3564 try_return( dwStatus = WN_MORE_DATA);
3567 try_return( dwStatus = WN_SUCCESS);
3571 #ifdef AFS_DEBUG_TRACE
3572 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3575 try_return( dwStatus = WN_BAD_VALUE);
3581 #ifdef AFS_DEBUG_TRACE
3582 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is not AFS\n",
3585 try_return( dwStatus = WN_NOT_CONNECTED);
3589 dwBufferSize = 0x1000;
3591 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
3593 if( pConnectCB == NULL)
3595 try_return( dwStatus = WN_OUT_OF_MEMORY);
3598 pConnectCB->LocalName = towupper(wchLocalName[0]);
3600 pConnectCB->RemoteNameLength = 0;
3602 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3604 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
3606 #ifdef AFS_DEBUG_TRACE
3607 AFSDbgPrint( L"NPGetUniversalName Retrieved authentication id %08lX-%08lX\n",
3608 pConnectCB->AuthenticationId.HighPart,
3609 pConnectCB->AuthenticationId.LowPart);
3612 hControlDevice = OpenRedirector();
3614 if( hControlDevice == NULL)
3617 try_return( dwStatus = WN_NET_ERROR);
3620 dwError = DeviceIoControl( hControlDevice,
3621 IOCTL_AFS_GET_CONNECTION,
3631 #ifdef AFS_DEBUG_TRACE
3632 DWORD gle = GetLastError();
3634 AFSDbgPrint( L"NPGetUniversalName Failed to get connection from file system for local %s gle 0x%x\n",
3637 try_return( dwStatus = WN_NOT_CONNECTED);
3640 switch( dwInfoLevel)
3643 case UNIVERSAL_NAME_INFO_LEVEL:
3646 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3648 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize + sizeof( WCHAR);
3650 *lpBufferSize += dwRemainingPathLength * sizeof( WCHAR);
3652 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3655 #ifdef AFS_DEBUG_TRACE
3656 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3659 try_return( dwStatus = WN_MORE_DATA);
3662 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3664 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3666 pch = (char *)pUniversalInfo->lpUniversalName;
3670 min( dwBufferSize, dwRemainingLength));
3672 pch += min( dwBufferSize, dwRemainingLength);
3674 dwRemainingLength -= min( dwBufferSize + sizeof(WCHAR), dwRemainingLength);
3678 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3680 pch += min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3682 dwRemainingLength -= min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3684 #ifdef AFS_DEBUG_TRACE
3685 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3687 pUniversalInfo->lpUniversalName,
3688 pUniversalInfo->lpUniversalName);
3691 if ( dwPassedSize < *lpBufferSize)
3694 try_return( dwStatus = WN_MORE_DATA);
3697 try_return( dwStatus = WN_SUCCESS);
3700 case REMOTE_NAME_INFO_LEVEL:
3703 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3705 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + (2 * dwBufferSize + sizeof( WCHAR)) + 2 * sizeof( WCHAR);
3707 *lpBufferSize += 2 * dwRemainingPathLength * sizeof( WCHAR);
3709 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3712 #ifdef AFS_DEBUG_TRACE
3713 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3716 try_return( dwStatus = WN_MORE_DATA);
3719 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3721 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3723 pch = (char *)pRemoteInfo->lpUniversalName;
3727 min( dwBufferSize, dwRemainingLength));
3729 pch += min( dwBufferSize, dwRemainingLength);
3731 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3735 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3737 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3739 dwRemainingLength -= min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3741 #ifdef AFS_DEBUG_TRACE
3742 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3744 pRemoteInfo->lpUniversalName,
3745 pRemoteInfo->lpUniversalName);
3748 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3750 pRemoteInfo->lpConnectionName = (LPWSTR)pch;
3754 min( dwBufferSize, dwRemainingLength));
3756 pch += min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3758 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3762 if ( dwRemainingLength > dwRemainingPathLength + sizeof( WCHAR))
3764 pRemoteInfo->lpRemainingPath = (LPWSTR)pch;
3768 min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength));
3770 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3772 dwRemainingLength -= min((dwLocalPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3775 #ifdef AFS_DEBUG_TRACE
3776 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3778 pRemoteInfo->lpConnectionName,
3779 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3781 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3783 pRemoteInfo->lpRemainingPath,
3784 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3787 if ( dwPassedSize < *lpBufferSize)
3790 try_return( dwStatus = WN_MORE_DATA);
3793 try_return( dwStatus = WN_SUCCESS);
3797 #ifdef AFS_DEBUG_TRACE
3798 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3801 try_return( dwStatus = WN_BAD_VALUE);
3806 #ifdef AFS_DEBUG_TRACE
3807 AFSDbgPrint( L"NPGetUniversalName BufferSize 0x%X\n",
3810 if ( hControlDevice != NULL)
3813 CloseHandle( hControlDevice);
3819 HeapFree( GetProcessHeap(), 0, (PVOID) pwchSubstName);
3822 if( pConnectCB != NULL)
3825 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3834 GetFormatFlags( DWORD dwFlags)
3836 static WCHAR Buffer[128] = L"";
3839 // WNFMT_MULTILINE 0x01
3840 // WNFMT_ABBREVIATED 0x02
3841 // WNFMT_INENUM 0x10
3842 // WNFMT_CONNECTION 0x20
3852 if ( dwFlags & WNFMT_MULTILINE )
3854 StringCbCat( Buffer, sizeof(Buffer), L"MULTILINE|");
3857 if ( dwFlags & WNFMT_INENUM )
3859 StringCbCat( Buffer, sizeof(Buffer), L"ABBREVIATED|");
3862 if ( dwFlags & WNFMT_INENUM )
3864 StringCbCat( Buffer, sizeof(Buffer), L"INENUM|");
3867 if ( dwFlags & WNFMT_CONNECTION )
3869 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTION|");
3872 if ( dwFlags & ~(WNFMT_MULTILINE|WNFMT_ABBREVIATED|WNFMT_INENUM|WNFMT_CONNECTION) )
3874 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
3877 Buffer[lstrlen(Buffer)-1] = L'\0';
3883 NPFormatNetworkName( LPTSTR lpRemoteName,
3884 LPTSTR lpFormattedName,
3887 DWORD dwAveCharPerLine)
3890 DWORD dwLen = 0, dwCurrentLen = 0;
3891 LPTSTR pCurrentName = lpRemoteName;
3893 #ifdef AFS_DEBUG_TRACE
3894 AFSDbgPrint( L"NPFormatNetworkName Remote %s Flags %s (0x%x) CharsPerLine %u\n",
3897 GetFormatFlags( dwFlags),
3903 // Walk back in the name until we hit a \
3906 dwLen = wcslen( lpRemoteName);
3908 pCurrentName += (dwLen - 1);
3910 if ( pCurrentName[ 0] != L'\\')
3916 if( pCurrentName[ 0] == L'\\')
3932 if( *lpnLength < dwCurrentLen * sizeof( WCHAR))
3935 *lpnLength = dwCurrentLen * sizeof( WCHAR);
3937 #ifdef AFS_DEBUG_TRACE
3938 AFSDbgPrint( L"NPFormatNetworkName remote name %s WN_MORE_DATA\n",
3942 return WN_MORE_DATA;
3945 StringCbCopy( lpFormattedName,
3949 *lpnLength = dwCurrentLen * sizeof( WCHAR);
3951 #ifdef AFS_DEBUG_TRACE
3952 AFSDbgPrint( L"NPFormatNetworkName remote name %s as %s\n",
3960 /************************************************************
3961 / Unsupported entry points
3962 /************************************************************/
3965 // AuthGroup processing is implemented in src/WINNT/afsd/afslogon.c
3970 LPCWSTR lpAuthentInfoType,
3971 LPVOID lpAuthentInfo,
3972 LPCWSTR lpPreviousAuthentInfoType,
3973 LPVOID lpPreviousAuthentInfo,
3974 LPWSTR lpStationName,
3975 LPVOID StationHandle,
3976 LPWSTR *lpLogonScript)
3979 #ifdef AFS_DEBUG_TRACE
3980 AFSDbgPrint( L"NPLogonNotify, returning WN_NOT_SUPPORTED\n");
3983 return WN_NOT_SUPPORTED;
3987 NPPasswordChangeNotify (
3988 LPCWSTR lpAuthentInfoType,
3989 LPVOID lpAuthentInfo,
3990 LPCWSTR lpPreviousAuthentInfoType,
3991 LPVOID lpPreviousAuthentInfo,
3992 LPWSTR lpStationName,
3993 LPVOID StationHandle,
3994 DWORD dwChangeInfo )
3997 #ifdef AFS_DEBUG_TRACE
3998 AFSDbgPrint( L"NPPasswordChangeNotify, returning WN_NOT_SUPPORTED\n");
4001 SetLastError( WN_NOT_SUPPORTED );
4003 return WN_NOT_SUPPORTED;
4007 NPGetUser( LPTSTR lpName,
4009 LPDWORD lpBufferSize)
4012 DWORD rc = WN_NOT_SUPPORTED;
4014 AFSDbgPrint( L"NPGetUser Entry Name %s\n", lpName);
4022 NPGetReconnectFlags( LPWSTR lpRemoteName,
4023 unsigned char *Parameter2)
4026 DWORD dwStatus = WN_NOT_SUPPORTED;
4028 AFSDbgPrint( L"NPGetReconnectFlags RemoteName %s\n",
4037 I_SystemFocusDialog( VOID)
4040 DWORD dwStatus = WN_NOT_SUPPORTED;
4042 AFSDbgPrint( L"I_SystemFocusDialog\n");
4047 /************************************************************
4048 / END Unsupported entry points
4049 /************************************************************/
4056 HANDLE hControlDevice = NULL;
4058 hControlDevice = CreateFile( AFS_SYMLINK_W,
4059 GENERIC_READ | GENERIC_WRITE,
4060 FILE_SHARE_READ | FILE_SHARE_WRITE,
4066 if( hControlDevice == INVALID_HANDLE_VALUE)
4069 hControlDevice = NULL;
4070 #ifdef AFS_DEBUG_TRACE
4071 AFSDbgPrint( L"Failed to open control device error: %d\n",
4077 // only do this if you want network shares to fail to mount
4078 // when the file system is not yet ready
4082 AFSDriverStatusRespCB respCB;
4085 memset( &respCB, '\0', sizeof( AFSDriverStatusRespCB));
4087 if ( !DeviceIoControl( hControlDevice,
4088 IOCTL_AFS_STATUS_REQUEST,
4092 sizeof( AFSDriverStatusRespCB),
4095 dwBytes != sizeof(AFSDriverStatusRespCB) ||
4096 respCB.Status != AFS_DRIVER_STATUS_READY )
4099 CloseHandle( hControlDevice);
4101 hControlDevice = NULL;
4106 return hControlDevice;
4113 LARGE_INTEGER liAuthId = {0,0};
4114 HANDLE hToken = NULL;
4115 TOKEN_STATISTICS stTokenInfo;
4116 DWORD dwCopyBytes = 0;
4118 if ( !OpenThreadToken( GetCurrentThread(),
4120 FALSE, // Impersonation
4123 if( !OpenProcessToken( GetCurrentProcess(),
4128 #ifdef AFS_DEBUG_TRACE
4129 AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve Thread and Process tokens 0x%X\n",
4136 #ifdef AFS_DEBUG_TRACE
4137 AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Process Token\n");
4144 #ifdef AFS_DEBUG_TRACE
4145 AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Thread Token\n");
4149 if ( hToken != NULL)
4152 if( !GetTokenInformation( hToken,
4155 sizeof( TOKEN_STATISTICS),
4159 #ifdef AFS_DEBUG_TRACE
4160 AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve token information 0x%X\n",
4167 liAuthId.HighPart = stTokenInfo.AuthenticationId.HighPart;
4168 liAuthId.LowPart = stTokenInfo.AuthenticationId.LowPart;
4171 CloseHandle( hToken);
4180 static int init = 0;
4181 static DWORD debug = 0;
4186 if (RegOpenKey (HKEY_LOCAL_MACHINE,
4187 TEXT("SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider"), &hk) == 0)
4189 DWORD dwSize = sizeof(BOOL);
4190 DWORD dwType = REG_DWORD;
4191 RegQueryValueEx (hk, TEXT("Debug"), NULL, &dwType, (PBYTE)&debug, &dwSize);
4201 cm_Utf16ToUtf8Alloc(const WCHAR * s, int cch_src, int *pcch_dest)
4206 if (s == NULL || cch_src == 0 || *s == L'\0') {
4208 *pcch_dest = ((cch_src != 0)?1:0);
4212 cch_dest = WideCharToMultiByte(CP_UTF8, 0, s, cch_src, NULL, 0, NULL, FALSE);
4214 if (cch_dest == 0) {
4216 *pcch_dest = cch_dest;
4220 dest = HeapAlloc( GetProcessHeap(), 0, (cch_dest + 1) * sizeof(char));
4222 WideCharToMultiByte(CP_UTF8, 0, s, cch_src, dest, cch_dest, NULL, FALSE);
4226 *pcch_dest = cch_dest;
4232 AppendDebugStringToLogFile(WCHAR *wszbuffer)
4240 if ( !wszbuffer || !wszbuffer[0] )
4243 len = (int)wcslen(wszbuffer);
4245 buffer = cm_Utf16ToUtf8Alloc(wszbuffer, len, &len);
4250 hFile = CreateFileW( L"C:\\TEMP\\AFSRDFSProvider.log",
4255 FILE_ATTRIBUTE_NORMAL,
4258 if ( hFile == INVALID_HANDLE_VALUE ) {
4259 OutputDebugString(L"C:\\AFSRDFSProvider.log cannot be opened.\n");
4263 bRet = WriteFile( hFile, buffer, len, &dwWritten, NULL);
4265 bRet = CloseHandle(hFile);
4267 HeapFree(GetProcessHeap(), 0, buffer);
4278 WCHAR wszbuffer[512];
4280 DWORD debug = Debug();
4285 va_start( marker, Format );
4287 StringCbPrintf( wszbuffer, sizeof(wszbuffer), L"[%d-%08X] ",
4293 GetCurrentThreadId());
4295 rc = StringCbVPrintfW( &wszbuffer[ 14], sizeof(wszbuffer) - 14, Format, marker);
4297 if (SUCCEEDED(rc)) {
4299 OutputDebugString( wszbuffer );
4301 AppendDebugStringToLogFile(wszbuffer);
4303 OutputDebugString(L"AFSDbgPrint Failed to create string\n");
4306 return SUCCEEDED(rc) ? 1 : 0;