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;
2242 hControlDevice = OpenRedirector();
2244 if( hControlDevice == NULL)
2247 #ifdef AFS_DEBUG_TRACE
2248 AFSDbgPrint( L"NPOpenEnum OpenRedirector failure, returning WN_NET_ERROR\n");
2251 return WN_NO_NETWORK;
2254 CloseHandle( hControlDevice);
2257 *lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( AFSEnumerationCB));
2259 if( *lphEnum == NULL)
2262 return WN_OUT_OF_MEMORY;
2265 pEnumCB = (AFSEnumerationCB *)*lphEnum;
2267 pEnumCB->CurrentIndex = 0;
2269 pEnumCB->Type = dwType;
2273 case RESOURCE_CONNECTED:
2276 pEnumCB->Scope = RESOURCE_CONNECTED;
2281 case RESOURCE_CONTEXT:
2284 pEnumCB->Scope = RESOURCE_CONTEXT;
2289 case RESOURCE_GLOBALNET:
2292 if( lpNetResource != NULL &&
2293 lpNetResource->lpRemoteName != NULL)
2296 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2298 if( pEnumCB->RemoteName == NULL)
2301 dwStatus = WN_OUT_OF_MEMORY;
2302 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2308 StringCbCopy( pEnumCB->RemoteName,
2310 lpNetResource->lpRemoteName);
2315 pEnumCB->Scope = RESOURCE_GLOBALNET;
2322 #ifdef AFS_DEBUG_TRACE
2323 AFSDbgPrint( L"NPOpenEnum Processing (Scope %s 0x%x) Type %s Usage %s, returning WN_NOT_SUPPORTED\n",
2324 GetScopeString(dwScope), dwScope, GetTypeString(dwType), GetUsageString(dwUsage));
2327 dwStatus = WN_NOT_SUPPORTED;
2328 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2340 NPEnumResource( HANDLE hEnum,
2343 LPDWORD lpBufferSize)
2346 DWORD dwStatus = WN_NO_MORE_ENTRIES; //WN_SUCCESS;
2348 ULONG EntriesCopied;
2349 ULONG EntriesRequested;
2351 LPNETRESOURCE pNetResource;
2353 ULONG SpaceAvailable;
2355 AFSNetworkProviderConnectionCB *pConnectionCB = NULL;
2356 void *pConnectionCBBase = NULL;
2358 UNICODE_STRING uniRemoteName;
2359 HANDLE hControlDevice = NULL;
2360 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2365 if ( lpBufferSize == NULL)
2367 #ifdef AFS_DEBUG_TRACE
2368 AFSDbgPrint( L"NPEnumResource No output size, returning WN_BAD_VALUE\n");
2370 try_return( dwStatus = WN_BAD_VALUE);
2373 ReadProviderNameString();
2375 pNetResource = (LPNETRESOURCE) lpBuffer;
2376 SpaceAvailable = *lpBufferSize;
2377 EntriesRequested = *lpcCount;
2378 *lpcCount = EntriesCopied = 0;
2379 StringZone = (PWCHAR) ((char *)lpBuffer + *lpBufferSize);
2381 #ifdef AFS_DEBUG_TRACE
2382 AFSDbgPrint( L"NPEnumResource Processing Remote name %s Scope %s Type %s Usage %s Index %d SpaceAvailable 0x%lX RequestedEntries %lu\n",
2383 pEnumCB->RemoteName ? pEnumCB->RemoteName : L"(Null)",
2384 GetScopeString(pEnumCB->Scope),
2385 GetTypeString(pEnumCB->Type),
2386 GetUsageString(pEnumCB->Type),
2387 pEnumCB->CurrentIndex,
2392 if ( NPIsFSDisabled())
2395 #ifdef AFS_DEBUG_TRACE
2396 AFSDbgPrint( L"NPEnumResource AFSRDFS is disabled, returning WN_NO_MORE_ENTRIES\n");
2399 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2402 pConnectionCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 0x1000);
2404 if( pConnectionCB == NULL)
2407 #ifdef AFS_DEBUG_TRACE
2408 AFSDbgPrint( L"NPEnumResource Out of Memory\n");
2411 try_return( dwStatus = WN_OUT_OF_MEMORY);
2414 pConnectionCBBase = (void *)pConnectionCB;
2416 hControlDevice = OpenRedirector();
2418 if( hControlDevice == NULL)
2421 #ifdef AFS_DEBUG_TRACE
2422 AFSDbgPrint( L"NPEnumResource OpenRedirector failure, returning WN_NET_ERROR\n");
2425 try_return( dwStatus = WN_NET_ERROR);
2428 if( pEnumCB->Type != RESOURCETYPE_ANY && pEnumCB->Type != RESOURCETYPE_DISK)
2431 #ifdef AFS_DEBUG_TRACE
2432 AFSDbgPrint( L"NPEnumResource Non-DISK queries are not supported, returning WN_NO_MORE_ENTRIES\n");
2434 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2438 // Setup what we are going to ask for
2441 pConnectionCB->Scope = pEnumCB->Scope;
2443 pConnectionCB->Type = pEnumCB->Type;
2445 pConnectionCB->CurrentIndex = pEnumCB->CurrentIndex;
2447 pConnectionCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
2450 // If this is a RESOURCE_GLOBALNET enumeration then pass down the remote name if
2454 pConnectionCB->RemoteNameLength = 0;
2456 if( pEnumCB->Scope == RESOURCE_GLOBALNET &&
2457 pEnumCB->RemoteName != NULL)
2460 pConnectionCB->RemoteNameLength = wcslen( pEnumCB->RemoteName) * sizeof( WCHAR);
2462 StringCbCopy( pConnectionCB->RemoteName,
2463 (0x1000 - sizeof(AFSNetworkProviderConnectionCB)) + sizeof(WCHAR),
2464 pEnumCB->RemoteName);
2467 dwError = DeviceIoControl( hControlDevice,
2468 IOCTL_AFS_LIST_CONNECTIONS,
2478 #ifdef AFS_DEBUG_TRACE
2479 DWORD gle = GetLastError();
2481 AFSDbgPrint( L"NPEnumResource Failed to list connections from file system - gle 0x%x\n",
2484 try_return( dwStatus = WN_NOT_CONNECTED);
2487 if( dwCopyBytes == 0)
2490 #ifdef AFS_DEBUG_TRACE
2491 AFSDbgPrint( L"NPEnumResource No More Entries\n");
2493 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2496 dwIndex = pEnumCB->CurrentIndex;
2498 while( EntriesCopied < EntriesRequested)
2501 uniRemoteName.Length = (USHORT)pConnectionCB->RemoteNameLength;
2502 uniRemoteName.MaximumLength = uniRemoteName.Length;
2503 uniRemoteName.Buffer = pConnectionCB->RemoteName;
2505 // Determine the space needed for this entry...
2509 if( pConnectionCB->LocalName != 0)
2512 SpaceNeeded += 3 * sizeof(WCHAR); // local name
2515 SpaceNeeded += pConnectionCB->RemoteNameLength + sizeof( WCHAR); // remote name
2517 if( pConnectionCB->CommentLength > 0)
2520 SpaceNeeded += pConnectionCB->CommentLength + sizeof( WCHAR); // comment
2523 SpaceNeeded += cbProviderNameLength + sizeof( WCHAR); // provider name
2525 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2528 if (EntriesCopied == 0) {
2530 dwStatus = WN_MORE_DATA;
2532 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2534 #ifdef AFS_DEBUG_TRACE
2535 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2542 #ifdef AFS_DEBUG_TRACE
2543 AFSDbgPrint( L"NPEnumResource Return SUCCESS but more entries Index %d\n",
2547 dwStatus = WN_SUCCESS;
2553 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2555 pNetResource->dwScope = pConnectionCB->Scope;
2556 pNetResource->dwType = pConnectionCB->Type;
2558 pNetResource->dwDisplayType = pConnectionCB->DisplayType;
2560 if ( pNetResource->dwType == RESOURCETYPE_ANY &&
2561 pNetResource->dwDisplayType == RESOURCEDISPLAYTYPE_SHARE)
2564 pNetResource->dwType = RESOURCETYPE_DISK;
2567 if ( pEnumCB->Scope == RESOURCE_CONNECTED)
2570 pNetResource->dwUsage = 0;
2575 pNetResource->dwUsage = pConnectionCB->Usage;
2578 // setup string area at opposite end of buffer
2579 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2582 if( pConnectionCB->LocalName != 0)
2585 pNetResource->lpLocalName = StringZone;
2586 *StringZone++ = towupper(pConnectionCB->LocalName);
2587 *StringZone++ = L':';
2588 *StringZone++ = L'\0';
2593 pNetResource->lpLocalName = NULL;
2596 #ifdef AFS_DEBUG_TRACE
2597 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2602 pNetResource->lpRemoteName = StringZone;
2604 CopyMemory( StringZone,
2605 pConnectionCB->RemoteName,
2606 pConnectionCB->RemoteNameLength);
2608 StringZone += (pConnectionCB->RemoteNameLength / sizeof(WCHAR));
2610 *StringZone++ = L'\0';
2613 if( pConnectionCB->CommentLength > 0)
2616 pNetResource->lpComment = StringZone;
2618 CopyMemory( StringZone,
2619 (void *)((char *)pConnectionCB + pConnectionCB->CommentOffset),
2620 pConnectionCB->CommentLength);
2622 StringZone += (pConnectionCB->CommentLength / sizeof(WCHAR));
2624 *StringZone++ = L'\0';
2629 pNetResource->lpComment = NULL;
2632 // copy provider name
2633 pNetResource->lpProvider = StringZone;
2634 StringCbCopy( StringZone,
2635 cbProviderNameLength + sizeof( WCHAR),
2638 StringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
2640 #ifdef AFS_DEBUG_TRACE
2641 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2643 GetScopeString(pNetResource->dwScope),
2644 GetTypeString(pNetResource->dwType),
2645 GetDisplayString(pNetResource->dwDisplayType),
2646 GetUsageString(pNetResource->dwUsage),
2647 pNetResource->lpLocalName,
2648 pNetResource->lpRemoteName,
2649 pNetResource->lpComment);
2652 // setup the new end of buffer
2653 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2661 dwCopyBytes -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2662 pConnectionCB->RemoteNameLength +
2663 pConnectionCB->CommentLength;
2665 if( dwCopyBytes == 0)
2668 dwStatus = WN_SUCCESS;
2673 pConnectionCB = (AFSNetworkProviderConnectionCB *)((char *)pConnectionCB +
2674 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2675 pConnectionCB->RemoteNameLength +
2676 pConnectionCB->CommentLength);
2679 *lpcCount = EntriesCopied;
2681 // update entry index
2682 pEnumCB->CurrentIndex = dwIndex;
2684 #ifdef AFS_DEBUG_TRACE
2685 AFSDbgPrint( L"NPEnumResource Completed Count %d Index %d\n",
2692 if ( hControlDevice != NULL)
2695 CloseHandle( hControlDevice);
2698 if( pConnectionCBBase != NULL)
2701 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectionCBBase);
2710 Routine Description:
2712 This routine closes the handle for enumeration of resources.
2716 hEnum - the enumeration handle
2720 WN_SUCCESS if successful, otherwise the appropriate error
2724 The sample only supports the notion of enumerating connected shares
2729 NPCloseEnum( HANDLE hEnum )
2732 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2734 #ifdef AFS_DEBUG_TRACE
2735 AFSDbgPrint( L"NPCloseEnum\n");
2738 if( pEnumCB->RemoteName != NULL)
2741 HeapFree( GetProcessHeap( ), 0, (PVOID) pEnumCB->RemoteName);
2744 HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum );
2750 NPGetResourceParent( LPNETRESOURCE lpNetResource,
2752 LPDWORD lpBufferSize )
2755 DWORD dwStatus = WN_ACCESS_DENIED;
2756 WCHAR *pwchRemoteName = NULL, *pwchSearch = NULL, *pwchSystem = NULL;
2757 LPNETRESOURCE lpOutResource = (LPNETRESOURCE) lpBuffer;
2759 if ( NPIsFSDisabled())
2762 #ifdef AFS_DEBUG_TRACE
2763 AFSDbgPrint( L"NPGetResourceParent AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
2766 return WN_BAD_NETNAME;
2769 if ( lpNetResource == NULL)
2771 #ifdef AFS_DEBUG_TRACE
2772 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2774 return WN_MORE_DATA;
2777 if( lpNetResource->lpRemoteName == NULL)
2779 #ifdef AFS_DEBUG_TRACE
2780 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2782 return WN_BAD_NETNAME;
2785 if ( lpNetResource->dwType != 0 &&
2786 lpNetResource->dwType != RESOURCETYPE_DISK)
2788 #ifdef AFS_DEBUG_TRACE
2789 AFSDbgPrint( L"NPGetResourceParent Bad dwType\n");
2791 return WN_BAD_VALUE;
2794 if ( lpBufferSize == NULL )
2797 #ifdef AFS_DEBUG_TRACE
2798 AFSDbgPrint( L"NPGetResourceParent Null lpBufferSize\n");
2800 return WN_BAD_VALUE;
2803 #ifdef AFS_DEBUG_TRACE
2804 AFSDbgPrint( L"NPGetResourceParent For remote name %s\n",
2805 lpNetResource->lpRemoteName);
2808 pwchRemoteName = lpNetResource->lpRemoteName;
2811 // The input will be of the form \\AFS\CELL\path.
2812 // \\AFS has no parent and by definition returns an empty NETRESOURCE.
2815 pwchSearch = pwchRemoteName + (wcslen( pwchRemoteName) - 1);
2817 while( pwchSearch != pwchRemoteName)
2820 if( *pwchSearch == L'\\')
2823 *pwchSearch = L'\0';
2831 if( pwchSearch != pwchRemoteName &&
2832 pwchSearch != pwchRemoteName + 1)
2835 #ifdef AFS_DEBUG_TRACE
2836 AFSDbgPrint( L"NPGetResourceParent Processing parent %s\n",
2837 lpNetResource->lpRemoteName);
2840 dwStatus = NPGetResourceInformation( lpNetResource,
2847 if ( lpOutResource == NULL ||
2848 *lpBufferSize < sizeof( NETRESOURCE) )
2850 *lpBufferSize = sizeof( NETRESOURCE);
2852 return WN_MORE_DATA;
2855 memset( lpOutResource, 0, sizeof( NETRESOURCE));
2865 NPGetResourceInformation( LPNETRESOURCE lpNetResource,
2867 LPDWORD lpBufferSize,
2868 LPWSTR *lplpSystem )
2871 DWORD dwStatus = WN_NOT_CONNECTED;
2872 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
2874 DWORD dwBufferSize = 0;
2875 HANDLE hControlDevice = NULL;
2876 NETRESOURCE *pNetResource = (NETRESOURCE *)lpBuffer;
2877 PWCHAR pStringZone = NULL;
2878 UNICODE_STRING uniRemoteName;
2879 DWORD ulRequiredLen = 0;
2890 ReadProviderNameString();
2892 if ( NPIsFSDisabled())
2895 #ifdef AFS_DEBUG_TRACE
2896 AFSDbgPrint( L"NPGetResourceInformation AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
2899 try_return( dwStatus = WN_BAD_NETNAME);
2902 if ( lpNetResource == NULL ||
2903 lpBufferSize == NULL )
2906 #ifdef AFS_DEBUG_TRACE
2907 AFSDbgPrint( L"NPGetResourceInformaton Null lpNetResource or lpBufferSize\n");
2909 return WN_BAD_VALUE;
2912 if( lpNetResource->lpRemoteName == NULL)
2914 #ifdef AFS_DEBUG_TRACE
2915 AFSDbgPrint( L"NPGetResourceInformation No resource name\n");
2918 try_return( dwStatus = WN_NOT_CONNECTED);
2921 dwPassedSize = *lpBufferSize;
2923 dwBufferSize = 0x1000;
2925 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
2927 if( pConnectCB == NULL)
2930 try_return( dwStatus = WN_OUT_OF_MEMORY);
2933 pConnectCB->RemoteNameLength = wcslen( lpNetResource->lpRemoteName) * sizeof( WCHAR);
2935 StringCbCopy( pConnectCB->RemoteName,
2936 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
2937 lpNetResource->lpRemoteName);
2939 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
2941 hControlDevice = OpenRedirector();
2943 if( hControlDevice == NULL)
2946 #ifdef AFS_DEBUG_TRACE
2947 AFSDbgPrint( L"NPGetResourceInformation OpenRedirector failure, returning WN_NET_ERROR\n");
2950 try_return( dwStatus = WN_NET_ERROR);
2953 uniRemoteName.Length = (USHORT)pConnectCB->RemoteNameLength;
2954 uniRemoteName.MaximumLength = uniRemoteName.Length;
2955 uniRemoteName.Buffer = pConnectCB->RemoteName;
2957 #ifdef AFS_DEBUG_TRACE
2958 AFSDbgPrint( L"NPGetResourceInformation For remote name %wZ Scope %08lX Type %08lX Usage %08lX\n",
2965 dwError = DeviceIoControl( hControlDevice,
2966 IOCTL_AFS_GET_CONNECTION_INFORMATION,
2976 dwStatus = GetLastError();
2978 #ifdef AFS_DEBUG_TRACE
2979 AFSDbgPrint( L"NPGetResourceInformation Failed to get connection info from file system for local %s gle 0x%x\n",
2980 lpNetResource->lpRemoteName, dwStatus);
2983 try_return( dwStatus);
2986 // Determine the space needed for this entry...
2988 ulRequiredLen = sizeof( NETRESOURCE);
2990 ulRequiredLen += pConnectCB->RemoteNameLength + sizeof( WCHAR);
2992 ulRequiredLen += pConnectCB->CommentLength + sizeof( WCHAR);
2994 ulRequiredLen += cbProviderNameLength + sizeof( WCHAR);
2996 ulRequiredLen += pConnectCB->RemainingPathLength + sizeof( WCHAR);
2998 if( pNetResource == NULL ||
2999 ulRequiredLen > dwPassedSize)
3002 *lpBufferSize = ulRequiredLen;
3004 try_return( dwStatus = WN_MORE_DATA);
3007 pStringZone = (PWCHAR) ((char *)lpBuffer + sizeof( NETRESOURCE));
3009 pNetResource->dwScope = 0 /* pConnectCB->Scope*/;
3010 pNetResource->dwType = 0 /* pConnectCB->Type */;
3012 pNetResource->dwDisplayType = pConnectCB->DisplayType;
3014 pNetResource->dwUsage = pConnectCB->Usage;
3016 pNetResource->lpLocalName = NULL;
3019 pNetResource->lpRemoteName = pStringZone;
3021 CopyMemory( pStringZone,
3022 pConnectCB->RemoteName,
3023 pConnectCB->RemoteNameLength);
3025 pStringZone += (pConnectCB->RemoteNameLength / sizeof(WCHAR));
3027 *pStringZone++ = L'\0';
3030 pNetResource->lpComment = pStringZone;
3032 CopyMemory( pStringZone,
3033 (void *)((char *)pConnectCB + pConnectCB->CommentOffset),
3034 pConnectCB->CommentLength);
3036 pStringZone += (pConnectCB->CommentLength / sizeof(WCHAR));
3038 *pStringZone++ = L'\0';
3040 // copy remaining path
3041 if (pConnectCB->RemainingPathLength > 0)
3043 *lplpSystem = pStringZone;
3045 CopyMemory( pStringZone,
3046 (void *)((char *)pConnectCB + pConnectCB->RemainingPathOffset),
3047 pConnectCB->RemainingPathLength);
3049 pStringZone += (pConnectCB->RemainingPathLength / sizeof(WCHAR));
3051 *pStringZone++ = L'\0';
3053 #ifdef AFS_DEBUG_TRACE
3054 AFSDbgPrint( L"NPGetResourceInformation For remote name %s returning remaining path %s\n",
3055 pNetResource->lpRemoteName,
3060 // copy provider name
3061 pNetResource->lpProvider = pStringZone;
3063 StringCbCopy( pStringZone,
3064 cbProviderNameLength + sizeof( WCHAR),
3067 pStringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
3069 *lpBufferSize = ulRequiredLen;
3071 dwStatus = WN_SUCCESS;
3075 if ( hControlDevice != NULL)
3078 CloseHandle( hControlDevice);
3081 if( pConnectCB != NULL)
3084 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3092 SeparateRemainingPath( WCHAR * lpConnectionName, WCHAR **lppRemainingPath)
3099 // at this point the lpConnectionName contains the full name. We need to
3100 // truncate it to \\server\share and move the remaining path back one position.
3103 for ( pwch = lpConnectionName, dwCount = 0; *pwch; pwch++)
3105 if ( *pwch == L'\\')
3119 // Found the remaining path that must be moved
3122 *lppRemainingPath = pwch + 1;
3129 for ( ; *pwch; pwch++);
3132 // and work backwards moving the string
3133 // and then make sure that there is at least
3134 // a path separator.
3139 for ( ;pwch > *lppRemainingPath; pwch--)
3141 *pwch = *(pwch - 1);
3149 NPGetUniversalName( LPCWSTR lpLocalPath,
3152 LPDWORD lpBufferSize)
3155 DWORD dwBufferSize = *lpBufferSize;
3158 dwStatus = NPGetUniversalNameCommon( lpLocalPath,
3164 if ( dwStatus == WN_NOT_CONNECTED)
3167 dwStatus = NPGetUniversalNameCommon( lpLocalPath,
3176 *lpBufferSize = dwBufferSize;
3182 static DWORD APIENTRY
3183 NPGetUniversalNameCommon( LPCWSTR lpLocalPath,
3186 LPDWORD lpBufferSize,
3189 DWORD dwStatus = WN_NOT_CONNECTED;
3190 WCHAR wchLocalName[3];
3191 WCHAR *pwchSubstName = NULL;
3192 DWORD dwSubstNameLength = 0;
3193 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3195 DWORD dwBufferSize = 0;
3196 DWORD dwPassedSize = *lpBufferSize;
3197 DWORD dwRemainingLength = *lpBufferSize;
3198 HANDLE hControlDevice = NULL;
3199 DWORD dwLocalPathLength = 0;
3200 DWORD dwRemainingPathLength = 0;
3206 #ifdef AFS_DEBUG_TRACE
3207 AFSDbgPrint( L"NPGetUniversalName local path %s level 0x%X\n",
3208 lpLocalPath ? lpLocalPath : L"(Null)",
3212 if ( NPIsFSDisabled())
3215 #ifdef AFS_DEBUG_TRACE
3216 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
3219 try_return( dwStatus = WN_NOT_CONNECTED);
3222 dwLocalPathLength = lstrlen( lpLocalPath);
3224 dwRemainingPathLength = dwLocalPathLength - 2; // no drive letter
3226 if( dwLocalPathLength == 0)
3229 #ifdef AFS_DEBUG_TRACE
3230 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_BAD_LOCALNAME\n");
3233 try_return( dwStatus = WN_BAD_LOCALNAME);
3236 if( lpBuffer == NULL ||
3237 lpBufferSize == NULL)
3239 #ifdef AFS_DEBUG_TRACE
3240 AFSDbgPrint( L"NPGetUniversalName No output buffer or size\n");
3242 try_return( dwStatus = WN_BAD_VALUE);
3245 dwSubstNameLength = 4096;
3247 pwchSubstName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSubstNameLength);
3249 if ( pwchSubstName == NULL)
3251 #ifdef AFS_DEBUG_TRACE
3252 AFSDbgPrint( L"NPGetUniversalName unable to allocate substitution name buffer.\n");
3254 try_return( dwStatus = WN_OUT_OF_MEMORY);
3257 memset(lpBuffer, 0, dwPassedSize);
3259 if ( !bDriveSubstOk ||
3260 !DriveSubstitution( lpLocalPath, pwchSubstName, dwSubstNameLength, &dwStatus))
3262 wchLocalName[0] = towupper(lpLocalPath[0]);
3263 wchLocalName[1] = L':';
3264 wchLocalName[2] = L'\0';
3266 #ifdef AFS_DEBUG_TRACE
3267 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for %s level 0x%X\n",
3275 ReadServerNameString();
3277 if ( pwchSubstName[0] != L'\\' &&
3278 pwchSubstName[1] == L':')
3281 wchLocalName[0] = towupper(pwchSubstName[0]);
3282 wchLocalName[1] = L':';
3283 wchLocalName[2] = L'\0';
3285 #ifdef AFS_DEBUG_TRACE
3286 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for drive substitution %s -> %s\n",
3291 else if ( _wcsnicmp( pwchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
3292 ( pwchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
3293 pwchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
3297 #ifdef AFS_DEBUG_TRACE
3298 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is AFS; Level 0x%x BufferSize 0x%x\n",
3304 dwBufferSize = (wcslen( pwchSubstName) + 1) * sizeof( WCHAR);
3306 switch( dwInfoLevel)
3309 case UNIVERSAL_NAME_INFO_LEVEL:
3312 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3314 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize;
3316 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3319 #ifdef AFS_DEBUG_TRACE
3320 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3323 try_return( dwStatus = WN_MORE_DATA);
3326 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3328 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3330 memcpy( pUniversalInfo->lpUniversalName,
3332 min( dwBufferSize, dwRemainingLength));
3334 dwRemainingLength -= min( dwBufferSize, dwRemainingLength);
3336 #ifdef AFS_DEBUG_TRACE
3337 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3339 pUniversalInfo->lpUniversalName,
3340 pUniversalInfo->lpUniversalName);
3343 if ( dwPassedSize < *lpBufferSize)
3346 try_return( dwStatus = WN_MORE_DATA);
3349 try_return( dwStatus = WN_SUCCESS);
3352 case REMOTE_NAME_INFO_LEVEL:
3355 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3357 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + 2 * dwBufferSize + sizeof( WCHAR);
3359 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3362 #ifdef AFS_DEBUG_TRACE
3363 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3366 try_return( dwStatus = WN_MORE_DATA);
3369 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3371 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3373 memcpy( pRemoteInfo->lpUniversalName,
3375 min( dwRemainingLength, dwBufferSize));
3377 dwRemainingLength -= min( dwRemainingLength, dwBufferSize);
3379 #ifdef AFS_DEBUG_TRACE
3380 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3382 pRemoteInfo->lpUniversalName,
3383 pRemoteInfo->lpUniversalName);
3386 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3388 pRemoteInfo->lpConnectionName = (LPTSTR)((char *)pRemoteInfo->lpUniversalName + dwBufferSize);
3390 memcpy( pRemoteInfo->lpConnectionName,
3392 min( dwRemainingLength, dwBufferSize));
3394 dwRemainingLength -= min( dwRemainingLength, dwBufferSize) - sizeof( WCHAR);
3396 SeparateRemainingPath( pRemoteInfo->lpConnectionName,
3397 &pRemoteInfo->lpRemainingPath);
3400 #ifdef AFS_DEBUG_TRACE
3401 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3403 pRemoteInfo->lpConnectionName,
3404 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3406 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3408 pRemoteInfo->lpRemainingPath,
3409 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3412 if ( dwPassedSize < *lpBufferSize)
3415 try_return( dwStatus = WN_MORE_DATA);
3418 try_return( dwStatus = WN_SUCCESS);
3422 #ifdef AFS_DEBUG_TRACE
3423 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3426 try_return( dwStatus = WN_BAD_VALUE);
3432 #ifdef AFS_DEBUG_TRACE
3433 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is not AFS\n",
3436 try_return( dwStatus = WN_NOT_CONNECTED);
3440 dwBufferSize = 0x1000;
3442 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
3444 if( pConnectCB == NULL)
3446 try_return( dwStatus = WN_OUT_OF_MEMORY);
3449 pConnectCB->LocalName = towupper(wchLocalName[0]);
3451 pConnectCB->RemoteNameLength = 0;
3453 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3455 hControlDevice = OpenRedirector();
3457 if( hControlDevice == NULL)
3460 try_return( dwStatus = WN_NET_ERROR);
3463 dwError = DeviceIoControl( hControlDevice,
3464 IOCTL_AFS_GET_CONNECTION,
3474 #ifdef AFS_DEBUG_TRACE
3475 DWORD gle = GetLastError();
3477 AFSDbgPrint( L"NPGetUniversalName Failed to get connection from file system for local %s gle 0x%x\n",
3480 try_return( dwStatus = WN_NOT_CONNECTED);
3483 switch( dwInfoLevel)
3486 case UNIVERSAL_NAME_INFO_LEVEL:
3489 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3491 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize + sizeof( WCHAR);
3493 *lpBufferSize += dwRemainingPathLength * sizeof( WCHAR);
3495 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3498 #ifdef AFS_DEBUG_TRACE
3499 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3502 try_return( dwStatus = WN_MORE_DATA);
3505 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3507 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3509 pch = (char *)pUniversalInfo->lpUniversalName;
3513 min( dwBufferSize, dwRemainingLength));
3515 pch += min( dwBufferSize, dwRemainingLength);
3517 dwRemainingLength -= min( dwBufferSize + sizeof(WCHAR), dwRemainingLength);
3521 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3523 pch += min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3525 dwRemainingLength -= min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3527 #ifdef AFS_DEBUG_TRACE
3528 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3530 pUniversalInfo->lpUniversalName,
3531 pUniversalInfo->lpUniversalName);
3534 if ( dwPassedSize < *lpBufferSize)
3537 try_return( dwStatus = WN_MORE_DATA);
3540 try_return( dwStatus = WN_SUCCESS);
3543 case REMOTE_NAME_INFO_LEVEL:
3546 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3548 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + (2 * dwBufferSize + sizeof( WCHAR)) + 2 * sizeof( WCHAR);
3550 *lpBufferSize += 2 * dwRemainingPathLength * sizeof( WCHAR);
3552 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3555 #ifdef AFS_DEBUG_TRACE
3556 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3559 try_return( dwStatus = WN_MORE_DATA);
3562 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3564 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3566 pch = (char *)pRemoteInfo->lpUniversalName;
3570 min( dwBufferSize, dwRemainingLength));
3572 pch += min( dwBufferSize, dwRemainingLength);
3574 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3578 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3580 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3582 dwRemainingLength -= min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3584 #ifdef AFS_DEBUG_TRACE
3585 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3587 pRemoteInfo->lpUniversalName,
3588 pRemoteInfo->lpUniversalName);
3591 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3593 pRemoteInfo->lpConnectionName = (LPWSTR)pch;
3597 min( dwBufferSize, dwRemainingLength));
3599 pch += min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3601 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3605 if ( dwRemainingLength > dwRemainingPathLength + sizeof( WCHAR))
3607 pRemoteInfo->lpRemainingPath = (LPWSTR)pch;
3611 min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength));
3613 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3615 dwRemainingLength -= min((dwLocalPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3618 #ifdef AFS_DEBUG_TRACE
3619 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3621 pRemoteInfo->lpConnectionName,
3622 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3624 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3626 pRemoteInfo->lpRemainingPath,
3627 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3630 if ( dwPassedSize < *lpBufferSize)
3633 try_return( dwStatus = WN_MORE_DATA);
3636 try_return( dwStatus = WN_SUCCESS);
3640 #ifdef AFS_DEBUG_TRACE
3641 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3644 try_return( dwStatus = WN_BAD_VALUE);
3649 #ifdef AFS_DEBUG_TRACE
3650 AFSDbgPrint( L"NPGetUniversalName BufferSize 0x%X\n",
3653 if ( hControlDevice != NULL)
3656 CloseHandle( hControlDevice);
3662 HeapFree( GetProcessHeap(), 0, (PVOID) pwchSubstName);
3665 if( pConnectCB != NULL)
3668 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3677 GetFormatFlags( DWORD dwFlags)
3679 static WCHAR Buffer[128] = L"";
3682 // WNFMT_MULTILINE 0x01
3683 // WNFMT_ABBREVIATED 0x02
3684 // WNFMT_INENUM 0x10
3685 // WNFMT_CONNECTION 0x20
3695 if ( dwFlags & WNFMT_MULTILINE )
3697 StringCbCat( Buffer, sizeof(Buffer), L"MULTILINE|");
3700 if ( dwFlags & WNFMT_INENUM )
3702 StringCbCat( Buffer, sizeof(Buffer), L"ABBREVIATED|");
3705 if ( dwFlags & WNFMT_INENUM )
3707 StringCbCat( Buffer, sizeof(Buffer), L"INENUM|");
3710 if ( dwFlags & WNFMT_CONNECTION )
3712 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTION|");
3715 if ( dwFlags & ~(WNFMT_MULTILINE|WNFMT_ABBREVIATED|WNFMT_INENUM|WNFMT_CONNECTION) )
3717 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
3720 Buffer[lstrlen(Buffer)-1] = L'\0';
3726 NPFormatNetworkName( LPTSTR lpRemoteName,
3727 LPTSTR lpFormattedName,
3730 DWORD dwAveCharPerLine)
3733 DWORD dwLen = 0, dwCurrentLen = 0;
3734 LPTSTR pCurrentName = lpRemoteName;
3736 #ifdef AFS_DEBUG_TRACE
3737 AFSDbgPrint( L"NPFormatNetworkName Remote %s Flags %s (0x%x) CharsPerLine %u\n",
3739 GetFormatFlags( dwFlags),
3746 // Walk back in the name until we hit a \
3749 dwLen = wcslen( lpRemoteName);
3751 pCurrentName += (dwLen - 1);
3753 if ( pCurrentName[ 0] != L'\\')
3759 if( pCurrentName[ 0] == L'\\')
3775 if( *lpnLength < dwCurrentLen * sizeof( WCHAR))
3778 *lpnLength = dwCurrentLen * sizeof( WCHAR);
3780 #ifdef AFS_DEBUG_TRACE
3781 AFSDbgPrint( L"NPFormatNetworkName remote name %s WN_MORE_DATA\n",
3785 return WN_MORE_DATA;
3788 StringCbCopy( lpFormattedName,
3792 *lpnLength = dwCurrentLen * sizeof( WCHAR);
3794 #ifdef AFS_DEBUG_TRACE
3795 AFSDbgPrint( L"NPFormatNetworkName remote name %s as %s\n",
3803 /************************************************************
3804 / Unsupported entry points
3805 /************************************************************/
3808 // AuthGroup processing is implemented in src/WINNT/afsd/afslogon.c
3813 LPCWSTR lpAuthentInfoType,
3814 LPVOID lpAuthentInfo,
3815 LPCWSTR lpPreviousAuthentInfoType,
3816 LPVOID lpPreviousAuthentInfo,
3817 LPWSTR lpStationName,
3818 LPVOID StationHandle,
3819 LPWSTR *lpLogonScript)
3822 #ifdef AFS_DEBUG_TRACE
3823 AFSDbgPrint( L"NPLogonNotify, returning WN_NOT_SUPPORTED\n");
3826 return WN_NOT_SUPPORTED;
3830 NPPasswordChangeNotify (
3831 LPCWSTR lpAuthentInfoType,
3832 LPVOID lpAuthentInfo,
3833 LPCWSTR lpPreviousAuthentInfoType,
3834 LPVOID lpPreviousAuthentInfo,
3835 LPWSTR lpStationName,
3836 LPVOID StationHandle,
3837 DWORD dwChangeInfo )
3840 #ifdef AFS_DEBUG_TRACE
3841 AFSDbgPrint( L"NPPasswordChangeNotify, returning WN_NOT_SUPPORTED\n");
3844 SetLastError( WN_NOT_SUPPORTED );
3846 return WN_NOT_SUPPORTED;
3850 NPGetUser( LPTSTR lpName,
3852 LPDWORD lpBufferSize)
3855 DWORD rc = WN_NOT_SUPPORTED;
3857 AFSDbgPrint( L"NPGetUser Entry Name %s\n", lpName);
3865 NPGetReconnectFlags( LPWSTR lpRemoteName,
3866 unsigned char *Parameter2)
3869 DWORD dwStatus = WN_NOT_SUPPORTED;
3871 AFSDbgPrint( L"NPGetReconnectFlags RemoteName %s\n",
3880 I_SystemFocusDialog( VOID)
3883 DWORD dwStatus = WN_NOT_SUPPORTED;
3885 AFSDbgPrint( L"I_SystemFocusDialog\n");
3890 /************************************************************
3891 / END Unsupported entry points
3892 /************************************************************/
3899 HANDLE hControlDevice = NULL;
3901 hControlDevice = CreateFile( AFS_SYMLINK_W,
3902 GENERIC_READ | GENERIC_WRITE,
3903 FILE_SHARE_READ | FILE_SHARE_WRITE,
3909 if( hControlDevice == INVALID_HANDLE_VALUE)
3912 hControlDevice = NULL;
3913 #ifdef AFS_DEBUG_TRACE
3914 AFSDbgPrint( L"Failed to open control device error: %d\n",
3919 return hControlDevice;
3925 static int init = 0;
3926 static DWORD debug = 0;
3931 if (RegOpenKey (HKEY_LOCAL_MACHINE,
3932 TEXT("SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider"), &hk) == 0)
3934 DWORD dwSize = sizeof(BOOL);
3935 DWORD dwType = REG_DWORD;
3936 RegQueryValueEx (hk, TEXT("Debug"), NULL, &dwType, (PBYTE)&debug, &dwSize);
3946 cm_Utf16ToUtf8Alloc(const WCHAR * s, int cch_src, int *pcch_dest)
3951 if (s == NULL || cch_src == 0 || *s == L'\0') {
3953 *pcch_dest = ((cch_src != 0)?1:0);
3957 cch_dest = WideCharToMultiByte(CP_UTF8, 0, s, cch_src, NULL, 0, NULL, FALSE);
3959 if (cch_dest == 0) {
3961 *pcch_dest = cch_dest;
3965 dest = HeapAlloc( GetProcessHeap(), 0, (cch_dest + 1) * sizeof(char));
3967 WideCharToMultiByte(CP_UTF8, 0, s, cch_src, dest, cch_dest, NULL, FALSE);
3971 *pcch_dest = cch_dest;
3977 AppendDebugStringToLogFile(WCHAR *wszbuffer)
3985 if ( !wszbuffer || !wszbuffer[0] )
3988 len = (int)wcslen(wszbuffer);
3990 buffer = cm_Utf16ToUtf8Alloc(wszbuffer, len, &len);
3995 hFile = CreateFileW( L"C:\\TEMP\\AFSRDFSProvider.log",
4000 FILE_ATTRIBUTE_NORMAL,
4003 if ( hFile == INVALID_HANDLE_VALUE ) {
4004 OutputDebugString(L"C:\\AFSRDFSProvider.log cannot be opened.\n");
4008 bRet = WriteFile( hFile, buffer, len, &dwWritten, NULL);
4010 bRet = CloseHandle(hFile);
4012 HeapFree(GetProcessHeap(), 0, buffer);
4023 WCHAR wszbuffer[512];
4025 DWORD debug = Debug();
4030 va_start( marker, Format );
4032 StringCbPrintf( wszbuffer, sizeof(wszbuffer), L"[%d-%08X] ",
4038 GetCurrentThreadId());
4040 rc = StringCbVPrintfW( &wszbuffer[ 14], sizeof(wszbuffer) - 14 * sizeof(WCHAR), Format, marker);
4042 if (SUCCEEDED(rc)) {
4044 OutputDebugString( wszbuffer );
4046 AppendDebugStringToLogFile(wszbuffer);
4048 OutputDebugString(L"AFSDbgPrint Failed to create string\n");
4051 return SUCCEEDED(rc) ? 1 : 0;