2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2015 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #define _WIN32_WINNT 0x0500
49 #define AFS_DEBUG_TRACE 1
51 #ifndef WNNC_NET_OPENAFS
52 #define WNNC_NET_OPENAFS 0x00390000
55 #include "AFSUserDefines.h"
56 #include "AFSUserIoctl.h"
57 #include "AFSUserStructs.h"
58 #include "AFSProvider.h"
59 #include "AFS_Npdll.h"
67 #define SCRATCHSZ 1024
73 ULONG _cdecl AFSDbgPrint( PWCHAR Format, ... );
76 NPGetConnectionCommon( LPWSTR lpLocalName,
82 NPGetConnection3Common( LPCWSTR lpLocalName,
89 NPGetUniversalNameCommon( LPCWSTR lpLocalPath,
96 DriveSubstitution( LPCWSTR drivestr,
101 #define WNNC_DRIVER( major, minor ) ( major * 0x00010000 + minor )
103 #define OPENAFS_PROVIDER_NAME L"OpenAFS Network"
104 #define OPENAFS_PROVIDER_NAME_LENGTH 30
106 #define MAX_PROVIDER_NAME_LENGTH 256
108 static ULONG cbProviderNameLength = OPENAFS_PROVIDER_NAME_LENGTH;
110 static wchar_t wszProviderName[MAX_PROVIDER_NAME_LENGTH+1] = OPENAFS_PROVIDER_NAME;
112 static BOOL bProviderNameRead = FALSE;
114 #define OPENAFS_SERVER_NAME L"AFS"
115 #define OPENAFS_SERVER_NAME_LENGTH 6
117 #define OPENAFS_SERVER_COMMENT L"AFS Root"
118 #define OPENAFS_SERVER_COMMENT_LENGTH 16
120 #define MAX_SERVER_NAME_LENGTH 30
122 static ULONG cbServerNameLength = 0;
124 static ULONG cbServerNameUNCLength = 0;
126 static ULONG cbServerCommentLength = OPENAFS_SERVER_COMMENT_LENGTH;
128 static wchar_t wszServerName[MAX_SERVER_NAME_LENGTH+1];
130 static wchar_t wszServerNameUNC[MAX_SERVER_NAME_LENGTH+3];
132 static wchar_t wszServerComment[] = OPENAFS_SERVER_COMMENT;
134 static BOOL bServerNameRead = FALSE;
137 ReadProviderNameString( void)
143 if ( bProviderNameRead )
146 code = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
147 L"SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider",
148 0, KEY_QUERY_VALUE, &hk);
150 if ( code == ERROR_SUCCESS) {
152 dwLen = sizeof(wszProviderName);
154 code = RegQueryValueExW( hk, L"Name", NULL, NULL,
155 (LPBYTE) wszProviderName, &dwLen);
157 if ( code == ERROR_SUCCESS)
160 wszProviderName[MAX_PROVIDER_NAME_LENGTH] = '\0';
162 cbProviderNameLength = wcslen( wszProviderName) * sizeof( WCHAR);
168 bProviderNameRead = TRUE;
172 ReadServerNameString( void)
178 if ( bServerNameRead )
181 code = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
182 L"SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters",
183 0, KEY_QUERY_VALUE, &hk);
185 if ( code == ERROR_SUCCESS) {
187 dwLen = sizeof(wszProviderName);
189 code = RegQueryValueExW( hk, L"NetbiosName", NULL, NULL,
190 (LPBYTE) wszServerName, &dwLen);
192 if ( code == ERROR_SUCCESS)
195 wszServerName[MAX_SERVER_NAME_LENGTH] = '\0';
197 cbServerNameLength = wcslen( wszServerName) * sizeof( WCHAR);
199 wszServerNameUNC[0] = wszServerNameUNC[1] = L'\\';
201 memcpy(&wszServerNameUNC[2], wszServerName, (cbServerNameLength + 1) * sizeof( WCHAR));
203 cbServerNameUNCLength = cbServerNameLength + 2 * sizeof( WCHAR);
209 bServerNameRead = TRUE;
214 /* returns TRUE if the file system is disabled or not installed */
216 NPIsFSDisabled( void)
221 DWORD dwStart = SERVICE_DISABLED;
223 code = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
224 L"SYSTEM\\CurrentControlSet\\Services\\AFSRedirector",
225 0, KEY_QUERY_VALUE, &hk);
227 if ( code != ERROR_SUCCESS)
232 dwLen = sizeof(dwStart);
234 code = RegQueryValueExW( hk, L"Start", NULL, NULL,
235 (LPBYTE) &dwStart, &dwLen);
239 return ( dwStart == SERVICE_DISABLED);
243 #define try_return(S) { S; goto try_exit; }
249 typedef struct _UNICODE_STRING {
251 USHORT MaximumLength;
253 } UNICODE_STRING, *PUNICODE_STRING;
256 OpenRedirector( void);
258 typedef struct _AFS_ENUM_CB
273 // Recursively evaluate drivestr to find the final
274 // dos drive letter to which the source is mapped.
277 DriveSubstitution(LPCWSTR drivestr, LPWSTR subststr, size_t substlen, DWORD * pStatus)
280 WCHAR device[MAX_PATH + 26];
283 *pStatus = WN_SUCCESS;
285 memset( subststr, 0, substlen);
286 drive[0] = drivestr[0];
287 drive[1] = drivestr[1];
290 if ( substlen < 3 * sizeof( WCHAR))
293 // Cannot represent "D:"
298 if ( QueryDosDevice(drive, device, MAX_PATH + 26) )
300 #ifdef AFS_DEBUG_TRACE
301 AFSDbgPrint( L"DriveSubstitution QueryDosDevice %s [%s -> %s]\n",
306 if ( device[0] == L'\\' &&
309 device[3] == L'\\' &&
310 iswalpha(device[4]) &&
313 drive[0] = device[4];
317 if ( !DriveSubstitution(drive, subststr, substlen, pStatus) )
320 subststr[0] = drive[0];
329 hr = StringCbCat( subststr, substlen, &device[6]);
331 if ( SUCCEEDED(hr) && drivestr[2] )
333 hr = StringCbCat( subststr, substlen, &drivestr[2]);
336 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
339 if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER )
340 *pStatus = WN_MORE_DATA;
342 #ifdef AFS_DEBUG_TRACE
343 AFSDbgPrint( L"DriveSubstitution (hr = %X) %s -> %s\n",
351 else if ( device[0] == L'\\' &&
354 device[3] == L'\\' &&
363 hr = StringCbCopyN(&subststr[1], substlen - sizeof(WCHAR), &device[7], sizeof(device) - 7 * sizeof(WCHAR));
365 if ( SUCCEEDED(hr) && drivestr[2] )
367 hr = StringCbCat( subststr, substlen, &drivestr[2]);
370 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
373 if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER )
374 *pStatus = WN_MORE_DATA;
376 #ifdef AFS_DEBUG_TRACE
377 AFSDbgPrint( L"DriveSubstitution (hr = %X) %s -> %s\n",
385 #ifdef AFS_DEBUG_TRACE
386 AFSDbgPrint( L"DriveSubstitution StringCbCopyN 1 hr 0x%X\n",
390 else if ( _wcsnicmp( AFS_RDR_DEVICE_NAME, device, sizeof( AFS_RDR_DEVICE_NAME) / sizeof( WCHAR) - 1) == 0)
393 // \Device\AFSRedirector\;X:\\afs\cellname
396 hr = StringCbCopy( subststr, substlen,
397 &device[3 + sizeof( AFS_RDR_DEVICE_NAME) / sizeof( WCHAR)]);
399 if ( SUCCEEDED(hr) && drivestr[2] )
401 hr = StringCbCat( subststr, substlen, &drivestr[2]);
404 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
407 if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER )
408 *pStatus = WN_MORE_DATA;
410 #ifdef AFS_DEBUG_TRACE
411 AFSDbgPrint( L"DriveSubstitution (hr = %X) %s -> %s\n",
419 #ifdef AFS_DEBUG_TRACE
420 AFSDbgPrint( L"DriveSubstitution StringCbCopyN 2 hr 0x%X\n",
425 #ifdef AFS_DEBUG_TRACE
426 AFSDbgPrint( L"DriveSubstitution no substitution or match %s !! %s\n",
433 #ifdef AFS_DEBUG_TRACE
434 AFSDbgPrint( L"DriveSubstitution QueryDosDevice failed %s gle 0x%X\n",
445 NPGetCapsQueryString( DWORD nIndex)
448 case WNNC_SPEC_VERSION:
449 return L"WNNC_SPEC_VERSION";
452 return L"WNNC_NET_TYPE";
454 case WNNC_DRIVER_VERSION:
455 return L"WNNC_DRIVER_VERSION";
460 case WNNC_CONNECTION:
461 return L"WNNC_CONNECTION";
464 return L"WNNC_DIALOG";
467 return L"WNNC_ADMIN";
469 case WNNC_ENUMERATION:
470 return L"WNNC_ENUMERATION";
473 return L"WNNC_START";
475 case WNNC_CONNECTION_FLAGS:
476 return L"WNNC_CONNECTION_FLAGS";
484 // This is the only function which must be exported, everything else is optional
489 NPGetCaps( DWORD nIndex )
494 #ifdef AFS_DEBUG_TRACE
495 AFSDbgPrint( L"NPGetCaps Index %u %s\n", nIndex,
496 NPGetCapsQueryString( nIndex));
500 case WNNC_SPEC_VERSION:
503 rc = WNNC_SPEC_VERSION51;
509 rc = WNNC_NET_OPENAFS;
513 case WNNC_DRIVER_VERSION:
516 rc = WNNC_DRIVER(1, 0);
520 case WNNC_CONNECTION:
528 rc = WNNC_CON_GETCONNECTIONS |
529 WNNC_CON_CANCELCONNECTION |
530 WNNC_CON_ADDCONNECTION |
531 WNNC_CON_ADDCONNECTION3 |
532 WNNC_CON_GETPERFORMANCE;
537 case WNNC_ENUMERATION:
539 rc = WNNC_ENUM_LOCAL |
549 rc = WNNC_WAIT_FOR_START;
559 // WNNC_DLG_DEVICEMODE
560 // WNNC_DLG_PROPERTYDIALOG
561 // WNNC_DLG_SEARCHDIALOG
562 // WNNC_DLG_PERMISSIONEDITOR
565 rc = WNNC_DLG_FORMATNETWORKNAME |
566 WNNC_DLG_GETRESOURCEINFORMATION |
567 WNNC_DLG_GETRESOURCEPARENT;
586 // WNNC_ADM_GETDIRECTORYTYPE
587 // WNNC_ADM_DIRECTORYNOTIFY
588 // used by the old File Manager
599 NPAddConnection( LPNETRESOURCE lpNetResource,
604 #ifdef AFS_DEBUG_TRACE
605 AFSDbgPrint( L"NPAddConnection forwarding to NPAddConnection3\n");
607 return NPAddConnection3( NULL, lpNetResource, lpPassword, lpUserName, 0 );
611 Add3FlagsToString( DWORD dwFlags, WCHAR *wszBuffer, size_t wch)
618 if (dwFlags & CONNECT_TEMPORARY) {
620 hr = StringCbCat( wszBuffer, wch, L"TEMPORARY");
630 if (dwFlags & CONNECT_INTERACTIVE) {
634 hr = StringCbCat( wszBuffer, wch, L"|");
642 hr = StringCbCat( wszBuffer, wch, L"INTERACTIVE");
652 if (dwFlags & CONNECT_PROMPT) {
656 hr = StringCbCat( wszBuffer, wch, L"|");
664 hr = StringCbCat( wszBuffer, wch, L"PROMPT");
674 if (dwFlags & CONNECT_INTERACTIVE) {
678 hr = StringCbCat( wszBuffer, wch, L"|");
686 hr = StringCbCat( wszBuffer, wch, L"DEFERRED");
699 NPAddConnection3( HWND hwndOwner,
700 LPNETRESOURCE lpNetResource,
706 DWORD dwStatus = WN_SUCCESS;
707 WCHAR wchRemoteName[MAX_PATH+1];
708 WCHAR wchLocalName[3];
709 DWORD dwCopyBytes = 0;
710 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
712 DWORD dwBufferSize = 0;
713 HANDLE hControlDevice = NULL;
714 HANDLE hToken = NULL;
715 LARGE_INTEGER liAuthId = {0,0};
717 WCHAR wszFlagsString[1024]=L"";
721 if ( NPIsFSDisabled())
724 #ifdef AFS_DEBUG_TRACE
725 AFSDbgPrint( L"NPAddConnection3 AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
728 return WN_BAD_NETNAME;
731 if ((lpNetResource->lpRemoteName == NULL) ||
732 (lpNetResource->lpRemoteName[0] != L'\\') ||
733 (lpNetResource->lpRemoteName[1] != L'\\') ||
734 ((lpNetResource->dwType != RESOURCETYPE_DISK) &&
735 (lpNetResource->dwType != RESOURCETYPE_ANY)))
738 #ifdef AFS_DEBUG_TRACE
739 AFSDbgPrint( L"NPAddConnection3 invalid input, returning WN_BAD_NETNAME\n");
741 return WN_BAD_NETNAME;
744 #ifdef AFS_DEBUG_TRACE
745 Add3FlagsToString( dwFlags, wszFlagsString, 1024);
747 AFSDbgPrint( L"NPAddConnection3 processing Remote %s User %s Pass %s Flags %s\n",
748 lpNetResource->lpRemoteName,
749 lpUserName == NULL? L"use-default": lpUserName[0] ? lpUserName : L"no-username",
750 lpPassword == NULL? L"use-default": lpPassword[0] ? L"provided" : L"no-password",
753 if( lpNetResource->lpLocalName != NULL)
756 wchLocalName[0] = towupper(lpNetResource->lpLocalName[0]);
757 wchLocalName[1] = L':';
758 wchLocalName[2] = L'\0';
761 hr = StringCbCopy(wchRemoteName, sizeof( wchRemoteName), lpNetResource->lpRemoteName);
765 #ifdef AFS_DEBUG_TRACE
766 AFSDbgPrint( L"NPAddConnection3 lpRemoteName longer than MAX_PATH, returning WN_BAD_NETNAME\n");
768 return WN_BAD_NETNAME;
772 // Allocate our buffer to pass to the redirector filter
775 dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + (wcslen( wchRemoteName) * sizeof( WCHAR));
777 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
779 if( pConnectCB == NULL)
782 try_return( dwStatus = WN_OUT_OF_MEMORY);
785 if( lpNetResource->lpLocalName != NULL)
788 pConnectCB->LocalName = towupper(wchLocalName[0]);
790 #ifdef AFS_DEBUG_TRACE
791 AFSDbgPrint( L"NPAddConnection3 Adding mapping for drive %s remote name %s\n",
799 pConnectCB->LocalName = L'\0';
801 #ifdef AFS_DEBUG_TRACE
802 AFSDbgPrint( L"NPAddConnection3 Adding mapping for NO drive remote name %s\n",
807 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
809 pConnectCB->RemoteNameLength = wcslen( wchRemoteName) * sizeof( WCHAR);
811 memcpy( pConnectCB->RemoteName,
813 pConnectCB->RemoteNameLength);
815 pConnectCB->Type = lpNetResource->dwType;
817 hControlDevice = OpenRedirector();
819 if( hControlDevice == NULL)
822 #ifdef AFS_DEBUG_TRACE
823 AFSDbgPrint( L"NPAddConnection3 OpenRedirector failure, returning WN_NET_ERROR\n");
826 try_return( dwStatus = WN_NET_ERROR);
829 dwError = DeviceIoControl( hControlDevice,
830 IOCTL_AFS_ADD_CONNECTION,
840 #ifdef AFS_DEBUG_TRACE
841 AFSDbgPrint( L"NPAddConnection3 Failed to add connection to file system %d\n", GetLastError());
843 try_return( dwStatus = WN_NET_ERROR);
847 // The status returned from the driver will indicate how it was handled
850 if( dwStatus == WN_SUCCESS &&
851 lpNetResource->lpLocalName != NULL)
854 WCHAR TempBuf[MAX_PATH+26];
856 if( !QueryDosDeviceW( wchLocalName,
861 if( GetLastError() != ERROR_FILE_NOT_FOUND)
864 #ifdef AFS_DEBUG_TRACE
865 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW failed with file not found\n");
867 NPCancelConnection( wchLocalName, TRUE);
869 dwStatus = ERROR_ALREADY_ASSIGNED;
874 UNICODE_STRING uniConnectionName;
877 // Create a symbolic link object to the device we are redirecting
880 uniConnectionName.MaximumLength = (USHORT)( wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR) +
881 pConnectCB->RemoteNameLength +
882 8 + // Local name and \;
883 sizeof(WCHAR)); // Space for NULL-termination.
886 // Don't include NULL-termination.
889 uniConnectionName.Length = uniConnectionName.MaximumLength - sizeof(WCHAR);
891 uniConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
892 uniConnectionName.MaximumLength);
894 if( uniConnectionName.Buffer == NULL)
897 try_return( dwStatus = GetLastError());
900 hr = StringCbCopyW( uniConnectionName.Buffer,
901 uniConnectionName.MaximumLength,
902 AFS_RDR_DEVICE_NAME);
905 #ifdef AFS_DEBUG_TRACE
906 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
908 try_return( dwStatus = WN_OUT_OF_MEMORY);
911 hr = StringCbCatW( uniConnectionName.Buffer,
912 uniConnectionName.MaximumLength,
916 #ifdef AFS_DEBUG_TRACE
917 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
919 try_return( dwStatus = WN_OUT_OF_MEMORY);
922 hr = StringCbCatW( uniConnectionName.Buffer,
923 uniConnectionName.MaximumLength,
927 #ifdef AFS_DEBUG_TRACE
928 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
930 try_return( dwStatus = WN_OUT_OF_MEMORY);
933 hr = StringCbCatW( uniConnectionName.Buffer,
934 uniConnectionName.MaximumLength,
938 #ifdef AFS_DEBUG_TRACE
939 AFSDbgPrint( L"NPAddConnection3 uniConnectionBuffer too small\n");
941 try_return( dwStatus = WN_OUT_OF_MEMORY);
944 #ifdef AFS_DEBUG_TRACE
945 AFSDbgPrint( L"NPAddConnection3 DefineDosDevice Local %s connection name %s\n",
947 uniConnectionName.Buffer);
950 if( !DefineDosDeviceW( DDD_RAW_TARGET_PATH |
951 DDD_NO_BROADCAST_SYSTEM,
953 uniConnectionName.Buffer))
955 #ifdef AFS_DEBUG_TRACE
956 AFSDbgPrint( L"NPAddConnection3 Failed to assign drive\n");
958 dwStatus = GetLastError();
963 #ifdef AFS_DEBUG_TRACE
964 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW assigned drive %s\n", wchLocalName);
967 dwStatus = WN_SUCCESS;
970 LocalFree( uniConnectionName.Buffer);
976 #ifdef AFS_DEBUG_TRACE
977 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW %Z already existed\n", TempBuf);
979 NPCancelConnection( wchLocalName, TRUE);
981 dwStatus = ERROR_ALREADY_ASSIGNED;
987 if ( hControlDevice != NULL)
990 CloseHandle( hControlDevice);
993 if( pConnectCB != NULL)
996 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1005 NPCancelConnection( LPWSTR lpName,
1009 WCHAR wchRemoteName[MAX_PATH+1];
1010 DWORD dwRemoteNameLength = (MAX_PATH+1) * sizeof(WCHAR);
1011 DWORD dwStatus = WN_NOT_CONNECTED;
1012 DWORD dwCopyBytes = 0;
1013 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1014 AFSCancelConnectionResultCB stCancelConn;
1016 DWORD dwBufferSize = 0;
1017 BOOL bLocalName = TRUE;
1018 HANDLE hControlDevice = NULL;
1019 WCHAR wchLocalName[ 3];
1020 WCHAR *pwchLocalName = NULL;
1026 if ( NPIsFSDisabled())
1029 #ifdef AFS_DEBUG_TRACE
1030 AFSDbgPrint( L"NPCancelConnection AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1033 try_return( dwStatus = WN_NOT_CONNECTED);
1036 if( *lpName == L'\\' &&
1037 *(lpName + 1) == L'\\')
1042 wchLocalName[0] = L'\0';
1044 hr = StringCbCopyW( wchRemoteName, sizeof( wchRemoteName), lpName);
1048 #ifdef AFS_DEBUG_TRACE
1049 AFSDbgPrint( L"NPCancelConnection lpName longer than MAX_PATH\n");
1051 try_return( dwStatus = WN_OUT_OF_MEMORY);
1054 dwRemoteNameLength = (wcslen( wchRemoteName) * sizeof( WCHAR));
1059 wchLocalName[0] = towupper(lpName[0]);
1060 wchLocalName[1] = L':';
1061 wchLocalName[2] = L'\0';
1064 // Get the remote name for the connection, if we are handling it
1067 dwStatus = NPGetConnectionCommon( wchLocalName,
1069 &dwRemoteNameLength,
1072 if( dwStatus != WN_SUCCESS ||
1073 dwRemoteNameLength == 0)
1076 #ifdef AFS_DEBUG_TRACE
1077 AFSDbgPrint( L"NPCancelConnection Status 0x%x NameLength %u, returning WN_NOT_CONNECTED\n",
1078 dwStatus, dwRemoteNameLength);
1080 try_return( dwStatus = WN_NOT_CONNECTED);
1084 // NPGetConnection returns the buffer size not the length without NUL
1086 dwRemoteNameLength -= sizeof( WCHAR);
1089 wchRemoteName[ dwRemoteNameLength/sizeof( WCHAR)] = L'\0';
1091 #ifdef AFS_DEBUG_TRACE
1092 AFSDbgPrint( L"NPCancelConnection Attempting to cancel '%s' -> '%s'\n",
1093 wchLocalName, wchRemoteName);
1096 dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + dwRemoteNameLength;
1098 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1100 if( pConnectCB == NULL)
1103 try_return( dwStatus = WN_OUT_OF_MEMORY);
1109 pConnectCB->LocalName = wchLocalName[0];
1114 pConnectCB->LocalName = L'\0';
1117 pConnectCB->RemoteNameLength = (USHORT)dwRemoteNameLength;
1119 StringCbCopyW( pConnectCB->RemoteName,
1120 dwRemoteNameLength + sizeof( WCHAR),
1123 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1125 hControlDevice = OpenRedirector();
1127 if( hControlDevice == NULL)
1130 #ifdef AFS_DEBUG_TRACE
1131 AFSDbgPrint( L"NPCancelConnection OpenRedirector failure, returning WN_NET_ERROR\n");
1134 try_return( dwStatus = WN_NET_ERROR);
1137 memset( &stCancelConn,
1139 sizeof( AFSCancelConnectionResultCB));
1141 dwError = DeviceIoControl( hControlDevice,
1142 IOCTL_AFS_CANCEL_CONNECTION,
1146 sizeof( AFSCancelConnectionResultCB),
1152 #ifdef AFS_DEBUG_TRACE
1153 DWORD gle = GetLastError();
1155 AFSDbgPrint( L"NPCancelConnection DeviceIoControl failed - gle 0x%x\n", gle);
1157 try_return( dwStatus = WN_NOT_CONNECTED);
1160 dwStatus = stCancelConn.Status;
1162 #ifdef AFS_DEBUG_TRACE
1163 if ( dwStatus == WN_NOT_CONNECTED )
1166 AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status WN_NOT_CONNECTED\n",
1172 AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status %08lX\n",
1178 if( dwStatus == WN_SUCCESS &&
1180 stCancelConn.LocalName != L'\0'))
1183 UNICODE_STRING uniConnectionName;
1186 // Create a symbolic link object to the device we are redirecting
1189 uniConnectionName.MaximumLength = (USHORT)( wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR) +
1190 dwRemoteNameLength +
1191 8 + // Local name and \;
1192 sizeof(WCHAR)); // Space for NULL-termination.
1195 // Don't include NULL-termination.
1198 uniConnectionName.Length = uniConnectionName.MaximumLength - sizeof(WCHAR);
1200 uniConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
1201 uniConnectionName.MaximumLength);
1203 if( uniConnectionName.Buffer == NULL)
1206 try_return( dwStatus = GetLastError());
1209 hr = StringCbCopyW( uniConnectionName.Buffer,
1210 uniConnectionName.MaximumLength,
1211 AFS_RDR_DEVICE_NAME);
1215 #ifdef AFS_DEBUG_TRACE
1216 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (1)\n");
1218 try_return( dwStatus = WN_OUT_OF_MEMORY);
1221 hr = StringCbCatW( uniConnectionName.Buffer,
1222 uniConnectionName.MaximumLength,
1227 #ifdef AFS_DEBUG_TRACE
1228 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (2)\n");
1230 try_return( dwStatus = WN_OUT_OF_MEMORY);
1236 wchLocalName[ 0] = stCancelConn.LocalName;
1238 wchLocalName[ 1] = L':';
1240 wchLocalName[ 2] = L'\0';
1242 hr = StringCbCatW( uniConnectionName.Buffer,
1243 uniConnectionName.MaximumLength,
1248 #ifdef AFS_DEBUG_TRACE
1249 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (3)\n");
1251 try_return( dwStatus = WN_OUT_OF_MEMORY);
1254 pwchLocalName = wchLocalName;
1259 hr = StringCbCatW( uniConnectionName.Buffer,
1260 uniConnectionName.MaximumLength,
1265 #ifdef AFS_DEBUG_TRACE
1266 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (4)\n");
1268 try_return( dwStatus = WN_OUT_OF_MEMORY);
1271 pwchLocalName = lpName;
1274 hr = StringCbCatW( uniConnectionName.Buffer,
1275 uniConnectionName.MaximumLength,
1280 #ifdef AFS_DEBUG_TRACE
1281 AFSDbgPrint( L"NPCancelConnection uniConnectionName buffer too small (5)\n");
1283 try_return( dwStatus = WN_OUT_OF_MEMORY);
1286 if( !DefineDosDevice( DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE,
1288 uniConnectionName.Buffer))
1291 #ifdef AFS_DEBUG_TRACE
1292 DWORD gle = GetLastError();
1294 AFSDbgPrint( L"NPCancelConnection Failed to cancel connection to system - gle 0x%x Name %s connection %wZ\n",
1297 &uniConnectionName);
1302 #ifdef AFS_DEBUG_TRACE
1304 AFSDbgPrint( L"NPCancelConnection Canceled connection to system - Name %s connection %wZ\n",
1306 &uniConnectionName);
1313 if ( hControlDevice != NULL)
1316 CloseHandle( hControlDevice);
1320 if( pConnectCB != NULL)
1323 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1333 NPGetConnection( LPWSTR lpLocalName,
1334 LPWSTR lpRemoteName,
1335 LPDWORD lpBufferSize)
1338 DWORD dwBufferSize = *lpBufferSize;
1341 dwStatus = NPGetConnectionCommon( lpLocalName,
1346 if ( dwStatus == WN_NOT_CONNECTED)
1349 dwStatus = NPGetConnectionCommon( lpLocalName,
1357 *lpBufferSize = dwBufferSize;
1365 NPGetConnectionCommon( LPWSTR lpLocalName,
1366 LPWSTR lpRemoteName,
1367 LPDWORD lpBufferSize,
1371 DWORD dwStatus = WN_NOT_CONNECTED;
1372 WCHAR wchLocalName[3];
1373 WCHAR wchSubstName[1024 + 26];
1374 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1376 DWORD dwBufferSize = 0;
1377 HANDLE hControlDevice = NULL;
1383 if ( NPIsFSDisabled())
1386 #ifdef AFS_DEBUG_TRACE
1387 AFSDbgPrint( L"NPGetConnection AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1390 try_return( dwStatus = WN_NOT_CONNECTED);
1393 if( lstrlen( lpLocalName) == 0)
1395 #ifdef AFS_DEBUG_TRACE
1396 AFSDbgPrint( L"NPGetConnection No local name, returning WN_BAD_LOCALNAME\n");
1398 try_return( dwStatus = WN_BAD_LOCALNAME);
1401 if ( lpBufferSize == NULL)
1403 #ifdef AFS_DEBUG_TRACE
1404 AFSDbgPrint( L"NPGetConnection No output size, returning WN_BAD_LOCALNAME\n");
1406 try_return( dwStatus = WN_BAD_VALUE);
1409 dwPassedSize = *lpBufferSize;
1411 if ( !bDriveSubstOk ||
1412 !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName), &dwStatus))
1414 wchLocalName[0] = towupper(lpLocalName[0]);
1415 wchLocalName[1] = L':';
1416 wchLocalName[2] = L'\0';
1418 #ifdef AFS_DEBUG_TRACE
1419 AFSDbgPrint( L"NPGetConnection Requesting connection for %s\n",
1425 ReadServerNameString();
1427 if ( wchSubstName[0] != L'\\' &&
1428 wchSubstName[1] == L':')
1431 wchLocalName[0] = towupper(wchSubstName[0]);
1432 wchLocalName[1] = L':';
1433 wchLocalName[2] = L'\0';
1435 #ifdef AFS_DEBUG_TRACE
1436 AFSDbgPrint( L"NPGetConnection Requesting connection for drive substitution %s -> %s\n",
1441 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
1442 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
1443 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
1448 DWORD dwRequiredSize;
1450 #ifdef AFS_DEBUG_TRACE
1451 AFSDbgPrint( L"NPGetConnection drive substitution %s is AFS\n",
1455 dwRequiredSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
1457 if ( lpRemoteName == NULL ||
1458 dwPassedSize == 0 ||
1459 dwRequiredSize > *lpBufferSize)
1462 *lpBufferSize = dwRequiredSize;
1464 try_return( dwStatus = WN_MORE_DATA);
1468 hr = StringCbCopyN(lpRemoteName, *lpBufferSize, wchSubstName, sizeof( wchSubstName));
1473 for ( dwCount = 0, pwch = lpRemoteName; *pwch && pwch < lpRemoteName + (*lpBufferSize); pwch++ )
1475 if ( *pwch == L'\\' )
1489 *lpBufferSize = wcslen( lpRemoteName) * sizeof( WCHAR) + sizeof( WCHAR);
1491 try_return( dwStatus = WN_SUCCESS);
1493 else if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER)
1496 *lpBufferSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
1498 for ( dwCount = 0, pwch = lpRemoteName; *pwch; pwch++ )
1500 if ( *pwch == L'\\' )
1508 *lpBufferSize = wcslen( lpRemoteName) * sizeof( WCHAR) + sizeof( WCHAR);
1510 try_return( dwStatus = WN_SUCCESS);
1516 try_return( dwStatus = WN_MORE_DATA);
1521 #ifdef AFS_DEBUG_TRACE
1522 AFSDbgPrint( L"NPGetConnection StringCbCopyN failure 0x%X\n",
1525 try_return( dwStatus = WN_NET_ERROR);
1531 #ifdef AFS_DEBUG_TRACE
1532 AFSDbgPrint( L"NPGetConnection drive substitution %s is not AFS\n",
1535 try_return( dwStatus = WN_NOT_CONNECTED);
1539 #ifdef AFS_DEBUG_TRACE
1540 AFSDbgPrint( L"NPGetConnection Requesting connection for %s\n",
1544 dwBufferSize = 0x1000;
1546 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1548 if( pConnectCB == NULL)
1551 try_return( dwStatus = WN_OUT_OF_MEMORY);
1554 pConnectCB->LocalName = towupper(wchLocalName[0]);
1556 pConnectCB->RemoteNameLength = 0;
1558 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1560 hControlDevice = OpenRedirector();
1562 if( hControlDevice == NULL)
1565 #ifdef AFS_DEBUG_TRACE
1566 AFSDbgPrint( L"NPGetConnection OpenRedirector failure, returning WN_NET_ERROR\n");
1569 try_return( dwStatus = WN_NET_ERROR);
1572 dwError = DeviceIoControl( hControlDevice,
1573 IOCTL_AFS_GET_CONNECTION,
1583 #ifdef AFS_DEBUG_TRACE
1584 DWORD gle = GetLastError();
1586 AFSDbgPrint( L"NPGetConnection Failed to get connection from file system for local %s gle 0x%x\n",
1589 try_return( dwStatus = WN_NOT_CONNECTED);
1593 // IOCTL_AFS_GET_CONNECTION returns a counted string
1596 if( lpRemoteName == NULL ||
1597 *lpBufferSize + sizeof( WCHAR) > dwPassedSize)
1600 *lpBufferSize += sizeof( WCHAR);
1602 try_return( dwStatus = WN_MORE_DATA);
1605 memcpy( lpRemoteName,
1609 lpRemoteName[ *lpBufferSize/sizeof( WCHAR)] = L'\0';
1611 *lpBufferSize += sizeof( WCHAR);
1613 #ifdef AFS_DEBUG_TRACE
1614 AFSDbgPrint( L"NPGetConnection local %s remote %s\n",
1618 dwStatus = WN_SUCCESS;
1622 if ( hControlDevice != NULL)
1625 CloseHandle( hControlDevice);
1628 if( pConnectCB != NULL)
1631 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1639 NPGetConnection3( IN LPCWSTR lpLocalName,
1641 OUT LPVOID lpBuffer,
1642 IN OUT LPDWORD lpBufferSize)
1645 DWORD dwBufferSize = *lpBufferSize;
1648 dwStatus = NPGetConnection3Common( lpLocalName,
1654 if ( dwStatus == WN_NOT_CONNECTED)
1657 dwStatus = NPGetConnection3Common( lpLocalName,
1666 *lpBufferSize = dwBufferSize;
1673 static DWORD APIENTRY
1674 NPGetConnection3Common( IN LPCWSTR lpLocalName,
1676 OUT LPVOID lpBuffer,
1677 IN OUT LPDWORD lpBufferSize,
1678 IN BOOL bDriveSubstOk)
1681 DWORD dwStatus = WN_NOT_CONNECTED;
1682 WCHAR wchLocalName[3];
1683 WCHAR wchSubstName[1024 + 26];
1684 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1686 DWORD dwBufferSize = 0;
1687 HANDLE hControlDevice = NULL;
1689 DWORD *pConnectState =(DWORD *)lpBuffer;
1694 if ( NPIsFSDisabled())
1697 #ifdef AFS_DEBUG_TRACE
1698 AFSDbgPrint( L"NPGetConnection3 AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1701 try_return( dwStatus = WN_NOT_CONNECTED);
1704 if( lstrlen( lpLocalName) == 0)
1706 #ifdef AFS_DEBUG_TRACE
1707 AFSDbgPrint( L"NPGetConnection3 No local name, returning WN_BAD_LOCALNAME\n");
1709 try_return( dwStatus = WN_BAD_LOCALNAME);
1713 // LanMan NPGetConnection3 only responds to level 1
1716 if ( dwLevel != 0x1)
1718 #ifdef AFS_DEBUG_TRACE
1719 AFSDbgPrint( L"NPGetConnection3 Level 0x%X returning WN_BAD_LEVEL\n", dwLevel);
1721 try_return( dwStatus = WN_BAD_LEVEL);
1724 if ( lpBufferSize == NULL)
1726 #ifdef AFS_DEBUG_TRACE
1727 AFSDbgPrint( L"NPGetConnection3 No output size, returning WN_BAD_VALUE\n");
1729 try_return( dwStatus = WN_BAD_VALUE);
1732 dwPassedSize = *lpBufferSize;
1734 if ( dwPassedSize == 0 ||
1738 *lpBufferSize = sizeof( DWORD);
1740 try_return( dwStatus = WN_MORE_DATA);
1743 if ( !bDriveSubstOk ||
1744 !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName), &dwStatus))
1746 wchLocalName[0] = towupper(lpLocalName[0]);
1747 wchLocalName[1] = L':';
1748 wchLocalName[2] = L'\0';
1750 #ifdef AFS_DEBUG_TRACE
1751 AFSDbgPrint( L"NPGetConnection3 Requesting connection for %s level 0x%X\n",
1759 ReadServerNameString();
1761 if ( wchSubstName[0] != L'\\' &&
1762 wchSubstName[1] == L':')
1765 wchLocalName[0] = towupper(wchSubstName[0]);
1766 wchLocalName[1] = L':';
1767 wchLocalName[2] = L'\0';
1769 #ifdef AFS_DEBUG_TRACE
1770 AFSDbgPrint( L"NPGetConnection3 Requesting connection for drive substitution %s -> %s level 0x%x\n",
1776 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
1777 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
1778 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
1781 #ifdef AFS_DEBUG_TRACE
1782 AFSDbgPrint( L"NPGetConnection3 drive substitution %s is AFS return connected\n",
1785 *pConnectState = WNGETCON_CONNECTED;
1787 *lpBufferSize = sizeof( DWORD);
1789 try_return( dwStatus = WN_SUCCESS);
1794 #ifdef AFS_DEBUG_TRACE
1795 AFSDbgPrint( L"NPGetConnection3 drive substitution %s is not AFS return not connected\n",
1798 try_return( dwStatus = WN_NOT_CONNECTED);
1802 dwBufferSize = 0x1000;
1804 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1806 if( pConnectCB == NULL)
1809 try_return( dwStatus = WN_OUT_OF_MEMORY);
1812 pConnectCB->LocalName = towupper(wchLocalName[0]);
1814 pConnectCB->RemoteNameLength = 0;
1816 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1818 hControlDevice = OpenRedirector();
1820 if( hControlDevice == NULL)
1823 #ifdef AFS_DEBUG_TRACE
1824 AFSDbgPrint( L"NPGetConnection3 OpenRedirector failure, returning WN_NET_ERROR\n");
1827 try_return( dwStatus = WN_NET_ERROR);
1830 dwError = DeviceIoControl( hControlDevice,
1831 IOCTL_AFS_GET_CONNECTION,
1841 #ifdef AFS_DEBUG_TRACE
1842 DWORD gle = GetLastError();
1844 AFSDbgPrint( L"NPGetConnection3 Failed to get connection from file system for local %s gle 0x%x\n",
1847 try_return( dwStatus = WN_NOT_CONNECTED);
1850 *lpBufferSize = sizeof( DWORD);
1852 if( sizeof( DWORD) > dwPassedSize)
1855 try_return( dwStatus = WN_MORE_DATA);
1858 *pConnectState = WNGETCON_CONNECTED;
1860 #ifdef AFS_DEBUG_TRACE
1861 AFSDbgPrint( L"NPGetConnection3 local %s connect-state 0x%x\n",
1865 dwStatus = WN_SUCCESS;
1869 if ( hControlDevice != NULL)
1872 CloseHandle( hControlDevice);
1875 if( pConnectCB != NULL)
1878 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1887 NPGetConnectionPerformance( LPCWSTR lpRemoteName,
1888 LPNETCONNECTINFOSTRUCT lpNetConnectInfo)
1891 DWORD dwReturn = WN_SUCCESS;
1892 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1893 DWORD dwBufferSize = 0;
1894 HANDLE hControlDevice = NULL;
1900 if ( NPIsFSDisabled())
1903 #ifdef AFS_DEBUG_TRACE
1904 AFSDbgPrint( L"NPGetConnectionPerformance AFSRDFS is disabled, returning WN_NET_ERROR\n");
1907 return WN_NET_ERROR;
1910 AFSDbgPrint( L"NPGetConnectionPerformance Entry for remote connection %S\n",
1913 dwBufferSize = 0x1000;
1915 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1917 if( pConnectCB == NULL)
1919 try_return( dwReturn = WN_OUT_OF_MEMORY);
1922 pConnectCB->RemoteNameLength = wcslen( lpRemoteName) * sizeof( WCHAR);
1924 StringCbCopy( pConnectCB->RemoteName,
1925 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
1928 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1930 hControlDevice = OpenRedirector();
1932 if( hControlDevice == NULL)
1934 AFSDbgPrint( L"NPGetConnectionPerformance OpenRedirector failure, returning WN_NET_ERROR\n");
1936 try_return( dwReturn = WN_NET_ERROR);
1939 dwError = DeviceIoControl( hControlDevice,
1940 IOCTL_AFS_GET_CONNECTION_INFORMATION,
1950 #ifdef AFS_DEBUG_TRACE
1951 DWORD gle = GetLastError();
1953 AFSDbgPrint( L"NPGetConnectionPerformance Failed to get connection info from file system for remote %S gle 0x%x\n",
1957 try_return( dwReturn = WN_NOT_CONNECTED);
1960 lpNetConnectInfo->dwFlags = 0;
1962 lpNetConnectInfo->dwSpeed = 0;
1964 lpNetConnectInfo->dwDelay = 0;
1966 lpNetConnectInfo->dwOptDataSize = 0x10000;
1968 AFSDbgPrint( L"NPGetConnectionPerformance Successfully returned information for remote connection %S\n",
1973 if ( hControlDevice != NULL)
1975 CloseHandle( hControlDevice);
1978 if( pConnectCB != NULL)
1980 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1988 GetUsageString( DWORD dwUsage)
1990 static WCHAR Buffer[128] = L"";
1992 // RESOURCEUSAGE_CONNECTABLE 0x00000001
1993 // RESOURCEUSAGE_CONTAINER 0x00000002
1994 // RESOURCEUSAGE_NOLOCALDEVICE 0x00000004
1995 // RESOURCEUSAGE_SIBLING 0x00000008
1996 // RESOURCEUSAGE_ATTACHED 0x00000010
1997 // RESOURCEUSAGE_ALL (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED)
1998 // RESOURCEUSAGE_RESERVED 0x80000000
2003 if ( dwUsage == RESOURCEUSAGE_ALL )
2013 if ( dwUsage & RESOURCEUSAGE_CONNECTABLE )
2015 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTABLE|");
2018 if ( dwUsage & RESOURCEUSAGE_CONTAINER )
2020 StringCbCat( Buffer, sizeof(Buffer), L"CONTAINER|");
2023 if ( dwUsage & RESOURCEUSAGE_NOLOCALDEVICE )
2025 StringCbCat( Buffer, sizeof(Buffer), L"NOLOCALDEVICE|");
2028 if ( dwUsage & RESOURCEUSAGE_SIBLING )
2030 StringCbCat( Buffer, sizeof(Buffer), L"SIBLING|");
2033 if ( dwUsage & RESOURCEUSAGE_ATTACHED )
2035 StringCbCat( Buffer, sizeof(Buffer), L"ATTACHED|");
2038 if ( dwUsage & RESOURCEUSAGE_RESERVED )
2040 StringCbCat( Buffer, sizeof(Buffer), L"RESERVED|");
2043 if ( dwUsage & ~(RESOURCEUSAGE_ALL|RESOURCEUSAGE_NOLOCALDEVICE|RESOURCEUSAGE_SIBLING|RESOURCEUSAGE_RESERVED) )
2045 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
2048 Buffer[lstrlen(Buffer)-1] = L'\0';
2054 GetTypeString( DWORD dwType)
2056 static WCHAR Buffer[128] = L"";
2059 // RESOURCETYPE_ANY 0x00000000
2060 // RESOURCETYPE_DISK 0x00000001
2061 // RESOURCETYPE_PRINT 0x00000002
2062 // RESOURCETYPE_RESERVED 0x00000008
2063 // RESOURCETYPE_UNKNOWN 0xFFFFFFFF
2068 if ( dwType == RESOURCETYPE_ANY )
2073 if ( dwType == RESOURCETYPE_UNKNOWN )
2078 if ( dwType & RESOURCETYPE_DISK )
2080 StringCbCat( Buffer, sizeof(Buffer), L"DISK|");
2083 if ( dwType & RESOURCETYPE_PRINT )
2085 StringCbCat( Buffer, sizeof(Buffer), L"PRINT|");
2088 if ( dwType & RESOURCETYPE_RESERVED )
2090 StringCbCat( Buffer, sizeof(Buffer), L"RESERVED|");
2093 if ( dwType & ~(RESOURCETYPE_DISK|RESOURCETYPE_PRINT|RESOURCETYPE_RESERVED) )
2095 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
2098 Buffer[lstrlen(Buffer)-1] = L'\0';
2104 GetScopeString( DWORD dwScope)
2106 static WCHAR Buffer[128] = L"";
2109 // RESOURCE_CONNECTED 0x00000001
2110 // RESOURCE_GLOBALNET 0x00000002
2111 // RESOURCE_REMEMBERED 0x00000003
2112 // RESOURCE_RECENT 0x00000004
2113 // RESOURCE_CONTEXT 0x00000005
2118 if ( dwScope == RESOURCE_CONNECTED )
2120 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTED|");
2123 if ( dwScope == RESOURCE_GLOBALNET )
2125 StringCbCat( Buffer, sizeof(Buffer), L"GLOBALNET|");
2128 if ( dwScope == RESOURCE_REMEMBERED )
2130 StringCbCat( Buffer, sizeof(Buffer), L"REMEMBERED|");
2133 if ( dwScope == RESOURCE_RECENT )
2135 StringCbCat( Buffer, sizeof(Buffer), L"RECENT|");
2138 if ( dwScope == RESOURCE_CONTEXT )
2140 StringCbCat( Buffer, sizeof(Buffer), L"CONTEXT|");
2143 if ( dwScope & ~(RESOURCE_CONNECTED|RESOURCE_GLOBALNET|RESOURCE_REMEMBERED|RESOURCE_RECENT|RESOURCE_CONTEXT) )
2145 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
2148 Buffer[lstrlen(Buffer)-1] = L'\0';
2154 GetDisplayString( DWORD dwDisplay)
2157 // RESOURCEDISPLAYTYPE_GENERIC 0x00000000
2158 // RESOURCEDISPLAYTYPE_DOMAIN 0x00000001
2159 // RESOURCEDISPLAYTYPE_SERVER 0x00000002
2160 // RESOURCEDISPLAYTYPE_SHARE 0x00000003
2161 // RESOURCEDISPLAYTYPE_FILE 0x00000004
2162 // RESOURCEDISPLAYTYPE_GROUP 0x00000005
2163 // RESOURCEDISPLAYTYPE_NETWORK 0x00000006
2164 // RESOURCEDISPLAYTYPE_ROOT 0x00000007
2165 // RESOURCEDISPLAYTYPE_SHAREADMIN 0x00000008
2166 // RESOURCEDISPLAYTYPE_DIRECTORY 0x00000009
2167 // RESOURCEDISPLAYTYPE_TREE 0x0000000A
2168 // RESOURCEDISPLAYTYPE_NDSCONTAINER 0x0000000B
2171 switch ( dwDisplay ) {
2172 case RESOURCEDISPLAYTYPE_GENERIC:
2174 case RESOURCEDISPLAYTYPE_DOMAIN:
2176 case RESOURCEDISPLAYTYPE_SERVER:
2178 case RESOURCEDISPLAYTYPE_SHARE:
2180 case RESOURCEDISPLAYTYPE_FILE:
2182 case RESOURCEDISPLAYTYPE_GROUP:
2184 case RESOURCEDISPLAYTYPE_NETWORK:
2186 case RESOURCEDISPLAYTYPE_ROOT:
2188 case RESOURCEDISPLAYTYPE_SHAREADMIN:
2189 return L"SHAREADMIN";
2190 case RESOURCEDISPLAYTYPE_DIRECTORY:
2191 return L"DIRECTORY";
2192 case RESOURCEDISPLAYTYPE_TREE:
2194 case RESOURCEDISPLAYTYPE_NDSCONTAINER:
2195 return L"NDSCONTAINER";
2203 NPOpenEnum( DWORD dwScope,
2206 LPNETRESOURCE lpNetResource,
2210 DWORD dwStatus = WN_SUCCESS;
2211 AFSEnumerationCB *pEnumCB = NULL;
2212 HANDLE hControlDevice = NULL;
2214 #ifdef AFS_DEBUG_TRACE
2215 if ( lpNetResource == NULL)
2217 AFSDbgPrint( L"NPOpenEnum Scope %s Type %s Usage %s NetResource: (Null)\n",
2218 GetScopeString(dwScope), GetTypeString(dwType), GetUsageString(dwUsage));
2222 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",
2223 GetScopeString(dwScope),
2224 GetTypeString(dwType),
2225 GetUsageString(dwUsage),
2227 GetScopeString(lpNetResource->dwScope),
2228 GetTypeString(lpNetResource->dwType),
2229 GetDisplayString(lpNetResource->dwDisplayType),
2230 GetUsageString(lpNetResource->dwUsage),
2231 lpNetResource->lpLocalName,
2232 lpNetResource->lpRemoteName,
2233 lpNetResource->lpComment);
2239 dwUsage = RESOURCEUSAGE_ALL;
2243 if ( dwType == 0 || dwType == RESOURCEUSAGE_ATTACHED)
2245 dwType |= RESOURCETYPE_DISK | RESOURCETYPE_PRINT;
2249 hControlDevice = OpenRedirector();
2251 if( hControlDevice == NULL)
2254 #ifdef AFS_DEBUG_TRACE
2255 AFSDbgPrint( L"NPOpenEnum OpenRedirector failure, returning WN_NET_ERROR\n");
2258 return WN_NO_NETWORK;
2261 CloseHandle( hControlDevice);
2264 *lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( AFSEnumerationCB));
2266 if( *lphEnum == NULL)
2269 return WN_OUT_OF_MEMORY;
2272 pEnumCB = (AFSEnumerationCB *)*lphEnum;
2274 pEnumCB->CurrentIndex = 0;
2276 pEnumCB->Type = dwType;
2280 case RESOURCE_CONNECTED:
2283 pEnumCB->Scope = RESOURCE_CONNECTED;
2288 case RESOURCE_CONTEXT:
2291 pEnumCB->Scope = RESOURCE_CONTEXT;
2296 case RESOURCE_GLOBALNET:
2299 if( lpNetResource != NULL &&
2300 lpNetResource->lpRemoteName != NULL)
2303 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2305 if( pEnumCB->RemoteName == NULL)
2308 dwStatus = WN_OUT_OF_MEMORY;
2309 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2315 StringCbCopy( pEnumCB->RemoteName,
2317 lpNetResource->lpRemoteName);
2322 pEnumCB->Scope = RESOURCE_GLOBALNET;
2329 #ifdef AFS_DEBUG_TRACE
2330 AFSDbgPrint( L"NPOpenEnum Processing (Scope %s 0x%x) Type %s Usage %s, returning WN_NOT_SUPPORTED\n",
2331 GetScopeString(dwScope), dwScope, GetTypeString(dwType), GetUsageString(dwUsage));
2334 dwStatus = WN_NOT_SUPPORTED;
2335 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2347 NPEnumResource( HANDLE hEnum,
2350 LPDWORD lpBufferSize)
2353 DWORD dwStatus = WN_NO_MORE_ENTRIES; //WN_SUCCESS;
2355 ULONG EntriesCopied;
2356 ULONG EntriesRequested;
2358 LPNETRESOURCE pNetResource;
2360 ULONG SpaceAvailable;
2362 AFSNetworkProviderConnectionCB *pConnectionCB = NULL;
2363 void *pConnectionCBBase = NULL;
2365 UNICODE_STRING uniRemoteName;
2366 HANDLE hControlDevice = NULL;
2367 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2372 if ( lpBufferSize == NULL)
2374 #ifdef AFS_DEBUG_TRACE
2375 AFSDbgPrint( L"NPEnumResource No output size, returning WN_BAD_VALUE\n");
2377 try_return( dwStatus = WN_BAD_VALUE);
2380 ReadProviderNameString();
2382 pNetResource = (LPNETRESOURCE) lpBuffer;
2383 SpaceAvailable = *lpBufferSize;
2384 EntriesRequested = *lpcCount;
2385 *lpcCount = EntriesCopied = 0;
2386 StringZone = (PWCHAR) ((char *)lpBuffer + *lpBufferSize);
2388 #ifdef AFS_DEBUG_TRACE
2389 AFSDbgPrint( L"NPEnumResource Processing Remote name %s Scope %s Type %s Usage %s Index %d SpaceAvailable 0x%lX RequestedEntries %lu\n",
2390 pEnumCB->RemoteName ? pEnumCB->RemoteName : L"(Null)",
2391 GetScopeString(pEnumCB->Scope),
2392 GetTypeString(pEnumCB->Type),
2393 GetUsageString(pEnumCB->Type),
2394 pEnumCB->CurrentIndex,
2399 if ( NPIsFSDisabled())
2402 #ifdef AFS_DEBUG_TRACE
2403 AFSDbgPrint( L"NPEnumResource AFSRDFS is disabled, returning WN_NO_MORE_ENTRIES\n");
2406 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2409 pConnectionCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 0x1000);
2411 if( pConnectionCB == NULL)
2414 #ifdef AFS_DEBUG_TRACE
2415 AFSDbgPrint( L"NPEnumResource Out of Memory\n");
2418 try_return( dwStatus = WN_OUT_OF_MEMORY);
2421 pConnectionCBBase = (void *)pConnectionCB;
2423 hControlDevice = OpenRedirector();
2425 if( hControlDevice == NULL)
2428 #ifdef AFS_DEBUG_TRACE
2429 AFSDbgPrint( L"NPEnumResource OpenRedirector failure, returning WN_NET_ERROR\n");
2432 try_return( dwStatus = WN_NET_ERROR);
2435 if( pEnumCB->Type != RESOURCETYPE_ANY && pEnumCB->Type != RESOURCETYPE_DISK)
2438 #ifdef AFS_DEBUG_TRACE
2439 AFSDbgPrint( L"NPEnumResource Non-DISK queries are not supported, returning WN_NO_MORE_ENTRIES\n");
2441 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2445 // Handle the special cases here
2446 // 0. Provider Network Root
2451 if ( pEnumCB->Scope == RESOURCE_GLOBALNET)
2454 ReadServerNameString();
2456 if ( pEnumCB->CurrentIndex == 0 &&
2457 pEnumCB->RemoteName == NULL)
2460 // Determine the space needed for this entry...
2462 SpaceNeeded = 2 * ( cbProviderNameLength + sizeof( WCHAR));
2464 uniRemoteName.Length = (USHORT)cbProviderNameLength;
2465 uniRemoteName.MaximumLength = uniRemoteName.Length;
2466 uniRemoteName.Buffer = wszProviderName;
2468 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2471 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2473 #ifdef AFS_DEBUG_TRACE
2474 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2478 try_return( dwStatus = WN_MORE_DATA);
2481 #ifdef AFS_DEBUG_TRACE
2482 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2486 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2488 pNetResource->dwScope = RESOURCE_GLOBALNET;
2489 pNetResource->dwType = RESOURCETYPE_ANY;
2490 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_NETWORK;
2491 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_RESERVED;
2493 // setup string area at opposite end of buffer
2494 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2496 pNetResource->lpLocalName = NULL;
2499 pNetResource->lpRemoteName = StringZone;
2501 StringCbCopy( StringZone,
2502 cbProviderNameLength + sizeof( WCHAR),
2505 StringZone += cbProviderNameLength / sizeof(WCHAR) + 1;
2507 pNetResource->lpComment = NULL;
2509 // copy provider name
2510 pNetResource->lpProvider = StringZone;
2511 StringCbCopy( StringZone,
2512 cbProviderNameLength + sizeof( WCHAR),
2515 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2517 #ifdef AFS_DEBUG_TRACE
2518 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2520 GetScopeString(pNetResource->dwScope),
2521 GetTypeString(pNetResource->dwType),
2522 GetDisplayString(pNetResource->dwDisplayType),
2523 GetUsageString(pNetResource->dwUsage),
2524 pNetResource->lpLocalName,
2525 pNetResource->lpRemoteName,
2526 pNetResource->lpComment);
2529 // setup the new end of buffer
2530 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2536 // do not change the index since we did not query the redirector
2537 pEnumCB->CurrentIndex = 0;
2539 // remember that we returned the provider name
2540 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2542 if( pEnumCB->RemoteName == NULL)
2545 try_return( dwStatus = WN_OUT_OF_MEMORY);
2550 StringCbCopy( pEnumCB->RemoteName,
2556 if ( pEnumCB->CurrentIndex == 0 &&
2557 lstrlen( pEnumCB->RemoteName) == cbProviderNameLength / sizeof( WCHAR) &&
2558 _wcsnicmp( pEnumCB->RemoteName, wszProviderName, cbProviderNameLength / sizeof( WCHAR)) == 0 &&
2559 EntriesCopied < EntriesRequested)
2563 // After the network provider entry comes the server entry
2566 // Determine the space needed for this entry...
2568 SpaceNeeded = cbProviderNameLength + cbServerNameUNCLength + cbServerCommentLength + 3 * sizeof( WCHAR);
2570 uniRemoteName.Length = (USHORT)cbServerNameUNCLength;
2571 uniRemoteName.MaximumLength = uniRemoteName.Length;
2572 uniRemoteName.Buffer = wszServerNameUNC;
2574 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2577 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2579 #ifdef AFS_DEBUG_TRACE
2580 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2584 try_return( dwStatus = WN_MORE_DATA);
2587 #ifdef AFS_DEBUG_TRACE
2588 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2592 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2594 pNetResource->dwScope = 0;
2595 pNetResource->dwType = RESOURCETYPE_ANY;
2596 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
2597 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
2599 // setup string area at opposite end of buffer
2600 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2602 pNetResource->lpLocalName = NULL;
2605 pNetResource->lpRemoteName = StringZone;
2607 StringCbCopy( StringZone,
2608 cbServerNameUNCLength + sizeof( WCHAR),
2611 StringZone += cbServerNameUNCLength / sizeof(WCHAR) + 1;
2614 pNetResource->lpComment = StringZone;
2616 StringCbCopy( StringZone,
2617 cbServerCommentLength + sizeof( WCHAR),
2620 StringZone += cbServerCommentLength / sizeof( WCHAR) + 1;
2622 // copy provider name
2623 pNetResource->lpProvider = StringZone;
2624 StringCbCopy( StringZone,
2625 cbProviderNameLength + sizeof( WCHAR),
2628 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2630 #ifdef AFS_DEBUG_TRACE
2631 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2633 GetScopeString(pNetResource->dwScope),
2634 GetTypeString(pNetResource->dwType),
2635 GetDisplayString(pNetResource->dwDisplayType),
2636 GetUsageString(pNetResource->dwUsage),
2637 pNetResource->lpLocalName,
2638 pNetResource->lpRemoteName,
2639 pNetResource->lpComment);
2642 // setup the new end of buffer
2643 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2649 // do not update the index because we did not query the redirector
2650 pEnumCB->CurrentIndex = 0;
2652 // remember that we returned the server
2653 StringCbCopy( pEnumCB->RemoteName,
2661 // Setup what we are going to ask for
2664 pConnectionCB->Scope = pEnumCB->Scope;
2666 pConnectionCB->Type = pEnumCB->Type;
2668 pConnectionCB->CurrentIndex = pEnumCB->CurrentIndex;
2670 pConnectionCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
2673 // If this is a RESOURCE_GLOBALNET enumeration then pass down the remote name if
2677 pConnectionCB->RemoteNameLength = 0;
2679 if( pEnumCB->Scope == RESOURCE_GLOBALNET &&
2680 pEnumCB->RemoteName != NULL)
2683 pConnectionCB->RemoteNameLength = wcslen( pEnumCB->RemoteName) * sizeof( WCHAR);
2685 StringCbCopy( pConnectionCB->RemoteName,
2686 (0x1000 - sizeof(AFSNetworkProviderConnectionCB)) + sizeof(WCHAR),
2687 pEnumCB->RemoteName);
2690 dwError = DeviceIoControl( hControlDevice,
2691 IOCTL_AFS_LIST_CONNECTIONS,
2701 #ifdef AFS_DEBUG_TRACE
2702 DWORD gle = GetLastError();
2704 AFSDbgPrint( L"NPEnumResource Failed to list connections from file system - gle 0x%x\n",
2707 try_return( dwStatus = WN_NOT_CONNECTED);
2710 if( dwCopyBytes == 0)
2713 #ifdef AFS_DEBUG_TRACE
2714 AFSDbgPrint( L"NPEnumResource No More Entries\n");
2716 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2719 dwIndex = pEnumCB->CurrentIndex;
2721 while( EntriesCopied < EntriesRequested)
2724 uniRemoteName.Length = (USHORT)pConnectionCB->RemoteNameLength;
2725 uniRemoteName.MaximumLength = uniRemoteName.Length;
2726 uniRemoteName.Buffer = pConnectionCB->RemoteName;
2728 // Determine the space needed for this entry...
2732 if( pConnectionCB->LocalName != 0)
2735 SpaceNeeded += 3 * sizeof(WCHAR); // local name
2738 SpaceNeeded += pConnectionCB->RemoteNameLength + sizeof( WCHAR); // remote name
2740 if( pConnectionCB->CommentLength > 0)
2743 SpaceNeeded += pConnectionCB->CommentLength + sizeof( WCHAR); // comment
2746 SpaceNeeded += cbProviderNameLength + sizeof( WCHAR); // provider name
2748 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2751 if (EntriesCopied == 0) {
2753 dwStatus = WN_MORE_DATA;
2755 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2757 #ifdef AFS_DEBUG_TRACE
2758 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2765 #ifdef AFS_DEBUG_TRACE
2766 AFSDbgPrint( L"NPEnumResource Return SUCCESS but more entries Index %d\n",
2770 dwStatus = WN_SUCCESS;
2776 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2778 pNetResource->dwScope = pConnectionCB->Scope;
2779 pNetResource->dwType = pConnectionCB->Type;
2781 pNetResource->dwDisplayType = pConnectionCB->DisplayType;
2783 if ( pNetResource->dwType == RESOURCETYPE_ANY &&
2784 pNetResource->dwDisplayType == RESOURCEDISPLAYTYPE_SHARE)
2787 pNetResource->dwType = RESOURCETYPE_DISK;
2790 if ( pEnumCB->Scope == RESOURCE_CONNECTED)
2793 pNetResource->dwUsage = 0;
2798 pNetResource->dwUsage = pConnectionCB->Usage;
2801 // setup string area at opposite end of buffer
2802 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2805 if( pConnectionCB->LocalName != 0)
2808 pNetResource->lpLocalName = StringZone;
2809 *StringZone++ = towupper(pConnectionCB->LocalName);
2810 *StringZone++ = L':';
2811 *StringZone++ = L'\0';
2816 pNetResource->lpLocalName = NULL;
2819 #ifdef AFS_DEBUG_TRACE
2820 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2825 pNetResource->lpRemoteName = StringZone;
2827 CopyMemory( StringZone,
2828 pConnectionCB->RemoteName,
2829 pConnectionCB->RemoteNameLength);
2831 StringZone += (pConnectionCB->RemoteNameLength / sizeof(WCHAR));
2833 *StringZone++ = L'\0';
2836 if( pConnectionCB->CommentLength > 0)
2839 pNetResource->lpComment = StringZone;
2841 CopyMemory( StringZone,
2842 (void *)((char *)pConnectionCB + pConnectionCB->CommentOffset),
2843 pConnectionCB->CommentLength);
2845 StringZone += (pConnectionCB->CommentLength / sizeof(WCHAR));
2847 *StringZone++ = L'\0';
2852 pNetResource->lpComment = NULL;
2855 // copy provider name
2856 pNetResource->lpProvider = StringZone;
2857 StringCbCopy( StringZone,
2858 cbProviderNameLength + sizeof( WCHAR),
2861 StringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
2863 #ifdef AFS_DEBUG_TRACE
2864 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2866 GetScopeString(pNetResource->dwScope),
2867 GetTypeString(pNetResource->dwType),
2868 GetDisplayString(pNetResource->dwDisplayType),
2869 GetUsageString(pNetResource->dwUsage),
2870 pNetResource->lpLocalName,
2871 pNetResource->lpRemoteName,
2872 pNetResource->lpComment);
2875 // setup the new end of buffer
2876 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2884 dwCopyBytes -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2885 pConnectionCB->RemoteNameLength +
2886 pConnectionCB->CommentLength;
2888 if( dwCopyBytes == 0)
2891 dwStatus = WN_SUCCESS;
2896 pConnectionCB = (AFSNetworkProviderConnectionCB *)((char *)pConnectionCB +
2897 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2898 pConnectionCB->RemoteNameLength +
2899 pConnectionCB->CommentLength);
2902 *lpcCount = EntriesCopied;
2904 // update entry index
2905 pEnumCB->CurrentIndex = dwIndex;
2907 #ifdef AFS_DEBUG_TRACE
2908 AFSDbgPrint( L"NPEnumResource Completed Count %d Index %d\n",
2915 if ( hControlDevice != NULL)
2918 CloseHandle( hControlDevice);
2921 if( pConnectionCBBase != NULL)
2924 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectionCBBase);
2933 Routine Description:
2935 This routine closes the handle for enumeration of resources.
2939 hEnum - the enumeration handle
2943 WN_SUCCESS if successful, otherwise the appropriate error
2947 The sample only supports the notion of enumerating connected shares
2952 NPCloseEnum( HANDLE hEnum )
2955 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2957 #ifdef AFS_DEBUG_TRACE
2958 AFSDbgPrint( L"NPCloseEnum\n");
2961 if( pEnumCB->RemoteName != NULL)
2964 HeapFree( GetProcessHeap( ), 0, (PVOID) pEnumCB->RemoteName);
2967 HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum );
2973 NPGetResourceParent( LPNETRESOURCE lpNetResource,
2975 LPDWORD lpBufferSize )
2978 DWORD dwStatus = WN_ACCESS_DENIED;
2979 WCHAR *pwchRemoteName = NULL, *pwchSearch = NULL, *pwchSystem = NULL;
2980 LPNETRESOURCE lpOutResource = (LPNETRESOURCE) lpBuffer;
2982 if ( NPIsFSDisabled())
2985 #ifdef AFS_DEBUG_TRACE
2986 AFSDbgPrint( L"NPGetResourceParent AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
2989 return WN_BAD_NETNAME;
2992 if ( lpNetResource == NULL)
2994 #ifdef AFS_DEBUG_TRACE
2995 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2997 return WN_MORE_DATA;
3000 if( lpNetResource->lpRemoteName == NULL)
3002 #ifdef AFS_DEBUG_TRACE
3003 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
3005 return WN_BAD_NETNAME;
3008 if ( lpNetResource->dwType != 0 &&
3009 lpNetResource->dwType != RESOURCETYPE_DISK)
3011 #ifdef AFS_DEBUG_TRACE
3012 AFSDbgPrint( L"NPGetResourceParent Bad dwType\n");
3014 return WN_BAD_VALUE;
3017 if ( lpBufferSize == NULL )
3020 #ifdef AFS_DEBUG_TRACE
3021 AFSDbgPrint( L"NPGetResourceParent Null lpBufferSize\n");
3023 return WN_BAD_VALUE;
3026 #ifdef AFS_DEBUG_TRACE
3027 AFSDbgPrint( L"NPGetResourceParent For remote name %s\n",
3028 lpNetResource->lpRemoteName);
3031 pwchRemoteName = lpNetResource->lpRemoteName;
3034 // The input will be of the form \\AFS\CELL\path.
3035 // \\AFS has no parent and by definition returns an empty NETRESOURCE.
3038 pwchSearch = pwchRemoteName + (wcslen( pwchRemoteName) - 1);
3040 while( pwchSearch != pwchRemoteName)
3043 if( *pwchSearch == L'\\')
3046 *pwchSearch = L'\0';
3054 if( pwchSearch != pwchRemoteName &&
3055 pwchSearch != pwchRemoteName + 1)
3058 #ifdef AFS_DEBUG_TRACE
3059 AFSDbgPrint( L"NPGetResourceParent Processing parent %s\n",
3060 lpNetResource->lpRemoteName);
3063 dwStatus = NPGetResourceInformation( lpNetResource,
3070 if ( lpOutResource == NULL ||
3071 *lpBufferSize < sizeof( NETRESOURCE) )
3073 *lpBufferSize = sizeof( NETRESOURCE);
3075 return WN_MORE_DATA;
3078 memset( lpOutResource, 0, sizeof( NETRESOURCE));
3088 NPGetResourceInformation( LPNETRESOURCE lpNetResource,
3090 LPDWORD lpBufferSize,
3091 LPWSTR *lplpSystem )
3094 DWORD dwStatus = WN_NOT_CONNECTED;
3095 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3097 DWORD dwBufferSize = 0;
3098 HANDLE hControlDevice = NULL;
3099 NETRESOURCE *pNetResource = (NETRESOURCE *)lpBuffer;
3100 PWCHAR pStringZone = NULL;
3101 UNICODE_STRING uniRemoteName;
3102 DWORD ulRequiredLen = 0;
3113 ReadProviderNameString();
3115 if ( NPIsFSDisabled())
3118 #ifdef AFS_DEBUG_TRACE
3119 AFSDbgPrint( L"NPGetResourceInformation AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
3122 try_return( dwStatus = WN_BAD_NETNAME);
3125 if ( lpNetResource == NULL ||
3126 lpBufferSize == NULL )
3129 #ifdef AFS_DEBUG_TRACE
3130 AFSDbgPrint( L"NPGetResourceInformaton Null lpNetResource or lpBufferSize\n");
3132 return WN_BAD_VALUE;
3135 if( lpNetResource->lpRemoteName == NULL)
3137 #ifdef AFS_DEBUG_TRACE
3138 AFSDbgPrint( L"NPGetResourceInformation No resource name\n");
3141 try_return( dwStatus = WN_NOT_CONNECTED);
3144 dwPassedSize = *lpBufferSize;
3146 dwBufferSize = 0x1000;
3148 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
3150 if( pConnectCB == NULL)
3153 try_return( dwStatus = WN_OUT_OF_MEMORY);
3156 pConnectCB->RemoteNameLength = wcslen( lpNetResource->lpRemoteName) * sizeof( WCHAR);
3158 StringCbCopy( pConnectCB->RemoteName,
3159 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
3160 lpNetResource->lpRemoteName);
3162 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3164 hControlDevice = OpenRedirector();
3166 if( hControlDevice == NULL)
3169 #ifdef AFS_DEBUG_TRACE
3170 AFSDbgPrint( L"NPGetResourceInformation OpenRedirector failure, returning WN_NET_ERROR\n");
3173 try_return( dwStatus = WN_NET_ERROR);
3176 uniRemoteName.Length = (USHORT)pConnectCB->RemoteNameLength;
3177 uniRemoteName.MaximumLength = uniRemoteName.Length;
3178 uniRemoteName.Buffer = pConnectCB->RemoteName;
3180 #ifdef AFS_DEBUG_TRACE
3181 AFSDbgPrint( L"NPGetResourceInformation For remote name %wZ Scope %08lX Type %08lX Usage %08lX\n",
3188 dwError = DeviceIoControl( hControlDevice,
3189 IOCTL_AFS_GET_CONNECTION_INFORMATION,
3199 #ifdef AFS_DEBUG_TRACE
3200 DWORD gle = GetLastError();
3202 AFSDbgPrint( L"NPGetResourceInformation Failed to get connection info from file system for local %s gle 0x%x\n",
3203 lpNetResource->lpRemoteName, gle);
3205 try_return( dwStatus = WN_BAD_NETNAME);
3208 // Determine the space needed for this entry...
3210 ulRequiredLen = sizeof( NETRESOURCE);
3212 ulRequiredLen += pConnectCB->RemoteNameLength + sizeof( WCHAR);
3214 ulRequiredLen += pConnectCB->CommentLength + sizeof( WCHAR);
3216 ulRequiredLen += cbProviderNameLength + sizeof( WCHAR);
3218 ulRequiredLen += pConnectCB->RemainingPathLength + sizeof( WCHAR);
3220 if( pNetResource == NULL ||
3221 ulRequiredLen > dwPassedSize)
3224 *lpBufferSize = ulRequiredLen;
3226 try_return( dwStatus = WN_MORE_DATA);
3229 pStringZone = (PWCHAR) ((char *)lpBuffer + sizeof( NETRESOURCE));
3231 pNetResource->dwScope = 0 /* pConnectCB->Scope*/;
3232 pNetResource->dwType = 0 /* pConnectCB->Type */;
3234 pNetResource->dwDisplayType = pConnectCB->DisplayType;
3236 pNetResource->dwUsage = pConnectCB->Usage;
3238 pNetResource->lpLocalName = NULL;
3241 pNetResource->lpRemoteName = pStringZone;
3243 CopyMemory( pStringZone,
3244 pConnectCB->RemoteName,
3245 pConnectCB->RemoteNameLength);
3247 pStringZone += (pConnectCB->RemoteNameLength / sizeof(WCHAR));
3249 *pStringZone++ = L'\0';
3252 pNetResource->lpComment = pStringZone;
3254 CopyMemory( pStringZone,
3255 (void *)((char *)pConnectCB + pConnectCB->CommentOffset),
3256 pConnectCB->CommentLength);
3258 pStringZone += (pConnectCB->CommentLength / sizeof(WCHAR));
3260 *pStringZone++ = L'\0';
3262 // copy remaining path
3263 if (pConnectCB->RemainingPathLength > 0)
3265 *lplpSystem = pStringZone;
3267 CopyMemory( pStringZone,
3268 (void *)((char *)pConnectCB + pConnectCB->RemainingPathOffset),
3269 pConnectCB->RemainingPathLength);
3271 pStringZone += (pConnectCB->RemainingPathLength / sizeof(WCHAR));
3273 *pStringZone++ = L'\0';
3275 #ifdef AFS_DEBUG_TRACE
3276 AFSDbgPrint( L"NPGetResourceInformation For remote name %s returning remaining path %s\n",
3277 pNetResource->lpRemoteName,
3282 // copy provider name
3283 pNetResource->lpProvider = pStringZone;
3285 StringCbCopy( pStringZone,
3286 cbProviderNameLength + sizeof( WCHAR),
3289 pStringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
3291 *lpBufferSize = ulRequiredLen;
3293 dwStatus = WN_SUCCESS;
3297 if ( hControlDevice != NULL)
3300 CloseHandle( hControlDevice);
3303 if( pConnectCB != NULL)
3306 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3314 SeparateRemainingPath( WCHAR * lpConnectionName, WCHAR **lppRemainingPath)
3321 // at this point the lpConnectionName contains the full name. We need to
3322 // truncate it to \\server\share and move the remaining path back one position.
3325 for ( pwch = lpConnectionName, dwCount = 0; *pwch; pwch++)
3327 if ( *pwch == L'\\')
3341 // Found the remaining path that must be moved
3344 *lppRemainingPath = pwch + 1;
3351 for ( ; *pwch; pwch++);
3354 // and work backwards moving the string
3355 // and then make sure that there is at least
3356 // a path separator.
3361 for ( ;pwch > *lppRemainingPath; pwch--)
3363 *pwch = *(pwch - 1);
3371 NPGetUniversalName( LPCWSTR lpLocalPath,
3374 LPDWORD lpBufferSize)
3377 DWORD dwBufferSize = *lpBufferSize;
3380 dwStatus = NPGetUniversalNameCommon( lpLocalPath,
3386 if ( dwStatus == WN_NOT_CONNECTED)
3389 dwStatus = NPGetUniversalNameCommon( lpLocalPath,
3398 *lpBufferSize = dwBufferSize;
3404 static DWORD APIENTRY
3405 NPGetUniversalNameCommon( LPCWSTR lpLocalPath,
3408 LPDWORD lpBufferSize,
3411 DWORD dwStatus = WN_NOT_CONNECTED;
3412 WCHAR wchLocalName[3];
3413 WCHAR *pwchSubstName = NULL;
3414 DWORD dwSubstNameLength = 0;
3415 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3417 DWORD dwBufferSize = 0;
3418 DWORD dwPassedSize = *lpBufferSize;
3419 DWORD dwRemainingLength = *lpBufferSize;
3420 HANDLE hControlDevice = NULL;
3421 DWORD dwLocalPathLength = 0;
3422 DWORD dwRemainingPathLength = 0;
3428 #ifdef AFS_DEBUG_TRACE
3429 AFSDbgPrint( L"NPGetUniversalName local path %s level 0x%X\n",
3430 lpLocalPath ? lpLocalPath : L"(Null)",
3434 if ( NPIsFSDisabled())
3437 #ifdef AFS_DEBUG_TRACE
3438 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
3441 try_return( dwStatus = WN_NOT_CONNECTED);
3444 dwLocalPathLength = lstrlen( lpLocalPath);
3446 dwRemainingPathLength = dwLocalPathLength - 2; // no drive letter
3448 if( dwLocalPathLength == 0)
3451 #ifdef AFS_DEBUG_TRACE
3452 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_BAD_LOCALNAME\n");
3455 try_return( dwStatus = WN_BAD_LOCALNAME);
3458 if( lpBuffer == NULL ||
3459 lpBufferSize == NULL)
3461 #ifdef AFS_DEBUG_TRACE
3462 AFSDbgPrint( L"NPGetUniversalName No output buffer or size\n");
3464 try_return( dwStatus = WN_BAD_VALUE);
3467 dwSubstNameLength = 4096;
3469 pwchSubstName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSubstNameLength);
3471 if ( pwchSubstName == NULL)
3473 #ifdef AFS_DEBUG_TRACE
3474 AFSDbgPrint( L"NPGetUniversalName unable to allocate substitution name buffer.\n");
3476 try_return( dwStatus = WN_OUT_OF_MEMORY);
3479 memset(lpBuffer, 0, dwPassedSize);
3481 if ( !bDriveSubstOk ||
3482 !DriveSubstitution( lpLocalPath, pwchSubstName, dwSubstNameLength, &dwStatus))
3484 wchLocalName[0] = towupper(lpLocalPath[0]);
3485 wchLocalName[1] = L':';
3486 wchLocalName[2] = L'\0';
3488 #ifdef AFS_DEBUG_TRACE
3489 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for %s level 0x%X\n",
3497 ReadServerNameString();
3499 if ( pwchSubstName[0] != L'\\' &&
3500 pwchSubstName[1] == L':')
3503 wchLocalName[0] = towupper(pwchSubstName[0]);
3504 wchLocalName[1] = L':';
3505 wchLocalName[2] = L'\0';
3507 #ifdef AFS_DEBUG_TRACE
3508 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for drive substitution %s -> %s\n",
3513 else if ( _wcsnicmp( pwchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
3514 ( pwchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
3515 pwchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
3519 #ifdef AFS_DEBUG_TRACE
3520 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is AFS; Level 0x%x BufferSize 0x%x\n",
3526 dwBufferSize = (wcslen( pwchSubstName) + 1) * sizeof( WCHAR);
3528 switch( dwInfoLevel)
3531 case UNIVERSAL_NAME_INFO_LEVEL:
3534 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3536 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize;
3538 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3541 #ifdef AFS_DEBUG_TRACE
3542 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3545 try_return( dwStatus = WN_MORE_DATA);
3548 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3550 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3552 memcpy( pUniversalInfo->lpUniversalName,
3554 min( dwBufferSize, dwRemainingLength));
3556 dwRemainingLength -= min( dwBufferSize, dwRemainingLength);
3558 #ifdef AFS_DEBUG_TRACE
3559 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3561 pUniversalInfo->lpUniversalName,
3562 pUniversalInfo->lpUniversalName);
3565 if ( dwPassedSize < *lpBufferSize)
3568 try_return( dwStatus = WN_MORE_DATA);
3571 try_return( dwStatus = WN_SUCCESS);
3574 case REMOTE_NAME_INFO_LEVEL:
3577 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3579 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + 2 * dwBufferSize + sizeof( WCHAR);
3581 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3584 #ifdef AFS_DEBUG_TRACE
3585 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3588 try_return( dwStatus = WN_MORE_DATA);
3591 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3593 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3595 memcpy( pRemoteInfo->lpUniversalName,
3597 min( dwRemainingLength, dwBufferSize));
3599 dwRemainingLength -= min( dwRemainingLength, dwBufferSize);
3601 #ifdef AFS_DEBUG_TRACE
3602 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3604 pRemoteInfo->lpUniversalName,
3605 pRemoteInfo->lpUniversalName);
3608 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3610 pRemoteInfo->lpConnectionName = (LPTSTR)((char *)pRemoteInfo->lpUniversalName + dwBufferSize);
3612 memcpy( pRemoteInfo->lpConnectionName,
3614 min( dwRemainingLength, dwBufferSize));
3616 dwRemainingLength -= min( dwRemainingLength, dwBufferSize) - sizeof( WCHAR);
3618 SeparateRemainingPath( pRemoteInfo->lpConnectionName,
3619 &pRemoteInfo->lpRemainingPath);
3622 #ifdef AFS_DEBUG_TRACE
3623 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3625 pRemoteInfo->lpConnectionName,
3626 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3628 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3630 pRemoteInfo->lpRemainingPath,
3631 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3634 if ( dwPassedSize < *lpBufferSize)
3637 try_return( dwStatus = WN_MORE_DATA);
3640 try_return( dwStatus = WN_SUCCESS);
3644 #ifdef AFS_DEBUG_TRACE
3645 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3648 try_return( dwStatus = WN_BAD_VALUE);
3654 #ifdef AFS_DEBUG_TRACE
3655 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is not AFS\n",
3658 try_return( dwStatus = WN_NOT_CONNECTED);
3662 dwBufferSize = 0x1000;
3664 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
3666 if( pConnectCB == NULL)
3668 try_return( dwStatus = WN_OUT_OF_MEMORY);
3671 pConnectCB->LocalName = towupper(wchLocalName[0]);
3673 pConnectCB->RemoteNameLength = 0;
3675 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3677 hControlDevice = OpenRedirector();
3679 if( hControlDevice == NULL)
3682 try_return( dwStatus = WN_NET_ERROR);
3685 dwError = DeviceIoControl( hControlDevice,
3686 IOCTL_AFS_GET_CONNECTION,
3696 #ifdef AFS_DEBUG_TRACE
3697 DWORD gle = GetLastError();
3699 AFSDbgPrint( L"NPGetUniversalName Failed to get connection from file system for local %s gle 0x%x\n",
3702 try_return( dwStatus = WN_NOT_CONNECTED);
3705 switch( dwInfoLevel)
3708 case UNIVERSAL_NAME_INFO_LEVEL:
3711 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3713 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize + sizeof( WCHAR);
3715 *lpBufferSize += dwRemainingPathLength * sizeof( WCHAR);
3717 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3720 #ifdef AFS_DEBUG_TRACE
3721 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3724 try_return( dwStatus = WN_MORE_DATA);
3727 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3729 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3731 pch = (char *)pUniversalInfo->lpUniversalName;
3735 min( dwBufferSize, dwRemainingLength));
3737 pch += min( dwBufferSize, dwRemainingLength);
3739 dwRemainingLength -= min( dwBufferSize + sizeof(WCHAR), dwRemainingLength);
3743 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3745 pch += min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3747 dwRemainingLength -= min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3749 #ifdef AFS_DEBUG_TRACE
3750 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3752 pUniversalInfo->lpUniversalName,
3753 pUniversalInfo->lpUniversalName);
3756 if ( dwPassedSize < *lpBufferSize)
3759 try_return( dwStatus = WN_MORE_DATA);
3762 try_return( dwStatus = WN_SUCCESS);
3765 case REMOTE_NAME_INFO_LEVEL:
3768 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3770 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + (2 * dwBufferSize + sizeof( WCHAR)) + 2 * sizeof( WCHAR);
3772 *lpBufferSize += 2 * dwRemainingPathLength * sizeof( WCHAR);
3774 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3777 #ifdef AFS_DEBUG_TRACE
3778 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3781 try_return( dwStatus = WN_MORE_DATA);
3784 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3786 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3788 pch = (char *)pRemoteInfo->lpUniversalName;
3792 min( dwBufferSize, dwRemainingLength));
3794 pch += min( dwBufferSize, dwRemainingLength);
3796 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3800 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3802 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3804 dwRemainingLength -= min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3806 #ifdef AFS_DEBUG_TRACE
3807 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3809 pRemoteInfo->lpUniversalName,
3810 pRemoteInfo->lpUniversalName);
3813 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3815 pRemoteInfo->lpConnectionName = (LPWSTR)pch;
3819 min( dwBufferSize, dwRemainingLength));
3821 pch += min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3823 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3827 if ( dwRemainingLength > dwRemainingPathLength + sizeof( WCHAR))
3829 pRemoteInfo->lpRemainingPath = (LPWSTR)pch;
3833 min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength));
3835 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3837 dwRemainingLength -= min((dwLocalPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3840 #ifdef AFS_DEBUG_TRACE
3841 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3843 pRemoteInfo->lpConnectionName,
3844 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3846 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3848 pRemoteInfo->lpRemainingPath,
3849 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3852 if ( dwPassedSize < *lpBufferSize)
3855 try_return( dwStatus = WN_MORE_DATA);
3858 try_return( dwStatus = WN_SUCCESS);
3862 #ifdef AFS_DEBUG_TRACE
3863 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3866 try_return( dwStatus = WN_BAD_VALUE);
3871 #ifdef AFS_DEBUG_TRACE
3872 AFSDbgPrint( L"NPGetUniversalName BufferSize 0x%X\n",
3875 if ( hControlDevice != NULL)
3878 CloseHandle( hControlDevice);
3884 HeapFree( GetProcessHeap(), 0, (PVOID) pwchSubstName);
3887 if( pConnectCB != NULL)
3890 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3899 GetFormatFlags( DWORD dwFlags)
3901 static WCHAR Buffer[128] = L"";
3904 // WNFMT_MULTILINE 0x01
3905 // WNFMT_ABBREVIATED 0x02
3906 // WNFMT_INENUM 0x10
3907 // WNFMT_CONNECTION 0x20
3917 if ( dwFlags & WNFMT_MULTILINE )
3919 StringCbCat( Buffer, sizeof(Buffer), L"MULTILINE|");
3922 if ( dwFlags & WNFMT_INENUM )
3924 StringCbCat( Buffer, sizeof(Buffer), L"ABBREVIATED|");
3927 if ( dwFlags & WNFMT_INENUM )
3929 StringCbCat( Buffer, sizeof(Buffer), L"INENUM|");
3932 if ( dwFlags & WNFMT_CONNECTION )
3934 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTION|");
3937 if ( dwFlags & ~(WNFMT_MULTILINE|WNFMT_ABBREVIATED|WNFMT_INENUM|WNFMT_CONNECTION) )
3939 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
3942 Buffer[lstrlen(Buffer)-1] = L'\0';
3948 NPFormatNetworkName( LPTSTR lpRemoteName,
3949 LPTSTR lpFormattedName,
3952 DWORD dwAveCharPerLine)
3955 DWORD dwLen = 0, dwCurrentLen = 0;
3956 LPTSTR pCurrentName = lpRemoteName;
3958 #ifdef AFS_DEBUG_TRACE
3959 AFSDbgPrint( L"NPFormatNetworkName Remote %s Flags %s (0x%x) CharsPerLine %u\n",
3961 GetFormatFlags( dwFlags),
3968 // Walk back in the name until we hit a \
3971 dwLen = wcslen( lpRemoteName);
3973 pCurrentName += (dwLen - 1);
3975 if ( pCurrentName[ 0] != L'\\')
3981 if( pCurrentName[ 0] == L'\\')
3997 if( *lpnLength < dwCurrentLen * sizeof( WCHAR))
4000 *lpnLength = dwCurrentLen * sizeof( WCHAR);
4002 #ifdef AFS_DEBUG_TRACE
4003 AFSDbgPrint( L"NPFormatNetworkName remote name %s WN_MORE_DATA\n",
4007 return WN_MORE_DATA;
4010 StringCbCopy( lpFormattedName,
4014 *lpnLength = dwCurrentLen * sizeof( WCHAR);
4016 #ifdef AFS_DEBUG_TRACE
4017 AFSDbgPrint( L"NPFormatNetworkName remote name %s as %s\n",
4025 /************************************************************
4026 / Unsupported entry points
4027 /************************************************************/
4030 // AuthGroup processing is implemented in src/WINNT/afsd/afslogon.c
4035 LPCWSTR lpAuthentInfoType,
4036 LPVOID lpAuthentInfo,
4037 LPCWSTR lpPreviousAuthentInfoType,
4038 LPVOID lpPreviousAuthentInfo,
4039 LPWSTR lpStationName,
4040 LPVOID StationHandle,
4041 LPWSTR *lpLogonScript)
4044 #ifdef AFS_DEBUG_TRACE
4045 AFSDbgPrint( L"NPLogonNotify, returning WN_NOT_SUPPORTED\n");
4048 return WN_NOT_SUPPORTED;
4052 NPPasswordChangeNotify (
4053 LPCWSTR lpAuthentInfoType,
4054 LPVOID lpAuthentInfo,
4055 LPCWSTR lpPreviousAuthentInfoType,
4056 LPVOID lpPreviousAuthentInfo,
4057 LPWSTR lpStationName,
4058 LPVOID StationHandle,
4059 DWORD dwChangeInfo )
4062 #ifdef AFS_DEBUG_TRACE
4063 AFSDbgPrint( L"NPPasswordChangeNotify, returning WN_NOT_SUPPORTED\n");
4066 SetLastError( WN_NOT_SUPPORTED );
4068 return WN_NOT_SUPPORTED;
4072 NPGetUser( LPTSTR lpName,
4074 LPDWORD lpBufferSize)
4077 DWORD rc = WN_NOT_SUPPORTED;
4079 AFSDbgPrint( L"NPGetUser Entry Name %s\n", lpName);
4087 NPGetReconnectFlags( LPWSTR lpRemoteName,
4088 unsigned char *Parameter2)
4091 DWORD dwStatus = WN_NOT_SUPPORTED;
4093 AFSDbgPrint( L"NPGetReconnectFlags RemoteName %s\n",
4102 I_SystemFocusDialog( VOID)
4105 DWORD dwStatus = WN_NOT_SUPPORTED;
4107 AFSDbgPrint( L"I_SystemFocusDialog\n");
4112 /************************************************************
4113 / END Unsupported entry points
4114 /************************************************************/
4121 HANDLE hControlDevice = NULL;
4123 hControlDevice = CreateFile( AFS_SYMLINK_W,
4124 GENERIC_READ | GENERIC_WRITE,
4125 FILE_SHARE_READ | FILE_SHARE_WRITE,
4131 if( hControlDevice == INVALID_HANDLE_VALUE)
4134 hControlDevice = NULL;
4135 #ifdef AFS_DEBUG_TRACE
4136 AFSDbgPrint( L"Failed to open control device error: %d\n",
4142 // only do this if you want network shares to fail to mount
4143 // when the file system is not yet ready
4147 AFSDriverStatusRespCB respCB;
4150 memset( &respCB, '\0', sizeof( AFSDriverStatusRespCB));
4152 if ( !DeviceIoControl( hControlDevice,
4153 IOCTL_AFS_STATUS_REQUEST,
4157 sizeof( AFSDriverStatusRespCB),
4160 dwBytes != sizeof(AFSDriverStatusRespCB) ||
4161 respCB.Status != AFS_DRIVER_STATUS_READY )
4164 CloseHandle( hControlDevice);
4166 hControlDevice = NULL;
4171 return hControlDevice;
4177 static int init = 0;
4178 static DWORD debug = 0;
4183 if (RegOpenKey (HKEY_LOCAL_MACHINE,
4184 TEXT("SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider"), &hk) == 0)
4186 DWORD dwSize = sizeof(BOOL);
4187 DWORD dwType = REG_DWORD;
4188 RegQueryValueEx (hk, TEXT("Debug"), NULL, &dwType, (PBYTE)&debug, &dwSize);
4198 cm_Utf16ToUtf8Alloc(const WCHAR * s, int cch_src, int *pcch_dest)
4203 if (s == NULL || cch_src == 0 || *s == L'\0') {
4205 *pcch_dest = ((cch_src != 0)?1:0);
4209 cch_dest = WideCharToMultiByte(CP_UTF8, 0, s, cch_src, NULL, 0, NULL, FALSE);
4211 if (cch_dest == 0) {
4213 *pcch_dest = cch_dest;
4217 dest = HeapAlloc( GetProcessHeap(), 0, (cch_dest + 1) * sizeof(char));
4219 WideCharToMultiByte(CP_UTF8, 0, s, cch_src, dest, cch_dest, NULL, FALSE);
4223 *pcch_dest = cch_dest;
4229 AppendDebugStringToLogFile(WCHAR *wszbuffer)
4237 if ( !wszbuffer || !wszbuffer[0] )
4240 len = (int)wcslen(wszbuffer);
4242 buffer = cm_Utf16ToUtf8Alloc(wszbuffer, len, &len);
4247 hFile = CreateFileW( L"C:\\TEMP\\AFSRDFSProvider.log",
4252 FILE_ATTRIBUTE_NORMAL,
4255 if ( hFile == INVALID_HANDLE_VALUE ) {
4256 OutputDebugString(L"C:\\AFSRDFSProvider.log cannot be opened.\n");
4260 bRet = WriteFile( hFile, buffer, len, &dwWritten, NULL);
4262 bRet = CloseHandle(hFile);
4264 HeapFree(GetProcessHeap(), 0, buffer);
4275 WCHAR wszbuffer[512];
4277 DWORD debug = Debug();
4282 va_start( marker, Format );
4284 StringCbPrintf( wszbuffer, sizeof(wszbuffer), L"[%d-%08X] ",
4290 GetCurrentThreadId());
4292 rc = StringCbVPrintfW( &wszbuffer[ 14], sizeof(wszbuffer) - 14 * sizeof(WCHAR), Format, marker);
4294 if (SUCCEEDED(rc)) {
4296 OutputDebugString( wszbuffer );
4298 AppendDebugStringToLogFile(wszbuffer);
4300 OutputDebugString(L"AFSDbgPrint Failed to create string\n");
4303 return SUCCEEDED(rc) ? 1 : 0;