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;
2571 pNetResource->dwUsage = pConnectionCB->Usage;
2573 // setup string area at opposite end of buffer
2574 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2577 if( pConnectionCB->LocalName != 0)
2580 pNetResource->lpLocalName = StringZone;
2581 *StringZone++ = towupper(pConnectionCB->LocalName);
2582 *StringZone++ = L':';
2583 *StringZone++ = L'\0';
2588 pNetResource->lpLocalName = NULL;
2591 #ifdef AFS_DEBUG_TRACE
2592 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2597 pNetResource->lpRemoteName = StringZone;
2599 CopyMemory( StringZone,
2600 pConnectionCB->RemoteName,
2601 pConnectionCB->RemoteNameLength);
2603 StringZone += (pConnectionCB->RemoteNameLength / sizeof(WCHAR));
2605 *StringZone++ = L'\0';
2608 if( pConnectionCB->CommentLength > 0)
2611 pNetResource->lpComment = StringZone;
2613 CopyMemory( StringZone,
2614 (void *)((char *)pConnectionCB + pConnectionCB->CommentOffset),
2615 pConnectionCB->CommentLength);
2617 StringZone += (pConnectionCB->CommentLength / sizeof(WCHAR));
2619 *StringZone++ = L'\0';
2624 pNetResource->lpComment = NULL;
2627 // copy provider name
2628 pNetResource->lpProvider = StringZone;
2629 StringCbCopy( StringZone,
2630 cbProviderNameLength + sizeof( WCHAR),
2633 StringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
2635 #ifdef AFS_DEBUG_TRACE
2636 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2638 GetScopeString(pNetResource->dwScope),
2639 GetTypeString(pNetResource->dwType),
2640 GetDisplayString(pNetResource->dwDisplayType),
2641 GetUsageString(pNetResource->dwUsage),
2642 pNetResource->lpLocalName,
2643 pNetResource->lpRemoteName,
2644 pNetResource->lpComment);
2647 // setup the new end of buffer
2648 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2656 dwCopyBytes -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2657 pConnectionCB->RemoteNameLength +
2658 pConnectionCB->CommentLength;
2660 if( dwCopyBytes == 0)
2663 dwStatus = WN_SUCCESS;
2668 pConnectionCB = (AFSNetworkProviderConnectionCB *)((char *)pConnectionCB +
2669 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2670 pConnectionCB->RemoteNameLength +
2671 pConnectionCB->CommentLength);
2674 *lpcCount = EntriesCopied;
2676 // update entry index
2677 pEnumCB->CurrentIndex = dwIndex;
2679 #ifdef AFS_DEBUG_TRACE
2680 AFSDbgPrint( L"NPEnumResource Completed Count %d Index %d\n",
2687 if ( hControlDevice != NULL)
2690 CloseHandle( hControlDevice);
2693 if( pConnectionCBBase != NULL)
2696 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectionCBBase);
2705 Routine Description:
2707 This routine closes the handle for enumeration of resources.
2711 hEnum - the enumeration handle
2715 WN_SUCCESS if successful, otherwise the appropriate error
2719 The sample only supports the notion of enumerating connected shares
2724 NPCloseEnum( HANDLE hEnum )
2727 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2729 #ifdef AFS_DEBUG_TRACE
2730 AFSDbgPrint( L"NPCloseEnum\n");
2733 if( pEnumCB->RemoteName != NULL)
2736 HeapFree( GetProcessHeap( ), 0, (PVOID) pEnumCB->RemoteName);
2739 HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum );
2745 NPGetResourceParent( LPNETRESOURCE lpNetResource,
2747 LPDWORD lpBufferSize )
2750 DWORD dwStatus = WN_ACCESS_DENIED;
2751 WCHAR *pwchRemoteName = NULL, *pwchSearch = NULL, *pwchSystem = NULL;
2752 LPNETRESOURCE lpOutResource = (LPNETRESOURCE) lpBuffer;
2754 if ( lpNetResource == NULL)
2756 #ifdef AFS_DEBUG_TRACE
2757 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2759 return WN_MORE_DATA;
2762 if( lpNetResource->lpRemoteName == NULL)
2764 #ifdef AFS_DEBUG_TRACE
2765 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2767 return WN_BAD_NETNAME;
2770 if ( lpNetResource->dwType != 0 &&
2771 lpNetResource->dwType != RESOURCETYPE_DISK)
2773 #ifdef AFS_DEBUG_TRACE
2774 AFSDbgPrint( L"NPGetResourceParent Bad dwType\n");
2776 return WN_BAD_VALUE;
2779 if ( lpBufferSize == NULL )
2782 #ifdef AFS_DEBUG_TRACE
2783 AFSDbgPrint( L"NPGetResourceParent Null lpBufferSize\n");
2785 return WN_BAD_VALUE;
2788 #ifdef AFS_DEBUG_TRACE
2789 AFSDbgPrint( L"NPGetResourceParent For remote name %s\n",
2790 lpNetResource->lpRemoteName);
2793 pwchRemoteName = lpNetResource->lpRemoteName;
2795 pwchSearch = pwchRemoteName + (wcslen( pwchRemoteName) - 1);
2797 while( pwchSearch != pwchRemoteName)
2800 if( *pwchSearch == L'\\')
2803 *pwchSearch = L'\0';
2811 if( pwchSearch != pwchRemoteName)
2814 #ifdef AFS_DEBUG_TRACE
2815 AFSDbgPrint( L"NPGetResourceParent Processing parent %s\n",
2816 lpNetResource->lpRemoteName);
2819 dwStatus = NPGetResourceInformation( lpNetResource,
2826 if ( lpOutResource == NULL ||
2827 *lpBufferSize < sizeof( NETRESOURCE) )
2829 *lpBufferSize = sizeof( NETRESOURCE);
2831 return WN_MORE_DATA;
2834 memset( lpOutResource, 0, sizeof( NETRESOURCE));
2844 NPGetResourceInformation( LPNETRESOURCE lpNetResource,
2846 LPDWORD lpBufferSize,
2847 LPWSTR *lplpSystem )
2850 DWORD dwStatus = WN_NOT_CONNECTED;
2851 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
2853 DWORD dwBufferSize = 0;
2854 HANDLE hControlDevice = NULL;
2855 NETRESOURCE *pNetResource = (NETRESOURCE *)lpBuffer;
2856 PWCHAR pStringZone = NULL;
2857 UNICODE_STRING uniRemoteName;
2858 DWORD ulRequiredLen = 0;
2869 ReadProviderNameString();
2871 if ( NPIsFSDisabled())
2874 #ifdef AFS_DEBUG_TRACE
2875 AFSDbgPrint( L"NPGetResourceInformation AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
2878 try_return( dwStatus = WN_BAD_NETNAME);
2881 if ( lpNetResource == NULL ||
2882 lpBufferSize == NULL )
2885 #ifdef AFS_DEBUG_TRACE
2886 AFSDbgPrint( L"NPGetResourceInformaton Null lpNetResource or lpBufferSize\n");
2888 return WN_BAD_VALUE;
2891 if( lpNetResource->lpRemoteName == NULL)
2893 #ifdef AFS_DEBUG_TRACE
2894 AFSDbgPrint( L"NPGetResourceInformation No resource name\n");
2897 try_return( dwStatus = WN_NOT_CONNECTED);
2900 dwPassedSize = *lpBufferSize;
2902 dwBufferSize = 0x1000;
2904 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
2906 if( pConnectCB == NULL)
2909 try_return( dwStatus = WN_OUT_OF_MEMORY);
2912 pConnectCB->RemoteNameLength = wcslen( lpNetResource->lpRemoteName) * sizeof( WCHAR);
2914 StringCbCopy( pConnectCB->RemoteName,
2915 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
2916 lpNetResource->lpRemoteName);
2918 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
2920 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
2922 #ifdef AFS_DEBUG_TRACE
2923 AFSDbgPrint( L"NPGetResourceInformation Retrieved authentication id %08lX-%08lX\n",
2924 pConnectCB->AuthenticationId.HighPart,
2925 pConnectCB->AuthenticationId.LowPart);
2928 hControlDevice = OpenRedirector();
2930 if( hControlDevice == NULL)
2933 #ifdef AFS_DEBUG_TRACE
2934 AFSDbgPrint( L"NPGetResourceInformation OpenRedirector failure, returning WN_NET_ERROR\n");
2937 try_return( dwStatus = WN_NET_ERROR);
2940 dwError = DeviceIoControl( hControlDevice,
2941 IOCTL_AFS_GET_CONNECTION_INFORMATION,
2951 #ifdef AFS_DEBUG_TRACE
2952 DWORD gle = GetLastError();
2954 AFSDbgPrint( L"NPGetResourceInformation Failed to get connection info from file system for local %s gle 0x%x\n",
2955 lpNetResource->lpRemoteName, gle);
2957 try_return( dwStatus = WN_BAD_NETNAME);
2960 uniRemoteName.Length = (USHORT)pConnectCB->RemoteNameLength;
2961 uniRemoteName.MaximumLength = uniRemoteName.Length;
2962 uniRemoteName.Buffer = pConnectCB->RemoteName;
2964 #ifdef AFS_DEBUG_TRACE
2965 AFSDbgPrint( L"NPGetResourceInformation For remote name %wZ Scope %08lX Type %08lX Usage %08lX\n",
2972 // Determine the space needed for this entry...
2974 ulRequiredLen = sizeof( NETRESOURCE);
2976 ulRequiredLen += pConnectCB->RemoteNameLength + sizeof( WCHAR);
2978 ulRequiredLen += pConnectCB->CommentLength + sizeof( WCHAR);
2980 ulRequiredLen += cbProviderNameLength + sizeof( WCHAR);
2982 ulRequiredLen += pConnectCB->RemainingPathLength + sizeof( WCHAR);
2984 if( pNetResource == NULL ||
2985 ulRequiredLen > dwPassedSize)
2988 *lpBufferSize = ulRequiredLen;
2990 try_return( dwStatus = WN_MORE_DATA);
2993 pStringZone = (PWCHAR) ((char *)lpBuffer + sizeof( NETRESOURCE));
2995 pNetResource->dwScope = 0 /* pConnectCB->Scope*/;
2996 pNetResource->dwType = 0 /* pConnectCB->Type */;
2998 pNetResource->dwDisplayType = pConnectCB->DisplayType;
3000 pNetResource->dwUsage = pConnectCB->Usage;
3002 pNetResource->lpLocalName = NULL;
3005 pNetResource->lpRemoteName = pStringZone;
3007 CopyMemory( pStringZone,
3008 pConnectCB->RemoteName,
3009 pConnectCB->RemoteNameLength);
3011 pStringZone += (pConnectCB->RemoteNameLength / sizeof(WCHAR));
3013 *pStringZone++ = L'\0';
3016 pNetResource->lpComment = pStringZone;
3018 CopyMemory( pStringZone,
3019 (void *)((char *)pConnectCB + pConnectCB->CommentOffset),
3020 pConnectCB->CommentLength);
3022 pStringZone += (pConnectCB->CommentLength / sizeof(WCHAR));
3024 *pStringZone++ = L'\0';
3026 // copy remaining path
3027 if (pConnectCB->RemainingPathLength > 0)
3029 *lplpSystem = pStringZone;
3031 CopyMemory( pStringZone,
3032 (void *)((char *)pConnectCB + pConnectCB->RemainingPathOffset),
3033 pConnectCB->RemainingPathLength);
3035 pStringZone += (pConnectCB->RemainingPathLength / sizeof(WCHAR));
3037 *pStringZone++ = L'\0';
3039 #ifdef AFS_DEBUG_TRACE
3040 AFSDbgPrint( L"NPGetResourceInformation For remote name %s returning remaining path %s\n",
3041 pNetResource->lpRemoteName,
3046 // copy provider name
3047 pNetResource->lpProvider = pStringZone;
3049 StringCbCopy( pStringZone,
3050 cbProviderNameLength + sizeof( WCHAR),
3053 pStringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
3055 *lpBufferSize = ulRequiredLen;
3057 dwStatus = WN_SUCCESS;
3061 if ( hControlDevice != NULL)
3064 CloseHandle( hControlDevice);
3067 if( pConnectCB != NULL)
3070 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3078 SeparateRemainingPath( WCHAR * lpConnectionName, WCHAR **lppRemainingPath)
3085 // at this point the lpConnectionName contains the full name. We need to
3086 // truncate it to \\server\share and move the remaining path back one position.
3089 for ( pwch = lpConnectionName, dwCount = 0; *pwch; pwch++)
3091 if ( *pwch == L'\\')
3105 // Found the remaining path that must be moved
3108 *lppRemainingPath = pwch + 1;
3115 for ( ; *pwch; pwch++);
3118 // and work backwards moving the string
3119 // and then make sure that there is at least
3120 // a path separator.
3125 for ( ;pwch > *lppRemainingPath; pwch--)
3127 *pwch = *(pwch - 1);
3135 NPGetUniversalName( LPCWSTR lpLocalPath,
3138 LPDWORD lpBufferSize )
3140 DWORD dwStatus = WN_NOT_CONNECTED;
3141 WCHAR wchLocalName[3];
3142 WCHAR wchSubstName[MAX_PATH + 1];
3143 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3145 DWORD dwBufferSize = 0;
3146 DWORD dwPassedSize = *lpBufferSize;
3147 DWORD dwRemainingLength = *lpBufferSize;
3148 HANDLE hControlDevice = NULL;
3149 DWORD dwLocalPathLength = 0;
3150 DWORD dwRemainingPathLength = 0;
3156 #ifdef AFS_DEBUG_TRACE
3157 AFSDbgPrint( L"NPGetUniversalName local path %s level 0x%X\n",
3158 lpLocalPath ? lpLocalPath : L"(Null)",
3162 if ( NPIsFSDisabled())
3165 #ifdef AFS_DEBUG_TRACE
3166 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
3169 try_return( dwStatus = WN_NOT_CONNECTED);
3172 dwLocalPathLength = lstrlen( lpLocalPath);
3174 dwRemainingPathLength = dwLocalPathLength - 2; // no drive letter
3176 if( dwLocalPathLength == 0)
3179 #ifdef AFS_DEBUG_TRACE
3180 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_BAD_LOCALNAME\n");
3183 try_return( dwStatus = WN_BAD_LOCALNAME);
3186 if( lpBuffer == NULL ||
3187 lpBufferSize == NULL)
3189 #ifdef AFS_DEBUG_TRACE
3190 AFSDbgPrint( L"NPGetUniversalName No output buffer or size\n");
3192 try_return( dwStatus = WN_BAD_VALUE);
3195 memset(lpBuffer, 0, dwPassedSize);
3197 if ( !DriveSubstitution( lpLocalPath, wchSubstName, sizeof( wchSubstName)))
3199 wchLocalName[0] = towupper(lpLocalPath[0]);
3200 wchLocalName[1] = L':';
3201 wchLocalName[2] = L'\0';
3203 #ifdef AFS_DEBUG_TRACE
3204 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for %s level 0x%X\n",
3212 ReadServerNameString();
3214 if ( wchSubstName[0] != L'\\' &&
3215 wchSubstName[1] == L':')
3218 wchLocalName[0] = towupper(wchSubstName[0]);
3219 wchLocalName[1] = L':';
3220 wchLocalName[2] = L'\0';
3222 #ifdef AFS_DEBUG_TRACE
3223 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for drive substitution %s -> %s\n",
3228 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
3229 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
3230 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
3234 #ifdef AFS_DEBUG_TRACE
3235 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is AFS; Level 0x%x BufferSize 0x%x\n",
3241 dwBufferSize = (wcslen( wchSubstName) + 1) * sizeof( WCHAR);
3243 switch( dwInfoLevel)
3246 case UNIVERSAL_NAME_INFO_LEVEL:
3249 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3251 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize;
3253 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3256 #ifdef AFS_DEBUG_TRACE
3257 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3260 try_return( dwStatus = WN_MORE_DATA);
3263 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3265 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3267 memcpy( pUniversalInfo->lpUniversalName,
3269 min( dwBufferSize, dwRemainingLength));
3271 dwRemainingLength -= min( dwBufferSize, dwRemainingLength);
3273 #ifdef AFS_DEBUG_TRACE
3274 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3276 pUniversalInfo->lpUniversalName,
3277 pUniversalInfo->lpUniversalName);
3280 if ( dwPassedSize < *lpBufferSize)
3283 try_return( dwStatus = WN_MORE_DATA);
3286 try_return( dwStatus = WN_SUCCESS);
3289 case REMOTE_NAME_INFO_LEVEL:
3292 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3294 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + 2 * dwBufferSize + sizeof( WCHAR);
3296 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3299 #ifdef AFS_DEBUG_TRACE
3300 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3303 try_return( dwStatus = WN_MORE_DATA);
3306 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3308 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3310 memcpy( pRemoteInfo->lpUniversalName,
3312 min( dwRemainingLength, dwBufferSize));
3314 dwRemainingLength -= min( dwRemainingLength, dwBufferSize);
3316 #ifdef AFS_DEBUG_TRACE
3317 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3319 pRemoteInfo->lpUniversalName,
3320 pRemoteInfo->lpUniversalName);
3323 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3325 pRemoteInfo->lpConnectionName = (LPTSTR)((char *)pRemoteInfo->lpUniversalName + dwBufferSize);
3327 memcpy( pRemoteInfo->lpConnectionName,
3329 min( dwRemainingLength, dwBufferSize));
3331 dwRemainingLength -= min( dwRemainingLength, dwBufferSize) - sizeof( WCHAR);
3333 SeparateRemainingPath( pRemoteInfo->lpConnectionName,
3334 &pRemoteInfo->lpRemainingPath);
3337 #ifdef AFS_DEBUG_TRACE
3338 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3340 pRemoteInfo->lpConnectionName,
3341 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3343 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3345 pRemoteInfo->lpRemainingPath,
3346 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3349 if ( dwPassedSize < *lpBufferSize)
3352 try_return( dwStatus = WN_MORE_DATA);
3355 try_return( dwStatus = WN_SUCCESS);
3359 #ifdef AFS_DEBUG_TRACE
3360 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3363 try_return( dwStatus = WN_BAD_VALUE);
3369 #ifdef AFS_DEBUG_TRACE
3370 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is not AFS\n",
3373 try_return( dwStatus = WN_NOT_CONNECTED);
3377 dwBufferSize = 0x1000;
3379 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
3381 if( pConnectCB == NULL)
3383 try_return( dwStatus = WN_OUT_OF_MEMORY);
3386 pConnectCB->LocalName = towupper(wchLocalName[0]);
3388 pConnectCB->RemoteNameLength = 0;
3390 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3392 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
3394 #ifdef AFS_DEBUG_TRACE
3395 AFSDbgPrint( L"NPGetUniversalName Retrieved authentication id %08lX-%08lX\n",
3396 pConnectCB->AuthenticationId.HighPart,
3397 pConnectCB->AuthenticationId.LowPart);
3400 hControlDevice = OpenRedirector();
3402 if( hControlDevice == NULL)
3405 try_return( dwStatus = WN_NET_ERROR);
3408 dwError = DeviceIoControl( hControlDevice,
3409 IOCTL_AFS_GET_CONNECTION,
3419 #ifdef AFS_DEBUG_TRACE
3420 DWORD gle = GetLastError();
3422 AFSDbgPrint( L"NPGetUniversalName Failed to get connection from file system for local %s gle 0x%x\n",
3425 try_return( dwStatus = WN_NOT_CONNECTED);
3428 switch( dwInfoLevel)
3431 case UNIVERSAL_NAME_INFO_LEVEL:
3434 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3436 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize + sizeof( WCHAR);
3438 *lpBufferSize += dwRemainingPathLength * sizeof( WCHAR);
3440 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3443 #ifdef AFS_DEBUG_TRACE
3444 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3447 try_return( dwStatus = WN_MORE_DATA);
3450 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3452 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3454 pch = (char *)pUniversalInfo->lpUniversalName;
3458 min( dwBufferSize, dwRemainingLength));
3460 pch += min( dwBufferSize, dwRemainingLength);
3462 dwRemainingLength -= min( dwBufferSize + sizeof(WCHAR), dwRemainingLength);
3466 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3468 pch += min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3470 dwRemainingLength -= min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3472 #ifdef AFS_DEBUG_TRACE
3473 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3475 pUniversalInfo->lpUniversalName,
3476 pUniversalInfo->lpUniversalName);
3479 if ( dwPassedSize < *lpBufferSize)
3482 try_return( dwStatus = WN_MORE_DATA);
3485 try_return( dwStatus = WN_SUCCESS);
3488 case REMOTE_NAME_INFO_LEVEL:
3491 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3493 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + (2 * dwBufferSize + sizeof( WCHAR)) + 2 * sizeof( WCHAR);
3495 *lpBufferSize += 2 * dwRemainingPathLength * sizeof( WCHAR);
3497 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3500 #ifdef AFS_DEBUG_TRACE
3501 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3504 try_return( dwStatus = WN_MORE_DATA);
3507 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3509 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3511 pch = (char *)pRemoteInfo->lpUniversalName;
3515 min( dwBufferSize, dwRemainingLength));
3517 pch += min( dwBufferSize, dwRemainingLength);
3519 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3523 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3525 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3527 dwRemainingLength -= min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3529 #ifdef AFS_DEBUG_TRACE
3530 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3532 pRemoteInfo->lpUniversalName,
3533 pRemoteInfo->lpUniversalName);
3536 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3538 pRemoteInfo->lpConnectionName = (LPWSTR)pch;
3542 min( dwBufferSize, dwRemainingLength));
3544 pch += min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3546 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3550 if ( dwRemainingLength > dwRemainingPathLength + sizeof( WCHAR))
3552 pRemoteInfo->lpRemainingPath = (LPWSTR)pch;
3556 min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength));
3558 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3560 dwRemainingLength -= min((dwLocalPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3563 #ifdef AFS_DEBUG_TRACE
3564 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3566 pRemoteInfo->lpConnectionName,
3567 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3569 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3571 pRemoteInfo->lpRemainingPath,
3572 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3575 if ( dwPassedSize < *lpBufferSize)
3578 try_return( dwStatus = WN_MORE_DATA);
3581 try_return( dwStatus = WN_SUCCESS);
3585 #ifdef AFS_DEBUG_TRACE
3586 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3589 try_return( dwStatus = WN_BAD_VALUE);
3594 #ifdef AFS_DEBUG_TRACE
3595 AFSDbgPrint( L"NPGetUniversalName BufferSize 0x%X\n",
3598 if ( hControlDevice != NULL)
3601 CloseHandle( hControlDevice);
3604 if( pConnectCB != NULL)
3607 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3616 GetFormatFlags( DWORD dwFlags)
3618 static WCHAR Buffer[128] = L"";
3621 // WNFMT_MULTILINE 0x01
3622 // WNFMT_ABBREVIATED 0x02
3623 // WNFMT_INENUM 0x10
3624 // WNFMT_CONNECTION 0x20
3629 if ( dwFlags & WNFMT_MULTILINE )
3631 StringCbCat( Buffer, sizeof(Buffer), L"MULTILINE|");
3634 if ( dwFlags & WNFMT_INENUM )
3636 StringCbCat( Buffer, sizeof(Buffer), L"ABBREVIATED|");
3639 if ( dwFlags & WNFMT_INENUM )
3641 StringCbCat( Buffer, sizeof(Buffer), L"INENUM|");
3644 if ( dwFlags & WNFMT_CONNECTION )
3646 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTION|");
3649 if ( dwFlags & ~(WNFMT_MULTILINE|WNFMT_ABBREVIATED|WNFMT_INENUM|WNFMT_CONNECTION) )
3651 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
3654 Buffer[lstrlen(Buffer)-1] = L'\0';
3660 NPFormatNetworkName( LPTSTR lpRemoteName,
3661 LPTSTR lpFormattedName,
3664 DWORD dwAveCharPerLine)
3667 DWORD dwLen = 0, dwCurrentLen = 0;
3668 LPTSTR pCurrentName = lpRemoteName;
3670 #ifdef AFS_DEBUG_TRACE
3671 AFSDbgPrint( L"NPFormatNetworkName Remote %s Flags %s (0x%x) CharsPerLine %u\n",
3674 GetFormatFlags( dwFlags),
3680 // Walk back in the name until we hit a \
3683 dwLen = wcslen( lpRemoteName);
3685 pCurrentName += (dwLen - 1);
3687 if ( pCurrentName[ 0] != L'\\')
3693 if( pCurrentName[ 0] == L'\\')
3709 if( *lpnLength < dwCurrentLen * sizeof( WCHAR))
3712 *lpnLength = dwCurrentLen * sizeof( WCHAR);
3714 #ifdef AFS_DEBUG_TRACE
3715 AFSDbgPrint( L"NPFormatNetworkName remote name %s WN_MORE_DATA\n",
3719 return WN_MORE_DATA;
3722 StringCbCopy( lpFormattedName,
3726 *lpnLength = dwCurrentLen * sizeof( WCHAR);
3728 #ifdef AFS_DEBUG_TRACE
3729 AFSDbgPrint( L"NPFormatNetworkName remote name %s as %s\n",
3737 /************************************************************
3738 / Unsupported entry points
3739 /************************************************************/
3742 // AuthGroup processing is implemented in src/WINNT/afsd/afslogon.c
3747 LPCWSTR lpAuthentInfoType,
3748 LPVOID lpAuthentInfo,
3749 LPCWSTR lpPreviousAuthentInfoType,
3750 LPVOID lpPreviousAuthentInfo,
3751 LPWSTR lpStationName,
3752 LPVOID StationHandle,
3753 LPWSTR *lpLogonScript)
3756 #ifdef AFS_DEBUG_TRACE
3757 AFSDbgPrint( L"NPLogonNotify, returning WN_NOT_SUPPORTED\n");
3760 return WN_NOT_SUPPORTED;
3764 NPPasswordChangeNotify (
3765 LPCWSTR lpAuthentInfoType,
3766 LPVOID lpAuthentInfo,
3767 LPCWSTR lpPreviousAuthentInfoType,
3768 LPVOID lpPreviousAuthentInfo,
3769 LPWSTR lpStationName,
3770 LPVOID StationHandle,
3771 DWORD dwChangeInfo )
3774 #ifdef AFS_DEBUG_TRACE
3775 AFSDbgPrint( L"NPPasswordChangeNotify, returning WN_NOT_SUPPORTED\n");
3778 SetLastError( WN_NOT_SUPPORTED );
3780 return WN_NOT_SUPPORTED;
3784 NPGetUser( LPTSTR lpName,
3786 LPDWORD lpBufferSize)
3789 DWORD rc = WN_NOT_SUPPORTED;
3791 AFSDbgPrint( L"NPGetUser Entry Name %s\n", lpName);
3799 NPGetReconnectFlags( LPWSTR lpRemoteName,
3800 unsigned char *Parameter2)
3803 DWORD dwStatus = WN_NOT_SUPPORTED;
3805 AFSDbgPrint( L"NPGetReconnectFlags RemoteName %s\n",
3814 I_SystemFocusDialog( VOID)
3817 DWORD dwStatus = WN_NOT_SUPPORTED;
3819 AFSDbgPrint( L"I_SystemFocusDialog\n");
3824 /************************************************************
3825 / END Unsupported entry points
3826 /************************************************************/
3833 HANDLE hControlDevice = NULL;
3834 WCHAR wchError[ 256];
3836 hControlDevice = CreateFile( AFS_SYMLINK_W,
3837 GENERIC_READ | GENERIC_WRITE,
3838 FILE_SHARE_READ | FILE_SHARE_WRITE,
3844 if( hControlDevice == INVALID_HANDLE_VALUE)
3847 hControlDevice = NULL;
3848 #ifdef AFS_DEBUG_TRACE
3849 AFSDbgPrint( L"Failed to open control device error: %d\n",
3855 // only do this if you want network shares to fail to mount
3856 // when the file system is not yet ready
3860 AFSDriverStatusRespCB respCB;
3863 memset( &respCB, '\0', sizeof( AFSDriverStatusRespCB));
3865 if ( !DeviceIoControl( hControlDevice,
3866 IOCTL_AFS_STATUS_REQUEST,
3870 sizeof( AFSDriverStatusRespCB),
3873 dwBytes != sizeof(AFSDriverStatusRespCB) ||
3874 respCB.Status != AFS_DRIVER_STATUS_READY )
3877 CloseHandle( hControlDevice);
3879 hControlDevice = NULL;
3884 return hControlDevice;
3891 LARGE_INTEGER liAuthId = {0,0};
3892 HANDLE hToken = NULL;
3893 TOKEN_STATISTICS stTokenInfo;
3894 DWORD dwCopyBytes = 0;
3896 if ( !OpenThreadToken( GetCurrentThread(),
3898 FALSE, // Impersonation
3901 if( !OpenProcessToken( GetCurrentProcess(),
3906 #ifdef AFS_DEBUG_TRACE
3907 AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve Thread and Process tokens 0x%X\n",
3914 #ifdef AFS_DEBUG_TRACE
3915 AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Process Token\n");
3922 #ifdef AFS_DEBUG_TRACE
3923 AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Thread Token\n");
3927 if ( hToken != NULL)
3930 if( !GetTokenInformation( hToken,
3933 sizeof( TOKEN_STATISTICS),
3937 #ifdef AFS_DEBUG_TRACE
3938 AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve token information 0x%X\n",
3945 liAuthId.HighPart = stTokenInfo.AuthenticationId.HighPart;
3946 liAuthId.LowPart = stTokenInfo.AuthenticationId.LowPart;
3949 CloseHandle( hToken);
3958 static int init = 0;
3959 static DWORD debug = 0;
3964 if (RegOpenKey (HKEY_LOCAL_MACHINE,
3965 TEXT("SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider"), &hk) == 0)
3967 DWORD dwSize = sizeof(BOOL);
3968 DWORD dwType = REG_DWORD;
3969 RegQueryValueEx (hk, TEXT("Debug"), NULL, &dwType, (PBYTE)&debug, &dwSize);
3979 cm_Utf16ToUtf8Alloc(const WCHAR * s, int cch_src, int *pcch_dest)
3984 if (s == NULL || cch_src == 0 || *s == L'\0') {
3986 *pcch_dest = ((cch_src != 0)?1:0);
3990 cch_dest = WideCharToMultiByte(CP_UTF8, 0, s, cch_src, NULL, 0, NULL, FALSE);
3992 if (cch_dest == 0) {
3994 *pcch_dest = cch_dest;
3998 dest = HeapAlloc( GetProcessHeap(), 0, (cch_dest + 1) * sizeof(char));
4000 WideCharToMultiByte(CP_UTF8, 0, s, cch_src, dest, cch_dest, NULL, FALSE);
4004 *pcch_dest = cch_dest;
4010 AppendDebugStringToLogFile(WCHAR *wszbuffer)
4018 if ( !wszbuffer || !wszbuffer[0] )
4021 len = (int)wcslen(wszbuffer);
4023 buffer = cm_Utf16ToUtf8Alloc(wszbuffer, len, &len);
4028 hFile = CreateFileW( L"C:\\TEMP\\AFSRDFSProvider.log",
4033 FILE_ATTRIBUTE_NORMAL,
4036 if ( hFile == INVALID_HANDLE_VALUE ) {
4037 OutputDebugString(L"C:\\AFSRDFSProvider.log cannot be opened.\n");
4041 bRet = WriteFile( hFile, buffer, len, &dwWritten, NULL);
4043 bRet = CloseHandle(hFile);
4045 HeapFree(GetProcessHeap(), 0, buffer);
4056 WCHAR wszbuffer[512];
4058 DWORD debug = Debug();
4063 va_start( marker, Format );
4065 StringCbPrintf( wszbuffer, sizeof(wszbuffer), L"[%d-%08X] ",
4071 GetCurrentThreadId());
4073 rc = StringCbVPrintfW( &wszbuffer[ 14], sizeof(wszbuffer) - 14, Format, marker);
4075 if (SUCCEEDED(rc)) {
4077 OutputDebugString( wszbuffer );
4079 AppendDebugStringToLogFile(wszbuffer);
4081 OutputDebugString(L"AFSDbgPrint Failed to create string\n");
4084 return SUCCEEDED(rc) ? 1 : 0;