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,
81 #define WNNC_DRIVER( major, minor ) ( major * 0x00010000 + minor )
83 #define OPENAFS_PROVIDER_NAME L"OpenAFS Network"
84 #define OPENAFS_PROVIDER_NAME_LENGTH 30
86 #define MAX_PROVIDER_NAME_LENGTH 256
88 static ULONG cbProviderNameLength = OPENAFS_PROVIDER_NAME_LENGTH;
90 static wchar_t wszProviderName[MAX_PROVIDER_NAME_LENGTH+1] = OPENAFS_PROVIDER_NAME;
92 static BOOL bProviderNameRead = FALSE;
94 #define OPENAFS_SERVER_NAME L"AFS"
95 #define OPENAFS_SERVER_NAME_LENGTH 6
97 #define OPENAFS_SERVER_COMMENT L"AFS Root"
98 #define OPENAFS_SERVER_COMMENT_LENGTH 16
100 #define MAX_SERVER_NAME_LENGTH 30
102 static ULONG cbServerNameLength = 0;
104 static ULONG cbServerNameUNCLength = 0;
106 static ULONG cbServerCommentLength = OPENAFS_SERVER_COMMENT_LENGTH;
108 static wchar_t wszServerName[MAX_SERVER_NAME_LENGTH+1];
110 static wchar_t wszServerNameUNC[MAX_SERVER_NAME_LENGTH+3];
112 static wchar_t wszServerComment[] = OPENAFS_SERVER_COMMENT;
114 static BOOL bServerNameRead = FALSE;
117 AFSRetrieveAuthId( void);
120 ReadProviderNameString( void)
126 if ( bProviderNameRead )
129 code = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
130 L"SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider",
131 0, KEY_QUERY_VALUE, &hk);
133 if ( code == ERROR_SUCCESS) {
135 dwLen = sizeof(wszProviderName);
137 code = RegQueryValueExW( hk, L"Name", NULL, NULL,
138 (LPBYTE) wszProviderName, &dwLen);
140 if ( code == ERROR_SUCCESS)
143 wszProviderName[MAX_PROVIDER_NAME_LENGTH] = '\0';
145 cbProviderNameLength = wcslen( wszProviderName) * sizeof( WCHAR);
151 bProviderNameRead = TRUE;
155 ReadServerNameString( void)
161 if ( bServerNameRead )
164 code = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
165 L"SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters",
166 0, KEY_QUERY_VALUE, &hk);
168 if ( code == ERROR_SUCCESS) {
170 dwLen = sizeof(wszProviderName);
172 code = RegQueryValueExW( hk, L"NetbiosName", NULL, NULL,
173 (LPBYTE) wszServerName, &dwLen);
175 if ( code == ERROR_SUCCESS)
178 wszServerName[MAX_SERVER_NAME_LENGTH] = '\0';
180 cbServerNameLength = wcslen( wszServerName) * sizeof( WCHAR);
182 wszServerNameUNC[0] = wszServerNameUNC[1] = L'\\';
184 memcpy(&wszServerNameUNC[2], wszServerName, (cbServerNameLength + 1) * sizeof( WCHAR));
186 cbServerNameUNCLength = cbServerNameLength + 2 * sizeof( WCHAR);
192 bServerNameRead = TRUE;
197 /* returns TRUE if the file system is disabled or not installed */
199 NPIsFSDisabled( void)
204 DWORD dwStart = SERVICE_DISABLED;
206 code = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
207 L"SYSTEM\\CurrentControlSet\\Services\\AFSRedirector",
208 0, KEY_QUERY_VALUE, &hk);
210 if ( code != ERROR_SUCCESS)
215 dwLen = sizeof(dwStart);
217 code = RegQueryValueExW( hk, L"Start", NULL, NULL,
218 (LPBYTE) &dwStart, &dwLen);
222 return ( dwStart == SERVICE_DISABLED);
226 #define try_return(S) { S; goto try_exit; }
232 typedef struct _UNICODE_STRING {
234 USHORT MaximumLength;
236 } UNICODE_STRING, *PUNICODE_STRING;
239 OpenRedirector( void);
241 typedef struct _AFS_ENUM_CB
256 // Recursively evaluate drivestr to find the final
257 // dos drive letter to which the source is mapped.
260 DriveSubstitution(LPCWSTR drivestr, LPWSTR subststr, size_t substlen)
263 WCHAR device[MAX_PATH + 1];
266 memset( subststr, 0, substlen);
267 drive[0] = drivestr[0];
268 drive[1] = drivestr[1];
271 if ( QueryDosDevice(drive, device, MAX_PATH) )
273 #ifdef AFS_DEBUG_TRACE
274 AFSDbgPrint( L"DriveSubstitution QueryDosDevice %s [%s -> %s]\n",
279 if ( device[0] == L'\\' &&
282 device[3] == L'\\' &&
283 iswalpha(device[4]) &&
286 drive[0] = device[4];
290 if ( !DriveSubstitution(drive, subststr, substlen) )
293 subststr[0] = drive[0];
303 hr = StringCchCat( subststr, substlen, &device[6]);
305 if ( SUCCEEDED(hr) && drivestr[2] )
307 hr = StringCchCat( subststr, substlen, &drivestr[2]);
310 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
313 #ifdef AFS_DEBUG_TRACE
314 AFSDbgPrint( L"DriveSubstitution %s -> %s\n",
321 else if ( device[0] == L'\\' &&
324 device[3] == L'\\' &&
333 hr = StringCbCopyN(&subststr[1], substlen - sizeof(WCHAR), &device[7], MAX_PATH);
335 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
339 hr = StringCchCat( subststr, substlen, &drivestr[2]);
346 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
349 #ifdef AFS_DEBUG_TRACE
350 AFSDbgPrint( L"DriveSubstitution %s -> %s\n",
358 #ifdef AFS_DEBUG_TRACE
359 AFSDbgPrint( L"DriveSubstitution StringCbCopyN 1 hr 0x%X\n",
363 else if ( _wcsnicmp( AFS_RDR_DEVICE_NAME, device, sizeof( AFS_RDR_DEVICE_NAME) / sizeof( WCHAR) - 1) == 0)
366 // \Device\AFSRedirector\;X:\\afs\cellname
369 hr = StringCbCopyN( subststr, substlen,
370 &device[3 + sizeof( AFS_RDR_DEVICE_NAME) / sizeof( WCHAR)],
371 MAX_PATH * sizeof( WCHAR));
373 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
378 hr = StringCchCat( subststr, substlen, &drivestr[2]);
385 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
388 #ifdef AFS_DEBUG_TRACE
389 AFSDbgPrint( L"DriveSubstitution %s -> %s\n",
397 #ifdef AFS_DEBUG_TRACE
398 AFSDbgPrint( L"DriveSubstitution StringCbCopyN 2 hr 0x%X\n",
403 #ifdef AFS_DEBUG_TRACE
404 AFSDbgPrint( L"DriveSubstitution no substitution or match %s !! %s\n",
411 #ifdef AFS_DEBUG_TRACE
412 AFSDbgPrint( L"DriveSubstitution QueryDosDevice failed %s gle 0x%X\n",
425 NPGetCapsQueryString( DWORD nIndex)
428 case WNNC_SPEC_VERSION:
429 return L"WNNC_SPEC_VERSION";
432 return L"WNNC_NET_TYPE";
434 case WNNC_DRIVER_VERSION:
435 return L"WNNC_DRIVER_VERSION";
440 case WNNC_CONNECTION:
441 return L"WNNC_CONNECTION";
444 return L"WNNC_DIALOG";
447 return L"WNNC_ADMIN";
449 case WNNC_ENUMERATION:
450 return L"WNNC_ENUMERATION";
453 return L"WNNC_START";
455 case WNNC_CONNECTION_FLAGS:
456 return L"WNNC_CONNECTION_FLAGS";
464 // This is the only function which must be exported, everything else is optional
469 NPGetCaps( DWORD nIndex )
474 #ifdef AFS_DEBUG_TRACE
475 AFSDbgPrint( L"NPGetCaps Index %u %s\n", nIndex,
476 NPGetCapsQueryString( nIndex));
480 case WNNC_SPEC_VERSION:
483 rc = WNNC_SPEC_VERSION51;
489 rc = WNNC_NET_OPENAFS;
493 case WNNC_DRIVER_VERSION:
496 rc = WNNC_DRIVER(1, 0);
500 case WNNC_CONNECTION:
505 // WNNC_CON_GETPERFORMANCE
509 rc = WNNC_CON_GETCONNECTIONS |
510 WNNC_CON_CANCELCONNECTION |
511 WNNC_CON_ADDCONNECTION |
512 WNNC_CON_ADDCONNECTION3;
517 case WNNC_ENUMERATION:
519 rc = WNNC_ENUM_LOCAL |
529 rc = WNNC_WAIT_FOR_START;
539 // WNNC_DLG_DEVICEMODE
540 // WNNC_DLG_PROPERTYDIALOG
541 // WNNC_DLG_SEARCHDIALOG
542 // WNNC_DLG_PERMISSIONEDITOR
545 rc = WNNC_DLG_FORMATNETWORKNAME |
546 WNNC_DLG_GETRESOURCEINFORMATION |
547 WNNC_DLG_GETRESOURCEPARENT;
566 // WNNC_ADM_GETDIRECTORYTYPE
567 // WNNC_ADM_DIRECTORYNOTIFY
568 // used by the old File Manager
579 NPAddConnection( LPNETRESOURCE lpNetResource,
584 #ifdef AFS_DEBUG_TRACE
585 AFSDbgPrint( L"NPAddConnection forwarding to NPAddConnection3\n");
587 return NPAddConnection3( NULL, lpNetResource, lpPassword, lpUserName, 0 );
592 NPAddConnection3( HWND hwndOwner,
593 LPNETRESOURCE lpNetResource,
599 DWORD dwStatus = WN_SUCCESS;
600 WCHAR wchRemoteName[MAX_PATH+1];
601 WCHAR wchLocalName[3];
602 DWORD dwCopyBytes = 0;
603 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
605 DWORD dwBufferSize = 0;
606 HANDLE hControlDevice = NULL;
607 HANDLE hToken = NULL;
608 LARGE_INTEGER liAuthId = {0,0};
612 if ( NPIsFSDisabled())
615 #ifdef AFS_DEBUG_TRACE
616 AFSDbgPrint( L"NPAddConnection3 AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
619 return WN_BAD_NETNAME;
622 if ((lpNetResource->lpRemoteName == NULL) ||
623 (lpNetResource->lpRemoteName[0] != L'\\') ||
624 (lpNetResource->lpRemoteName[1] != L'\\') ||
625 ((lpNetResource->dwType != RESOURCETYPE_DISK) &&
626 (lpNetResource->dwType != RESOURCETYPE_ANY)))
629 #ifdef AFS_DEBUG_TRACE
630 AFSDbgPrint( L"NPAddConnection3 invalid input, returning WN_BAD_NETNAME\n");
632 return WN_BAD_NETNAME;
635 #ifdef AFS_DEBUG_TRACE
636 AFSDbgPrint( L"NPAddConnection3 processing\n");
638 if( lpNetResource->lpLocalName != NULL)
641 wchLocalName[0] = towupper(lpNetResource->lpLocalName[0]);
642 wchLocalName[1] = L':';
643 wchLocalName[2] = L'\0';
646 StringCchCopy(wchRemoteName, MAX_PATH+1, lpNetResource->lpRemoteName);
647 wchRemoteName[MAX_PATH] = L'\0';
650 // Allocate our buffer to pass to the redirector filter
653 dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + (wcslen( wchRemoteName) * sizeof( WCHAR));
655 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
657 if( pConnectCB == NULL)
660 try_return( dwStatus = WN_OUT_OF_MEMORY);
663 if( lpNetResource->lpLocalName != NULL)
666 pConnectCB->LocalName = towupper(wchLocalName[0]);
668 #ifdef AFS_DEBUG_TRACE
669 AFSDbgPrint( L"NPAddConnection3 Adding mapping for drive %s remote name %s\n",
677 pConnectCB->LocalName = L'\0';
679 #ifdef AFS_DEBUG_TRACE
680 AFSDbgPrint( L"NPAddConnection3 Adding mapping for NO drive remote name %s\n",
685 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
687 pConnectCB->RemoteNameLength = wcslen( wchRemoteName) * sizeof( WCHAR);
689 memcpy( pConnectCB->RemoteName,
691 pConnectCB->RemoteNameLength);
693 pConnectCB->Type = lpNetResource->dwType;
695 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
697 #ifdef AFS_DEBUG_TRACE
698 AFSDbgPrint( L"NPAddConnection3 Retrieved authentication id %08lX-%08lX\n",
699 pConnectCB->AuthenticationId.HighPart,
700 pConnectCB->AuthenticationId.LowPart);
703 hControlDevice = OpenRedirector();
705 if( hControlDevice == NULL)
708 #ifdef AFS_DEBUG_TRACE
709 AFSDbgPrint( L"NPAddConnection3 OpenRedirector failure, returning WN_NET_ERROR\n");
712 try_return( dwStatus = WN_NET_ERROR);
715 dwError = DeviceIoControl( hControlDevice,
716 IOCTL_AFS_ADD_CONNECTION,
726 #ifdef AFS_DEBUG_TRACE
727 AFSDbgPrint( L"NPAddConnection3 Failed to add connection to file system %d\n", GetLastError());
729 try_return( dwStatus = WN_OUT_OF_MEMORY);
733 // The status returned from the driver will indicate how it was handled
736 if( dwStatus == WN_SUCCESS &&
737 lpNetResource->lpLocalName != NULL)
740 WCHAR TempBuf[MAX_PATH+1];
742 if( !QueryDosDeviceW( wchLocalName,
747 if( GetLastError() != ERROR_FILE_NOT_FOUND)
750 #ifdef AFS_DEBUG_TRACE
751 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW failed with file not found\n");
753 NPCancelConnection( wchLocalName, TRUE);
755 dwStatus = ERROR_ALREADY_ASSIGNED;
760 UNICODE_STRING uniConnectionName;
761 UNICODE_STRING uniDeviceName;
763 uniDeviceName.Length = (wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR));
764 uniDeviceName.MaximumLength = uniDeviceName.Length;
765 uniDeviceName.Buffer = AFS_RDR_DEVICE_NAME;
768 // Create a symbolic link object to the device we are redirecting
771 uniConnectionName.MaximumLength = (USHORT)( uniDeviceName.Length +
772 pConnectCB->RemoteNameLength +
773 8 + // Local name and \;
774 sizeof(WCHAR)); // Space for NULL-termination.
777 // Don't include NULL-termination.
780 uniConnectionName.Length = uniConnectionName.MaximumLength - sizeof(WCHAR);
782 uniConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
783 uniConnectionName.MaximumLength);
785 if( uniConnectionName.Buffer == NULL)
788 try_return( dwStatus = GetLastError());
791 CopyMemory( uniConnectionName.Buffer,
792 uniDeviceName.Buffer,
793 uniDeviceName.Length);
795 StringCchCatW( uniConnectionName.Buffer,
796 uniConnectionName.MaximumLength,
799 StringCchCatW( uniConnectionName.Buffer,
800 uniConnectionName.MaximumLength,
803 StringCchCatW( uniConnectionName.Buffer,
804 uniConnectionName.MaximumLength,
807 #ifdef AFS_DEBUG_TRACE
808 AFSDbgPrint( L"NPAddConnection3 DefineDosDevice Local %s connection name %s\n",
810 uniConnectionName.Buffer);
813 if( !DefineDosDeviceW( DDD_RAW_TARGET_PATH |
814 DDD_NO_BROADCAST_SYSTEM,
816 uniConnectionName.Buffer))
818 #ifdef AFS_DEBUG_TRACE
819 AFSDbgPrint( L"NPAddConnection3 Failed to assign drive\n");
821 dwStatus = GetLastError();
826 #ifdef AFS_DEBUG_TRACE
827 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW assigned drive %s\n", wchLocalName);
830 dwStatus = WN_SUCCESS;
833 LocalFree( uniConnectionName.Buffer);
839 #ifdef AFS_DEBUG_TRACE
840 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW %Z already existed\n", TempBuf);
842 NPCancelConnection( wchLocalName, TRUE);
844 dwStatus = ERROR_ALREADY_ASSIGNED;
850 if ( hControlDevice != NULL)
853 CloseHandle( hControlDevice);
856 if( pConnectCB != NULL)
859 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
868 NPCancelConnection( LPWSTR lpName,
872 WCHAR wchRemoteName[MAX_PATH+1];
873 DWORD dwRemoteNameLength = (MAX_PATH+1) * sizeof(WCHAR);
874 DWORD dwStatus = WN_NOT_CONNECTED;
875 DWORD dwCopyBytes = 0;
876 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
877 AFSCancelConnectionResultCB stCancelConn;
879 DWORD dwBufferSize = 0;
880 BOOL bLocalName = TRUE;
881 HANDLE hControlDevice = NULL;
882 WCHAR wchLocalName[ 3];
883 WCHAR *pwchLocalName = NULL;
888 if ( NPIsFSDisabled())
891 #ifdef AFS_DEBUG_TRACE
892 AFSDbgPrint( L"NPCancelConnection AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
895 try_return( dwStatus = WN_NOT_CONNECTED);
898 if( *lpName == L'\\' &&
899 *(lpName + 1) == L'\\')
904 wchLocalName[0] = L'\0';
906 StringCchCopyW( wchRemoteName, MAX_PATH+1, lpName);
908 dwRemoteNameLength = (wcslen( wchRemoteName) * sizeof( WCHAR));
913 wchLocalName[0] = towupper(lpName[0]);
914 wchLocalName[1] = L':';
915 wchLocalName[2] = L'\0';
918 // Get the remote name for the connection, if we are handling it
921 dwStatus = NPGetConnectionCommon( wchLocalName,
926 if( dwStatus != WN_SUCCESS ||
927 dwRemoteNameLength == 0)
930 #ifdef AFS_DEBUG_TRACE
931 AFSDbgPrint( L"NPCancelConnection Status 0x%x NameLength %u, returning WN_NOT_CONNECTED\n",
932 dwStatus, dwRemoteNameLength);
934 try_return( dwStatus = WN_NOT_CONNECTED);
938 // NPGetConnection returns the buffer size not the length without NUL
940 dwRemoteNameLength -= sizeof( WCHAR);
943 wchRemoteName[ dwRemoteNameLength/sizeof( WCHAR)] = L'\0';
945 #ifdef AFS_DEBUG_TRACE
946 AFSDbgPrint( L"NPCancelConnection Attempting to cancel '%s' -> '%s'\n",
947 wchLocalName, wchRemoteName);
950 dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + dwRemoteNameLength;
952 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
954 if( pConnectCB == NULL)
957 try_return( dwStatus = WN_OUT_OF_MEMORY);
963 pConnectCB->LocalName = wchLocalName[0];
968 pConnectCB->LocalName = L'\0';
971 pConnectCB->RemoteNameLength = (USHORT)dwRemoteNameLength;
973 StringCchCopyW( pConnectCB->RemoteName,
977 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
979 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
981 #ifdef AFS_DEBUG_TRACE
982 AFSDbgPrint( L"NPCancelConnection Retrieved authentication id %08lX-%08lX\n",
983 pConnectCB->AuthenticationId.HighPart,
984 pConnectCB->AuthenticationId.LowPart);
987 hControlDevice = OpenRedirector();
989 if( hControlDevice == NULL)
992 #ifdef AFS_DEBUG_TRACE
993 AFSDbgPrint( L"NPCancelConnection OpenRedirector failure, returning WN_NET_ERROR\n");
996 try_return( dwStatus = WN_NET_ERROR);
999 memset( &stCancelConn,
1001 sizeof( AFSCancelConnectionResultCB));
1003 dwError = DeviceIoControl( hControlDevice,
1004 IOCTL_AFS_CANCEL_CONNECTION,
1008 sizeof( AFSCancelConnectionResultCB),
1014 #ifdef AFS_DEBUG_TRACE
1015 DWORD gle = GetLastError();
1017 AFSDbgPrint( L"NPCancelConnection DeviceIoControl failed - gle 0x%x\n", gle);
1019 try_return( dwStatus = WN_NOT_CONNECTED);
1022 dwStatus = stCancelConn.Status;
1024 #ifdef AFS_DEBUG_TRACE
1025 if ( dwStatus == WN_NOT_CONNECTED )
1028 AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status WN_NOT_CONNECTED\n",
1034 AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status %08lX\n",
1040 if( dwStatus == WN_SUCCESS &&
1042 stCancelConn.LocalName != L'\0'))
1045 UNICODE_STRING uniConnectionName;
1046 UNICODE_STRING uniDeviceName;
1048 uniDeviceName.Length = (wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR));
1049 uniDeviceName.MaximumLength = uniDeviceName.Length;
1050 uniDeviceName.Buffer = AFS_RDR_DEVICE_NAME;
1053 // Create a symbolic link object to the device we are redirecting
1056 uniConnectionName.MaximumLength = (USHORT)( uniDeviceName.Length +
1057 dwRemoteNameLength +
1058 8 + // Local name and \;
1059 sizeof(WCHAR)); // Space for NULL-termination.
1062 // Don't include NULL-termination.
1065 uniConnectionName.Length = uniConnectionName.MaximumLength - sizeof(WCHAR);
1067 uniConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
1068 uniConnectionName.MaximumLength);
1070 if( uniConnectionName.Buffer == NULL)
1073 try_return( dwStatus = GetLastError());
1076 CopyMemory( uniConnectionName.Buffer,
1077 uniDeviceName.Buffer,
1078 uniDeviceName.Length);
1080 StringCchCatW( uniConnectionName.Buffer,
1081 uniConnectionName.MaximumLength,
1087 wchLocalName[ 0] = stCancelConn.LocalName;
1089 wchLocalName[ 1] = L':';
1091 wchLocalName[ 2] = L'\0';
1093 StringCchCatW( uniConnectionName.Buffer,
1094 uniConnectionName.MaximumLength,
1097 pwchLocalName = wchLocalName;
1102 StringCchCatW( uniConnectionName.Buffer,
1103 uniConnectionName.MaximumLength,
1106 pwchLocalName = lpName;
1109 StringCchCatW( uniConnectionName.Buffer,
1110 uniConnectionName.MaximumLength,
1113 if( !DefineDosDevice( DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE,
1115 uniConnectionName.Buffer))
1118 #ifdef AFS_DEBUG_TRACE
1119 DWORD gle = GetLastError();
1121 AFSDbgPrint( L"NPCancelConnection Failed to cancel connection to system - gle 0x%x Name %s connection %wZ\n",
1124 &uniConnectionName);
1129 #ifdef AFS_DEBUG_TRACE
1131 AFSDbgPrint( L"NPCancelConnection Canceled connection to system - Name %s connection %wZ\n",
1133 &uniConnectionName);
1140 if ( hControlDevice != NULL)
1143 CloseHandle( hControlDevice);
1147 if( pConnectCB != NULL)
1150 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1160 NPGetConnection( LPWSTR lpLocalName,
1161 LPWSTR lpRemoteName,
1162 LPDWORD lpBufferSize)
1165 return NPGetConnectionCommon( lpLocalName,
1173 NPGetConnectionCommon( LPWSTR lpLocalName,
1174 LPWSTR lpRemoteName,
1175 LPDWORD lpBufferSize,
1179 DWORD dwStatus = WN_NOT_CONNECTED;
1180 WCHAR wchLocalName[3];
1181 WCHAR wchSubstName[MAX_PATH + 1];
1182 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1184 DWORD dwBufferSize = 0;
1185 HANDLE hControlDevice = NULL;
1191 if ( NPIsFSDisabled())
1194 #ifdef AFS_DEBUG_TRACE
1195 AFSDbgPrint( L"NPGetConnection AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1198 try_return( dwStatus = WN_NOT_CONNECTED);
1201 if( lstrlen( lpLocalName) == 0)
1203 #ifdef AFS_DEBUG_TRACE
1204 AFSDbgPrint( L"NPGetConnection No local name, returning WN_BAD_LOCALNAME\n");
1206 try_return( dwStatus = WN_BAD_LOCALNAME);
1209 if ( lpBufferSize == NULL)
1211 #ifdef AFS_DEBUG_TRACE
1212 AFSDbgPrint( L"NPGetConnection No output size, returning WN_BAD_LOCALNAME\n");
1214 try_return( dwStatus = WN_BAD_VALUE);
1217 dwPassedSize = *lpBufferSize;
1219 if ( !bDriveSubstOk ||
1220 !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName)))
1222 wchLocalName[0] = towupper(lpLocalName[0]);
1223 wchLocalName[1] = L':';
1224 wchLocalName[2] = L'\0';
1226 #ifdef AFS_DEBUG_TRACE
1227 AFSDbgPrint( L"NPGetConnection Requesting connection for %s\n",
1233 ReadServerNameString();
1235 if ( wchSubstName[0] != L'\\' &&
1236 wchSubstName[1] == L':')
1239 wchLocalName[0] = towupper(wchSubstName[0]);
1240 wchLocalName[1] = L':';
1241 wchLocalName[2] = L'\0';
1243 #ifdef AFS_DEBUG_TRACE
1244 AFSDbgPrint( L"NPGetConnection Requesting connection for drive substitution %s -> %s\n",
1249 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
1250 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
1251 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
1256 DWORD dwRequiredSize;
1258 #ifdef AFS_DEBUG_TRACE
1259 AFSDbgPrint( L"NPGetConnection drive substitution %s is AFS\n",
1263 dwRequiredSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
1265 if ( lpRemoteName == NULL ||
1266 dwPassedSize == 0 ||
1267 dwRequiredSize > *lpBufferSize)
1270 *lpBufferSize = dwRequiredSize;
1272 try_return( dwStatus = WN_MORE_DATA);
1276 hr = StringCbCopyN(lpRemoteName, *lpBufferSize, wchSubstName, sizeof( wchSubstName));
1281 for ( dwCount = 0, pwch = lpRemoteName; *pwch && pwch < lpRemoteName + (*lpBufferSize); pwch++ )
1283 if ( *pwch == L'\\' )
1297 *lpBufferSize = wcslen( lpRemoteName) * sizeof( WCHAR) + sizeof( WCHAR);
1299 try_return( dwStatus = WN_SUCCESS);
1301 else if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER)
1304 *lpBufferSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
1306 for ( dwCount = 0, pwch = lpRemoteName; *pwch; pwch++ )
1308 if ( *pwch == L'\\' )
1316 *lpBufferSize = wcslen( lpRemoteName) * sizeof( WCHAR) + sizeof( WCHAR);
1318 try_return( dwStatus = WN_SUCCESS);
1324 try_return( dwStatus = WN_MORE_DATA);
1329 #ifdef AFS_DEBUG_TRACE
1330 AFSDbgPrint( L"NPGetConnection StringCbCopyN failure 0x%X\n",
1333 try_return( dwStatus = WN_NET_ERROR);
1339 #ifdef AFS_DEBUG_TRACE
1340 AFSDbgPrint( L"NPGetConnection drive substitution %s is not AFS\n",
1343 try_return( dwStatus = WN_NOT_CONNECTED);
1347 #ifdef AFS_DEBUG_TRACE
1348 AFSDbgPrint( L"NPGetConnection Requesting connection for %s\n",
1352 dwBufferSize = 0x1000;
1354 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1356 if( pConnectCB == NULL)
1359 try_return( dwStatus = WN_OUT_OF_MEMORY);
1362 pConnectCB->LocalName = towupper(wchLocalName[0]);
1364 pConnectCB->RemoteNameLength = 0;
1366 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1368 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1370 #ifdef AFS_DEBUG_TRACE
1371 AFSDbgPrint( L"NPGetConnection Retrieved authentication id %08lX-%08lX\n",
1372 pConnectCB->AuthenticationId.HighPart,
1373 pConnectCB->AuthenticationId.LowPart);
1376 hControlDevice = OpenRedirector();
1378 if( hControlDevice == NULL)
1381 #ifdef AFS_DEBUG_TRACE
1382 AFSDbgPrint( L"NPGetConnection OpenRedirector failure, returning WN_NET_ERROR\n");
1385 try_return( dwStatus = WN_NET_ERROR);
1388 dwError = DeviceIoControl( hControlDevice,
1389 IOCTL_AFS_GET_CONNECTION,
1399 #ifdef AFS_DEBUG_TRACE
1400 DWORD gle = GetLastError();
1402 AFSDbgPrint( L"NPGetConnection Failed to get connection from file system for local %s gle 0x%x\n",
1405 try_return( dwStatus = WN_NOT_CONNECTED);
1409 // IOCTL_AFS_GET_CONNECTION returns a counted string
1412 if( lpRemoteName == NULL ||
1413 *lpBufferSize + sizeof( WCHAR) > dwPassedSize)
1416 *lpBufferSize += sizeof( WCHAR);
1418 try_return( dwStatus = WN_MORE_DATA);
1421 memcpy( lpRemoteName,
1425 lpRemoteName[ *lpBufferSize/sizeof( WCHAR)] = L'\0';
1427 *lpBufferSize += sizeof( WCHAR);
1429 #ifdef AFS_DEBUG_TRACE
1430 AFSDbgPrint( L"NPGetConnection local %s remote %s\n",
1434 dwStatus = WN_SUCCESS;
1438 if ( hControlDevice != NULL)
1441 CloseHandle( hControlDevice);
1444 if( pConnectCB != NULL)
1447 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1456 NPGetConnection3( IN LPCWSTR lpLocalName,
1458 OUT LPVOID lpBuffer,
1459 IN OUT LPDWORD lpBufferSize)
1462 DWORD dwStatus = WN_NOT_CONNECTED;
1463 WCHAR wchLocalName[3];
1464 WCHAR wchSubstName[MAX_PATH + 1];
1465 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1467 DWORD dwBufferSize = 0;
1468 HANDLE hControlDevice = NULL;
1470 DWORD *pConnectState =(DWORD *)lpBuffer;
1475 if ( NPIsFSDisabled())
1478 #ifdef AFS_DEBUG_TRACE
1479 AFSDbgPrint( L"NPGetConnection3 AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1482 try_return( dwStatus = WN_NOT_CONNECTED);
1485 if( lstrlen( lpLocalName) == 0)
1487 #ifdef AFS_DEBUG_TRACE
1488 AFSDbgPrint( L"NPGetConnection3 No local name, returning WN_BAD_LOCALNAME\n");
1490 try_return( dwStatus = WN_BAD_LOCALNAME);
1494 // LanMan NPGetConnection3 only responds to level 1
1497 if ( dwLevel != 0x1)
1499 #ifdef AFS_DEBUG_TRACE
1500 AFSDbgPrint( L"NPGetConnection3 Level 0x%X returning WN_BAD_LEVEL\n", dwLevel);
1502 try_return( dwStatus = WN_BAD_LEVEL);
1505 if ( lpBufferSize == NULL)
1507 #ifdef AFS_DEBUG_TRACE
1508 AFSDbgPrint( L"NPGetConnection3 No output size, returning WN_BAD_VALUE\n");
1510 try_return( dwStatus = WN_BAD_VALUE);
1513 dwPassedSize = *lpBufferSize;
1515 if ( dwPassedSize == 0 ||
1519 *lpBufferSize = sizeof( DWORD);
1521 try_return( dwStatus = WN_MORE_DATA);
1524 if ( !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName)))
1526 wchLocalName[0] = towupper(lpLocalName[0]);
1527 wchLocalName[1] = L':';
1528 wchLocalName[2] = L'\0';
1530 #ifdef AFS_DEBUG_TRACE
1531 AFSDbgPrint( L"NPGetConnection3 Requesting connection for %s level 0x%X\n",
1539 ReadServerNameString();
1541 if ( wchSubstName[0] != L'\\' &&
1542 wchSubstName[1] == L':')
1545 wchLocalName[0] = towupper(wchSubstName[0]);
1546 wchLocalName[1] = L':';
1547 wchLocalName[2] = L'\0';
1549 #ifdef AFS_DEBUG_TRACE
1550 AFSDbgPrint( L"NPGetConnection3 Requesting connection for drive substitution %s -> %s level 0x%x\n",
1556 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
1557 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
1558 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
1561 #ifdef AFS_DEBUG_TRACE
1562 AFSDbgPrint( L"NPGetConnection3 drive substitution %s is AFS return connected\n",
1565 *pConnectState = WNGETCON_CONNECTED;
1567 *lpBufferSize = sizeof( DWORD);
1569 try_return( dwStatus = WN_SUCCESS);
1574 #ifdef AFS_DEBUG_TRACE
1575 AFSDbgPrint( L"NPGetConnection3 drive substitution %s is not AFS return not connected\n",
1578 try_return( dwStatus = WN_NOT_CONNECTED);
1582 dwBufferSize = 0x1000;
1584 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1586 if( pConnectCB == NULL)
1589 try_return( dwStatus = WN_OUT_OF_MEMORY);
1592 pConnectCB->LocalName = towupper(wchLocalName[0]);
1594 pConnectCB->RemoteNameLength = 0;
1596 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1598 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1600 #ifdef AFS_DEBUG_TRACE
1601 AFSDbgPrint( L"NPGetConnection3 Retrieved authentication id %08lX-%08lX\n",
1602 pConnectCB->AuthenticationId.HighPart,
1603 pConnectCB->AuthenticationId.LowPart);
1606 hControlDevice = OpenRedirector();
1608 if( hControlDevice == NULL)
1611 #ifdef AFS_DEBUG_TRACE
1612 AFSDbgPrint( L"NPGetConnection3 OpenRedirector failure, returning WN_NET_ERROR\n");
1615 try_return( dwStatus = WN_NET_ERROR);
1618 dwError = DeviceIoControl( hControlDevice,
1619 IOCTL_AFS_GET_CONNECTION,
1629 #ifdef AFS_DEBUG_TRACE
1630 DWORD gle = GetLastError();
1632 AFSDbgPrint( L"NPGetConnection3 Failed to get connection from file system for local %s gle 0x%x\n",
1635 try_return( dwStatus = WN_NOT_CONNECTED);
1638 *lpBufferSize = sizeof( DWORD);
1640 if( sizeof( DWORD) > dwPassedSize)
1643 try_return( dwStatus = WN_MORE_DATA);
1646 *pConnectState = WNGETCON_CONNECTED;
1648 #ifdef AFS_DEBUG_TRACE
1649 AFSDbgPrint( L"NPGetConnection3 local %s connect-state 0x%x\n",
1653 dwStatus = WN_SUCCESS;
1657 if ( hControlDevice != NULL)
1660 CloseHandle( hControlDevice);
1663 if( pConnectCB != NULL)
1666 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1675 NPGetConnectionPerformance( LPCWSTR lpRemoteName,
1676 LPNETCONNECTINFOSTRUCT lpNetConnectInfo)
1679 DWORD dwReturn = WN_SUCCESS;
1680 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1681 DWORD dwBufferSize = 0;
1682 HANDLE hControlDevice = NULL;
1688 if ( NPIsFSDisabled())
1691 #ifdef AFS_DEBUG_TRACE
1692 AFSDbgPrint( L"NPGetConnectionPerformance AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
1695 return WN_NO_NETWORK;
1698 AFSDbgPrint( L"NPGetConnectionPerformance Entry for remote connection %S\n",
1701 dwBufferSize = 0x1000;
1703 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1705 if( pConnectCB == NULL)
1707 try_return( dwReturn = WN_OUT_OF_MEMORY);
1710 pConnectCB->RemoteNameLength = wcslen( lpRemoteName) * sizeof( WCHAR);
1712 StringCbCopy( pConnectCB->RemoteName,
1713 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
1716 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1718 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1720 hControlDevice = OpenRedirector();
1722 if( hControlDevice == NULL)
1724 AFSDbgPrint( L"NPGetConnectionPerformance OpenRedirector failure, returning WN_NET_ERROR\n");
1726 try_return( dwReturn = WN_NET_ERROR);
1729 dwError = DeviceIoControl( hControlDevice,
1730 IOCTL_AFS_GET_CONNECTION_INFORMATION,
1740 #ifdef AFS_DEBUG_TRACE
1741 DWORD gle = GetLastError();
1743 AFSDbgPrint( L"NPGetConnectionPerformance Failed to get connection info from file system for remote %S gle 0x%x\n",
1747 try_return( dwReturn = WN_NOT_CONNECTED);
1750 lpNetConnectInfo->dwFlags = WNCON_DYNAMIC;
1752 lpNetConnectInfo->dwSpeed = 500;
1754 lpNetConnectInfo->dwDelay = 0;
1756 lpNetConnectInfo->dwOptDataSize = 0x1000;
1758 AFSDbgPrint( L"NPGetConnectionPerformance Successfully returned information for remote connection %S\n",
1763 if ( hControlDevice != NULL)
1765 CloseHandle( hControlDevice);
1768 if( pConnectCB != NULL)
1770 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1778 GetUsageString( DWORD dwUsage)
1780 static WCHAR Buffer[128] = L"";
1782 // RESOURCEUSAGE_CONNECTABLE 0x00000001
1783 // RESOURCEUSAGE_CONTAINER 0x00000002
1784 // RESOURCEUSAGE_NOLOCALDEVICE 0x00000004
1785 // RESOURCEUSAGE_SIBLING 0x00000008
1786 // RESOURCEUSAGE_ATTACHED 0x00000010
1787 // RESOURCEUSAGE_ALL (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED)
1788 // RESOURCEUSAGE_RESERVED 0x80000000
1793 if ( dwUsage == RESOURCEUSAGE_ALL )
1803 if ( dwUsage & RESOURCEUSAGE_CONNECTABLE )
1805 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTABLE|");
1808 if ( dwUsage & RESOURCEUSAGE_CONTAINER )
1810 StringCbCat( Buffer, sizeof(Buffer), L"CONTAINER|");
1813 if ( dwUsage & RESOURCEUSAGE_NOLOCALDEVICE )
1815 StringCbCat( Buffer, sizeof(Buffer), L"NOLOCALDEVICE|");
1818 if ( dwUsage & RESOURCEUSAGE_SIBLING )
1820 StringCbCat( Buffer, sizeof(Buffer), L"SIBLING|");
1823 if ( dwUsage & RESOURCEUSAGE_ATTACHED )
1825 StringCbCat( Buffer, sizeof(Buffer), L"ATTACHED|");
1828 if ( dwUsage & RESOURCEUSAGE_RESERVED )
1830 StringCbCat( Buffer, sizeof(Buffer), L"RESERVED|");
1833 if ( dwUsage & ~(RESOURCEUSAGE_ALL|RESOURCEUSAGE_NOLOCALDEVICE|RESOURCEUSAGE_SIBLING|RESOURCEUSAGE_RESERVED) )
1835 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
1838 Buffer[lstrlen(Buffer)-1] = L'\0';
1844 GetTypeString( DWORD dwType)
1846 static WCHAR Buffer[128] = L"";
1849 // RESOURCETYPE_ANY 0x00000000
1850 // RESOURCETYPE_DISK 0x00000001
1851 // RESOURCETYPE_PRINT 0x00000002
1852 // RESOURCETYPE_RESERVED 0x00000008
1853 // RESOURCETYPE_UNKNOWN 0xFFFFFFFF
1858 if ( dwType == RESOURCETYPE_ANY )
1863 if ( dwType == RESOURCETYPE_UNKNOWN )
1868 if ( dwType & RESOURCETYPE_DISK )
1870 StringCbCat( Buffer, sizeof(Buffer), L"DISK|");
1873 if ( dwType & RESOURCETYPE_PRINT )
1875 StringCbCat( Buffer, sizeof(Buffer), L"PRINT|");
1878 if ( dwType & RESOURCETYPE_RESERVED )
1880 StringCbCat( Buffer, sizeof(Buffer), L"RESERVED|");
1883 if ( dwType & ~(RESOURCETYPE_DISK|RESOURCETYPE_PRINT|RESOURCETYPE_RESERVED) )
1885 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
1888 Buffer[lstrlen(Buffer)-1] = L'\0';
1894 GetScopeString( DWORD dwScope)
1896 static WCHAR Buffer[128] = L"";
1899 // RESOURCE_CONNECTED 0x00000001
1900 // RESOURCE_GLOBALNET 0x00000002
1901 // RESOURCE_REMEMBERED 0x00000003
1902 // RESOURCE_RECENT 0x00000004
1903 // RESOURCE_CONTEXT 0x00000005
1908 if ( dwScope == RESOURCE_CONNECTED )
1910 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTED|");
1913 if ( dwScope == RESOURCE_GLOBALNET )
1915 StringCbCat( Buffer, sizeof(Buffer), L"GLOBALNET|");
1918 if ( dwScope == RESOURCE_REMEMBERED )
1920 StringCbCat( Buffer, sizeof(Buffer), L"REMEMBERED|");
1923 if ( dwScope == RESOURCE_RECENT )
1925 StringCbCat( Buffer, sizeof(Buffer), L"RECENT|");
1928 if ( dwScope == RESOURCE_CONTEXT )
1930 StringCbCat( Buffer, sizeof(Buffer), L"CONTEXT|");
1933 if ( dwScope & ~(RESOURCE_CONNECTED|RESOURCE_GLOBALNET|RESOURCE_REMEMBERED|RESOURCE_RECENT|RESOURCE_CONTEXT) )
1935 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
1938 Buffer[lstrlen(Buffer)-1] = L'\0';
1944 GetDisplayString( DWORD dwDisplay)
1947 // RESOURCEDISPLAYTYPE_GENERIC 0x00000000
1948 // RESOURCEDISPLAYTYPE_DOMAIN 0x00000001
1949 // RESOURCEDISPLAYTYPE_SERVER 0x00000002
1950 // RESOURCEDISPLAYTYPE_SHARE 0x00000003
1951 // RESOURCEDISPLAYTYPE_FILE 0x00000004
1952 // RESOURCEDISPLAYTYPE_GROUP 0x00000005
1953 // RESOURCEDISPLAYTYPE_NETWORK 0x00000006
1954 // RESOURCEDISPLAYTYPE_ROOT 0x00000007
1955 // RESOURCEDISPLAYTYPE_SHAREADMIN 0x00000008
1956 // RESOURCEDISPLAYTYPE_DIRECTORY 0x00000009
1957 // RESOURCEDISPLAYTYPE_TREE 0x0000000A
1958 // RESOURCEDISPLAYTYPE_NDSCONTAINER 0x0000000B
1961 switch ( dwDisplay ) {
1962 case RESOURCEDISPLAYTYPE_GENERIC:
1964 case RESOURCEDISPLAYTYPE_DOMAIN:
1966 case RESOURCEDISPLAYTYPE_SERVER:
1968 case RESOURCEDISPLAYTYPE_SHARE:
1970 case RESOURCEDISPLAYTYPE_FILE:
1972 case RESOURCEDISPLAYTYPE_GROUP:
1974 case RESOURCEDISPLAYTYPE_NETWORK:
1976 case RESOURCEDISPLAYTYPE_ROOT:
1978 case RESOURCEDISPLAYTYPE_SHAREADMIN:
1979 return L"SHAREADMIN";
1980 case RESOURCEDISPLAYTYPE_DIRECTORY:
1981 return L"DIRECTORY";
1982 case RESOURCEDISPLAYTYPE_TREE:
1984 case RESOURCEDISPLAYTYPE_NDSCONTAINER:
1985 return L"NDSCONTAINER";
1993 NPOpenEnum( DWORD dwScope,
1996 LPNETRESOURCE lpNetResource,
2000 DWORD dwStatus = WN_SUCCESS;
2001 AFSEnumerationCB *pEnumCB = NULL;
2003 #ifdef AFS_DEBUG_TRACE
2004 if ( lpNetResource == NULL)
2006 AFSDbgPrint( L"NPOpenEnum Scope %s Type %s Usage %s NetResource: (Null)\n",
2007 GetScopeString(dwScope), GetTypeString(dwType), GetUsageString(dwUsage));
2011 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",
2012 GetScopeString(dwScope),
2013 GetTypeString(dwType),
2014 GetUsageString(dwUsage),
2016 GetScopeString(lpNetResource->dwScope),
2017 GetTypeString(lpNetResource->dwType),
2018 GetDisplayString(lpNetResource->dwDisplayType),
2019 GetUsageString(lpNetResource->dwUsage),
2020 lpNetResource->lpLocalName,
2021 lpNetResource->lpRemoteName,
2022 lpNetResource->lpComment);
2028 dwUsage = RESOURCEUSAGE_ALL;
2032 if ( dwType == 0 || dwType == RESOURCEUSAGE_ATTACHED)
2034 dwType |= RESOURCETYPE_DISK | RESOURCETYPE_PRINT;
2038 *lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( AFSEnumerationCB));
2040 if( *lphEnum == NULL)
2043 return WN_OUT_OF_MEMORY;
2046 pEnumCB = (AFSEnumerationCB *)*lphEnum;
2048 pEnumCB->CurrentIndex = 0;
2050 pEnumCB->Type = dwType;
2054 case RESOURCE_CONNECTED:
2057 pEnumCB->Scope = RESOURCE_CONNECTED;
2062 case RESOURCE_CONTEXT:
2065 pEnumCB->Scope = RESOURCE_CONTEXT;
2070 case RESOURCE_GLOBALNET:
2073 if( lpNetResource != NULL &&
2074 lpNetResource->lpRemoteName != NULL)
2077 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2079 if( pEnumCB->RemoteName == NULL)
2082 dwStatus = WN_OUT_OF_MEMORY;
2083 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2089 StringCbCopy( pEnumCB->RemoteName,
2091 lpNetResource->lpRemoteName);
2096 pEnumCB->Scope = RESOURCE_GLOBALNET;
2103 #ifdef AFS_DEBUG_TRACE
2104 AFSDbgPrint( L"NPOpenEnum Processing (Scope %s 0x%x) Type %s Usage %s, returning WN_NOT_SUPPORTED\n",
2105 GetScopeString(dwScope), dwScope, GetTypeString(dwType), GetUsageString(dwUsage));
2108 dwStatus = WN_NOT_SUPPORTED;
2109 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2121 NPEnumResource( HANDLE hEnum,
2124 LPDWORD lpBufferSize)
2127 DWORD dwStatus = WN_NO_MORE_ENTRIES; //WN_SUCCESS;
2129 ULONG EntriesCopied;
2130 ULONG EntriesRequested;
2132 LPNETRESOURCE pNetResource;
2134 ULONG SpaceAvailable;
2136 AFSNetworkProviderConnectionCB *pConnectionCB = NULL;
2137 void *pConnectionCBBase = NULL;
2139 UNICODE_STRING uniRemoteName;
2140 HANDLE hControlDevice = NULL;
2141 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2146 if ( lpBufferSize == NULL)
2148 #ifdef AFS_DEBUG_TRACE
2149 AFSDbgPrint( L"NPEnumResource No output size, returning WN_BAD_VALUE\n");
2151 try_return( dwStatus = WN_BAD_VALUE);
2154 ReadProviderNameString();
2156 pNetResource = (LPNETRESOURCE) lpBuffer;
2157 SpaceAvailable = *lpBufferSize;
2158 EntriesRequested = *lpcCount;
2159 *lpcCount = EntriesCopied = 0;
2160 StringZone = (PWCHAR) ((char *)lpBuffer + *lpBufferSize);
2162 #ifdef AFS_DEBUG_TRACE
2163 AFSDbgPrint( L"NPEnumResource Processing Remote name %s Scope %s Type %s Usage %s Index %d SpaceAvailable 0x%lX RequestedEntries %lu\n",
2164 pEnumCB->RemoteName ? pEnumCB->RemoteName : L"(Null)",
2165 GetScopeString(pEnumCB->Scope),
2166 GetTypeString(pEnumCB->Type),
2167 GetUsageString(pEnumCB->Type),
2168 pEnumCB->CurrentIndex,
2173 if ( NPIsFSDisabled())
2176 #ifdef AFS_DEBUG_TRACE
2177 AFSDbgPrint( L"NPEnumResource AFSRDFS is disabled, returning WN_NO_MORE_ENTRIES\n");
2180 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2183 pConnectionCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 0x1000);
2185 if( pConnectionCB == NULL)
2188 #ifdef AFS_DEBUG_TRACE
2189 AFSDbgPrint( L"NPEnumResource Out of Memory\n");
2192 try_return( dwStatus = WN_OUT_OF_MEMORY);
2195 pConnectionCBBase = (void *)pConnectionCB;
2197 hControlDevice = OpenRedirector();
2199 if( hControlDevice == NULL)
2202 #ifdef AFS_DEBUG_TRACE
2203 AFSDbgPrint( L"NPEnumResource OpenRedirector failure, returning WN_NET_ERROR\n");
2206 try_return( dwStatus = WN_NET_ERROR);
2209 if( pEnumCB->Type != RESOURCETYPE_ANY && pEnumCB->Type != RESOURCETYPE_DISK)
2212 #ifdef AFS_DEBUG_TRACE
2213 AFSDbgPrint( L"NPEnumResource Non-DISK queries are not supported, returning WN_NO_MORE_ENTRIES\n");
2215 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2219 // Handle the special cases here
2220 // 0. Provider Network Root
2225 if ( pEnumCB->Scope == RESOURCE_GLOBALNET)
2228 ReadServerNameString();
2230 if ( pEnumCB->CurrentIndex == 0 &&
2231 pEnumCB->RemoteName == NULL)
2234 // Determine the space needed for this entry...
2236 SpaceNeeded = 2 * ( cbProviderNameLength + sizeof( WCHAR));
2238 uniRemoteName.Length = (USHORT)cbProviderNameLength;
2239 uniRemoteName.MaximumLength = uniRemoteName.Length;
2240 uniRemoteName.Buffer = wszProviderName;
2242 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2245 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2247 #ifdef AFS_DEBUG_TRACE
2248 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2252 try_return( dwStatus = WN_MORE_DATA);
2255 #ifdef AFS_DEBUG_TRACE
2256 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2260 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2262 pNetResource->dwScope = RESOURCE_GLOBALNET;
2263 pNetResource->dwType = RESOURCETYPE_ANY;
2264 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_NETWORK;
2265 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_RESERVED;
2267 // setup string area at opposite end of buffer
2268 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2270 pNetResource->lpLocalName = NULL;
2273 pNetResource->lpRemoteName = StringZone;
2275 StringCbCopy( StringZone,
2276 cbProviderNameLength + sizeof( WCHAR),
2279 StringZone += cbProviderNameLength / sizeof(WCHAR) + 1;
2281 pNetResource->lpComment = NULL;
2283 // copy provider name
2284 pNetResource->lpProvider = StringZone;
2285 StringCbCopy( StringZone,
2286 cbProviderNameLength + sizeof( WCHAR),
2289 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2291 #ifdef AFS_DEBUG_TRACE
2292 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2294 GetScopeString(pNetResource->dwScope),
2295 GetTypeString(pNetResource->dwType),
2296 GetDisplayString(pNetResource->dwDisplayType),
2297 GetUsageString(pNetResource->dwUsage),
2298 pNetResource->lpLocalName,
2299 pNetResource->lpRemoteName,
2300 pNetResource->lpComment);
2303 // setup the new end of buffer
2304 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2310 // do not change the index since we did not query the redirector
2311 pEnumCB->CurrentIndex = 0;
2313 // remember that we returned the provider name
2314 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2316 if( pEnumCB->RemoteName == NULL)
2319 try_return( dwStatus = WN_OUT_OF_MEMORY);
2324 StringCbCopy( pEnumCB->RemoteName,
2330 if ( pEnumCB->CurrentIndex == 0 &&
2331 lstrlen( pEnumCB->RemoteName) == cbProviderNameLength / sizeof( WCHAR) &&
2332 _wcsnicmp( pEnumCB->RemoteName, wszProviderName, cbProviderNameLength / sizeof( WCHAR)) == 0 &&
2333 EntriesCopied < EntriesRequested)
2337 // After the network provider entry comes the server entry
2340 // Determine the space needed for this entry...
2342 SpaceNeeded = cbProviderNameLength + cbServerNameUNCLength + cbServerCommentLength + 3 * sizeof( WCHAR);
2344 uniRemoteName.Length = (USHORT)cbServerNameUNCLength;
2345 uniRemoteName.MaximumLength = uniRemoteName.Length;
2346 uniRemoteName.Buffer = wszServerNameUNC;
2348 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2351 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2353 #ifdef AFS_DEBUG_TRACE
2354 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2358 try_return( dwStatus = WN_MORE_DATA);
2361 #ifdef AFS_DEBUG_TRACE
2362 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2366 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2368 pNetResource->dwScope = 0;
2369 pNetResource->dwType = RESOURCETYPE_ANY;
2370 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
2371 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
2373 // setup string area at opposite end of buffer
2374 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2376 pNetResource->lpLocalName = NULL;
2379 pNetResource->lpRemoteName = StringZone;
2381 StringCbCopy( StringZone,
2382 cbServerNameUNCLength + sizeof( WCHAR),
2385 StringZone += cbServerNameUNCLength / sizeof(WCHAR) + 1;
2388 pNetResource->lpComment = StringZone;
2390 StringCbCopy( StringZone,
2391 cbServerCommentLength + sizeof( WCHAR),
2394 StringZone += cbServerCommentLength / sizeof( WCHAR) + 1;
2396 // copy provider name
2397 pNetResource->lpProvider = StringZone;
2398 StringCbCopy( StringZone,
2399 cbProviderNameLength + sizeof( WCHAR),
2402 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2404 #ifdef AFS_DEBUG_TRACE
2405 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2407 GetScopeString(pNetResource->dwScope),
2408 GetTypeString(pNetResource->dwType),
2409 GetDisplayString(pNetResource->dwDisplayType),
2410 GetUsageString(pNetResource->dwUsage),
2411 pNetResource->lpLocalName,
2412 pNetResource->lpRemoteName,
2413 pNetResource->lpComment);
2416 // setup the new end of buffer
2417 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2423 // do not update the index because we did not query the redirector
2424 pEnumCB->CurrentIndex = 0;
2426 // remember that we returned the server
2427 StringCbCopy( pEnumCB->RemoteName,
2435 // Setup what we are going to ask for
2438 pConnectionCB->Scope = pEnumCB->Scope;
2440 pConnectionCB->Type = pEnumCB->Type;
2442 pConnectionCB->CurrentIndex = pEnumCB->CurrentIndex;
2444 pConnectionCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
2447 // If this is a RESOURCE_GLOBALNET enumeration then pass down the remote name if
2451 pConnectionCB->RemoteNameLength = 0;
2453 if( pEnumCB->Scope == RESOURCE_GLOBALNET &&
2454 pEnumCB->RemoteName != NULL)
2457 pConnectionCB->RemoteNameLength = wcslen( pEnumCB->RemoteName) * sizeof( WCHAR);
2459 StringCbCopy( pConnectionCB->RemoteName,
2460 (0x1000 - sizeof(AFSNetworkProviderConnectionCB)) + sizeof(WCHAR),
2461 pEnumCB->RemoteName);
2464 pConnectionCB->AuthenticationId = AFSRetrieveAuthId();
2466 #ifdef AFS_DEBUG_TRACE
2467 AFSDbgPrint( L"NPEnumResource Retrieved authentication id %08lX-%08lX\n",
2468 pConnectionCB->AuthenticationId.HighPart,
2469 pConnectionCB->AuthenticationId.LowPart);
2472 dwError = DeviceIoControl( hControlDevice,
2473 IOCTL_AFS_LIST_CONNECTIONS,
2483 #ifdef AFS_DEBUG_TRACE
2484 DWORD gle = GetLastError();
2486 AFSDbgPrint( L"NPEnumResource Failed to list connections from file system - gle 0x%x\n",
2489 try_return( dwStatus = WN_NOT_CONNECTED);
2492 if( dwCopyBytes == 0)
2495 #ifdef AFS_DEBUG_TRACE
2496 AFSDbgPrint( L"NPEnumResource No More Entries\n");
2498 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2501 dwIndex = pEnumCB->CurrentIndex;
2503 while( EntriesCopied < EntriesRequested)
2506 uniRemoteName.Length = (USHORT)pConnectionCB->RemoteNameLength;
2507 uniRemoteName.MaximumLength = uniRemoteName.Length;
2508 uniRemoteName.Buffer = pConnectionCB->RemoteName;
2510 // Determine the space needed for this entry...
2514 if( pConnectionCB->LocalName != 0)
2517 SpaceNeeded += 3 * sizeof(WCHAR); // local name
2520 SpaceNeeded += pConnectionCB->RemoteNameLength + sizeof( WCHAR); // remote name
2522 if( pConnectionCB->CommentLength > 0)
2525 SpaceNeeded += pConnectionCB->CommentLength + sizeof( WCHAR); // comment
2528 SpaceNeeded += cbProviderNameLength + sizeof( WCHAR); // provider name
2530 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2533 if (EntriesCopied == 0) {
2535 dwStatus = WN_MORE_DATA;
2537 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2539 #ifdef AFS_DEBUG_TRACE
2540 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2547 #ifdef AFS_DEBUG_TRACE
2548 AFSDbgPrint( L"NPEnumResource Return SUCCESS but more entries Index %d\n",
2552 dwStatus = WN_SUCCESS;
2558 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2560 pNetResource->dwScope = pConnectionCB->Scope;
2561 pNetResource->dwType = pConnectionCB->Type;
2563 pNetResource->dwDisplayType = pConnectionCB->DisplayType;
2565 if ( pNetResource->dwType == RESOURCETYPE_ANY &&
2566 pNetResource->dwDisplayType == RESOURCEDISPLAYTYPE_SHARE)
2569 pNetResource->dwType = RESOURCETYPE_DISK;
2572 if ( pEnumCB->Scope == RESOURCE_CONNECTED)
2575 pNetResource->dwUsage = 0;
2580 pNetResource->dwUsage = pConnectionCB->Usage;
2583 // setup string area at opposite end of buffer
2584 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2587 if( pConnectionCB->LocalName != 0)
2590 pNetResource->lpLocalName = StringZone;
2591 *StringZone++ = towupper(pConnectionCB->LocalName);
2592 *StringZone++ = L':';
2593 *StringZone++ = L'\0';
2598 pNetResource->lpLocalName = NULL;
2601 #ifdef AFS_DEBUG_TRACE
2602 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2607 pNetResource->lpRemoteName = StringZone;
2609 CopyMemory( StringZone,
2610 pConnectionCB->RemoteName,
2611 pConnectionCB->RemoteNameLength);
2613 StringZone += (pConnectionCB->RemoteNameLength / sizeof(WCHAR));
2615 *StringZone++ = L'\0';
2618 if( pConnectionCB->CommentLength > 0)
2621 pNetResource->lpComment = StringZone;
2623 CopyMemory( StringZone,
2624 (void *)((char *)pConnectionCB + pConnectionCB->CommentOffset),
2625 pConnectionCB->CommentLength);
2627 StringZone += (pConnectionCB->CommentLength / sizeof(WCHAR));
2629 *StringZone++ = L'\0';
2634 pNetResource->lpComment = NULL;
2637 // copy provider name
2638 pNetResource->lpProvider = StringZone;
2639 StringCbCopy( StringZone,
2640 cbProviderNameLength + sizeof( WCHAR),
2643 StringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
2645 #ifdef AFS_DEBUG_TRACE
2646 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2648 GetScopeString(pNetResource->dwScope),
2649 GetTypeString(pNetResource->dwType),
2650 GetDisplayString(pNetResource->dwDisplayType),
2651 GetUsageString(pNetResource->dwUsage),
2652 pNetResource->lpLocalName,
2653 pNetResource->lpRemoteName,
2654 pNetResource->lpComment);
2657 // setup the new end of buffer
2658 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2666 dwCopyBytes -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2667 pConnectionCB->RemoteNameLength +
2668 pConnectionCB->CommentLength;
2670 if( dwCopyBytes == 0)
2673 dwStatus = WN_SUCCESS;
2678 pConnectionCB = (AFSNetworkProviderConnectionCB *)((char *)pConnectionCB +
2679 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2680 pConnectionCB->RemoteNameLength +
2681 pConnectionCB->CommentLength);
2684 *lpcCount = EntriesCopied;
2686 // update entry index
2687 pEnumCB->CurrentIndex = dwIndex;
2689 #ifdef AFS_DEBUG_TRACE
2690 AFSDbgPrint( L"NPEnumResource Completed Count %d Index %d\n",
2697 if ( hControlDevice != NULL)
2700 CloseHandle( hControlDevice);
2703 if( pConnectionCBBase != NULL)
2706 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectionCBBase);
2715 Routine Description:
2717 This routine closes the handle for enumeration of resources.
2721 hEnum - the enumeration handle
2725 WN_SUCCESS if successful, otherwise the appropriate error
2729 The sample only supports the notion of enumerating connected shares
2734 NPCloseEnum( HANDLE hEnum )
2737 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2739 #ifdef AFS_DEBUG_TRACE
2740 AFSDbgPrint( L"NPCloseEnum\n");
2743 if( pEnumCB->RemoteName != NULL)
2746 HeapFree( GetProcessHeap( ), 0, (PVOID) pEnumCB->RemoteName);
2749 HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum );
2755 NPGetResourceParent( LPNETRESOURCE lpNetResource,
2757 LPDWORD lpBufferSize )
2760 DWORD dwStatus = WN_ACCESS_DENIED;
2761 WCHAR *pwchRemoteName = NULL, *pwchSearch = NULL, *pwchSystem = NULL;
2762 LPNETRESOURCE lpOutResource = (LPNETRESOURCE) lpBuffer;
2764 if ( lpNetResource == NULL)
2766 #ifdef AFS_DEBUG_TRACE
2767 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2769 return WN_MORE_DATA;
2772 if( lpNetResource->lpRemoteName == NULL)
2774 #ifdef AFS_DEBUG_TRACE
2775 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2777 return WN_BAD_NETNAME;
2780 if ( lpNetResource->dwType != 0 &&
2781 lpNetResource->dwType != RESOURCETYPE_DISK)
2783 #ifdef AFS_DEBUG_TRACE
2784 AFSDbgPrint( L"NPGetResourceParent Bad dwType\n");
2786 return WN_BAD_VALUE;
2789 if ( lpBufferSize == NULL )
2792 #ifdef AFS_DEBUG_TRACE
2793 AFSDbgPrint( L"NPGetResourceParent Null lpBufferSize\n");
2795 return WN_BAD_VALUE;
2798 #ifdef AFS_DEBUG_TRACE
2799 AFSDbgPrint( L"NPGetResourceParent For remote name %s\n",
2800 lpNetResource->lpRemoteName);
2803 pwchRemoteName = lpNetResource->lpRemoteName;
2805 pwchSearch = pwchRemoteName + (wcslen( pwchRemoteName) - 1);
2807 while( pwchSearch != pwchRemoteName)
2810 if( *pwchSearch == L'\\')
2813 *pwchSearch = L'\0';
2821 if( pwchSearch != pwchRemoteName)
2824 #ifdef AFS_DEBUG_TRACE
2825 AFSDbgPrint( L"NPGetResourceParent Processing parent %s\n",
2826 lpNetResource->lpRemoteName);
2829 dwStatus = NPGetResourceInformation( lpNetResource,
2836 if ( lpOutResource == NULL ||
2837 *lpBufferSize < sizeof( NETRESOURCE) )
2839 *lpBufferSize = sizeof( NETRESOURCE);
2841 return WN_MORE_DATA;
2844 memset( lpOutResource, 0, sizeof( NETRESOURCE));
2854 NPGetResourceInformation( LPNETRESOURCE lpNetResource,
2856 LPDWORD lpBufferSize,
2857 LPWSTR *lplpSystem )
2860 DWORD dwStatus = WN_NOT_CONNECTED;
2861 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
2863 DWORD dwBufferSize = 0;
2864 HANDLE hControlDevice = NULL;
2865 NETRESOURCE *pNetResource = (NETRESOURCE *)lpBuffer;
2866 PWCHAR pStringZone = NULL;
2867 UNICODE_STRING uniRemoteName;
2868 DWORD ulRequiredLen = 0;
2879 ReadProviderNameString();
2881 if ( NPIsFSDisabled())
2884 #ifdef AFS_DEBUG_TRACE
2885 AFSDbgPrint( L"NPGetResourceInformation AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
2888 try_return( dwStatus = WN_BAD_NETNAME);
2891 if ( lpNetResource == NULL ||
2892 lpBufferSize == NULL )
2895 #ifdef AFS_DEBUG_TRACE
2896 AFSDbgPrint( L"NPGetResourceInformaton Null lpNetResource or lpBufferSize\n");
2898 return WN_BAD_VALUE;
2901 if( lpNetResource->lpRemoteName == NULL)
2903 #ifdef AFS_DEBUG_TRACE
2904 AFSDbgPrint( L"NPGetResourceInformation No resource name\n");
2907 try_return( dwStatus = WN_NOT_CONNECTED);
2910 dwPassedSize = *lpBufferSize;
2912 dwBufferSize = 0x1000;
2914 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
2916 if( pConnectCB == NULL)
2919 try_return( dwStatus = WN_OUT_OF_MEMORY);
2922 pConnectCB->RemoteNameLength = wcslen( lpNetResource->lpRemoteName) * sizeof( WCHAR);
2924 StringCbCopy( pConnectCB->RemoteName,
2925 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
2926 lpNetResource->lpRemoteName);
2928 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
2930 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
2932 #ifdef AFS_DEBUG_TRACE
2933 AFSDbgPrint( L"NPGetResourceInformation Retrieved authentication id %08lX-%08lX\n",
2934 pConnectCB->AuthenticationId.HighPart,
2935 pConnectCB->AuthenticationId.LowPart);
2938 hControlDevice = OpenRedirector();
2940 if( hControlDevice == NULL)
2943 #ifdef AFS_DEBUG_TRACE
2944 AFSDbgPrint( L"NPGetResourceInformation OpenRedirector failure, returning WN_NET_ERROR\n");
2947 try_return( dwStatus = WN_NET_ERROR);
2950 dwError = DeviceIoControl( hControlDevice,
2951 IOCTL_AFS_GET_CONNECTION_INFORMATION,
2961 #ifdef AFS_DEBUG_TRACE
2962 DWORD gle = GetLastError();
2964 AFSDbgPrint( L"NPGetResourceInformation Failed to get connection info from file system for local %s gle 0x%x\n",
2965 lpNetResource->lpRemoteName, gle);
2967 try_return( dwStatus = WN_BAD_NETNAME);
2970 uniRemoteName.Length = (USHORT)pConnectCB->RemoteNameLength;
2971 uniRemoteName.MaximumLength = uniRemoteName.Length;
2972 uniRemoteName.Buffer = pConnectCB->RemoteName;
2974 #ifdef AFS_DEBUG_TRACE
2975 AFSDbgPrint( L"NPGetResourceInformation For remote name %wZ Scope %08lX Type %08lX Usage %08lX\n",
2982 // Determine the space needed for this entry...
2984 ulRequiredLen = sizeof( NETRESOURCE);
2986 ulRequiredLen += pConnectCB->RemoteNameLength + sizeof( WCHAR);
2988 ulRequiredLen += pConnectCB->CommentLength + sizeof( WCHAR);
2990 ulRequiredLen += cbProviderNameLength + sizeof( WCHAR);
2992 ulRequiredLen += pConnectCB->RemainingPathLength + sizeof( WCHAR);
2994 if( pNetResource == NULL ||
2995 ulRequiredLen > dwPassedSize)
2998 *lpBufferSize = ulRequiredLen;
3000 try_return( dwStatus = WN_MORE_DATA);
3003 pStringZone = (PWCHAR) ((char *)lpBuffer + sizeof( NETRESOURCE));
3005 pNetResource->dwScope = 0 /* pConnectCB->Scope*/;
3006 pNetResource->dwType = 0 /* pConnectCB->Type */;
3008 pNetResource->dwDisplayType = pConnectCB->DisplayType;
3010 pNetResource->dwUsage = pConnectCB->Usage;
3012 pNetResource->lpLocalName = NULL;
3015 pNetResource->lpRemoteName = pStringZone;
3017 CopyMemory( pStringZone,
3018 pConnectCB->RemoteName,
3019 pConnectCB->RemoteNameLength);
3021 pStringZone += (pConnectCB->RemoteNameLength / sizeof(WCHAR));
3023 *pStringZone++ = L'\0';
3026 pNetResource->lpComment = pStringZone;
3028 CopyMemory( pStringZone,
3029 (void *)((char *)pConnectCB + pConnectCB->CommentOffset),
3030 pConnectCB->CommentLength);
3032 pStringZone += (pConnectCB->CommentLength / sizeof(WCHAR));
3034 *pStringZone++ = L'\0';
3036 // copy remaining path
3037 if (pConnectCB->RemainingPathLength > 0)
3039 *lplpSystem = pStringZone;
3041 CopyMemory( pStringZone,
3042 (void *)((char *)pConnectCB + pConnectCB->RemainingPathOffset),
3043 pConnectCB->RemainingPathLength);
3045 pStringZone += (pConnectCB->RemainingPathLength / sizeof(WCHAR));
3047 *pStringZone++ = L'\0';
3049 #ifdef AFS_DEBUG_TRACE
3050 AFSDbgPrint( L"NPGetResourceInformation For remote name %s returning remaining path %s\n",
3051 pNetResource->lpRemoteName,
3056 // copy provider name
3057 pNetResource->lpProvider = pStringZone;
3059 StringCbCopy( pStringZone,
3060 cbProviderNameLength + sizeof( WCHAR),
3063 pStringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
3065 *lpBufferSize = ulRequiredLen;
3067 dwStatus = WN_SUCCESS;
3071 if ( hControlDevice != NULL)
3074 CloseHandle( hControlDevice);
3077 if( pConnectCB != NULL)
3080 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3088 SeparateRemainingPath( WCHAR * lpConnectionName, WCHAR **lppRemainingPath)
3095 // at this point the lpConnectionName contains the full name. We need to
3096 // truncate it to \\server\share and move the remaining path back one position.
3099 for ( pwch = lpConnectionName, dwCount = 0; *pwch; pwch++)
3101 if ( *pwch == L'\\')
3115 // Found the remaining path that must be moved
3118 *lppRemainingPath = pwch + 1;
3125 for ( ; *pwch; pwch++);
3128 // and work backwards moving the string
3129 // and then make sure that there is at least
3130 // a path separator.
3135 for ( ;pwch > *lppRemainingPath; pwch--)
3137 *pwch = *(pwch - 1);
3145 NPGetUniversalName( LPCWSTR lpLocalPath,
3148 LPDWORD lpBufferSize )
3150 DWORD dwStatus = WN_NOT_CONNECTED;
3151 WCHAR wchLocalName[3];
3152 WCHAR wchSubstName[MAX_PATH + 1];
3153 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3155 DWORD dwBufferSize = 0;
3156 DWORD dwPassedSize = *lpBufferSize;
3157 DWORD dwRemainingLength = *lpBufferSize;
3158 HANDLE hControlDevice = NULL;
3159 DWORD dwLocalPathLength = 0;
3160 DWORD dwRemainingPathLength = 0;
3166 #ifdef AFS_DEBUG_TRACE
3167 AFSDbgPrint( L"NPGetUniversalName local path %s level 0x%X\n",
3168 lpLocalPath ? lpLocalPath : L"(Null)",
3172 if ( NPIsFSDisabled())
3175 #ifdef AFS_DEBUG_TRACE
3176 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
3179 try_return( dwStatus = WN_NOT_CONNECTED);
3182 dwLocalPathLength = lstrlen( lpLocalPath);
3184 dwRemainingPathLength = dwLocalPathLength - 2; // no drive letter
3186 if( dwLocalPathLength == 0)
3189 #ifdef AFS_DEBUG_TRACE
3190 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_BAD_LOCALNAME\n");
3193 try_return( dwStatus = WN_BAD_LOCALNAME);
3196 if( lpBuffer == NULL ||
3197 lpBufferSize == NULL)
3199 #ifdef AFS_DEBUG_TRACE
3200 AFSDbgPrint( L"NPGetUniversalName No output buffer or size\n");
3202 try_return( dwStatus = WN_BAD_VALUE);
3205 memset(lpBuffer, 0, dwPassedSize);
3207 if ( !DriveSubstitution( lpLocalPath, wchSubstName, sizeof( wchSubstName)))
3209 wchLocalName[0] = towupper(lpLocalPath[0]);
3210 wchLocalName[1] = L':';
3211 wchLocalName[2] = L'\0';
3213 #ifdef AFS_DEBUG_TRACE
3214 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for %s level 0x%X\n",
3222 ReadServerNameString();
3224 if ( wchSubstName[0] != L'\\' &&
3225 wchSubstName[1] == L':')
3228 wchLocalName[0] = towupper(wchSubstName[0]);
3229 wchLocalName[1] = L':';
3230 wchLocalName[2] = L'\0';
3232 #ifdef AFS_DEBUG_TRACE
3233 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for drive substitution %s -> %s\n",
3238 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
3239 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
3240 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
3244 #ifdef AFS_DEBUG_TRACE
3245 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is AFS; Level 0x%x BufferSize 0x%x\n",
3251 dwBufferSize = (wcslen( wchSubstName) + 1) * sizeof( WCHAR);
3253 switch( dwInfoLevel)
3256 case UNIVERSAL_NAME_INFO_LEVEL:
3259 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3261 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize;
3263 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3266 #ifdef AFS_DEBUG_TRACE
3267 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3270 try_return( dwStatus = WN_MORE_DATA);
3273 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3275 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3277 memcpy( pUniversalInfo->lpUniversalName,
3279 min( dwBufferSize, dwRemainingLength));
3281 dwRemainingLength -= min( dwBufferSize, dwRemainingLength);
3283 #ifdef AFS_DEBUG_TRACE
3284 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3286 pUniversalInfo->lpUniversalName,
3287 pUniversalInfo->lpUniversalName);
3290 if ( dwPassedSize < *lpBufferSize)
3293 try_return( dwStatus = WN_MORE_DATA);
3296 try_return( dwStatus = WN_SUCCESS);
3299 case REMOTE_NAME_INFO_LEVEL:
3302 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3304 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + 2 * dwBufferSize + sizeof( WCHAR);
3306 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3309 #ifdef AFS_DEBUG_TRACE
3310 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3313 try_return( dwStatus = WN_MORE_DATA);
3316 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3318 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3320 memcpy( pRemoteInfo->lpUniversalName,
3322 min( dwRemainingLength, dwBufferSize));
3324 dwRemainingLength -= min( dwRemainingLength, dwBufferSize);
3326 #ifdef AFS_DEBUG_TRACE
3327 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3329 pRemoteInfo->lpUniversalName,
3330 pRemoteInfo->lpUniversalName);
3333 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3335 pRemoteInfo->lpConnectionName = (LPTSTR)((char *)pRemoteInfo->lpUniversalName + dwBufferSize);
3337 memcpy( pRemoteInfo->lpConnectionName,
3339 min( dwRemainingLength, dwBufferSize));
3341 dwRemainingLength -= min( dwRemainingLength, dwBufferSize) - sizeof( WCHAR);
3343 SeparateRemainingPath( pRemoteInfo->lpConnectionName,
3344 &pRemoteInfo->lpRemainingPath);
3347 #ifdef AFS_DEBUG_TRACE
3348 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3350 pRemoteInfo->lpConnectionName,
3351 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3353 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3355 pRemoteInfo->lpRemainingPath,
3356 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3359 if ( dwPassedSize < *lpBufferSize)
3362 try_return( dwStatus = WN_MORE_DATA);
3365 try_return( dwStatus = WN_SUCCESS);
3369 #ifdef AFS_DEBUG_TRACE
3370 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3373 try_return( dwStatus = WN_BAD_VALUE);
3379 #ifdef AFS_DEBUG_TRACE
3380 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is not AFS\n",
3383 try_return( dwStatus = WN_NOT_CONNECTED);
3387 dwBufferSize = 0x1000;
3389 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
3391 if( pConnectCB == NULL)
3393 try_return( dwStatus = WN_OUT_OF_MEMORY);
3396 pConnectCB->LocalName = towupper(wchLocalName[0]);
3398 pConnectCB->RemoteNameLength = 0;
3400 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3402 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
3404 #ifdef AFS_DEBUG_TRACE
3405 AFSDbgPrint( L"NPGetUniversalName Retrieved authentication id %08lX-%08lX\n",
3406 pConnectCB->AuthenticationId.HighPart,
3407 pConnectCB->AuthenticationId.LowPart);
3410 hControlDevice = OpenRedirector();
3412 if( hControlDevice == NULL)
3415 try_return( dwStatus = WN_NET_ERROR);
3418 dwError = DeviceIoControl( hControlDevice,
3419 IOCTL_AFS_GET_CONNECTION,
3429 #ifdef AFS_DEBUG_TRACE
3430 DWORD gle = GetLastError();
3432 AFSDbgPrint( L"NPGetUniversalName Failed to get connection from file system for local %s gle 0x%x\n",
3435 try_return( dwStatus = WN_NOT_CONNECTED);
3438 switch( dwInfoLevel)
3441 case UNIVERSAL_NAME_INFO_LEVEL:
3444 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3446 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize + sizeof( WCHAR);
3448 *lpBufferSize += dwRemainingPathLength * sizeof( WCHAR);
3450 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3453 #ifdef AFS_DEBUG_TRACE
3454 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3457 try_return( dwStatus = WN_MORE_DATA);
3460 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3462 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3464 pch = (char *)pUniversalInfo->lpUniversalName;
3468 min( dwBufferSize, dwRemainingLength));
3470 pch += min( dwBufferSize, dwRemainingLength);
3472 dwRemainingLength -= min( dwBufferSize + sizeof(WCHAR), dwRemainingLength);
3476 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3478 pch += min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3480 dwRemainingLength -= min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3482 #ifdef AFS_DEBUG_TRACE
3483 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3485 pUniversalInfo->lpUniversalName,
3486 pUniversalInfo->lpUniversalName);
3489 if ( dwPassedSize < *lpBufferSize)
3492 try_return( dwStatus = WN_MORE_DATA);
3495 try_return( dwStatus = WN_SUCCESS);
3498 case REMOTE_NAME_INFO_LEVEL:
3501 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3503 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + (2 * dwBufferSize + sizeof( WCHAR)) + 2 * sizeof( WCHAR);
3505 *lpBufferSize += 2 * dwRemainingPathLength * sizeof( WCHAR);
3507 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3510 #ifdef AFS_DEBUG_TRACE
3511 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3514 try_return( dwStatus = WN_MORE_DATA);
3517 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3519 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3521 pch = (char *)pRemoteInfo->lpUniversalName;
3525 min( dwBufferSize, dwRemainingLength));
3527 pch += min( dwBufferSize, dwRemainingLength);
3529 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3533 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3535 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3537 dwRemainingLength -= min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3539 #ifdef AFS_DEBUG_TRACE
3540 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3542 pRemoteInfo->lpUniversalName,
3543 pRemoteInfo->lpUniversalName);
3546 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3548 pRemoteInfo->lpConnectionName = (LPWSTR)pch;
3552 min( dwBufferSize, dwRemainingLength));
3554 pch += min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3556 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3560 if ( dwRemainingLength > dwRemainingPathLength + sizeof( WCHAR))
3562 pRemoteInfo->lpRemainingPath = (LPWSTR)pch;
3566 min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength));
3568 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3570 dwRemainingLength -= min((dwLocalPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3573 #ifdef AFS_DEBUG_TRACE
3574 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3576 pRemoteInfo->lpConnectionName,
3577 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3579 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3581 pRemoteInfo->lpRemainingPath,
3582 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3585 if ( dwPassedSize < *lpBufferSize)
3588 try_return( dwStatus = WN_MORE_DATA);
3591 try_return( dwStatus = WN_SUCCESS);
3595 #ifdef AFS_DEBUG_TRACE
3596 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3599 try_return( dwStatus = WN_BAD_VALUE);
3604 #ifdef AFS_DEBUG_TRACE
3605 AFSDbgPrint( L"NPGetUniversalName BufferSize 0x%X\n",
3608 if ( hControlDevice != NULL)
3611 CloseHandle( hControlDevice);
3614 if( pConnectCB != NULL)
3617 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3626 GetFormatFlags( DWORD dwFlags)
3628 static WCHAR Buffer[128] = L"";
3631 // WNFMT_MULTILINE 0x01
3632 // WNFMT_ABBREVIATED 0x02
3633 // WNFMT_INENUM 0x10
3634 // WNFMT_CONNECTION 0x20
3639 if ( dwFlags & WNFMT_MULTILINE )
3641 StringCbCat( Buffer, sizeof(Buffer), L"MULTILINE|");
3644 if ( dwFlags & WNFMT_INENUM )
3646 StringCbCat( Buffer, sizeof(Buffer), L"ABBREVIATED|");
3649 if ( dwFlags & WNFMT_INENUM )
3651 StringCbCat( Buffer, sizeof(Buffer), L"INENUM|");
3654 if ( dwFlags & WNFMT_CONNECTION )
3656 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTION|");
3659 if ( dwFlags & ~(WNFMT_MULTILINE|WNFMT_ABBREVIATED|WNFMT_INENUM|WNFMT_CONNECTION) )
3661 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
3664 Buffer[lstrlen(Buffer)-1] = L'\0';
3670 NPFormatNetworkName( LPTSTR lpRemoteName,
3671 LPTSTR lpFormattedName,
3674 DWORD dwAveCharPerLine)
3677 DWORD dwLen = 0, dwCurrentLen = 0;
3678 LPTSTR pCurrentName = lpRemoteName;
3680 #ifdef AFS_DEBUG_TRACE
3681 AFSDbgPrint( L"NPFormatNetworkName Remote %s Flags %s (0x%x) CharsPerLine %u\n",
3684 GetFormatFlags( dwFlags),
3690 // Walk back in the name until we hit a \
3693 dwLen = wcslen( lpRemoteName);
3695 pCurrentName += (dwLen - 1);
3697 if ( pCurrentName[ 0] != L'\\')
3703 if( pCurrentName[ 0] == L'\\')
3719 if( *lpnLength < dwCurrentLen * sizeof( WCHAR))
3722 *lpnLength = dwCurrentLen * sizeof( WCHAR);
3724 #ifdef AFS_DEBUG_TRACE
3725 AFSDbgPrint( L"NPFormatNetworkName remote name %s WN_MORE_DATA\n",
3729 return WN_MORE_DATA;
3732 StringCbCopy( lpFormattedName,
3736 *lpnLength = dwCurrentLen * sizeof( WCHAR);
3738 #ifdef AFS_DEBUG_TRACE
3739 AFSDbgPrint( L"NPFormatNetworkName remote name %s as %s\n",
3747 /************************************************************
3748 / Unsupported entry points
3749 /************************************************************/
3752 // AuthGroup processing is implemented in src/WINNT/afsd/afslogon.c
3757 LPCWSTR lpAuthentInfoType,
3758 LPVOID lpAuthentInfo,
3759 LPCWSTR lpPreviousAuthentInfoType,
3760 LPVOID lpPreviousAuthentInfo,
3761 LPWSTR lpStationName,
3762 LPVOID StationHandle,
3763 LPWSTR *lpLogonScript)
3766 #ifdef AFS_DEBUG_TRACE
3767 AFSDbgPrint( L"NPLogonNotify, returning WN_NOT_SUPPORTED\n");
3770 return WN_NOT_SUPPORTED;
3774 NPPasswordChangeNotify (
3775 LPCWSTR lpAuthentInfoType,
3776 LPVOID lpAuthentInfo,
3777 LPCWSTR lpPreviousAuthentInfoType,
3778 LPVOID lpPreviousAuthentInfo,
3779 LPWSTR lpStationName,
3780 LPVOID StationHandle,
3781 DWORD dwChangeInfo )
3784 #ifdef AFS_DEBUG_TRACE
3785 AFSDbgPrint( L"NPPasswordChangeNotify, returning WN_NOT_SUPPORTED\n");
3788 SetLastError( WN_NOT_SUPPORTED );
3790 return WN_NOT_SUPPORTED;
3794 NPGetUser( LPTSTR lpName,
3796 LPDWORD lpBufferSize)
3799 DWORD rc = WN_NOT_SUPPORTED;
3801 AFSDbgPrint( L"NPGetUser Entry Name %s\n", lpName);
3809 NPGetReconnectFlags( LPWSTR lpRemoteName,
3810 unsigned char *Parameter2)
3813 DWORD dwStatus = WN_NOT_SUPPORTED;
3815 AFSDbgPrint( L"NPGetReconnectFlags RemoteName %s\n",
3824 I_SystemFocusDialog( VOID)
3827 DWORD dwStatus = WN_NOT_SUPPORTED;
3829 AFSDbgPrint( L"I_SystemFocusDialog\n");
3834 /************************************************************
3835 / END Unsupported entry points
3836 /************************************************************/
3843 HANDLE hControlDevice = NULL;
3844 WCHAR wchError[ 256];
3846 hControlDevice = CreateFile( AFS_SYMLINK_W,
3847 GENERIC_READ | GENERIC_WRITE,
3848 FILE_SHARE_READ | FILE_SHARE_WRITE,
3854 if( hControlDevice == INVALID_HANDLE_VALUE)
3857 hControlDevice = NULL;
3858 #ifdef AFS_DEBUG_TRACE
3859 AFSDbgPrint( L"Failed to open control device error: %d\n",
3865 // only do this if you want network shares to fail to mount
3866 // when the file system is not yet ready
3870 AFSDriverStatusRespCB respCB;
3873 memset( &respCB, '\0', sizeof( AFSDriverStatusRespCB));
3875 if ( !DeviceIoControl( hControlDevice,
3876 IOCTL_AFS_STATUS_REQUEST,
3880 sizeof( AFSDriverStatusRespCB),
3883 dwBytes != sizeof(AFSDriverStatusRespCB) ||
3884 respCB.Status != AFS_DRIVER_STATUS_READY )
3887 CloseHandle( hControlDevice);
3889 hControlDevice = NULL;
3894 return hControlDevice;
3901 LARGE_INTEGER liAuthId = {0,0};
3902 HANDLE hToken = NULL;
3903 TOKEN_STATISTICS stTokenInfo;
3904 DWORD dwCopyBytes = 0;
3906 if ( !OpenThreadToken( GetCurrentThread(),
3908 FALSE, // Impersonation
3911 if( !OpenProcessToken( GetCurrentProcess(),
3916 #ifdef AFS_DEBUG_TRACE
3917 AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve Thread and Process tokens 0x%X\n",
3924 #ifdef AFS_DEBUG_TRACE
3925 AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Process Token\n");
3932 #ifdef AFS_DEBUG_TRACE
3933 AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Thread Token\n");
3937 if ( hToken != NULL)
3940 if( !GetTokenInformation( hToken,
3943 sizeof( TOKEN_STATISTICS),
3947 #ifdef AFS_DEBUG_TRACE
3948 AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve token information 0x%X\n",
3955 liAuthId.HighPart = stTokenInfo.AuthenticationId.HighPart;
3956 liAuthId.LowPart = stTokenInfo.AuthenticationId.LowPart;
3959 CloseHandle( hToken);
3968 static int init = 0;
3969 static DWORD debug = 0;
3974 if (RegOpenKey (HKEY_LOCAL_MACHINE,
3975 TEXT("SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider"), &hk) == 0)
3977 DWORD dwSize = sizeof(BOOL);
3978 DWORD dwType = REG_DWORD;
3979 RegQueryValueEx (hk, TEXT("Debug"), NULL, &dwType, (PBYTE)&debug, &dwSize);
3989 cm_Utf16ToUtf8Alloc(const WCHAR * s, int cch_src, int *pcch_dest)
3994 if (s == NULL || cch_src == 0 || *s == L'\0') {
3996 *pcch_dest = ((cch_src != 0)?1:0);
4000 cch_dest = WideCharToMultiByte(CP_UTF8, 0, s, cch_src, NULL, 0, NULL, FALSE);
4002 if (cch_dest == 0) {
4004 *pcch_dest = cch_dest;
4008 dest = HeapAlloc( GetProcessHeap(), 0, (cch_dest + 1) * sizeof(char));
4010 WideCharToMultiByte(CP_UTF8, 0, s, cch_src, dest, cch_dest, NULL, FALSE);
4014 *pcch_dest = cch_dest;
4020 AppendDebugStringToLogFile(WCHAR *wszbuffer)
4028 if ( !wszbuffer || !wszbuffer[0] )
4031 len = (int)wcslen(wszbuffer);
4033 buffer = cm_Utf16ToUtf8Alloc(wszbuffer, len, &len);
4038 hFile = CreateFileW( L"C:\\TEMP\\AFSRDFSProvider.log",
4043 FILE_ATTRIBUTE_NORMAL,
4046 if ( hFile == INVALID_HANDLE_VALUE ) {
4047 OutputDebugString(L"C:\\AFSRDFSProvider.log cannot be opened.\n");
4051 bRet = WriteFile( hFile, buffer, len, &dwWritten, NULL);
4053 bRet = CloseHandle(hFile);
4055 HeapFree(GetProcessHeap(), 0, buffer);
4066 WCHAR wszbuffer[512];
4068 DWORD debug = Debug();
4073 va_start( marker, Format );
4075 StringCbPrintf( wszbuffer, sizeof(wszbuffer), L"[%d-%08X] ",
4081 GetCurrentThreadId());
4083 rc = StringCbVPrintfW( &wszbuffer[ 14], sizeof(wszbuffer) - 14, Format, marker);
4085 if (SUCCEEDED(rc)) {
4087 OutputDebugString( wszbuffer );
4089 AppendDebugStringToLogFile(wszbuffer);
4091 OutputDebugString(L"AFSDbgPrint Failed to create string\n");
4094 return SUCCEEDED(rc) ? 1 : 0;