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 + 26];
266 memset( subststr, 0, substlen);
267 drive[0] = drivestr[0];
268 drive[1] = drivestr[1];
271 if ( substlen < 3 * sizeof( WCHAR))
274 // Cannot represent "D:"
279 if ( QueryDosDevice(drive, device, MAX_PATH + 26) )
281 #ifdef AFS_DEBUG_TRACE
282 AFSDbgPrint( L"DriveSubstitution QueryDosDevice %s [%s -> %s]\n",
287 if ( device[0] == L'\\' &&
290 device[3] == L'\\' &&
291 iswalpha(device[4]) &&
294 drive[0] = device[4];
298 if ( !DriveSubstitution(drive, subststr, substlen) )
301 subststr[0] = drive[0];
310 hr = StringCbCat( subststr, substlen, &device[6]);
312 if ( SUCCEEDED(hr) && drivestr[2] )
314 hr = StringCbCat( subststr, substlen, &drivestr[2]);
317 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
320 #ifdef AFS_DEBUG_TRACE
321 AFSDbgPrint( L"DriveSubstitution %s -> %s\n",
328 else if ( device[0] == L'\\' &&
331 device[3] == L'\\' &&
340 hr = StringCbCopyN(&subststr[1], substlen - sizeof(WCHAR), &device[7], sizeof(device));
342 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
346 hr = StringCbCat( subststr, substlen, &drivestr[2]);
353 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
356 #ifdef AFS_DEBUG_TRACE
357 AFSDbgPrint( L"DriveSubstitution %s -> %s\n",
365 #ifdef AFS_DEBUG_TRACE
366 AFSDbgPrint( L"DriveSubstitution StringCbCopyN 1 hr 0x%X\n",
370 else if ( _wcsnicmp( AFS_RDR_DEVICE_NAME, device, sizeof( AFS_RDR_DEVICE_NAME) / sizeof( WCHAR) - 1) == 0)
373 // \Device\AFSRedirector\;X:\\afs\cellname
376 hr = StringCbCopy( subststr, substlen,
377 &device[3 + sizeof( AFS_RDR_DEVICE_NAME) / sizeof( WCHAR)]);
379 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
384 hr = StringCbCat( subststr, substlen, &drivestr[2]);
391 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
394 #ifdef AFS_DEBUG_TRACE
395 AFSDbgPrint( L"DriveSubstitution %s -> %s\n",
403 #ifdef AFS_DEBUG_TRACE
404 AFSDbgPrint( L"DriveSubstitution StringCbCopyN 2 hr 0x%X\n",
409 #ifdef AFS_DEBUG_TRACE
410 AFSDbgPrint( L"DriveSubstitution no substitution or match %s !! %s\n",
417 #ifdef AFS_DEBUG_TRACE
418 AFSDbgPrint( L"DriveSubstitution QueryDosDevice failed %s gle 0x%X\n",
431 NPGetCapsQueryString( DWORD nIndex)
434 case WNNC_SPEC_VERSION:
435 return L"WNNC_SPEC_VERSION";
438 return L"WNNC_NET_TYPE";
440 case WNNC_DRIVER_VERSION:
441 return L"WNNC_DRIVER_VERSION";
446 case WNNC_CONNECTION:
447 return L"WNNC_CONNECTION";
450 return L"WNNC_DIALOG";
453 return L"WNNC_ADMIN";
455 case WNNC_ENUMERATION:
456 return L"WNNC_ENUMERATION";
459 return L"WNNC_START";
461 case WNNC_CONNECTION_FLAGS:
462 return L"WNNC_CONNECTION_FLAGS";
470 // This is the only function which must be exported, everything else is optional
475 NPGetCaps( DWORD nIndex )
480 #ifdef AFS_DEBUG_TRACE
481 AFSDbgPrint( L"NPGetCaps Index %u %s\n", nIndex,
482 NPGetCapsQueryString( nIndex));
486 case WNNC_SPEC_VERSION:
489 rc = WNNC_SPEC_VERSION51;
495 rc = WNNC_NET_OPENAFS;
499 case WNNC_DRIVER_VERSION:
502 rc = WNNC_DRIVER(1, 0);
506 case WNNC_CONNECTION:
511 // WNNC_CON_GETPERFORMANCE
515 rc = WNNC_CON_GETCONNECTIONS |
516 WNNC_CON_CANCELCONNECTION |
517 WNNC_CON_ADDCONNECTION |
518 WNNC_CON_ADDCONNECTION3;
523 case WNNC_ENUMERATION:
525 rc = WNNC_ENUM_LOCAL |
535 rc = WNNC_WAIT_FOR_START;
545 // WNNC_DLG_DEVICEMODE
546 // WNNC_DLG_PROPERTYDIALOG
547 // WNNC_DLG_SEARCHDIALOG
548 // WNNC_DLG_PERMISSIONEDITOR
551 rc = WNNC_DLG_FORMATNETWORKNAME |
552 WNNC_DLG_GETRESOURCEINFORMATION |
553 WNNC_DLG_GETRESOURCEPARENT;
572 // WNNC_ADM_GETDIRECTORYTYPE
573 // WNNC_ADM_DIRECTORYNOTIFY
574 // used by the old File Manager
585 NPAddConnection( LPNETRESOURCE lpNetResource,
590 #ifdef AFS_DEBUG_TRACE
591 AFSDbgPrint( L"NPAddConnection forwarding to NPAddConnection3\n");
593 return NPAddConnection3( NULL, lpNetResource, lpPassword, lpUserName, 0 );
598 NPAddConnection3( HWND hwndOwner,
599 LPNETRESOURCE lpNetResource,
605 DWORD dwStatus = WN_SUCCESS;
606 WCHAR wchRemoteName[MAX_PATH+1];
607 WCHAR wchLocalName[3];
608 DWORD dwCopyBytes = 0;
609 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
611 DWORD dwBufferSize = 0;
612 HANDLE hControlDevice = NULL;
613 HANDLE hToken = NULL;
614 LARGE_INTEGER liAuthId = {0,0};
619 if ( NPIsFSDisabled())
622 #ifdef AFS_DEBUG_TRACE
623 AFSDbgPrint( L"NPAddConnection3 AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
626 return WN_BAD_NETNAME;
629 if ((lpNetResource->lpRemoteName == NULL) ||
630 (lpNetResource->lpRemoteName[0] != L'\\') ||
631 (lpNetResource->lpRemoteName[1] != L'\\') ||
632 ((lpNetResource->dwType != RESOURCETYPE_DISK) &&
633 (lpNetResource->dwType != RESOURCETYPE_ANY)))
636 #ifdef AFS_DEBUG_TRACE
637 AFSDbgPrint( L"NPAddConnection3 invalid input, returning WN_BAD_NETNAME\n");
639 return WN_BAD_NETNAME;
642 #ifdef AFS_DEBUG_TRACE
643 AFSDbgPrint( L"NPAddConnection3 processing\n");
645 if( lpNetResource->lpLocalName != NULL)
648 wchLocalName[0] = towupper(lpNetResource->lpLocalName[0]);
649 wchLocalName[1] = L':';
650 wchLocalName[2] = L'\0';
653 hr = StringCbCopy(wchRemoteName, sizeof( wchRemoteName), lpNetResource->lpRemoteName);
657 #ifdef AFS_DEBUG_TRACE
658 AFSDbgPrint( L"NPAddConnection3 lpRemoteName longer than MAX_PATH, returning WN_BAD_NETNAME\n");
660 return WN_BAD_NETNAME;
664 // Allocate our buffer to pass to the redirector filter
667 dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + (wcslen( wchRemoteName) * sizeof( WCHAR));
669 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
671 if( pConnectCB == NULL)
674 try_return( dwStatus = WN_OUT_OF_MEMORY);
677 if( lpNetResource->lpLocalName != NULL)
680 pConnectCB->LocalName = towupper(wchLocalName[0]);
682 #ifdef AFS_DEBUG_TRACE
683 AFSDbgPrint( L"NPAddConnection3 Adding mapping for drive %s remote name %s\n",
691 pConnectCB->LocalName = L'\0';
693 #ifdef AFS_DEBUG_TRACE
694 AFSDbgPrint( L"NPAddConnection3 Adding mapping for NO drive remote name %s\n",
699 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
701 pConnectCB->RemoteNameLength = wcslen( wchRemoteName) * sizeof( WCHAR);
703 memcpy( pConnectCB->RemoteName,
705 pConnectCB->RemoteNameLength);
707 pConnectCB->Type = lpNetResource->dwType;
709 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
711 #ifdef AFS_DEBUG_TRACE
712 AFSDbgPrint( L"NPAddConnection3 Retrieved authentication id %08lX-%08lX\n",
713 pConnectCB->AuthenticationId.HighPart,
714 pConnectCB->AuthenticationId.LowPart);
717 hControlDevice = OpenRedirector();
719 if( hControlDevice == NULL)
722 #ifdef AFS_DEBUG_TRACE
723 AFSDbgPrint( L"NPAddConnection3 OpenRedirector failure, returning WN_NET_ERROR\n");
726 try_return( dwStatus = WN_NET_ERROR);
729 dwError = DeviceIoControl( hControlDevice,
730 IOCTL_AFS_ADD_CONNECTION,
740 #ifdef AFS_DEBUG_TRACE
741 AFSDbgPrint( L"NPAddConnection3 Failed to add connection to file system %d\n", GetLastError());
743 try_return( dwStatus = WN_OUT_OF_MEMORY);
747 // The status returned from the driver will indicate how it was handled
750 if( dwStatus == WN_SUCCESS &&
751 lpNetResource->lpLocalName != NULL)
754 WCHAR TempBuf[MAX_PATH+26];
756 if( !QueryDosDeviceW( wchLocalName,
761 if( GetLastError() != ERROR_FILE_NOT_FOUND)
764 #ifdef AFS_DEBUG_TRACE
765 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW failed with file not found\n");
767 NPCancelConnection( wchLocalName, TRUE);
769 dwStatus = ERROR_ALREADY_ASSIGNED;
774 UNICODE_STRING uniConnectionName;
777 // Create a symbolic link object to the device we are redirecting
780 uniConnectionName.MaximumLength = (USHORT)( wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR) +
781 pConnectCB->RemoteNameLength +
782 8 + // Local name and \;
783 sizeof(WCHAR)); // Space for NULL-termination.
786 // Don't include NULL-termination.
789 uniConnectionName.Length = uniConnectionName.MaximumLength - sizeof(WCHAR);
791 uniConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
792 uniConnectionName.MaximumLength);
794 if( uniConnectionName.Buffer == NULL)
797 try_return( dwStatus = GetLastError());
800 hr = StringCbCopyW( uniConnectionName.Buffer,
801 uniConnectionName.MaximumLength,
802 AFS_RDR_DEVICE_NAME);
805 #ifdef AFS_DEBUG_TRACE
806 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
808 try_return( dwStatus = WN_OUT_OF_MEMORY);
811 hr = StringCbCatW( uniConnectionName.Buffer,
812 uniConnectionName.MaximumLength,
816 #ifdef AFS_DEBUG_TRACE
817 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
819 try_return( dwStatus = WN_OUT_OF_MEMORY);
822 hr = StringCbCatW( uniConnectionName.Buffer,
823 uniConnectionName.MaximumLength,
827 #ifdef AFS_DEBUG_TRACE
828 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
830 try_return( dwStatus = WN_OUT_OF_MEMORY);
833 hr = StringCbCatW( uniConnectionName.Buffer,
834 uniConnectionName.MaximumLength,
838 #ifdef AFS_DEBUG_TRACE
839 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
841 try_return( dwStatus = WN_OUT_OF_MEMORY);
844 #ifdef AFS_DEBUG_TRACE
845 AFSDbgPrint( L"NPAddConnection3 DefineDosDevice Local %s connection name %s\n",
847 uniConnectionName.Buffer);
850 if( !DefineDosDeviceW( DDD_RAW_TARGET_PATH |
851 DDD_NO_BROADCAST_SYSTEM,
853 uniConnectionName.Buffer))
855 #ifdef AFS_DEBUG_TRACE
856 AFSDbgPrint( L"NPAddConnection3 Failed to assign drive\n");
858 dwStatus = GetLastError();
863 #ifdef AFS_DEBUG_TRACE
864 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW assigned drive %s\n", wchLocalName);
867 dwStatus = WN_SUCCESS;
870 LocalFree( uniConnectionName.Buffer);
876 #ifdef AFS_DEBUG_TRACE
877 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW %Z already existed\n", TempBuf);
879 NPCancelConnection( wchLocalName, TRUE);
881 dwStatus = ERROR_ALREADY_ASSIGNED;
887 if ( hControlDevice != NULL)
890 CloseHandle( hControlDevice);
893 if( pConnectCB != NULL)
896 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
905 NPCancelConnection( LPWSTR lpName,
909 WCHAR wchRemoteName[MAX_PATH+1];
910 DWORD dwRemoteNameLength = (MAX_PATH+1) * sizeof(WCHAR);
911 DWORD dwStatus = WN_NOT_CONNECTED;
912 DWORD dwCopyBytes = 0;
913 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
914 AFSCancelConnectionResultCB stCancelConn;
916 DWORD dwBufferSize = 0;
917 BOOL bLocalName = TRUE;
918 HANDLE hControlDevice = NULL;
919 WCHAR wchLocalName[ 3];
920 WCHAR *pwchLocalName = NULL;
926 if ( NPIsFSDisabled())
929 #ifdef AFS_DEBUG_TRACE
930 AFSDbgPrint( L"NPCancelConnection AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
933 try_return( dwStatus = WN_NOT_CONNECTED);
936 if( *lpName == L'\\' &&
937 *(lpName + 1) == L'\\')
942 wchLocalName[0] = L'\0';
944 hr = StringCbCopyW( wchRemoteName, sizeof( wchRemoteName), lpName);
948 #ifdef AFS_DEBUG_TRACE
949 AFSDbgPrint( L"NPCancelConnection lpName longer than MAX_PATH\n");
951 try_return( dwStatus = WN_OUT_OF_MEMORY);
954 dwRemoteNameLength = (wcslen( wchRemoteName) * sizeof( WCHAR));
959 wchLocalName[0] = towupper(lpName[0]);
960 wchLocalName[1] = L':';
961 wchLocalName[2] = L'\0';
964 // Get the remote name for the connection, if we are handling it
967 dwStatus = NPGetConnectionCommon( wchLocalName,
972 if( dwStatus != WN_SUCCESS ||
973 dwRemoteNameLength == 0)
976 #ifdef AFS_DEBUG_TRACE
977 AFSDbgPrint( L"NPCancelConnection Status 0x%x NameLength %u, returning WN_NOT_CONNECTED\n",
978 dwStatus, dwRemoteNameLength);
980 try_return( dwStatus = WN_NOT_CONNECTED);
984 // NPGetConnection returns the buffer size not the length without NUL
986 dwRemoteNameLength -= sizeof( WCHAR);
989 wchRemoteName[ dwRemoteNameLength/sizeof( WCHAR)] = L'\0';
991 #ifdef AFS_DEBUG_TRACE
992 AFSDbgPrint( L"NPCancelConnection Attempting to cancel '%s' -> '%s'\n",
993 wchLocalName, wchRemoteName);
996 dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + dwRemoteNameLength;
998 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1000 if( pConnectCB == NULL)
1003 try_return( dwStatus = WN_OUT_OF_MEMORY);
1009 pConnectCB->LocalName = wchLocalName[0];
1014 pConnectCB->LocalName = L'\0';
1017 pConnectCB->RemoteNameLength = (USHORT)dwRemoteNameLength;
1019 StringCbCopyW( pConnectCB->RemoteName,
1020 dwRemoteNameLength + sizeof( WCHAR),
1023 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1025 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1027 #ifdef AFS_DEBUG_TRACE
1028 AFSDbgPrint( L"NPCancelConnection Retrieved authentication id %08lX-%08lX\n",
1029 pConnectCB->AuthenticationId.HighPart,
1030 pConnectCB->AuthenticationId.LowPart);
1033 hControlDevice = OpenRedirector();
1035 if( hControlDevice == NULL)
1038 #ifdef AFS_DEBUG_TRACE
1039 AFSDbgPrint( L"NPCancelConnection OpenRedirector failure, returning WN_NET_ERROR\n");
1042 try_return( dwStatus = WN_NET_ERROR);
1045 memset( &stCancelConn,
1047 sizeof( AFSCancelConnectionResultCB));
1049 dwError = DeviceIoControl( hControlDevice,
1050 IOCTL_AFS_CANCEL_CONNECTION,
1054 sizeof( AFSCancelConnectionResultCB),
1060 #ifdef AFS_DEBUG_TRACE
1061 DWORD gle = GetLastError();
1063 AFSDbgPrint( L"NPCancelConnection DeviceIoControl failed - gle 0x%x\n", gle);
1065 try_return( dwStatus = WN_NOT_CONNECTED);
1068 dwStatus = stCancelConn.Status;
1070 #ifdef AFS_DEBUG_TRACE
1071 if ( dwStatus == WN_NOT_CONNECTED )
1074 AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status WN_NOT_CONNECTED\n",
1080 AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status %08lX\n",
1086 if( dwStatus == WN_SUCCESS &&
1088 stCancelConn.LocalName != L'\0'))
1091 UNICODE_STRING uniConnectionName;
1094 // Create a symbolic link object to the device we are redirecting
1097 uniConnectionName.MaximumLength = (USHORT)( wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR) +
1098 dwRemoteNameLength +
1099 8 + // Local name and \;
1100 sizeof(WCHAR)); // Space for NULL-termination.
1103 // Don't include NULL-termination.
1106 uniConnectionName.Length = uniConnectionName.MaximumLength - sizeof(WCHAR);
1108 uniConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
1109 uniConnectionName.MaximumLength);
1111 if( uniConnectionName.Buffer == NULL)
1114 try_return( dwStatus = GetLastError());
1117 hr = StringCbCopyW( uniConnectionName.Buffer,
1118 uniConnectionName.MaximumLength,
1119 AFS_RDR_DEVICE_NAME);
1123 #ifdef AFS_DEBUG_TRACE
1124 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (1)\n");
1126 try_return( dwStatus = WN_OUT_OF_MEMORY);
1129 hr = StringCbCatW( uniConnectionName.Buffer,
1130 uniConnectionName.MaximumLength,
1135 #ifdef AFS_DEBUG_TRACE
1136 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (2)\n");
1138 try_return( dwStatus = WN_OUT_OF_MEMORY);
1144 wchLocalName[ 0] = stCancelConn.LocalName;
1146 wchLocalName[ 1] = L':';
1148 wchLocalName[ 2] = L'\0';
1150 hr = StringCbCatW( uniConnectionName.Buffer,
1151 uniConnectionName.MaximumLength,
1156 #ifdef AFS_DEBUG_TRACE
1157 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (3)\n");
1159 try_return( dwStatus = WN_OUT_OF_MEMORY);
1162 pwchLocalName = wchLocalName;
1167 hr = StringCbCatW( uniConnectionName.Buffer,
1168 uniConnectionName.MaximumLength,
1173 #ifdef AFS_DEBUG_TRACE
1174 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (4)\n");
1176 try_return( dwStatus = WN_OUT_OF_MEMORY);
1179 pwchLocalName = lpName;
1182 hr = StringCbCatW( uniConnectionName.Buffer,
1183 uniConnectionName.MaximumLength,
1188 #ifdef AFS_DEBUG_TRACE
1189 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (5)\n");
1191 try_return( dwStatus = WN_OUT_OF_MEMORY);
1194 if( !DefineDosDevice( DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE,
1196 uniConnectionName.Buffer))
1199 #ifdef AFS_DEBUG_TRACE
1200 DWORD gle = GetLastError();
1202 AFSDbgPrint( L"NPCancelConnection Failed to cancel connection to system - gle 0x%x Name %s connection %wZ\n",
1205 &uniConnectionName);
1210 #ifdef AFS_DEBUG_TRACE
1212 AFSDbgPrint( L"NPCancelConnection Canceled connection to system - Name %s connection %wZ\n",
1214 &uniConnectionName);
1221 if ( hControlDevice != NULL)
1224 CloseHandle( hControlDevice);
1228 if( pConnectCB != NULL)
1231 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1241 NPGetConnection( LPWSTR lpLocalName,
1242 LPWSTR lpRemoteName,
1243 LPDWORD lpBufferSize)
1246 return NPGetConnectionCommon( lpLocalName,
1254 NPGetConnectionCommon( LPWSTR lpLocalName,
1255 LPWSTR lpRemoteName,
1256 LPDWORD lpBufferSize,
1260 DWORD dwStatus = WN_NOT_CONNECTED;
1261 WCHAR wchLocalName[3];
1262 WCHAR wchSubstName[1024 + 26];
1263 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1265 DWORD dwBufferSize = 0;
1266 HANDLE hControlDevice = NULL;
1272 if ( NPIsFSDisabled())
1275 #ifdef AFS_DEBUG_TRACE
1276 AFSDbgPrint( L"NPGetConnection AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1279 try_return( dwStatus = WN_NOT_CONNECTED);
1282 if( lstrlen( lpLocalName) == 0)
1284 #ifdef AFS_DEBUG_TRACE
1285 AFSDbgPrint( L"NPGetConnection No local name, returning WN_BAD_LOCALNAME\n");
1287 try_return( dwStatus = WN_BAD_LOCALNAME);
1290 if ( lpBufferSize == NULL)
1292 #ifdef AFS_DEBUG_TRACE
1293 AFSDbgPrint( L"NPGetConnection No output size, returning WN_BAD_LOCALNAME\n");
1295 try_return( dwStatus = WN_BAD_VALUE);
1298 dwPassedSize = *lpBufferSize;
1300 if ( !bDriveSubstOk ||
1301 !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName)))
1303 wchLocalName[0] = towupper(lpLocalName[0]);
1304 wchLocalName[1] = L':';
1305 wchLocalName[2] = L'\0';
1307 #ifdef AFS_DEBUG_TRACE
1308 AFSDbgPrint( L"NPGetConnection Requesting connection for %s\n",
1314 ReadServerNameString();
1316 if ( wchSubstName[0] != L'\\' &&
1317 wchSubstName[1] == L':')
1320 wchLocalName[0] = towupper(wchSubstName[0]);
1321 wchLocalName[1] = L':';
1322 wchLocalName[2] = L'\0';
1324 #ifdef AFS_DEBUG_TRACE
1325 AFSDbgPrint( L"NPGetConnection Requesting connection for drive substitution %s -> %s\n",
1330 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
1331 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
1332 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
1337 DWORD dwRequiredSize;
1339 #ifdef AFS_DEBUG_TRACE
1340 AFSDbgPrint( L"NPGetConnection drive substitution %s is AFS\n",
1344 dwRequiredSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
1346 if ( lpRemoteName == NULL ||
1347 dwPassedSize == 0 ||
1348 dwRequiredSize > *lpBufferSize)
1351 *lpBufferSize = dwRequiredSize;
1353 try_return( dwStatus = WN_MORE_DATA);
1357 hr = StringCbCopyN(lpRemoteName, *lpBufferSize, wchSubstName, sizeof( wchSubstName));
1362 for ( dwCount = 0, pwch = lpRemoteName; *pwch && pwch < lpRemoteName + (*lpBufferSize); pwch++ )
1364 if ( *pwch == L'\\' )
1378 *lpBufferSize = wcslen( lpRemoteName) * sizeof( WCHAR) + sizeof( WCHAR);
1380 try_return( dwStatus = WN_SUCCESS);
1382 else if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER)
1385 *lpBufferSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
1387 for ( dwCount = 0, pwch = lpRemoteName; *pwch; pwch++ )
1389 if ( *pwch == L'\\' )
1397 *lpBufferSize = wcslen( lpRemoteName) * sizeof( WCHAR) + sizeof( WCHAR);
1399 try_return( dwStatus = WN_SUCCESS);
1405 try_return( dwStatus = WN_MORE_DATA);
1410 #ifdef AFS_DEBUG_TRACE
1411 AFSDbgPrint( L"NPGetConnection StringCbCopyN failure 0x%X\n",
1414 try_return( dwStatus = WN_NET_ERROR);
1420 #ifdef AFS_DEBUG_TRACE
1421 AFSDbgPrint( L"NPGetConnection drive substitution %s is not AFS\n",
1424 try_return( dwStatus = WN_NOT_CONNECTED);
1428 #ifdef AFS_DEBUG_TRACE
1429 AFSDbgPrint( L"NPGetConnection Requesting connection for %s\n",
1433 dwBufferSize = 0x1000;
1435 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1437 if( pConnectCB == NULL)
1440 try_return( dwStatus = WN_OUT_OF_MEMORY);
1443 pConnectCB->LocalName = towupper(wchLocalName[0]);
1445 pConnectCB->RemoteNameLength = 0;
1447 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1449 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1451 #ifdef AFS_DEBUG_TRACE
1452 AFSDbgPrint( L"NPGetConnection Retrieved authentication id %08lX-%08lX\n",
1453 pConnectCB->AuthenticationId.HighPart,
1454 pConnectCB->AuthenticationId.LowPart);
1457 hControlDevice = OpenRedirector();
1459 if( hControlDevice == NULL)
1462 #ifdef AFS_DEBUG_TRACE
1463 AFSDbgPrint( L"NPGetConnection OpenRedirector failure, returning WN_NET_ERROR\n");
1466 try_return( dwStatus = WN_NET_ERROR);
1469 dwError = DeviceIoControl( hControlDevice,
1470 IOCTL_AFS_GET_CONNECTION,
1480 #ifdef AFS_DEBUG_TRACE
1481 DWORD gle = GetLastError();
1483 AFSDbgPrint( L"NPGetConnection Failed to get connection from file system for local %s gle 0x%x\n",
1486 try_return( dwStatus = WN_NOT_CONNECTED);
1490 // IOCTL_AFS_GET_CONNECTION returns a counted string
1493 if( lpRemoteName == NULL ||
1494 *lpBufferSize + sizeof( WCHAR) > dwPassedSize)
1497 *lpBufferSize += sizeof( WCHAR);
1499 try_return( dwStatus = WN_MORE_DATA);
1502 memcpy( lpRemoteName,
1506 lpRemoteName[ *lpBufferSize/sizeof( WCHAR)] = L'\0';
1508 *lpBufferSize += sizeof( WCHAR);
1510 #ifdef AFS_DEBUG_TRACE
1511 AFSDbgPrint( L"NPGetConnection local %s remote %s\n",
1515 dwStatus = WN_SUCCESS;
1519 if ( hControlDevice != NULL)
1522 CloseHandle( hControlDevice);
1525 if( pConnectCB != NULL)
1528 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1537 NPGetConnection3( IN LPCWSTR lpLocalName,
1539 OUT LPVOID lpBuffer,
1540 IN OUT LPDWORD lpBufferSize)
1543 DWORD dwStatus = WN_NOT_CONNECTED;
1544 WCHAR wchLocalName[3];
1545 WCHAR wchSubstName[1024 + 26];
1546 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1548 DWORD dwBufferSize = 0;
1549 HANDLE hControlDevice = NULL;
1551 DWORD *pConnectState =(DWORD *)lpBuffer;
1556 if ( NPIsFSDisabled())
1559 #ifdef AFS_DEBUG_TRACE
1560 AFSDbgPrint( L"NPGetConnection3 AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1563 try_return( dwStatus = WN_NOT_CONNECTED);
1566 if( lstrlen( lpLocalName) == 0)
1568 #ifdef AFS_DEBUG_TRACE
1569 AFSDbgPrint( L"NPGetConnection3 No local name, returning WN_BAD_LOCALNAME\n");
1571 try_return( dwStatus = WN_BAD_LOCALNAME);
1575 // LanMan NPGetConnection3 only responds to level 1
1578 if ( dwLevel != 0x1)
1580 #ifdef AFS_DEBUG_TRACE
1581 AFSDbgPrint( L"NPGetConnection3 Level 0x%X returning WN_BAD_LEVEL\n", dwLevel);
1583 try_return( dwStatus = WN_BAD_LEVEL);
1586 if ( lpBufferSize == NULL)
1588 #ifdef AFS_DEBUG_TRACE
1589 AFSDbgPrint( L"NPGetConnection3 No output size, returning WN_BAD_VALUE\n");
1591 try_return( dwStatus = WN_BAD_VALUE);
1594 dwPassedSize = *lpBufferSize;
1596 if ( dwPassedSize == 0 ||
1600 *lpBufferSize = sizeof( DWORD);
1602 try_return( dwStatus = WN_MORE_DATA);
1605 if ( !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName)))
1607 wchLocalName[0] = towupper(lpLocalName[0]);
1608 wchLocalName[1] = L':';
1609 wchLocalName[2] = L'\0';
1611 #ifdef AFS_DEBUG_TRACE
1612 AFSDbgPrint( L"NPGetConnection3 Requesting connection for %s level 0x%X\n",
1620 ReadServerNameString();
1622 if ( wchSubstName[0] != L'\\' &&
1623 wchSubstName[1] == L':')
1626 wchLocalName[0] = towupper(wchSubstName[0]);
1627 wchLocalName[1] = L':';
1628 wchLocalName[2] = L'\0';
1630 #ifdef AFS_DEBUG_TRACE
1631 AFSDbgPrint( L"NPGetConnection3 Requesting connection for drive substitution %s -> %s level 0x%x\n",
1637 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
1638 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
1639 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
1642 #ifdef AFS_DEBUG_TRACE
1643 AFSDbgPrint( L"NPGetConnection3 drive substitution %s is AFS return connected\n",
1646 *pConnectState = WNGETCON_CONNECTED;
1648 *lpBufferSize = sizeof( DWORD);
1650 try_return( dwStatus = WN_SUCCESS);
1655 #ifdef AFS_DEBUG_TRACE
1656 AFSDbgPrint( L"NPGetConnection3 drive substitution %s is not AFS return not connected\n",
1659 try_return( dwStatus = WN_NOT_CONNECTED);
1663 dwBufferSize = 0x1000;
1665 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1667 if( pConnectCB == NULL)
1670 try_return( dwStatus = WN_OUT_OF_MEMORY);
1673 pConnectCB->LocalName = towupper(wchLocalName[0]);
1675 pConnectCB->RemoteNameLength = 0;
1677 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1679 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1681 #ifdef AFS_DEBUG_TRACE
1682 AFSDbgPrint( L"NPGetConnection3 Retrieved authentication id %08lX-%08lX\n",
1683 pConnectCB->AuthenticationId.HighPart,
1684 pConnectCB->AuthenticationId.LowPart);
1687 hControlDevice = OpenRedirector();
1689 if( hControlDevice == NULL)
1692 #ifdef AFS_DEBUG_TRACE
1693 AFSDbgPrint( L"NPGetConnection3 OpenRedirector failure, returning WN_NET_ERROR\n");
1696 try_return( dwStatus = WN_NET_ERROR);
1699 dwError = DeviceIoControl( hControlDevice,
1700 IOCTL_AFS_GET_CONNECTION,
1710 #ifdef AFS_DEBUG_TRACE
1711 DWORD gle = GetLastError();
1713 AFSDbgPrint( L"NPGetConnection3 Failed to get connection from file system for local %s gle 0x%x\n",
1716 try_return( dwStatus = WN_NOT_CONNECTED);
1719 *lpBufferSize = sizeof( DWORD);
1721 if( sizeof( DWORD) > dwPassedSize)
1724 try_return( dwStatus = WN_MORE_DATA);
1727 *pConnectState = WNGETCON_CONNECTED;
1729 #ifdef AFS_DEBUG_TRACE
1730 AFSDbgPrint( L"NPGetConnection3 local %s connect-state 0x%x\n",
1734 dwStatus = WN_SUCCESS;
1738 if ( hControlDevice != NULL)
1741 CloseHandle( hControlDevice);
1744 if( pConnectCB != NULL)
1747 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1756 NPGetConnectionPerformance( LPCWSTR lpRemoteName,
1757 LPNETCONNECTINFOSTRUCT lpNetConnectInfo)
1760 DWORD dwReturn = WN_SUCCESS;
1761 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1762 DWORD dwBufferSize = 0;
1763 HANDLE hControlDevice = NULL;
1769 if ( NPIsFSDisabled())
1772 #ifdef AFS_DEBUG_TRACE
1773 AFSDbgPrint( L"NPGetConnectionPerformance AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
1776 return WN_NO_NETWORK;
1779 AFSDbgPrint( L"NPGetConnectionPerformance Entry for remote connection %S\n",
1782 dwBufferSize = 0x1000;
1784 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1786 if( pConnectCB == NULL)
1788 try_return( dwReturn = WN_OUT_OF_MEMORY);
1791 pConnectCB->RemoteNameLength = wcslen( lpRemoteName) * sizeof( WCHAR);
1793 StringCbCopy( pConnectCB->RemoteName,
1794 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
1797 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1799 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1801 hControlDevice = OpenRedirector();
1803 if( hControlDevice == NULL)
1805 AFSDbgPrint( L"NPGetConnectionPerformance OpenRedirector failure, returning WN_NET_ERROR\n");
1807 try_return( dwReturn = WN_NET_ERROR);
1810 dwError = DeviceIoControl( hControlDevice,
1811 IOCTL_AFS_GET_CONNECTION_INFORMATION,
1821 #ifdef AFS_DEBUG_TRACE
1822 DWORD gle = GetLastError();
1824 AFSDbgPrint( L"NPGetConnectionPerformance Failed to get connection info from file system for remote %S gle 0x%x\n",
1828 try_return( dwReturn = WN_NOT_CONNECTED);
1831 lpNetConnectInfo->dwFlags = WNCON_DYNAMIC;
1833 lpNetConnectInfo->dwSpeed = 500;
1835 lpNetConnectInfo->dwDelay = 0;
1837 lpNetConnectInfo->dwOptDataSize = 0x1000;
1839 AFSDbgPrint( L"NPGetConnectionPerformance Successfully returned information for remote connection %S\n",
1844 if ( hControlDevice != NULL)
1846 CloseHandle( hControlDevice);
1849 if( pConnectCB != NULL)
1851 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1859 GetUsageString( DWORD dwUsage)
1861 static WCHAR Buffer[128] = L"";
1863 // RESOURCEUSAGE_CONNECTABLE 0x00000001
1864 // RESOURCEUSAGE_CONTAINER 0x00000002
1865 // RESOURCEUSAGE_NOLOCALDEVICE 0x00000004
1866 // RESOURCEUSAGE_SIBLING 0x00000008
1867 // RESOURCEUSAGE_ATTACHED 0x00000010
1868 // RESOURCEUSAGE_ALL (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED)
1869 // RESOURCEUSAGE_RESERVED 0x80000000
1874 if ( dwUsage == RESOURCEUSAGE_ALL )
1884 if ( dwUsage & RESOURCEUSAGE_CONNECTABLE )
1886 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTABLE|");
1889 if ( dwUsage & RESOURCEUSAGE_CONTAINER )
1891 StringCbCat( Buffer, sizeof(Buffer), L"CONTAINER|");
1894 if ( dwUsage & RESOURCEUSAGE_NOLOCALDEVICE )
1896 StringCbCat( Buffer, sizeof(Buffer), L"NOLOCALDEVICE|");
1899 if ( dwUsage & RESOURCEUSAGE_SIBLING )
1901 StringCbCat( Buffer, sizeof(Buffer), L"SIBLING|");
1904 if ( dwUsage & RESOURCEUSAGE_ATTACHED )
1906 StringCbCat( Buffer, sizeof(Buffer), L"ATTACHED|");
1909 if ( dwUsage & RESOURCEUSAGE_RESERVED )
1911 StringCbCat( Buffer, sizeof(Buffer), L"RESERVED|");
1914 if ( dwUsage & ~(RESOURCEUSAGE_ALL|RESOURCEUSAGE_NOLOCALDEVICE|RESOURCEUSAGE_SIBLING|RESOURCEUSAGE_RESERVED) )
1916 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
1919 Buffer[lstrlen(Buffer)-1] = L'\0';
1925 GetTypeString( DWORD dwType)
1927 static WCHAR Buffer[128] = L"";
1930 // RESOURCETYPE_ANY 0x00000000
1931 // RESOURCETYPE_DISK 0x00000001
1932 // RESOURCETYPE_PRINT 0x00000002
1933 // RESOURCETYPE_RESERVED 0x00000008
1934 // RESOURCETYPE_UNKNOWN 0xFFFFFFFF
1939 if ( dwType == RESOURCETYPE_ANY )
1944 if ( dwType == RESOURCETYPE_UNKNOWN )
1949 if ( dwType & RESOURCETYPE_DISK )
1951 StringCbCat( Buffer, sizeof(Buffer), L"DISK|");
1954 if ( dwType & RESOURCETYPE_PRINT )
1956 StringCbCat( Buffer, sizeof(Buffer), L"PRINT|");
1959 if ( dwType & RESOURCETYPE_RESERVED )
1961 StringCbCat( Buffer, sizeof(Buffer), L"RESERVED|");
1964 if ( dwType & ~(RESOURCETYPE_DISK|RESOURCETYPE_PRINT|RESOURCETYPE_RESERVED) )
1966 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
1969 Buffer[lstrlen(Buffer)-1] = L'\0';
1975 GetScopeString( DWORD dwScope)
1977 static WCHAR Buffer[128] = L"";
1980 // RESOURCE_CONNECTED 0x00000001
1981 // RESOURCE_GLOBALNET 0x00000002
1982 // RESOURCE_REMEMBERED 0x00000003
1983 // RESOURCE_RECENT 0x00000004
1984 // RESOURCE_CONTEXT 0x00000005
1989 if ( dwScope == RESOURCE_CONNECTED )
1991 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTED|");
1994 if ( dwScope == RESOURCE_GLOBALNET )
1996 StringCbCat( Buffer, sizeof(Buffer), L"GLOBALNET|");
1999 if ( dwScope == RESOURCE_REMEMBERED )
2001 StringCbCat( Buffer, sizeof(Buffer), L"REMEMBERED|");
2004 if ( dwScope == RESOURCE_RECENT )
2006 StringCbCat( Buffer, sizeof(Buffer), L"RECENT|");
2009 if ( dwScope == RESOURCE_CONTEXT )
2011 StringCbCat( Buffer, sizeof(Buffer), L"CONTEXT|");
2014 if ( dwScope & ~(RESOURCE_CONNECTED|RESOURCE_GLOBALNET|RESOURCE_REMEMBERED|RESOURCE_RECENT|RESOURCE_CONTEXT) )
2016 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
2019 Buffer[lstrlen(Buffer)-1] = L'\0';
2025 GetDisplayString( DWORD dwDisplay)
2028 // RESOURCEDISPLAYTYPE_GENERIC 0x00000000
2029 // RESOURCEDISPLAYTYPE_DOMAIN 0x00000001
2030 // RESOURCEDISPLAYTYPE_SERVER 0x00000002
2031 // RESOURCEDISPLAYTYPE_SHARE 0x00000003
2032 // RESOURCEDISPLAYTYPE_FILE 0x00000004
2033 // RESOURCEDISPLAYTYPE_GROUP 0x00000005
2034 // RESOURCEDISPLAYTYPE_NETWORK 0x00000006
2035 // RESOURCEDISPLAYTYPE_ROOT 0x00000007
2036 // RESOURCEDISPLAYTYPE_SHAREADMIN 0x00000008
2037 // RESOURCEDISPLAYTYPE_DIRECTORY 0x00000009
2038 // RESOURCEDISPLAYTYPE_TREE 0x0000000A
2039 // RESOURCEDISPLAYTYPE_NDSCONTAINER 0x0000000B
2042 switch ( dwDisplay ) {
2043 case RESOURCEDISPLAYTYPE_GENERIC:
2045 case RESOURCEDISPLAYTYPE_DOMAIN:
2047 case RESOURCEDISPLAYTYPE_SERVER:
2049 case RESOURCEDISPLAYTYPE_SHARE:
2051 case RESOURCEDISPLAYTYPE_FILE:
2053 case RESOURCEDISPLAYTYPE_GROUP:
2055 case RESOURCEDISPLAYTYPE_NETWORK:
2057 case RESOURCEDISPLAYTYPE_ROOT:
2059 case RESOURCEDISPLAYTYPE_SHAREADMIN:
2060 return L"SHAREADMIN";
2061 case RESOURCEDISPLAYTYPE_DIRECTORY:
2062 return L"DIRECTORY";
2063 case RESOURCEDISPLAYTYPE_TREE:
2065 case RESOURCEDISPLAYTYPE_NDSCONTAINER:
2066 return L"NDSCONTAINER";
2074 NPOpenEnum( DWORD dwScope,
2077 LPNETRESOURCE lpNetResource,
2081 DWORD dwStatus = WN_SUCCESS;
2082 AFSEnumerationCB *pEnumCB = NULL;
2084 #ifdef AFS_DEBUG_TRACE
2085 if ( lpNetResource == NULL)
2087 AFSDbgPrint( L"NPOpenEnum Scope %s Type %s Usage %s NetResource: (Null)\n",
2088 GetScopeString(dwScope), GetTypeString(dwType), GetUsageString(dwUsage));
2092 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",
2093 GetScopeString(dwScope),
2094 GetTypeString(dwType),
2095 GetUsageString(dwUsage),
2097 GetScopeString(lpNetResource->dwScope),
2098 GetTypeString(lpNetResource->dwType),
2099 GetDisplayString(lpNetResource->dwDisplayType),
2100 GetUsageString(lpNetResource->dwUsage),
2101 lpNetResource->lpLocalName,
2102 lpNetResource->lpRemoteName,
2103 lpNetResource->lpComment);
2109 dwUsage = RESOURCEUSAGE_ALL;
2113 if ( dwType == 0 || dwType == RESOURCEUSAGE_ATTACHED)
2115 dwType |= RESOURCETYPE_DISK | RESOURCETYPE_PRINT;
2119 *lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( AFSEnumerationCB));
2121 if( *lphEnum == NULL)
2124 return WN_OUT_OF_MEMORY;
2127 pEnumCB = (AFSEnumerationCB *)*lphEnum;
2129 pEnumCB->CurrentIndex = 0;
2131 pEnumCB->Type = dwType;
2135 case RESOURCE_CONNECTED:
2138 pEnumCB->Scope = RESOURCE_CONNECTED;
2143 case RESOURCE_CONTEXT:
2146 pEnumCB->Scope = RESOURCE_CONTEXT;
2151 case RESOURCE_GLOBALNET:
2154 if( lpNetResource != NULL &&
2155 lpNetResource->lpRemoteName != NULL)
2158 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2160 if( pEnumCB->RemoteName == NULL)
2163 dwStatus = WN_OUT_OF_MEMORY;
2164 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2170 StringCbCopy( pEnumCB->RemoteName,
2172 lpNetResource->lpRemoteName);
2177 pEnumCB->Scope = RESOURCE_GLOBALNET;
2184 #ifdef AFS_DEBUG_TRACE
2185 AFSDbgPrint( L"NPOpenEnum Processing (Scope %s 0x%x) Type %s Usage %s, returning WN_NOT_SUPPORTED\n",
2186 GetScopeString(dwScope), dwScope, GetTypeString(dwType), GetUsageString(dwUsage));
2189 dwStatus = WN_NOT_SUPPORTED;
2190 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2202 NPEnumResource( HANDLE hEnum,
2205 LPDWORD lpBufferSize)
2208 DWORD dwStatus = WN_NO_MORE_ENTRIES; //WN_SUCCESS;
2210 ULONG EntriesCopied;
2211 ULONG EntriesRequested;
2213 LPNETRESOURCE pNetResource;
2215 ULONG SpaceAvailable;
2217 AFSNetworkProviderConnectionCB *pConnectionCB = NULL;
2218 void *pConnectionCBBase = NULL;
2220 UNICODE_STRING uniRemoteName;
2221 HANDLE hControlDevice = NULL;
2222 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2227 if ( lpBufferSize == NULL)
2229 #ifdef AFS_DEBUG_TRACE
2230 AFSDbgPrint( L"NPEnumResource No output size, returning WN_BAD_VALUE\n");
2232 try_return( dwStatus = WN_BAD_VALUE);
2235 ReadProviderNameString();
2237 pNetResource = (LPNETRESOURCE) lpBuffer;
2238 SpaceAvailable = *lpBufferSize;
2239 EntriesRequested = *lpcCount;
2240 *lpcCount = EntriesCopied = 0;
2241 StringZone = (PWCHAR) ((char *)lpBuffer + *lpBufferSize);
2243 #ifdef AFS_DEBUG_TRACE
2244 AFSDbgPrint( L"NPEnumResource Processing Remote name %s Scope %s Type %s Usage %s Index %d SpaceAvailable 0x%lX RequestedEntries %lu\n",
2245 pEnumCB->RemoteName ? pEnumCB->RemoteName : L"(Null)",
2246 GetScopeString(pEnumCB->Scope),
2247 GetTypeString(pEnumCB->Type),
2248 GetUsageString(pEnumCB->Type),
2249 pEnumCB->CurrentIndex,
2254 if ( NPIsFSDisabled())
2257 #ifdef AFS_DEBUG_TRACE
2258 AFSDbgPrint( L"NPEnumResource AFSRDFS is disabled, returning WN_NO_MORE_ENTRIES\n");
2261 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2264 pConnectionCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 0x1000);
2266 if( pConnectionCB == NULL)
2269 #ifdef AFS_DEBUG_TRACE
2270 AFSDbgPrint( L"NPEnumResource Out of Memory\n");
2273 try_return( dwStatus = WN_OUT_OF_MEMORY);
2276 pConnectionCBBase = (void *)pConnectionCB;
2278 hControlDevice = OpenRedirector();
2280 if( hControlDevice == NULL)
2283 #ifdef AFS_DEBUG_TRACE
2284 AFSDbgPrint( L"NPEnumResource OpenRedirector failure, returning WN_NET_ERROR\n");
2287 try_return( dwStatus = WN_NET_ERROR);
2290 if( pEnumCB->Type != RESOURCETYPE_ANY && pEnumCB->Type != RESOURCETYPE_DISK)
2293 #ifdef AFS_DEBUG_TRACE
2294 AFSDbgPrint( L"NPEnumResource Non-DISK queries are not supported, returning WN_NO_MORE_ENTRIES\n");
2296 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2300 // Handle the special cases here
2301 // 0. Provider Network Root
2306 if ( pEnumCB->Scope == RESOURCE_GLOBALNET)
2309 ReadServerNameString();
2311 if ( pEnumCB->CurrentIndex == 0 &&
2312 pEnumCB->RemoteName == NULL)
2315 // Determine the space needed for this entry...
2317 SpaceNeeded = 2 * ( cbProviderNameLength + sizeof( WCHAR));
2319 uniRemoteName.Length = (USHORT)cbProviderNameLength;
2320 uniRemoteName.MaximumLength = uniRemoteName.Length;
2321 uniRemoteName.Buffer = wszProviderName;
2323 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2326 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2328 #ifdef AFS_DEBUG_TRACE
2329 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2333 try_return( dwStatus = WN_MORE_DATA);
2336 #ifdef AFS_DEBUG_TRACE
2337 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2341 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2343 pNetResource->dwScope = RESOURCE_GLOBALNET;
2344 pNetResource->dwType = RESOURCETYPE_ANY;
2345 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_NETWORK;
2346 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_RESERVED;
2348 // setup string area at opposite end of buffer
2349 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2351 pNetResource->lpLocalName = NULL;
2354 pNetResource->lpRemoteName = StringZone;
2356 StringCbCopy( StringZone,
2357 cbProviderNameLength + sizeof( WCHAR),
2360 StringZone += cbProviderNameLength / sizeof(WCHAR) + 1;
2362 pNetResource->lpComment = NULL;
2364 // copy provider name
2365 pNetResource->lpProvider = StringZone;
2366 StringCbCopy( StringZone,
2367 cbProviderNameLength + sizeof( WCHAR),
2370 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2372 #ifdef AFS_DEBUG_TRACE
2373 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2375 GetScopeString(pNetResource->dwScope),
2376 GetTypeString(pNetResource->dwType),
2377 GetDisplayString(pNetResource->dwDisplayType),
2378 GetUsageString(pNetResource->dwUsage),
2379 pNetResource->lpLocalName,
2380 pNetResource->lpRemoteName,
2381 pNetResource->lpComment);
2384 // setup the new end of buffer
2385 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2391 // do not change the index since we did not query the redirector
2392 pEnumCB->CurrentIndex = 0;
2394 // remember that we returned the provider name
2395 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2397 if( pEnumCB->RemoteName == NULL)
2400 try_return( dwStatus = WN_OUT_OF_MEMORY);
2405 StringCbCopy( pEnumCB->RemoteName,
2411 if ( pEnumCB->CurrentIndex == 0 &&
2412 lstrlen( pEnumCB->RemoteName) == cbProviderNameLength / sizeof( WCHAR) &&
2413 _wcsnicmp( pEnumCB->RemoteName, wszProviderName, cbProviderNameLength / sizeof( WCHAR)) == 0 &&
2414 EntriesCopied < EntriesRequested)
2418 // After the network provider entry comes the server entry
2421 // Determine the space needed for this entry...
2423 SpaceNeeded = cbProviderNameLength + cbServerNameUNCLength + cbServerCommentLength + 3 * sizeof( WCHAR);
2425 uniRemoteName.Length = (USHORT)cbServerNameUNCLength;
2426 uniRemoteName.MaximumLength = uniRemoteName.Length;
2427 uniRemoteName.Buffer = wszServerNameUNC;
2429 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2432 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2434 #ifdef AFS_DEBUG_TRACE
2435 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2439 try_return( dwStatus = WN_MORE_DATA);
2442 #ifdef AFS_DEBUG_TRACE
2443 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2447 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2449 pNetResource->dwScope = 0;
2450 pNetResource->dwType = RESOURCETYPE_ANY;
2451 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
2452 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
2454 // setup string area at opposite end of buffer
2455 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2457 pNetResource->lpLocalName = NULL;
2460 pNetResource->lpRemoteName = StringZone;
2462 StringCbCopy( StringZone,
2463 cbServerNameUNCLength + sizeof( WCHAR),
2466 StringZone += cbServerNameUNCLength / sizeof(WCHAR) + 1;
2469 pNetResource->lpComment = StringZone;
2471 StringCbCopy( StringZone,
2472 cbServerCommentLength + sizeof( WCHAR),
2475 StringZone += cbServerCommentLength / sizeof( WCHAR) + 1;
2477 // copy provider name
2478 pNetResource->lpProvider = StringZone;
2479 StringCbCopy( StringZone,
2480 cbProviderNameLength + sizeof( WCHAR),
2483 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2485 #ifdef AFS_DEBUG_TRACE
2486 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2488 GetScopeString(pNetResource->dwScope),
2489 GetTypeString(pNetResource->dwType),
2490 GetDisplayString(pNetResource->dwDisplayType),
2491 GetUsageString(pNetResource->dwUsage),
2492 pNetResource->lpLocalName,
2493 pNetResource->lpRemoteName,
2494 pNetResource->lpComment);
2497 // setup the new end of buffer
2498 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2504 // do not update the index because we did not query the redirector
2505 pEnumCB->CurrentIndex = 0;
2507 // remember that we returned the server
2508 StringCbCopy( pEnumCB->RemoteName,
2516 // Setup what we are going to ask for
2519 pConnectionCB->Scope = pEnumCB->Scope;
2521 pConnectionCB->Type = pEnumCB->Type;
2523 pConnectionCB->CurrentIndex = pEnumCB->CurrentIndex;
2525 pConnectionCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
2528 // If this is a RESOURCE_GLOBALNET enumeration then pass down the remote name if
2532 pConnectionCB->RemoteNameLength = 0;
2534 if( pEnumCB->Scope == RESOURCE_GLOBALNET &&
2535 pEnumCB->RemoteName != NULL)
2538 pConnectionCB->RemoteNameLength = wcslen( pEnumCB->RemoteName) * sizeof( WCHAR);
2540 StringCbCopy( pConnectionCB->RemoteName,
2541 (0x1000 - sizeof(AFSNetworkProviderConnectionCB)) + sizeof(WCHAR),
2542 pEnumCB->RemoteName);
2545 pConnectionCB->AuthenticationId = AFSRetrieveAuthId();
2547 #ifdef AFS_DEBUG_TRACE
2548 AFSDbgPrint( L"NPEnumResource Retrieved authentication id %08lX-%08lX\n",
2549 pConnectionCB->AuthenticationId.HighPart,
2550 pConnectionCB->AuthenticationId.LowPart);
2553 dwError = DeviceIoControl( hControlDevice,
2554 IOCTL_AFS_LIST_CONNECTIONS,
2564 #ifdef AFS_DEBUG_TRACE
2565 DWORD gle = GetLastError();
2567 AFSDbgPrint( L"NPEnumResource Failed to list connections from file system - gle 0x%x\n",
2570 try_return( dwStatus = WN_NOT_CONNECTED);
2573 if( dwCopyBytes == 0)
2576 #ifdef AFS_DEBUG_TRACE
2577 AFSDbgPrint( L"NPEnumResource No More Entries\n");
2579 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2582 dwIndex = pEnumCB->CurrentIndex;
2584 while( EntriesCopied < EntriesRequested)
2587 uniRemoteName.Length = (USHORT)pConnectionCB->RemoteNameLength;
2588 uniRemoteName.MaximumLength = uniRemoteName.Length;
2589 uniRemoteName.Buffer = pConnectionCB->RemoteName;
2591 // Determine the space needed for this entry...
2595 if( pConnectionCB->LocalName != 0)
2598 SpaceNeeded += 3 * sizeof(WCHAR); // local name
2601 SpaceNeeded += pConnectionCB->RemoteNameLength + sizeof( WCHAR); // remote name
2603 if( pConnectionCB->CommentLength > 0)
2606 SpaceNeeded += pConnectionCB->CommentLength + sizeof( WCHAR); // comment
2609 SpaceNeeded += cbProviderNameLength + sizeof( WCHAR); // provider name
2611 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2614 if (EntriesCopied == 0) {
2616 dwStatus = WN_MORE_DATA;
2618 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2620 #ifdef AFS_DEBUG_TRACE
2621 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2628 #ifdef AFS_DEBUG_TRACE
2629 AFSDbgPrint( L"NPEnumResource Return SUCCESS but more entries Index %d\n",
2633 dwStatus = WN_SUCCESS;
2639 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2641 pNetResource->dwScope = pConnectionCB->Scope;
2642 pNetResource->dwType = pConnectionCB->Type;
2644 pNetResource->dwDisplayType = pConnectionCB->DisplayType;
2646 if ( pNetResource->dwType == RESOURCETYPE_ANY &&
2647 pNetResource->dwDisplayType == RESOURCEDISPLAYTYPE_SHARE)
2650 pNetResource->dwType = RESOURCETYPE_DISK;
2653 if ( pEnumCB->Scope == RESOURCE_CONNECTED)
2656 pNetResource->dwUsage = 0;
2661 pNetResource->dwUsage = pConnectionCB->Usage;
2664 // setup string area at opposite end of buffer
2665 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2668 if( pConnectionCB->LocalName != 0)
2671 pNetResource->lpLocalName = StringZone;
2672 *StringZone++ = towupper(pConnectionCB->LocalName);
2673 *StringZone++ = L':';
2674 *StringZone++ = L'\0';
2679 pNetResource->lpLocalName = NULL;
2682 #ifdef AFS_DEBUG_TRACE
2683 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2688 pNetResource->lpRemoteName = StringZone;
2690 CopyMemory( StringZone,
2691 pConnectionCB->RemoteName,
2692 pConnectionCB->RemoteNameLength);
2694 StringZone += (pConnectionCB->RemoteNameLength / sizeof(WCHAR));
2696 *StringZone++ = L'\0';
2699 if( pConnectionCB->CommentLength > 0)
2702 pNetResource->lpComment = StringZone;
2704 CopyMemory( StringZone,
2705 (void *)((char *)pConnectionCB + pConnectionCB->CommentOffset),
2706 pConnectionCB->CommentLength);
2708 StringZone += (pConnectionCB->CommentLength / sizeof(WCHAR));
2710 *StringZone++ = L'\0';
2715 pNetResource->lpComment = NULL;
2718 // copy provider name
2719 pNetResource->lpProvider = StringZone;
2720 StringCbCopy( StringZone,
2721 cbProviderNameLength + sizeof( WCHAR),
2724 StringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
2726 #ifdef AFS_DEBUG_TRACE
2727 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2729 GetScopeString(pNetResource->dwScope),
2730 GetTypeString(pNetResource->dwType),
2731 GetDisplayString(pNetResource->dwDisplayType),
2732 GetUsageString(pNetResource->dwUsage),
2733 pNetResource->lpLocalName,
2734 pNetResource->lpRemoteName,
2735 pNetResource->lpComment);
2738 // setup the new end of buffer
2739 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2747 dwCopyBytes -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2748 pConnectionCB->RemoteNameLength +
2749 pConnectionCB->CommentLength;
2751 if( dwCopyBytes == 0)
2754 dwStatus = WN_SUCCESS;
2759 pConnectionCB = (AFSNetworkProviderConnectionCB *)((char *)pConnectionCB +
2760 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2761 pConnectionCB->RemoteNameLength +
2762 pConnectionCB->CommentLength);
2765 *lpcCount = EntriesCopied;
2767 // update entry index
2768 pEnumCB->CurrentIndex = dwIndex;
2770 #ifdef AFS_DEBUG_TRACE
2771 AFSDbgPrint( L"NPEnumResource Completed Count %d Index %d\n",
2778 if ( hControlDevice != NULL)
2781 CloseHandle( hControlDevice);
2784 if( pConnectionCBBase != NULL)
2787 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectionCBBase);
2796 Routine Description:
2798 This routine closes the handle for enumeration of resources.
2802 hEnum - the enumeration handle
2806 WN_SUCCESS if successful, otherwise the appropriate error
2810 The sample only supports the notion of enumerating connected shares
2815 NPCloseEnum( HANDLE hEnum )
2818 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2820 #ifdef AFS_DEBUG_TRACE
2821 AFSDbgPrint( L"NPCloseEnum\n");
2824 if( pEnumCB->RemoteName != NULL)
2827 HeapFree( GetProcessHeap( ), 0, (PVOID) pEnumCB->RemoteName);
2830 HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum );
2836 NPGetResourceParent( LPNETRESOURCE lpNetResource,
2838 LPDWORD lpBufferSize )
2841 DWORD dwStatus = WN_ACCESS_DENIED;
2842 WCHAR *pwchRemoteName = NULL, *pwchSearch = NULL, *pwchSystem = NULL;
2843 LPNETRESOURCE lpOutResource = (LPNETRESOURCE) lpBuffer;
2845 if ( lpNetResource == NULL)
2847 #ifdef AFS_DEBUG_TRACE
2848 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2850 return WN_MORE_DATA;
2853 if( lpNetResource->lpRemoteName == NULL)
2855 #ifdef AFS_DEBUG_TRACE
2856 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2858 return WN_BAD_NETNAME;
2861 if ( lpNetResource->dwType != 0 &&
2862 lpNetResource->dwType != RESOURCETYPE_DISK)
2864 #ifdef AFS_DEBUG_TRACE
2865 AFSDbgPrint( L"NPGetResourceParent Bad dwType\n");
2867 return WN_BAD_VALUE;
2870 if ( lpBufferSize == NULL )
2873 #ifdef AFS_DEBUG_TRACE
2874 AFSDbgPrint( L"NPGetResourceParent Null lpBufferSize\n");
2876 return WN_BAD_VALUE;
2879 #ifdef AFS_DEBUG_TRACE
2880 AFSDbgPrint( L"NPGetResourceParent For remote name %s\n",
2881 lpNetResource->lpRemoteName);
2884 pwchRemoteName = lpNetResource->lpRemoteName;
2886 pwchSearch = pwchRemoteName + (wcslen( pwchRemoteName) - 1);
2888 while( pwchSearch != pwchRemoteName)
2891 if( *pwchSearch == L'\\')
2894 *pwchSearch = L'\0';
2902 if( pwchSearch != pwchRemoteName)
2905 #ifdef AFS_DEBUG_TRACE
2906 AFSDbgPrint( L"NPGetResourceParent Processing parent %s\n",
2907 lpNetResource->lpRemoteName);
2910 dwStatus = NPGetResourceInformation( lpNetResource,
2917 if ( lpOutResource == NULL ||
2918 *lpBufferSize < sizeof( NETRESOURCE) )
2920 *lpBufferSize = sizeof( NETRESOURCE);
2922 return WN_MORE_DATA;
2925 memset( lpOutResource, 0, sizeof( NETRESOURCE));
2935 NPGetResourceInformation( LPNETRESOURCE lpNetResource,
2937 LPDWORD lpBufferSize,
2938 LPWSTR *lplpSystem )
2941 DWORD dwStatus = WN_NOT_CONNECTED;
2942 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
2944 DWORD dwBufferSize = 0;
2945 HANDLE hControlDevice = NULL;
2946 NETRESOURCE *pNetResource = (NETRESOURCE *)lpBuffer;
2947 PWCHAR pStringZone = NULL;
2948 UNICODE_STRING uniRemoteName;
2949 DWORD ulRequiredLen = 0;
2960 ReadProviderNameString();
2962 if ( NPIsFSDisabled())
2965 #ifdef AFS_DEBUG_TRACE
2966 AFSDbgPrint( L"NPGetResourceInformation AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
2969 try_return( dwStatus = WN_BAD_NETNAME);
2972 if ( lpNetResource == NULL ||
2973 lpBufferSize == NULL )
2976 #ifdef AFS_DEBUG_TRACE
2977 AFSDbgPrint( L"NPGetResourceInformaton Null lpNetResource or lpBufferSize\n");
2979 return WN_BAD_VALUE;
2982 if( lpNetResource->lpRemoteName == NULL)
2984 #ifdef AFS_DEBUG_TRACE
2985 AFSDbgPrint( L"NPGetResourceInformation No resource name\n");
2988 try_return( dwStatus = WN_NOT_CONNECTED);
2991 dwPassedSize = *lpBufferSize;
2993 dwBufferSize = 0x1000;
2995 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
2997 if( pConnectCB == NULL)
3000 try_return( dwStatus = WN_OUT_OF_MEMORY);
3003 pConnectCB->RemoteNameLength = wcslen( lpNetResource->lpRemoteName) * sizeof( WCHAR);
3005 StringCbCopy( pConnectCB->RemoteName,
3006 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
3007 lpNetResource->lpRemoteName);
3009 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3011 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
3013 #ifdef AFS_DEBUG_TRACE
3014 AFSDbgPrint( L"NPGetResourceInformation Retrieved authentication id %08lX-%08lX\n",
3015 pConnectCB->AuthenticationId.HighPart,
3016 pConnectCB->AuthenticationId.LowPart);
3019 hControlDevice = OpenRedirector();
3021 if( hControlDevice == NULL)
3024 #ifdef AFS_DEBUG_TRACE
3025 AFSDbgPrint( L"NPGetResourceInformation OpenRedirector failure, returning WN_NET_ERROR\n");
3028 try_return( dwStatus = WN_NET_ERROR);
3031 dwError = DeviceIoControl( hControlDevice,
3032 IOCTL_AFS_GET_CONNECTION_INFORMATION,
3042 #ifdef AFS_DEBUG_TRACE
3043 DWORD gle = GetLastError();
3045 AFSDbgPrint( L"NPGetResourceInformation Failed to get connection info from file system for local %s gle 0x%x\n",
3046 lpNetResource->lpRemoteName, gle);
3048 try_return( dwStatus = WN_BAD_NETNAME);
3051 uniRemoteName.Length = (USHORT)pConnectCB->RemoteNameLength;
3052 uniRemoteName.MaximumLength = uniRemoteName.Length;
3053 uniRemoteName.Buffer = pConnectCB->RemoteName;
3055 #ifdef AFS_DEBUG_TRACE
3056 AFSDbgPrint( L"NPGetResourceInformation For remote name %wZ Scope %08lX Type %08lX Usage %08lX\n",
3063 // Determine the space needed for this entry...
3065 ulRequiredLen = sizeof( NETRESOURCE);
3067 ulRequiredLen += pConnectCB->RemoteNameLength + sizeof( WCHAR);
3069 ulRequiredLen += pConnectCB->CommentLength + sizeof( WCHAR);
3071 ulRequiredLen += cbProviderNameLength + sizeof( WCHAR);
3073 ulRequiredLen += pConnectCB->RemainingPathLength + sizeof( WCHAR);
3075 if( pNetResource == NULL ||
3076 ulRequiredLen > dwPassedSize)
3079 *lpBufferSize = ulRequiredLen;
3081 try_return( dwStatus = WN_MORE_DATA);
3084 pStringZone = (PWCHAR) ((char *)lpBuffer + sizeof( NETRESOURCE));
3086 pNetResource->dwScope = 0 /* pConnectCB->Scope*/;
3087 pNetResource->dwType = 0 /* pConnectCB->Type */;
3089 pNetResource->dwDisplayType = pConnectCB->DisplayType;
3091 pNetResource->dwUsage = pConnectCB->Usage;
3093 pNetResource->lpLocalName = NULL;
3096 pNetResource->lpRemoteName = pStringZone;
3098 CopyMemory( pStringZone,
3099 pConnectCB->RemoteName,
3100 pConnectCB->RemoteNameLength);
3102 pStringZone += (pConnectCB->RemoteNameLength / sizeof(WCHAR));
3104 *pStringZone++ = L'\0';
3107 pNetResource->lpComment = pStringZone;
3109 CopyMemory( pStringZone,
3110 (void *)((char *)pConnectCB + pConnectCB->CommentOffset),
3111 pConnectCB->CommentLength);
3113 pStringZone += (pConnectCB->CommentLength / sizeof(WCHAR));
3115 *pStringZone++ = L'\0';
3117 // copy remaining path
3118 if (pConnectCB->RemainingPathLength > 0)
3120 *lplpSystem = pStringZone;
3122 CopyMemory( pStringZone,
3123 (void *)((char *)pConnectCB + pConnectCB->RemainingPathOffset),
3124 pConnectCB->RemainingPathLength);
3126 pStringZone += (pConnectCB->RemainingPathLength / sizeof(WCHAR));
3128 *pStringZone++ = L'\0';
3130 #ifdef AFS_DEBUG_TRACE
3131 AFSDbgPrint( L"NPGetResourceInformation For remote name %s returning remaining path %s\n",
3132 pNetResource->lpRemoteName,
3137 // copy provider name
3138 pNetResource->lpProvider = pStringZone;
3140 StringCbCopy( pStringZone,
3141 cbProviderNameLength + sizeof( WCHAR),
3144 pStringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
3146 *lpBufferSize = ulRequiredLen;
3148 dwStatus = WN_SUCCESS;
3152 if ( hControlDevice != NULL)
3155 CloseHandle( hControlDevice);
3158 if( pConnectCB != NULL)
3161 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3169 SeparateRemainingPath( WCHAR * lpConnectionName, WCHAR **lppRemainingPath)
3176 // at this point the lpConnectionName contains the full name. We need to
3177 // truncate it to \\server\share and move the remaining path back one position.
3180 for ( pwch = lpConnectionName, dwCount = 0; *pwch; pwch++)
3182 if ( *pwch == L'\\')
3196 // Found the remaining path that must be moved
3199 *lppRemainingPath = pwch + 1;
3206 for ( ; *pwch; pwch++);
3209 // and work backwards moving the string
3210 // and then make sure that there is at least
3211 // a path separator.
3216 for ( ;pwch > *lppRemainingPath; pwch--)
3218 *pwch = *(pwch - 1);
3226 NPGetUniversalName( LPCWSTR lpLocalPath,
3229 LPDWORD lpBufferSize )
3231 DWORD dwStatus = WN_NOT_CONNECTED;
3232 WCHAR wchLocalName[3];
3233 WCHAR *pwchSubstName = NULL;
3234 DWORD dwSubstNameLength = 0;
3235 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3237 DWORD dwBufferSize = 0;
3238 DWORD dwPassedSize = *lpBufferSize;
3239 DWORD dwRemainingLength = *lpBufferSize;
3240 HANDLE hControlDevice = NULL;
3241 DWORD dwLocalPathLength = 0;
3242 DWORD dwRemainingPathLength = 0;
3248 #ifdef AFS_DEBUG_TRACE
3249 AFSDbgPrint( L"NPGetUniversalName local path %s level 0x%X\n",
3250 lpLocalPath ? lpLocalPath : L"(Null)",
3254 if ( NPIsFSDisabled())
3257 #ifdef AFS_DEBUG_TRACE
3258 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
3261 try_return( dwStatus = WN_NOT_CONNECTED);
3264 dwLocalPathLength = lstrlen( lpLocalPath);
3266 dwRemainingPathLength = dwLocalPathLength - 2; // no drive letter
3268 if( dwLocalPathLength == 0)
3271 #ifdef AFS_DEBUG_TRACE
3272 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_BAD_LOCALNAME\n");
3275 try_return( dwStatus = WN_BAD_LOCALNAME);
3278 if( lpBuffer == NULL ||
3279 lpBufferSize == NULL)
3281 #ifdef AFS_DEBUG_TRACE
3282 AFSDbgPrint( L"NPGetUniversalName No output buffer or size\n");
3284 try_return( dwStatus = WN_BAD_VALUE);
3287 dwSubstNameLength = (dwLocalPathLength + 26) * sizeof( WCHAR);
3289 pwchSubstName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSubstNameLength);
3291 if ( pwchSubstName == NULL)
3293 #ifdef AFS_DEBUG_TRACE
3294 AFSDbgPrint( L"NPGetUniversalName unable to allocate substitution name buffer.\n");
3296 try_return( dwStatus = WN_OUT_OF_MEMORY);
3299 memset(lpBuffer, 0, dwPassedSize);
3301 if ( !DriveSubstitution( lpLocalPath, pwchSubstName, dwSubstNameLength))
3303 wchLocalName[0] = towupper(lpLocalPath[0]);
3304 wchLocalName[1] = L':';
3305 wchLocalName[2] = L'\0';
3307 #ifdef AFS_DEBUG_TRACE
3308 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for %s level 0x%X\n",
3316 ReadServerNameString();
3318 if ( pwchSubstName[0] != L'\\' &&
3319 pwchSubstName[1] == L':')
3322 wchLocalName[0] = towupper(pwchSubstName[0]);
3323 wchLocalName[1] = L':';
3324 wchLocalName[2] = L'\0';
3326 #ifdef AFS_DEBUG_TRACE
3327 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for drive substitution %s -> %s\n",
3332 else if ( _wcsnicmp( pwchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
3333 ( pwchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
3334 pwchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
3338 #ifdef AFS_DEBUG_TRACE
3339 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is AFS; Level 0x%x BufferSize 0x%x\n",
3345 dwBufferSize = (wcslen( pwchSubstName) + 1) * sizeof( WCHAR);
3347 switch( dwInfoLevel)
3350 case UNIVERSAL_NAME_INFO_LEVEL:
3353 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3355 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize;
3357 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3360 #ifdef AFS_DEBUG_TRACE
3361 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3364 try_return( dwStatus = WN_MORE_DATA);
3367 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3369 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3371 memcpy( pUniversalInfo->lpUniversalName,
3373 min( dwBufferSize, dwRemainingLength));
3375 dwRemainingLength -= min( dwBufferSize, dwRemainingLength);
3377 #ifdef AFS_DEBUG_TRACE
3378 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3380 pUniversalInfo->lpUniversalName,
3381 pUniversalInfo->lpUniversalName);
3384 if ( dwPassedSize < *lpBufferSize)
3387 try_return( dwStatus = WN_MORE_DATA);
3390 try_return( dwStatus = WN_SUCCESS);
3393 case REMOTE_NAME_INFO_LEVEL:
3396 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3398 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + 2 * dwBufferSize + sizeof( WCHAR);
3400 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3403 #ifdef AFS_DEBUG_TRACE
3404 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3407 try_return( dwStatus = WN_MORE_DATA);
3410 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3412 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3414 memcpy( pRemoteInfo->lpUniversalName,
3416 min( dwRemainingLength, dwBufferSize));
3418 dwRemainingLength -= min( dwRemainingLength, dwBufferSize);
3420 #ifdef AFS_DEBUG_TRACE
3421 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3423 pRemoteInfo->lpUniversalName,
3424 pRemoteInfo->lpUniversalName);
3427 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3429 pRemoteInfo->lpConnectionName = (LPTSTR)((char *)pRemoteInfo->lpUniversalName + dwBufferSize);
3431 memcpy( pRemoteInfo->lpConnectionName,
3433 min( dwRemainingLength, dwBufferSize));
3435 dwRemainingLength -= min( dwRemainingLength, dwBufferSize) - sizeof( WCHAR);
3437 SeparateRemainingPath( pRemoteInfo->lpConnectionName,
3438 &pRemoteInfo->lpRemainingPath);
3441 #ifdef AFS_DEBUG_TRACE
3442 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3444 pRemoteInfo->lpConnectionName,
3445 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3447 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3449 pRemoteInfo->lpRemainingPath,
3450 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3453 if ( dwPassedSize < *lpBufferSize)
3456 try_return( dwStatus = WN_MORE_DATA);
3459 try_return( dwStatus = WN_SUCCESS);
3463 #ifdef AFS_DEBUG_TRACE
3464 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3467 try_return( dwStatus = WN_BAD_VALUE);
3473 #ifdef AFS_DEBUG_TRACE
3474 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is not AFS\n",
3477 try_return( dwStatus = WN_NOT_CONNECTED);
3481 dwBufferSize = 0x1000;
3483 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
3485 if( pConnectCB == NULL)
3487 try_return( dwStatus = WN_OUT_OF_MEMORY);
3490 pConnectCB->LocalName = towupper(wchLocalName[0]);
3492 pConnectCB->RemoteNameLength = 0;
3494 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3496 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
3498 #ifdef AFS_DEBUG_TRACE
3499 AFSDbgPrint( L"NPGetUniversalName Retrieved authentication id %08lX-%08lX\n",
3500 pConnectCB->AuthenticationId.HighPart,
3501 pConnectCB->AuthenticationId.LowPart);
3504 hControlDevice = OpenRedirector();
3506 if( hControlDevice == NULL)
3509 try_return( dwStatus = WN_NET_ERROR);
3512 dwError = DeviceIoControl( hControlDevice,
3513 IOCTL_AFS_GET_CONNECTION,
3523 #ifdef AFS_DEBUG_TRACE
3524 DWORD gle = GetLastError();
3526 AFSDbgPrint( L"NPGetUniversalName Failed to get connection from file system for local %s gle 0x%x\n",
3529 try_return( dwStatus = WN_NOT_CONNECTED);
3532 switch( dwInfoLevel)
3535 case UNIVERSAL_NAME_INFO_LEVEL:
3538 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3540 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize + sizeof( WCHAR);
3542 *lpBufferSize += dwRemainingPathLength * sizeof( WCHAR);
3544 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3547 #ifdef AFS_DEBUG_TRACE
3548 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3551 try_return( dwStatus = WN_MORE_DATA);
3554 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3556 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3558 pch = (char *)pUniversalInfo->lpUniversalName;
3562 min( dwBufferSize, dwRemainingLength));
3564 pch += min( dwBufferSize, dwRemainingLength);
3566 dwRemainingLength -= min( dwBufferSize + sizeof(WCHAR), dwRemainingLength);
3570 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3572 pch += min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3574 dwRemainingLength -= min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3576 #ifdef AFS_DEBUG_TRACE
3577 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3579 pUniversalInfo->lpUniversalName,
3580 pUniversalInfo->lpUniversalName);
3583 if ( dwPassedSize < *lpBufferSize)
3586 try_return( dwStatus = WN_MORE_DATA);
3589 try_return( dwStatus = WN_SUCCESS);
3592 case REMOTE_NAME_INFO_LEVEL:
3595 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3597 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + (2 * dwBufferSize + sizeof( WCHAR)) + 2 * sizeof( WCHAR);
3599 *lpBufferSize += 2 * dwRemainingPathLength * sizeof( WCHAR);
3601 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3604 #ifdef AFS_DEBUG_TRACE
3605 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3608 try_return( dwStatus = WN_MORE_DATA);
3611 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3613 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3615 pch = (char *)pRemoteInfo->lpUniversalName;
3619 min( dwBufferSize, dwRemainingLength));
3621 pch += min( dwBufferSize, dwRemainingLength);
3623 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3627 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3629 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3631 dwRemainingLength -= min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3633 #ifdef AFS_DEBUG_TRACE
3634 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3636 pRemoteInfo->lpUniversalName,
3637 pRemoteInfo->lpUniversalName);
3640 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3642 pRemoteInfo->lpConnectionName = (LPWSTR)pch;
3646 min( dwBufferSize, dwRemainingLength));
3648 pch += min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3650 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3654 if ( dwRemainingLength > dwRemainingPathLength + sizeof( WCHAR))
3656 pRemoteInfo->lpRemainingPath = (LPWSTR)pch;
3660 min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength));
3662 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3664 dwRemainingLength -= min((dwLocalPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3667 #ifdef AFS_DEBUG_TRACE
3668 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3670 pRemoteInfo->lpConnectionName,
3671 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3673 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3675 pRemoteInfo->lpRemainingPath,
3676 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3679 if ( dwPassedSize < *lpBufferSize)
3682 try_return( dwStatus = WN_MORE_DATA);
3685 try_return( dwStatus = WN_SUCCESS);
3689 #ifdef AFS_DEBUG_TRACE
3690 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3693 try_return( dwStatus = WN_BAD_VALUE);
3698 #ifdef AFS_DEBUG_TRACE
3699 AFSDbgPrint( L"NPGetUniversalName BufferSize 0x%X\n",
3702 if ( hControlDevice != NULL)
3705 CloseHandle( hControlDevice);
3711 HeapFree( GetProcessHeap(), 0, (PVOID) pwchSubstName);
3714 if( pConnectCB != NULL)
3717 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3726 GetFormatFlags( DWORD dwFlags)
3728 static WCHAR Buffer[128] = L"";
3731 // WNFMT_MULTILINE 0x01
3732 // WNFMT_ABBREVIATED 0x02
3733 // WNFMT_INENUM 0x10
3734 // WNFMT_CONNECTION 0x20
3744 if ( dwFlags & WNFMT_MULTILINE )
3746 StringCbCat( Buffer, sizeof(Buffer), L"MULTILINE|");
3749 if ( dwFlags & WNFMT_INENUM )
3751 StringCbCat( Buffer, sizeof(Buffer), L"ABBREVIATED|");
3754 if ( dwFlags & WNFMT_INENUM )
3756 StringCbCat( Buffer, sizeof(Buffer), L"INENUM|");
3759 if ( dwFlags & WNFMT_CONNECTION )
3761 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTION|");
3764 if ( dwFlags & ~(WNFMT_MULTILINE|WNFMT_ABBREVIATED|WNFMT_INENUM|WNFMT_CONNECTION) )
3766 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
3769 Buffer[lstrlen(Buffer)-1] = L'\0';
3775 NPFormatNetworkName( LPTSTR lpRemoteName,
3776 LPTSTR lpFormattedName,
3779 DWORD dwAveCharPerLine)
3782 DWORD dwLen = 0, dwCurrentLen = 0;
3783 LPTSTR pCurrentName = lpRemoteName;
3785 #ifdef AFS_DEBUG_TRACE
3786 AFSDbgPrint( L"NPFormatNetworkName Remote %s Flags %s (0x%x) CharsPerLine %u\n",
3789 GetFormatFlags( dwFlags),
3795 // Walk back in the name until we hit a \
3798 dwLen = wcslen( lpRemoteName);
3800 pCurrentName += (dwLen - 1);
3802 if ( pCurrentName[ 0] != L'\\')
3808 if( pCurrentName[ 0] == L'\\')
3824 if( *lpnLength < dwCurrentLen * sizeof( WCHAR))
3827 *lpnLength = dwCurrentLen * sizeof( WCHAR);
3829 #ifdef AFS_DEBUG_TRACE
3830 AFSDbgPrint( L"NPFormatNetworkName remote name %s WN_MORE_DATA\n",
3834 return WN_MORE_DATA;
3837 StringCbCopy( lpFormattedName,
3841 *lpnLength = dwCurrentLen * sizeof( WCHAR);
3843 #ifdef AFS_DEBUG_TRACE
3844 AFSDbgPrint( L"NPFormatNetworkName remote name %s as %s\n",
3852 /************************************************************
3853 / Unsupported entry points
3854 /************************************************************/
3857 // AuthGroup processing is implemented in src/WINNT/afsd/afslogon.c
3862 LPCWSTR lpAuthentInfoType,
3863 LPVOID lpAuthentInfo,
3864 LPCWSTR lpPreviousAuthentInfoType,
3865 LPVOID lpPreviousAuthentInfo,
3866 LPWSTR lpStationName,
3867 LPVOID StationHandle,
3868 LPWSTR *lpLogonScript)
3871 #ifdef AFS_DEBUG_TRACE
3872 AFSDbgPrint( L"NPLogonNotify, returning WN_NOT_SUPPORTED\n");
3875 return WN_NOT_SUPPORTED;
3879 NPPasswordChangeNotify (
3880 LPCWSTR lpAuthentInfoType,
3881 LPVOID lpAuthentInfo,
3882 LPCWSTR lpPreviousAuthentInfoType,
3883 LPVOID lpPreviousAuthentInfo,
3884 LPWSTR lpStationName,
3885 LPVOID StationHandle,
3886 DWORD dwChangeInfo )
3889 #ifdef AFS_DEBUG_TRACE
3890 AFSDbgPrint( L"NPPasswordChangeNotify, returning WN_NOT_SUPPORTED\n");
3893 SetLastError( WN_NOT_SUPPORTED );
3895 return WN_NOT_SUPPORTED;
3899 NPGetUser( LPTSTR lpName,
3901 LPDWORD lpBufferSize)
3904 DWORD rc = WN_NOT_SUPPORTED;
3906 AFSDbgPrint( L"NPGetUser Entry Name %s\n", lpName);
3914 NPGetReconnectFlags( LPWSTR lpRemoteName,
3915 unsigned char *Parameter2)
3918 DWORD dwStatus = WN_NOT_SUPPORTED;
3920 AFSDbgPrint( L"NPGetReconnectFlags RemoteName %s\n",
3929 I_SystemFocusDialog( VOID)
3932 DWORD dwStatus = WN_NOT_SUPPORTED;
3934 AFSDbgPrint( L"I_SystemFocusDialog\n");
3939 /************************************************************
3940 / END Unsupported entry points
3941 /************************************************************/
3948 HANDLE hControlDevice = NULL;
3950 hControlDevice = CreateFile( AFS_SYMLINK_W,
3951 GENERIC_READ | GENERIC_WRITE,
3952 FILE_SHARE_READ | FILE_SHARE_WRITE,
3958 if( hControlDevice == INVALID_HANDLE_VALUE)
3961 hControlDevice = NULL;
3962 #ifdef AFS_DEBUG_TRACE
3963 AFSDbgPrint( L"Failed to open control device error: %d\n",
3969 // only do this if you want network shares to fail to mount
3970 // when the file system is not yet ready
3974 AFSDriverStatusRespCB respCB;
3977 memset( &respCB, '\0', sizeof( AFSDriverStatusRespCB));
3979 if ( !DeviceIoControl( hControlDevice,
3980 IOCTL_AFS_STATUS_REQUEST,
3984 sizeof( AFSDriverStatusRespCB),
3987 dwBytes != sizeof(AFSDriverStatusRespCB) ||
3988 respCB.Status != AFS_DRIVER_STATUS_READY )
3991 CloseHandle( hControlDevice);
3993 hControlDevice = NULL;
3998 return hControlDevice;
4005 LARGE_INTEGER liAuthId = {0,0};
4006 HANDLE hToken = NULL;
4007 TOKEN_STATISTICS stTokenInfo;
4008 DWORD dwCopyBytes = 0;
4010 if ( !OpenThreadToken( GetCurrentThread(),
4012 FALSE, // Impersonation
4015 if( !OpenProcessToken( GetCurrentProcess(),
4020 #ifdef AFS_DEBUG_TRACE
4021 AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve Thread and Process tokens 0x%X\n",
4028 #ifdef AFS_DEBUG_TRACE
4029 AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Process Token\n");
4036 #ifdef AFS_DEBUG_TRACE
4037 AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Thread Token\n");
4041 if ( hToken != NULL)
4044 if( !GetTokenInformation( hToken,
4047 sizeof( TOKEN_STATISTICS),
4051 #ifdef AFS_DEBUG_TRACE
4052 AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve token information 0x%X\n",
4059 liAuthId.HighPart = stTokenInfo.AuthenticationId.HighPart;
4060 liAuthId.LowPart = stTokenInfo.AuthenticationId.LowPart;
4063 CloseHandle( hToken);
4072 static int init = 0;
4073 static DWORD debug = 0;
4078 if (RegOpenKey (HKEY_LOCAL_MACHINE,
4079 TEXT("SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider"), &hk) == 0)
4081 DWORD dwSize = sizeof(BOOL);
4082 DWORD dwType = REG_DWORD;
4083 RegQueryValueEx (hk, TEXT("Debug"), NULL, &dwType, (PBYTE)&debug, &dwSize);
4093 cm_Utf16ToUtf8Alloc(const WCHAR * s, int cch_src, int *pcch_dest)
4098 if (s == NULL || cch_src == 0 || *s == L'\0') {
4100 *pcch_dest = ((cch_src != 0)?1:0);
4104 cch_dest = WideCharToMultiByte(CP_UTF8, 0, s, cch_src, NULL, 0, NULL, FALSE);
4106 if (cch_dest == 0) {
4108 *pcch_dest = cch_dest;
4112 dest = HeapAlloc( GetProcessHeap(), 0, (cch_dest + 1) * sizeof(char));
4114 WideCharToMultiByte(CP_UTF8, 0, s, cch_src, dest, cch_dest, NULL, FALSE);
4118 *pcch_dest = cch_dest;
4124 AppendDebugStringToLogFile(WCHAR *wszbuffer)
4132 if ( !wszbuffer || !wszbuffer[0] )
4135 len = (int)wcslen(wszbuffer);
4137 buffer = cm_Utf16ToUtf8Alloc(wszbuffer, len, &len);
4142 hFile = CreateFileW( L"C:\\TEMP\\AFSRDFSProvider.log",
4147 FILE_ATTRIBUTE_NORMAL,
4150 if ( hFile == INVALID_HANDLE_VALUE ) {
4151 OutputDebugString(L"C:\\AFSRDFSProvider.log cannot be opened.\n");
4155 bRet = WriteFile( hFile, buffer, len, &dwWritten, NULL);
4157 bRet = CloseHandle(hFile);
4159 HeapFree(GetProcessHeap(), 0, buffer);
4170 WCHAR wszbuffer[512];
4172 DWORD debug = Debug();
4177 va_start( marker, Format );
4179 StringCbPrintf( wszbuffer, sizeof(wszbuffer), L"[%d-%08X] ",
4185 GetCurrentThreadId());
4187 rc = StringCbVPrintfW( &wszbuffer[ 14], sizeof(wszbuffer) - 14, Format, marker);
4189 if (SUCCEEDED(rc)) {
4191 OutputDebugString( wszbuffer );
4193 AppendDebugStringToLogFile(wszbuffer);
4195 OutputDebugString(L"AFSDbgPrint Failed to create string\n");
4198 return SUCCEEDED(rc) ? 1 : 0;