2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #define _WIN32_WINNT 0x0500
49 #define AFS_DEBUG_TRACE 1
51 #ifndef WNNC_NET_OPENAFS
52 #define WNNC_NET_OPENAFS 0x00390000
55 #include "AFSUserDefines.h"
56 #include "AFSUserIoctl.h"
57 #include "AFSUserStructs.h"
58 #include "AFSProvider.h"
59 #include "AFS_Npdll.h"
67 #define SCRATCHSZ 1024
73 ULONG _cdecl AFSDbgPrint( PWCHAR Format, ... );
75 #define WNNC_DRIVER( major, minor ) ( major * 0x00010000 + minor )
77 #define OPENAFS_PROVIDER_NAME L"OpenAFS Network"
78 #define OPENAFS_PROVIDER_NAME_LENGTH 30
80 #define MAX_PROVIDER_NAME_LENGTH 256
82 static ULONG cbProviderNameLength = OPENAFS_PROVIDER_NAME_LENGTH;
84 static wchar_t wszProviderName[MAX_PROVIDER_NAME_LENGTH+1] = OPENAFS_PROVIDER_NAME;
86 static BOOL bProviderNameRead = FALSE;
88 #define OPENAFS_SERVER_NAME L"AFS"
89 #define OPENAFS_SERVER_NAME_LENGTH 6
91 #define OPENAFS_SERVER_COMMENT L"AFS Root"
92 #define OPENAFS_SERVER_COMMENT_LENGTH 16
94 #define MAX_SERVER_NAME_LENGTH 30
96 static ULONG cbServerNameLength = 0;
98 static ULONG cbServerNameUNCLength = 0;
100 static ULONG cbServerCommentLength = OPENAFS_SERVER_COMMENT_LENGTH;
102 static wchar_t wszServerName[MAX_SERVER_NAME_LENGTH+1];
104 static wchar_t wszServerNameUNC[MAX_SERVER_NAME_LENGTH+3];
106 static wchar_t wszServerComment[] = OPENAFS_SERVER_COMMENT;
108 static BOOL bServerNameRead = FALSE;
111 AFSRetrieveAuthId( void);
114 ReadProviderNameString( void)
120 if ( bProviderNameRead )
123 code = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
124 L"SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider",
125 0, KEY_QUERY_VALUE, &hk);
127 if ( code == ERROR_SUCCESS) {
129 dwLen = sizeof(wszProviderName);
131 code = RegQueryValueExW( hk, L"Name", NULL, NULL,
132 (LPBYTE) wszProviderName, &dwLen);
134 if ( code == ERROR_SUCCESS)
137 wszProviderName[MAX_PROVIDER_NAME_LENGTH] = '\0';
139 cbProviderNameLength = wcslen( wszProviderName) * sizeof( WCHAR);
145 bProviderNameRead = TRUE;
149 ReadServerNameString( void)
155 if ( bServerNameRead )
158 code = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
159 L"SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters",
160 0, KEY_QUERY_VALUE, &hk);
162 if ( code == ERROR_SUCCESS) {
164 dwLen = sizeof(wszProviderName);
166 code = RegQueryValueExW( hk, L"NetbiosName", NULL, NULL,
167 (LPBYTE) wszServerName, &dwLen);
169 if ( code == ERROR_SUCCESS)
172 wszServerName[MAX_SERVER_NAME_LENGTH] = '\0';
174 cbServerNameLength = wcslen( wszServerName) * sizeof( WCHAR);
176 wszServerNameUNC[0] = wszServerNameUNC[1] = L'\\';
178 memcpy(&wszServerNameUNC[2], wszServerName, (cbServerNameLength + 1) * sizeof( WCHAR));
180 cbServerNameUNCLength = cbServerNameLength + 2 * sizeof( WCHAR);
186 bServerNameRead = TRUE;
191 /* returns TRUE if the file system is disabled or not installed */
193 NPIsFSDisabled( void)
198 DWORD dwStart = SERVICE_DISABLED;
200 code = RegOpenKeyExW( HKEY_LOCAL_MACHINE,
201 L"SYSTEM\\CurrentControlSet\\Services\\AFSRedirector",
202 0, KEY_QUERY_VALUE, &hk);
204 if ( code != ERROR_SUCCESS)
209 dwLen = sizeof(dwStart);
211 code = RegQueryValueExW( hk, L"Start", NULL, NULL,
212 (LPBYTE) &dwStart, &dwLen);
216 return ( dwStart == SERVICE_DISABLED);
220 #define try_return(S) { S; goto try_exit; }
226 typedef struct _UNICODE_STRING {
228 USHORT MaximumLength;
230 } UNICODE_STRING, *PUNICODE_STRING;
233 OpenRedirector( void);
235 typedef struct _AFS_ENUM_CB
250 // Recursively evaluate drivestr to find the final
251 // dos drive letter to which the source is mapped.
254 DriveSubstitution(LPCWSTR drivestr, LPWSTR subststr, size_t substlen)
257 WCHAR device[MAX_PATH + 1];
260 memset( subststr, 0, substlen);
261 drive[0] = drivestr[0];
262 drive[1] = drivestr[1];
265 if ( QueryDosDevice(drive, device, MAX_PATH) )
267 #ifdef AFS_DEBUG_TRACE
268 AFSDbgPrint( L"DriveSubstitution QueryDosDevice %s [%s -> %s]\n",
273 if ( device[0] == L'\\' &&
276 device[3] == L'\\' &&
277 iswalpha(device[4]) &&
280 drive[0] = device[4];
284 if ( !DriveSubstitution(drive, subststr, substlen) )
287 subststr[0] = drive[0];
297 hr = StringCchCat( subststr, substlen, &device[6]);
299 if ( SUCCEEDED(hr) && drivestr[2] )
301 hr = StringCchCat( subststr, substlen, &drivestr[2]);
304 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
307 #ifdef AFS_DEBUG_TRACE
308 AFSDbgPrint( L"DriveSubstitution %s -> %s\n",
315 else if ( device[0] == L'\\' &&
318 device[3] == L'\\' &&
327 hr = StringCbCopyN(&subststr[1], substlen - sizeof(WCHAR), &device[7], MAX_PATH);
329 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
333 hr = StringCchCat( subststr, substlen, &drivestr[2]);
340 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
343 #ifdef AFS_DEBUG_TRACE
344 AFSDbgPrint( L"DriveSubstitution %s -> %s\n",
352 #ifdef AFS_DEBUG_TRACE
353 AFSDbgPrint( L"DriveSubstitution StringCbCopyN 1 hr 0x%X\n",
357 else if ( _wcsnicmp( AFS_RDR_DEVICE_NAME, device, sizeof( AFS_RDR_DEVICE_NAME) / sizeof( WCHAR) - 1) == 0)
360 // \Device\AFSRedirector\;X:\\afs\cellname
363 hr = StringCbCopyN( subststr, substlen,
364 &device[3 + sizeof( AFS_RDR_DEVICE_NAME) / sizeof( WCHAR)],
365 MAX_PATH * sizeof( WCHAR));
367 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
372 hr = StringCchCat( subststr, substlen, &drivestr[2]);
379 if ( SUCCEEDED(hr) || hr == STRSAFE_E_INSUFFICIENT_BUFFER)
382 #ifdef AFS_DEBUG_TRACE
383 AFSDbgPrint( L"DriveSubstitution %s -> %s\n",
391 #ifdef AFS_DEBUG_TRACE
392 AFSDbgPrint( L"DriveSubstitution StringCbCopyN 2 hr 0x%X\n",
397 #ifdef AFS_DEBUG_TRACE
398 AFSDbgPrint( L"DriveSubstitution no substitution or match %s !! %s\n",
405 #ifdef AFS_DEBUG_TRACE
406 AFSDbgPrint( L"DriveSubstitution QueryDosDevice failed %s gle 0x%X\n",
419 NPGetCapsQueryString( DWORD nIndex)
422 case WNNC_SPEC_VERSION:
423 return L"WNNC_SPEC_VERSION";
426 return L"WNNC_NET_TYPE";
428 case WNNC_DRIVER_VERSION:
429 return L"WNNC_DRIVER_VERSION";
434 case WNNC_CONNECTION:
435 return L"WNNC_CONNECTION";
438 return L"WNNC_DIALOG";
441 return L"WNNC_ADMIN";
443 case WNNC_ENUMERATION:
444 return L"WNNC_ENUMERATION";
447 return L"WNNC_START";
449 case WNNC_CONNECTION_FLAGS:
450 return L"WNNC_CONNECTION_FLAGS";
458 // This is the only function which must be exported, everything else is optional
463 NPGetCaps( DWORD nIndex )
468 #ifdef AFS_DEBUG_TRACE
469 AFSDbgPrint( L"NPGetCaps Index %u %s\n", nIndex,
470 NPGetCapsQueryString( nIndex));
474 case WNNC_SPEC_VERSION:
477 rc = WNNC_SPEC_VERSION51;
483 rc = WNNC_NET_OPENAFS;
487 case WNNC_DRIVER_VERSION:
490 rc = WNNC_DRIVER(1, 0);
494 case WNNC_CONNECTION:
499 // WNNC_CON_GETPERFORMANCE
503 rc = WNNC_CON_GETCONNECTIONS |
504 WNNC_CON_CANCELCONNECTION |
505 WNNC_CON_ADDCONNECTION |
506 WNNC_CON_ADDCONNECTION3;
511 case WNNC_ENUMERATION:
513 rc = WNNC_ENUM_LOCAL |
523 rc = WNNC_WAIT_FOR_START;
533 // WNNC_DLG_DEVICEMODE
534 // WNNC_DLG_PROPERTYDIALOG
535 // WNNC_DLG_SEARCHDIALOG
536 // WNNC_DLG_PERMISSIONEDITOR
539 rc = WNNC_DLG_FORMATNETWORKNAME |
540 WNNC_DLG_GETRESOURCEINFORMATION |
541 WNNC_DLG_GETRESOURCEPARENT;
560 // WNNC_ADM_GETDIRECTORYTYPE
561 // WNNC_ADM_DIRECTORYNOTIFY
562 // used by the old File Manager
573 NPAddConnection( LPNETRESOURCE lpNetResource,
578 #ifdef AFS_DEBUG_TRACE
579 AFSDbgPrint( L"NPAddConnection forwarding to NPAddConnection3\n");
581 return NPAddConnection3( NULL, lpNetResource, lpPassword, lpUserName, 0 );
586 NPAddConnection3( HWND hwndOwner,
587 LPNETRESOURCE lpNetResource,
593 DWORD dwStatus = WN_SUCCESS;
594 WCHAR wchRemoteName[MAX_PATH+1];
595 WCHAR wchLocalName[3];
596 DWORD dwCopyBytes = 0;
597 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
599 DWORD dwBufferSize = 0;
600 HANDLE hControlDevice = NULL;
601 HANDLE hToken = NULL;
602 LARGE_INTEGER liAuthId = {0,0};
606 if ( NPIsFSDisabled())
609 #ifdef AFS_DEBUG_TRACE
610 AFSDbgPrint( L"NPAddConnection3 AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
613 return WN_BAD_NETNAME;
616 if ((lpNetResource->lpRemoteName == NULL) ||
617 (lpNetResource->lpRemoteName[0] != L'\\') ||
618 (lpNetResource->lpRemoteName[1] != L'\\') ||
619 ((lpNetResource->dwType != RESOURCETYPE_DISK) &&
620 (lpNetResource->dwType != RESOURCETYPE_ANY)))
623 #ifdef AFS_DEBUG_TRACE
624 AFSDbgPrint( L"NPAddConnection3 invalid input, returning WN_BAD_NETNAME\n");
626 return WN_BAD_NETNAME;
629 #ifdef AFS_DEBUG_TRACE
630 AFSDbgPrint( L"NPAddConnection3 processing\n");
632 if( lpNetResource->lpLocalName != NULL)
635 wchLocalName[0] = towupper(lpNetResource->lpLocalName[0]);
636 wchLocalName[1] = L':';
637 wchLocalName[2] = L'\0';
640 StringCchCopy(wchRemoteName, MAX_PATH+1, lpNetResource->lpRemoteName);
641 wchRemoteName[MAX_PATH] = L'\0';
644 // Allocate our buffer to pass to the redirector filter
647 dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + (wcslen( wchRemoteName) * sizeof( WCHAR));
649 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
651 if( pConnectCB == NULL)
654 try_return( dwStatus = WN_OUT_OF_MEMORY);
657 if( lpNetResource->lpLocalName != NULL)
660 pConnectCB->LocalName = towupper(wchLocalName[0]);
662 #ifdef AFS_DEBUG_TRACE
663 AFSDbgPrint( L"NPAddConnection3 Adding mapping for drive %s remote name %s\n",
671 pConnectCB->LocalName = L'\0';
673 #ifdef AFS_DEBUG_TRACE
674 AFSDbgPrint( L"NPAddConnection3 Adding mapping for NO drive remote name %s\n",
679 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
681 pConnectCB->RemoteNameLength = wcslen( wchRemoteName) * sizeof( WCHAR);
683 memcpy( pConnectCB->RemoteName,
685 pConnectCB->RemoteNameLength);
687 pConnectCB->Type = lpNetResource->dwType;
689 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
691 #ifdef AFS_DEBUG_TRACE
692 AFSDbgPrint( L"NPAddConnection3 Retrieved authentication id %08lX-%08lX\n",
693 pConnectCB->AuthenticationId.HighPart,
694 pConnectCB->AuthenticationId.LowPart);
697 hControlDevice = OpenRedirector();
699 if( hControlDevice == NULL)
702 #ifdef AFS_DEBUG_TRACE
703 AFSDbgPrint( L"NPAddConnection3 OpenRedirector failure, returning WN_NET_ERROR\n");
706 try_return( dwStatus = WN_NET_ERROR);
709 dwError = DeviceIoControl( hControlDevice,
710 IOCTL_AFS_ADD_CONNECTION,
720 #ifdef AFS_DEBUG_TRACE
721 AFSDbgPrint( L"NPAddConnection3 Failed to add connection to file system %d\n", GetLastError());
723 try_return( dwStatus = WN_OUT_OF_MEMORY);
727 // The status returned from the driver will indicate how it was handled
730 if( dwStatus == WN_SUCCESS &&
731 lpNetResource->lpLocalName != NULL)
734 WCHAR TempBuf[MAX_PATH+1];
736 if( !QueryDosDeviceW( wchLocalName,
741 if( GetLastError() != ERROR_FILE_NOT_FOUND)
744 #ifdef AFS_DEBUG_TRACE
745 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW failed with file not found\n");
747 NPCancelConnection( wchLocalName, TRUE);
749 dwStatus = ERROR_ALREADY_ASSIGNED;
754 UNICODE_STRING uniConnectionName;
755 UNICODE_STRING uniDeviceName;
757 uniDeviceName.Length = (wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR));
758 uniDeviceName.MaximumLength = uniDeviceName.Length;
759 uniDeviceName.Buffer = AFS_RDR_DEVICE_NAME;
762 // Create a symbolic link object to the device we are redirecting
765 uniConnectionName.MaximumLength = (USHORT)( uniDeviceName.Length +
766 pConnectCB->RemoteNameLength +
767 8 + // Local name and \;
768 sizeof(WCHAR)); // Space for NULL-termination.
771 // Don't include NULL-termination.
774 uniConnectionName.Length = uniConnectionName.MaximumLength - sizeof(WCHAR);
776 uniConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
777 uniConnectionName.MaximumLength);
779 if( uniConnectionName.Buffer == NULL)
782 try_return( dwStatus = GetLastError());
785 CopyMemory( uniConnectionName.Buffer,
786 uniDeviceName.Buffer,
787 uniDeviceName.Length);
789 StringCchCatW( uniConnectionName.Buffer,
790 uniConnectionName.MaximumLength,
793 StringCchCatW( uniConnectionName.Buffer,
794 uniConnectionName.MaximumLength,
797 StringCchCatW( uniConnectionName.Buffer,
798 uniConnectionName.MaximumLength,
801 #ifdef AFS_DEBUG_TRACE
802 AFSDbgPrint( L"NPAddConnection3 DefineDosDevice Local %s connection name %s\n",
804 uniConnectionName.Buffer);
807 if( !DefineDosDeviceW( DDD_RAW_TARGET_PATH |
808 DDD_NO_BROADCAST_SYSTEM,
810 uniConnectionName.Buffer))
812 #ifdef AFS_DEBUG_TRACE
813 AFSDbgPrint( L"NPAddConnection3 Failed to assign drive\n");
815 dwStatus = GetLastError();
820 #ifdef AFS_DEBUG_TRACE
821 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW assigned drive %s\n", wchLocalName);
824 dwStatus = WN_SUCCESS;
827 LocalFree( uniConnectionName.Buffer);
833 #ifdef AFS_DEBUG_TRACE
834 AFSDbgPrint( L"NPAddConnection3 QueryDosDeviceW %Z already existed\n", TempBuf);
836 NPCancelConnection( wchLocalName, TRUE);
838 dwStatus = ERROR_ALREADY_ASSIGNED;
844 if ( hControlDevice != NULL)
847 CloseHandle( hControlDevice);
850 if( pConnectCB != NULL)
853 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
862 NPCancelConnection( LPWSTR lpName,
866 WCHAR wchRemoteName[MAX_PATH+1];
867 DWORD dwRemoteNameLength = (MAX_PATH+1) * sizeof(WCHAR);
868 DWORD dwStatus = WN_NOT_CONNECTED;
869 DWORD dwCopyBytes = 0;
870 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
871 AFSCancelConnectionResultCB stCancelConn;
873 DWORD dwBufferSize = 0;
874 BOOL bLocalName = TRUE;
875 HANDLE hControlDevice = NULL;
876 WCHAR wchLocalName[ 3];
877 WCHAR *pwchLocalName = NULL;
882 if ( NPIsFSDisabled())
885 #ifdef AFS_DEBUG_TRACE
886 AFSDbgPrint( L"NPCancelConnection AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
889 try_return( dwStatus = WN_NOT_CONNECTED);
892 if( *lpName == L'\\' &&
893 *(lpName + 1) == L'\\')
898 wchLocalName[0] = L'\0';
900 StringCchCopyW( wchRemoteName, MAX_PATH+1, lpName);
902 dwRemoteNameLength = (wcslen( wchRemoteName) * sizeof( WCHAR));
907 wchLocalName[0] = towupper(lpName[0]);
908 wchLocalName[1] = L':';
909 wchLocalName[2] = L'\0';
912 // Get the remote name for the connection, if we are handling it
915 dwStatus = NPGetConnection( lpName,
917 &dwRemoteNameLength);
919 if( dwStatus != WN_SUCCESS ||
920 dwRemoteNameLength == 0)
923 #ifdef AFS_DEBUG_TRACE
924 AFSDbgPrint( L"NPCancelConnection Status 0x%x NameLength %u, returning WN_NOT_CONNECTED\n",
925 dwStatus, dwRemoteNameLength);
927 try_return( dwStatus = WN_NOT_CONNECTED);
931 // NPGetConnection returns the buffer size not the length without NUL
933 dwRemoteNameLength -= sizeof( WCHAR);
936 wchRemoteName[ dwRemoteNameLength/sizeof( WCHAR)] = L'\0';
938 #ifdef AFS_DEBUG_TRACE
939 AFSDbgPrint( L"NPCancelConnection Attempting to cancel '%s' -> '%s'\n",
940 wchLocalName, wchRemoteName);
943 dwBufferSize = sizeof( AFSNetworkProviderConnectionCB) + dwRemoteNameLength;
945 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
947 if( pConnectCB == NULL)
950 try_return( dwStatus = WN_OUT_OF_MEMORY);
956 pConnectCB->LocalName = wchLocalName[0];
961 pConnectCB->LocalName = L'\0';
964 pConnectCB->RemoteNameLength = (USHORT)dwRemoteNameLength;
966 StringCchCopyW( pConnectCB->RemoteName,
970 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
972 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
974 #ifdef AFS_DEBUG_TRACE
975 AFSDbgPrint( L"NPCancelConnection Retrieved authentication id %08lX-%08lX\n",
976 pConnectCB->AuthenticationId.HighPart,
977 pConnectCB->AuthenticationId.LowPart);
980 hControlDevice = OpenRedirector();
982 if( hControlDevice == NULL)
985 #ifdef AFS_DEBUG_TRACE
986 AFSDbgPrint( L"NPCancelConnection OpenRedirector failure, returning WN_NET_ERROR\n");
989 try_return( dwStatus = WN_NET_ERROR);
992 memset( &stCancelConn,
994 sizeof( AFSCancelConnectionResultCB));
996 dwError = DeviceIoControl( hControlDevice,
997 IOCTL_AFS_CANCEL_CONNECTION,
1001 sizeof( AFSCancelConnectionResultCB),
1007 #ifdef AFS_DEBUG_TRACE
1008 DWORD gle = GetLastError();
1010 AFSDbgPrint( L"NPCancelConnection DeviceIoControl failed - gle 0x%x\n", gle);
1012 try_return( dwStatus = WN_NOT_CONNECTED);
1015 dwStatus = stCancelConn.Status;
1017 #ifdef AFS_DEBUG_TRACE
1018 if ( dwStatus == WN_NOT_CONNECTED )
1021 AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status WN_NOT_CONNECTED\n",
1027 AFSDbgPrint( L"NPCancelConnection Cancel connection to file system - Name %s Status %08lX\n",
1033 if( dwStatus == WN_SUCCESS &&
1035 stCancelConn.LocalName != L'\0'))
1038 UNICODE_STRING uniConnectionName;
1039 UNICODE_STRING uniDeviceName;
1041 uniDeviceName.Length = (wcslen( AFS_RDR_DEVICE_NAME) * sizeof( WCHAR));
1042 uniDeviceName.MaximumLength = uniDeviceName.Length;
1043 uniDeviceName.Buffer = AFS_RDR_DEVICE_NAME;
1046 // Create a symbolic link object to the device we are redirecting
1049 uniConnectionName.MaximumLength = (USHORT)( uniDeviceName.Length +
1050 dwRemoteNameLength +
1051 8 + // Local name and \;
1052 sizeof(WCHAR)); // Space for NULL-termination.
1055 // Don't include NULL-termination.
1058 uniConnectionName.Length = uniConnectionName.MaximumLength - sizeof(WCHAR);
1060 uniConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
1061 uniConnectionName.MaximumLength);
1063 if( uniConnectionName.Buffer == NULL)
1066 try_return( dwStatus = GetLastError());
1069 CopyMemory( uniConnectionName.Buffer,
1070 uniDeviceName.Buffer,
1071 uniDeviceName.Length);
1073 StringCchCatW( uniConnectionName.Buffer,
1074 uniConnectionName.MaximumLength,
1080 wchLocalName[ 0] = stCancelConn.LocalName;
1082 wchLocalName[ 1] = L':';
1084 wchLocalName[ 2] = L'\0';
1086 StringCchCatW( uniConnectionName.Buffer,
1087 uniConnectionName.MaximumLength,
1090 pwchLocalName = wchLocalName;
1095 StringCchCatW( uniConnectionName.Buffer,
1096 uniConnectionName.MaximumLength,
1099 pwchLocalName = lpName;
1102 StringCchCatW( uniConnectionName.Buffer,
1103 uniConnectionName.MaximumLength,
1106 if( !DefineDosDevice( DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE,
1108 uniConnectionName.Buffer))
1111 #ifdef AFS_DEBUG_TRACE
1112 DWORD gle = GetLastError();
1114 AFSDbgPrint( L"NPCancelConnection Failed to cancel connection to system - gle 0x%x Name %s connection %wZ\n",
1117 &uniConnectionName);
1122 #ifdef AFS_DEBUG_TRACE
1124 AFSDbgPrint( L"NPCancelConnection Canceled connection to system - Name %s connection %wZ\n",
1126 &uniConnectionName);
1133 if ( hControlDevice != NULL)
1136 CloseHandle( hControlDevice);
1140 if( pConnectCB != NULL)
1143 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1153 NPGetConnection( LPWSTR lpLocalName,
1154 LPWSTR lpRemoteName,
1155 LPDWORD lpBufferSize)
1158 DWORD dwStatus = WN_NOT_CONNECTED;
1159 WCHAR wchLocalName[3];
1160 WCHAR wchSubstName[MAX_PATH + 1];
1161 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1163 DWORD dwBufferSize = 0;
1164 HANDLE hControlDevice = NULL;
1170 if ( NPIsFSDisabled())
1173 #ifdef AFS_DEBUG_TRACE
1174 AFSDbgPrint( L"NPGetConnection AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1177 try_return( dwStatus = WN_NOT_CONNECTED);
1180 if( lstrlen( lpLocalName) == 0)
1182 #ifdef AFS_DEBUG_TRACE
1183 AFSDbgPrint( L"NPGetConnection No local name, returning WN_BAD_LOCALNAME\n");
1185 try_return( dwStatus = WN_BAD_LOCALNAME);
1188 if ( lpBufferSize == NULL)
1190 #ifdef AFS_DEBUG_TRACE
1191 AFSDbgPrint( L"NPGetConnection No output size, returning WN_BAD_LOCALNAME\n");
1193 try_return( dwStatus = WN_BAD_VALUE);
1196 dwPassedSize = *lpBufferSize;
1198 if ( !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName)))
1200 wchLocalName[0] = towupper(lpLocalName[0]);
1201 wchLocalName[1] = L':';
1202 wchLocalName[2] = L'\0';
1204 #ifdef AFS_DEBUG_TRACE
1205 AFSDbgPrint( L"NPGetConnection Requesting connection for %s\n",
1211 ReadServerNameString();
1213 if ( wchSubstName[0] != L'\\' &&
1214 wchSubstName[1] == L':')
1217 wchLocalName[0] = towupper(wchSubstName[0]);
1218 wchLocalName[1] = L':';
1219 wchLocalName[2] = L'\0';
1221 #ifdef AFS_DEBUG_TRACE
1222 AFSDbgPrint( L"NPGetConnection Requesting connection for drive substitution %s -> %s\n",
1227 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
1228 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
1229 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
1235 #ifdef AFS_DEBUG_TRACE
1236 AFSDbgPrint( L"NPGetConnection drive substitution %s is AFS\n",
1240 if ( lpRemoteName == NULL ||
1244 *lpBufferSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
1246 try_return( dwStatus = WN_MORE_DATA);
1250 hr = StringCbCopyN(lpRemoteName, *lpBufferSize, wchSubstName, sizeof( wchSubstName));
1255 for ( dwCount = 0, pwch = lpRemoteName; *pwch; pwch++ )
1257 if ( *pwch == L'\\' )
1271 *lpBufferSize = wcslen( lpRemoteName) * sizeof( WCHAR) + sizeof( WCHAR);
1273 try_return( dwStatus = WN_SUCCESS);
1275 else if ( hr == STRSAFE_E_INSUFFICIENT_BUFFER)
1278 *lpBufferSize = wcslen( wchSubstName) * sizeof( WCHAR) + sizeof( WCHAR);
1280 for ( dwCount = 0, pwch = lpRemoteName; *pwch; pwch++ )
1282 if ( *pwch == L'\\' )
1290 *lpBufferSize = wcslen( lpRemoteName) * sizeof( WCHAR) + sizeof( WCHAR);
1292 try_return( dwStatus = WN_SUCCESS);
1298 try_return( dwStatus = WN_MORE_DATA);
1303 #ifdef AFS_DEBUG_TRACE
1304 AFSDbgPrint( L"NPGetConnection StringCbCopyN failure 0x%X\n",
1307 try_return( dwStatus = WN_NET_ERROR);
1313 #ifdef AFS_DEBUG_TRACE
1314 AFSDbgPrint( L"NPGetConnection drive substitution %s is not AFS\n",
1317 try_return( dwStatus = WN_NOT_CONNECTED);
1321 #ifdef AFS_DEBUG_TRACE
1322 AFSDbgPrint( L"NPGetConnection Requesting connection for %s\n",
1326 dwBufferSize = 0x1000;
1328 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1330 if( pConnectCB == NULL)
1333 try_return( dwStatus = WN_OUT_OF_MEMORY);
1336 pConnectCB->LocalName = towupper(wchLocalName[0]);
1338 pConnectCB->RemoteNameLength = 0;
1340 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1342 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1344 #ifdef AFS_DEBUG_TRACE
1345 AFSDbgPrint( L"NPGetConnection Retrieved authentication id %08lX-%08lX\n",
1346 pConnectCB->AuthenticationId.HighPart,
1347 pConnectCB->AuthenticationId.LowPart);
1350 hControlDevice = OpenRedirector();
1352 if( hControlDevice == NULL)
1355 #ifdef AFS_DEBUG_TRACE
1356 AFSDbgPrint( L"NPGetConnection OpenRedirector failure, returning WN_NET_ERROR\n");
1359 try_return( dwStatus = WN_NET_ERROR);
1362 dwError = DeviceIoControl( hControlDevice,
1363 IOCTL_AFS_GET_CONNECTION,
1373 #ifdef AFS_DEBUG_TRACE
1374 DWORD gle = GetLastError();
1376 AFSDbgPrint( L"NPGetConnection Failed to get connection from file system for local %s gle 0x%x\n",
1379 try_return( dwStatus = WN_NOT_CONNECTED);
1383 // IOCTL_AFS_GET_CONNECTION returns a counted string
1386 if( lpRemoteName == NULL ||
1387 *lpBufferSize + sizeof( WCHAR) > dwPassedSize)
1390 *lpBufferSize += sizeof( WCHAR);
1392 try_return( dwStatus = WN_MORE_DATA);
1395 memcpy( lpRemoteName,
1399 lpRemoteName[ *lpBufferSize/sizeof( WCHAR)] = L'\0';
1401 *lpBufferSize += sizeof( WCHAR);
1403 #ifdef AFS_DEBUG_TRACE
1404 AFSDbgPrint( L"NPGetConnection local %s remote %s\n",
1408 dwStatus = WN_SUCCESS;
1412 if ( hControlDevice != NULL)
1415 CloseHandle( hControlDevice);
1418 if( pConnectCB != NULL)
1421 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1430 NPGetConnection3( IN LPCWSTR lpLocalName,
1432 OUT LPVOID lpBuffer,
1433 IN OUT LPDWORD lpBufferSize)
1436 DWORD dwStatus = WN_NOT_CONNECTED;
1437 WCHAR wchLocalName[3];
1438 WCHAR wchSubstName[MAX_PATH + 1];
1439 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1441 DWORD dwBufferSize = 0;
1442 HANDLE hControlDevice = NULL;
1444 DWORD *pConnectState =(DWORD *)lpBuffer;
1449 if ( NPIsFSDisabled())
1452 #ifdef AFS_DEBUG_TRACE
1453 AFSDbgPrint( L"NPGetConnection3 AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
1456 try_return( dwStatus = WN_NOT_CONNECTED);
1459 if( lstrlen( lpLocalName) == 0)
1461 #ifdef AFS_DEBUG_TRACE
1462 AFSDbgPrint( L"NPGetConnection3 No local name, returning WN_BAD_LOCALNAME\n");
1464 try_return( dwStatus = WN_BAD_LOCALNAME);
1468 // LanMan NPGetConnection3 only responds to level 1
1471 if ( dwLevel != 0x1)
1473 #ifdef AFS_DEBUG_TRACE
1474 AFSDbgPrint( L"NPGetConnection3 Level 0x%X returning WN_BAD_LEVEL\n", dwLevel);
1476 try_return( dwStatus = WN_BAD_LEVEL);
1479 if ( lpBufferSize == NULL)
1481 #ifdef AFS_DEBUG_TRACE
1482 AFSDbgPrint( L"NPGetConnection3 No output size, returning WN_BAD_VALUE\n");
1484 try_return( dwStatus = WN_BAD_VALUE);
1487 dwPassedSize = *lpBufferSize;
1489 if ( dwPassedSize == 0 ||
1493 *lpBufferSize = sizeof( DWORD);
1495 try_return( dwStatus = WN_MORE_DATA);
1498 if ( !DriveSubstitution( lpLocalName, wchSubstName, sizeof( wchSubstName)))
1500 wchLocalName[0] = towupper(lpLocalName[0]);
1501 wchLocalName[1] = L':';
1502 wchLocalName[2] = L'\0';
1504 #ifdef AFS_DEBUG_TRACE
1505 AFSDbgPrint( L"NPGetConnection3 Requesting connection for %s level 0x%X\n",
1513 ReadServerNameString();
1515 if ( wchSubstName[0] != L'\\' &&
1516 wchSubstName[1] == L':')
1519 wchLocalName[0] = towupper(wchSubstName[0]);
1520 wchLocalName[1] = L':';
1521 wchLocalName[2] = L'\0';
1523 #ifdef AFS_DEBUG_TRACE
1524 AFSDbgPrint( L"NPGetConnection3 Requesting connection for drive substitution %s -> %s level 0x%x\n",
1530 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
1531 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
1532 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
1535 #ifdef AFS_DEBUG_TRACE
1536 AFSDbgPrint( L"NPGetConnection3 drive substitution %s is AFS return connected\n",
1539 *pConnectState = WNGETCON_CONNECTED;
1541 *lpBufferSize = sizeof( DWORD);
1543 try_return( dwStatus = WN_SUCCESS);
1548 #ifdef AFS_DEBUG_TRACE
1549 AFSDbgPrint( L"NPGetConnection3 drive substitution %s is not AFS return not connected\n",
1552 try_return( dwStatus = WN_NOT_CONNECTED);
1556 dwBufferSize = 0x1000;
1558 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1560 if( pConnectCB == NULL)
1563 try_return( dwStatus = WN_OUT_OF_MEMORY);
1566 pConnectCB->LocalName = towupper(wchLocalName[0]);
1568 pConnectCB->RemoteNameLength = 0;
1570 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1572 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1574 #ifdef AFS_DEBUG_TRACE
1575 AFSDbgPrint( L"NPGetConnection3 Retrieved authentication id %08lX-%08lX\n",
1576 pConnectCB->AuthenticationId.HighPart,
1577 pConnectCB->AuthenticationId.LowPart);
1580 hControlDevice = OpenRedirector();
1582 if( hControlDevice == NULL)
1585 #ifdef AFS_DEBUG_TRACE
1586 AFSDbgPrint( L"NPGetConnection3 OpenRedirector failure, returning WN_NET_ERROR\n");
1589 try_return( dwStatus = WN_NET_ERROR);
1592 dwError = DeviceIoControl( hControlDevice,
1593 IOCTL_AFS_GET_CONNECTION,
1603 #ifdef AFS_DEBUG_TRACE
1604 DWORD gle = GetLastError();
1606 AFSDbgPrint( L"NPGetConnection3 Failed to get connection from file system for local %s gle 0x%x\n",
1609 try_return( dwStatus = WN_NOT_CONNECTED);
1612 *lpBufferSize = sizeof( DWORD);
1614 if( sizeof( DWORD) > dwPassedSize)
1617 try_return( dwStatus = WN_MORE_DATA);
1620 *pConnectState = WNGETCON_CONNECTED;
1622 #ifdef AFS_DEBUG_TRACE
1623 AFSDbgPrint( L"NPGetConnection3 local %s connect-state 0x%x\n",
1627 dwStatus = WN_SUCCESS;
1631 if ( hControlDevice != NULL)
1634 CloseHandle( hControlDevice);
1637 if( pConnectCB != NULL)
1640 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1649 NPGetConnectionPerformance( LPCWSTR lpRemoteName,
1650 LPNETCONNECTINFOSTRUCT lpNetConnectInfo)
1653 DWORD dwReturn = WN_SUCCESS;
1654 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
1655 DWORD dwBufferSize = 0;
1656 HANDLE hControlDevice = NULL;
1662 if ( NPIsFSDisabled())
1665 #ifdef AFS_DEBUG_TRACE
1666 AFSDbgPrint( L"NPGetConnectionPerformance AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
1669 return WN_NO_NETWORK;
1672 AFSDbgPrint( L"NPGetConnectionPerformance Entry for remote connection %S\n",
1675 dwBufferSize = 0x1000;
1677 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
1679 if( pConnectCB == NULL)
1681 try_return( dwReturn = WN_OUT_OF_MEMORY);
1684 pConnectCB->RemoteNameLength = wcslen( lpRemoteName) * sizeof( WCHAR);
1686 StringCbCopy( pConnectCB->RemoteName,
1687 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
1690 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
1692 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
1694 hControlDevice = OpenRedirector();
1696 if( hControlDevice == NULL)
1698 AFSDbgPrint( L"NPGetConnectionPerformance OpenRedirector failure, returning WN_NET_ERROR\n");
1700 try_return( dwReturn = WN_NET_ERROR);
1703 dwError = DeviceIoControl( hControlDevice,
1704 IOCTL_AFS_GET_CONNECTION_INFORMATION,
1714 #ifdef AFS_DEBUG_TRACE
1715 DWORD gle = GetLastError();
1717 AFSDbgPrint( L"NPGetConnectionPerformance Failed to get connection info from file system for remote %S gle 0x%x\n",
1721 try_return( dwReturn = WN_NOT_CONNECTED);
1724 lpNetConnectInfo->dwFlags = WNCON_DYNAMIC;
1726 lpNetConnectInfo->dwSpeed = 500;
1728 lpNetConnectInfo->dwDelay = 0;
1730 lpNetConnectInfo->dwOptDataSize = 0x1000;
1732 AFSDbgPrint( L"NPGetConnectionPerformance Successfully returned information for remote connection %S\n",
1737 if ( hControlDevice != NULL)
1739 CloseHandle( hControlDevice);
1742 if( pConnectCB != NULL)
1744 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
1752 GetUsageString( DWORD dwUsage)
1754 static WCHAR Buffer[128] = L"";
1756 // RESOURCEUSAGE_CONNECTABLE 0x00000001
1757 // RESOURCEUSAGE_CONTAINER 0x00000002
1758 // RESOURCEUSAGE_NOLOCALDEVICE 0x00000004
1759 // RESOURCEUSAGE_SIBLING 0x00000008
1760 // RESOURCEUSAGE_ATTACHED 0x00000010
1761 // RESOURCEUSAGE_ALL (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED)
1762 // RESOURCEUSAGE_RESERVED 0x80000000
1767 if ( dwUsage == RESOURCEUSAGE_ALL )
1777 if ( dwUsage & RESOURCEUSAGE_CONNECTABLE )
1779 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTABLE|");
1782 if ( dwUsage & RESOURCEUSAGE_CONTAINER )
1784 StringCbCat( Buffer, sizeof(Buffer), L"CONTAINER|");
1787 if ( dwUsage & RESOURCEUSAGE_NOLOCALDEVICE )
1789 StringCbCat( Buffer, sizeof(Buffer), L"NOLOCALDEVICE|");
1792 if ( dwUsage & RESOURCEUSAGE_SIBLING )
1794 StringCbCat( Buffer, sizeof(Buffer), L"SIBLING|");
1797 if ( dwUsage & RESOURCEUSAGE_ATTACHED )
1799 StringCbCat( Buffer, sizeof(Buffer), L"ATTACHED|");
1802 if ( dwUsage & RESOURCEUSAGE_RESERVED )
1804 StringCbCat( Buffer, sizeof(Buffer), L"RESERVED|");
1807 if ( dwUsage & ~(RESOURCEUSAGE_ALL|RESOURCEUSAGE_NOLOCALDEVICE|RESOURCEUSAGE_SIBLING|RESOURCEUSAGE_RESERVED) )
1809 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
1812 Buffer[lstrlen(Buffer)-1] = L'\0';
1818 GetTypeString( DWORD dwType)
1820 static WCHAR Buffer[128] = L"";
1823 // RESOURCETYPE_ANY 0x00000000
1824 // RESOURCETYPE_DISK 0x00000001
1825 // RESOURCETYPE_PRINT 0x00000002
1826 // RESOURCETYPE_RESERVED 0x00000008
1827 // RESOURCETYPE_UNKNOWN 0xFFFFFFFF
1832 if ( dwType == RESOURCETYPE_ANY )
1837 if ( dwType == RESOURCETYPE_UNKNOWN )
1842 if ( dwType & RESOURCETYPE_DISK )
1844 StringCbCat( Buffer, sizeof(Buffer), L"DISK|");
1847 if ( dwType & RESOURCETYPE_PRINT )
1849 StringCbCat( Buffer, sizeof(Buffer), L"PRINT|");
1852 if ( dwType & RESOURCETYPE_RESERVED )
1854 StringCbCat( Buffer, sizeof(Buffer), L"RESERVED|");
1857 if ( dwType & ~(RESOURCETYPE_DISK|RESOURCETYPE_PRINT|RESOURCETYPE_RESERVED) )
1859 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
1862 Buffer[lstrlen(Buffer)-1] = L'\0';
1868 GetScopeString( DWORD dwScope)
1870 static WCHAR Buffer[128] = L"";
1873 // RESOURCE_CONNECTED 0x00000001
1874 // RESOURCE_GLOBALNET 0x00000002
1875 // RESOURCE_REMEMBERED 0x00000003
1876 // RESOURCE_RECENT 0x00000004
1877 // RESOURCE_CONTEXT 0x00000005
1882 if ( dwScope == RESOURCE_CONNECTED )
1884 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTED|");
1887 if ( dwScope == RESOURCE_GLOBALNET )
1889 StringCbCat( Buffer, sizeof(Buffer), L"GLOBALNET|");
1892 if ( dwScope == RESOURCE_REMEMBERED )
1894 StringCbCat( Buffer, sizeof(Buffer), L"REMEMBERED|");
1897 if ( dwScope == RESOURCE_RECENT )
1899 StringCbCat( Buffer, sizeof(Buffer), L"RECENT|");
1902 if ( dwScope == RESOURCE_CONTEXT )
1904 StringCbCat( Buffer, sizeof(Buffer), L"CONTEXT|");
1907 if ( dwScope & ~(RESOURCE_CONNECTED|RESOURCE_GLOBALNET|RESOURCE_REMEMBERED|RESOURCE_RECENT|RESOURCE_CONTEXT) )
1909 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
1912 Buffer[lstrlen(Buffer)-1] = L'\0';
1918 GetDisplayString( DWORD dwDisplay)
1921 // RESOURCEDISPLAYTYPE_GENERIC 0x00000000
1922 // RESOURCEDISPLAYTYPE_DOMAIN 0x00000001
1923 // RESOURCEDISPLAYTYPE_SERVER 0x00000002
1924 // RESOURCEDISPLAYTYPE_SHARE 0x00000003
1925 // RESOURCEDISPLAYTYPE_FILE 0x00000004
1926 // RESOURCEDISPLAYTYPE_GROUP 0x00000005
1927 // RESOURCEDISPLAYTYPE_NETWORK 0x00000006
1928 // RESOURCEDISPLAYTYPE_ROOT 0x00000007
1929 // RESOURCEDISPLAYTYPE_SHAREADMIN 0x00000008
1930 // RESOURCEDISPLAYTYPE_DIRECTORY 0x00000009
1931 // RESOURCEDISPLAYTYPE_TREE 0x0000000A
1932 // RESOURCEDISPLAYTYPE_NDSCONTAINER 0x0000000B
1935 switch ( dwDisplay ) {
1936 case RESOURCEDISPLAYTYPE_GENERIC:
1938 case RESOURCEDISPLAYTYPE_DOMAIN:
1940 case RESOURCEDISPLAYTYPE_SERVER:
1942 case RESOURCEDISPLAYTYPE_SHARE:
1944 case RESOURCEDISPLAYTYPE_FILE:
1946 case RESOURCEDISPLAYTYPE_GROUP:
1948 case RESOURCEDISPLAYTYPE_NETWORK:
1950 case RESOURCEDISPLAYTYPE_ROOT:
1952 case RESOURCEDISPLAYTYPE_SHAREADMIN:
1953 return L"SHAREADMIN";
1954 case RESOURCEDISPLAYTYPE_DIRECTORY:
1955 return L"DIRECTORY";
1956 case RESOURCEDISPLAYTYPE_TREE:
1958 case RESOURCEDISPLAYTYPE_NDSCONTAINER:
1959 return L"NDSCONTAINER";
1967 NPOpenEnum( DWORD dwScope,
1970 LPNETRESOURCE lpNetResource,
1974 DWORD dwStatus = WN_SUCCESS;
1975 AFSEnumerationCB *pEnumCB = NULL;
1977 #ifdef AFS_DEBUG_TRACE
1978 if ( lpNetResource == NULL)
1980 AFSDbgPrint( L"NPOpenEnum Scope %s Type %s Usage %s NetResource: (Null)\n",
1981 GetScopeString(dwScope), GetTypeString(dwType), GetUsageString(dwUsage));
1985 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",
1986 GetScopeString(dwScope),
1987 GetTypeString(dwType),
1988 GetUsageString(dwUsage),
1990 GetScopeString(lpNetResource->dwScope),
1991 GetTypeString(lpNetResource->dwType),
1992 GetDisplayString(lpNetResource->dwDisplayType),
1993 GetUsageString(lpNetResource->dwUsage),
1994 lpNetResource->lpLocalName,
1995 lpNetResource->lpRemoteName,
1996 lpNetResource->lpComment);
2002 dwUsage = RESOURCEUSAGE_ALL;
2006 if ( dwType == 0 || dwType == RESOURCEUSAGE_ATTACHED)
2008 dwType |= RESOURCETYPE_DISK | RESOURCETYPE_PRINT;
2012 *lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( AFSEnumerationCB));
2014 if( *lphEnum == NULL)
2017 return WN_OUT_OF_MEMORY;
2020 pEnumCB = (AFSEnumerationCB *)*lphEnum;
2022 pEnumCB->CurrentIndex = 0;
2024 pEnumCB->Type = dwType;
2028 case RESOURCE_CONNECTED:
2031 pEnumCB->Scope = RESOURCE_CONNECTED;
2036 case RESOURCE_CONTEXT:
2039 pEnumCB->Scope = RESOURCE_CONTEXT;
2044 case RESOURCE_GLOBALNET:
2047 if( lpNetResource != NULL &&
2048 lpNetResource->lpRemoteName != NULL)
2051 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2053 if( pEnumCB->RemoteName == NULL)
2056 dwStatus = WN_OUT_OF_MEMORY;
2057 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2063 StringCbCopy( pEnumCB->RemoteName,
2065 lpNetResource->lpRemoteName);
2070 pEnumCB->Scope = RESOURCE_GLOBALNET;
2077 #ifdef AFS_DEBUG_TRACE
2078 AFSDbgPrint( L"NPOpenEnum Processing (Scope %s 0x%x) Type %s Usage %s, returning WN_NOT_SUPPORTED\n",
2079 GetScopeString(dwScope), dwScope, GetTypeString(dwType), GetUsageString(dwUsage));
2082 dwStatus = WN_NOT_SUPPORTED;
2083 HeapFree( GetProcessHeap( ), 0, (PVOID) *lphEnum );
2095 NPEnumResource( HANDLE hEnum,
2098 LPDWORD lpBufferSize)
2101 DWORD dwStatus = WN_NO_MORE_ENTRIES; //WN_SUCCESS;
2103 ULONG EntriesCopied;
2104 ULONG EntriesRequested;
2106 LPNETRESOURCE pNetResource;
2108 ULONG SpaceAvailable;
2110 AFSNetworkProviderConnectionCB *pConnectionCB = NULL;
2111 void *pConnectionCBBase = NULL;
2113 UNICODE_STRING uniRemoteName;
2114 HANDLE hControlDevice = NULL;
2115 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2120 if ( lpBufferSize == NULL)
2122 #ifdef AFS_DEBUG_TRACE
2123 AFSDbgPrint( L"NPEnumResource No output size, returning WN_BAD_VALUE\n");
2125 try_return( dwStatus = WN_BAD_VALUE);
2128 ReadProviderNameString();
2130 pNetResource = (LPNETRESOURCE) lpBuffer;
2131 SpaceAvailable = *lpBufferSize;
2132 EntriesRequested = *lpcCount;
2133 *lpcCount = EntriesCopied = 0;
2134 StringZone = (PWCHAR) ((char *)lpBuffer + *lpBufferSize);
2136 #ifdef AFS_DEBUG_TRACE
2137 AFSDbgPrint( L"NPEnumResource Processing Remote name %s Scope %s Type %s Usage %s Index %d SpaceAvailable 0x%lX RequestedEntries %lu\n",
2138 pEnumCB->RemoteName ? pEnumCB->RemoteName : L"(Null)",
2139 GetScopeString(pEnumCB->Scope),
2140 GetTypeString(pEnumCB->Type),
2141 GetUsageString(pEnumCB->Type),
2142 pEnumCB->CurrentIndex,
2147 if ( NPIsFSDisabled())
2150 #ifdef AFS_DEBUG_TRACE
2151 AFSDbgPrint( L"NPEnumResource AFSRDFS is disabled, returning WN_NO_MORE_ENTRIES\n");
2154 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2157 pConnectionCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 0x1000);
2159 if( pConnectionCB == NULL)
2162 #ifdef AFS_DEBUG_TRACE
2163 AFSDbgPrint( L"NPEnumResource Out of Memory\n");
2166 try_return( dwStatus = WN_OUT_OF_MEMORY);
2169 pConnectionCBBase = (void *)pConnectionCB;
2171 hControlDevice = OpenRedirector();
2173 if( hControlDevice == NULL)
2176 #ifdef AFS_DEBUG_TRACE
2177 AFSDbgPrint( L"NPEnumResource OpenRedirector failure, returning WN_NET_ERROR\n");
2180 try_return( dwStatus = WN_NET_ERROR);
2184 // Handle the special cases here
2185 // 0. Provider Network Root
2190 if ( pEnumCB->Scope == RESOURCE_GLOBALNET)
2193 ReadServerNameString();
2195 if ( pEnumCB->CurrentIndex == 0 &&
2196 pEnumCB->RemoteName == NULL)
2199 // Determine the space needed for this entry...
2201 SpaceNeeded = 2 * ( cbProviderNameLength + sizeof( WCHAR));
2203 uniRemoteName.Length = (USHORT)cbProviderNameLength;
2204 uniRemoteName.MaximumLength = uniRemoteName.Length;
2205 uniRemoteName.Buffer = wszProviderName;
2207 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2210 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2212 #ifdef AFS_DEBUG_TRACE
2213 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2217 try_return( dwStatus = WN_MORE_DATA);
2220 #ifdef AFS_DEBUG_TRACE
2221 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2225 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2227 pNetResource->dwScope = RESOURCE_GLOBALNET;
2228 pNetResource->dwType = RESOURCETYPE_ANY;
2229 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_NETWORK;
2230 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_RESERVED;
2232 // setup string area at opposite end of buffer
2233 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2235 pNetResource->lpLocalName = NULL;
2238 pNetResource->lpRemoteName = StringZone;
2240 StringCbCopy( StringZone,
2241 cbProviderNameLength + sizeof( WCHAR),
2244 StringZone += cbProviderNameLength / sizeof(WCHAR) + 1;
2246 pNetResource->lpComment = NULL;
2248 // copy provider name
2249 pNetResource->lpProvider = StringZone;
2250 StringCbCopy( StringZone,
2251 cbProviderNameLength + sizeof( WCHAR),
2254 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2256 #ifdef AFS_DEBUG_TRACE
2257 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2259 GetScopeString(pNetResource->dwScope),
2260 GetTypeString(pNetResource->dwType),
2261 GetDisplayString(pNetResource->dwDisplayType),
2262 GetUsageString(pNetResource->dwUsage),
2263 pNetResource->lpLocalName,
2264 pNetResource->lpRemoteName,
2265 pNetResource->lpComment);
2268 // setup the new end of buffer
2269 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2275 // do not change the index since we did not query the redirector
2276 pEnumCB->CurrentIndex = 0;
2278 // remember that we returned the provider name
2279 pEnumCB->RemoteName = (WCHAR *)HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, 0x1000);
2281 if( pEnumCB->RemoteName == NULL)
2284 try_return( dwStatus = WN_OUT_OF_MEMORY);
2289 StringCbCopy( pEnumCB->RemoteName,
2295 if ( pEnumCB->CurrentIndex == 0 &&
2296 lstrlen( pEnumCB->RemoteName) == cbProviderNameLength / sizeof( WCHAR) &&
2297 _wcsnicmp( pEnumCB->RemoteName, wszProviderName, cbProviderNameLength / sizeof( WCHAR)) == 0 &&
2298 EntriesCopied < EntriesRequested)
2302 // After the network provider entry comes the server entry
2305 // Determine the space needed for this entry...
2307 SpaceNeeded = cbProviderNameLength + cbServerNameUNCLength + cbServerCommentLength + 3 * sizeof( WCHAR);
2309 uniRemoteName.Length = (USHORT)cbServerNameUNCLength;
2310 uniRemoteName.MaximumLength = uniRemoteName.Length;
2311 uniRemoteName.Buffer = wszServerNameUNC;
2313 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2316 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2318 #ifdef AFS_DEBUG_TRACE
2319 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2323 try_return( dwStatus = WN_MORE_DATA);
2326 #ifdef AFS_DEBUG_TRACE
2327 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2331 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2333 pNetResource->dwScope = 0;
2334 pNetResource->dwType = RESOURCETYPE_ANY;
2335 pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
2336 pNetResource->dwUsage = RESOURCEUSAGE_CONTAINER;
2338 // setup string area at opposite end of buffer
2339 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2341 pNetResource->lpLocalName = NULL;
2344 pNetResource->lpRemoteName = StringZone;
2346 StringCbCopy( StringZone,
2347 cbServerNameUNCLength + sizeof( WCHAR),
2350 StringZone += cbServerNameUNCLength / sizeof(WCHAR) + 1;
2353 pNetResource->lpComment = StringZone;
2355 StringCbCopy( StringZone,
2356 cbServerCommentLength + sizeof( WCHAR),
2359 StringZone += cbServerCommentLength / sizeof( WCHAR) + 1;
2361 // copy provider name
2362 pNetResource->lpProvider = StringZone;
2363 StringCbCopy( StringZone,
2364 cbProviderNameLength + sizeof( WCHAR),
2367 StringZone += cbProviderNameLength / sizeof( WCHAR) + 1;
2369 #ifdef AFS_DEBUG_TRACE
2370 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2372 GetScopeString(pNetResource->dwScope),
2373 GetTypeString(pNetResource->dwType),
2374 GetDisplayString(pNetResource->dwDisplayType),
2375 GetUsageString(pNetResource->dwUsage),
2376 pNetResource->lpLocalName,
2377 pNetResource->lpRemoteName,
2378 pNetResource->lpComment);
2381 // setup the new end of buffer
2382 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2388 // do not update the index because we did not query the redirector
2389 pEnumCB->CurrentIndex = 0;
2391 // remember that we returned the server
2392 StringCbCopy( pEnumCB->RemoteName,
2400 // Setup what we are going to ask for
2403 pConnectionCB->Scope = pEnumCB->Scope;
2405 pConnectionCB->Type = pEnumCB->Type;
2407 pConnectionCB->CurrentIndex = pEnumCB->CurrentIndex;
2409 pConnectionCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
2412 // If this is a RESOURCE_GLOBALNET enumeration then pass down the remote name if
2416 pConnectionCB->RemoteNameLength = 0;
2418 if( pEnumCB->Scope == RESOURCE_GLOBALNET &&
2419 pEnumCB->RemoteName != NULL)
2422 pConnectionCB->RemoteNameLength = wcslen( pEnumCB->RemoteName) * sizeof( WCHAR);
2424 StringCbCopy( pConnectionCB->RemoteName,
2425 (0x1000 - sizeof(AFSNetworkProviderConnectionCB)) + sizeof(WCHAR),
2426 pEnumCB->RemoteName);
2429 pConnectionCB->AuthenticationId = AFSRetrieveAuthId();
2431 #ifdef AFS_DEBUG_TRACE
2432 AFSDbgPrint( L"NPEnumResource Retrieved authentication id %08lX-%08lX\n",
2433 pConnectionCB->AuthenticationId.HighPart,
2434 pConnectionCB->AuthenticationId.LowPart);
2437 dwError = DeviceIoControl( hControlDevice,
2438 IOCTL_AFS_LIST_CONNECTIONS,
2448 #ifdef AFS_DEBUG_TRACE
2449 DWORD gle = GetLastError();
2451 AFSDbgPrint( L"NPEnumResource Failed to list connections from file system - gle 0x%x\n",
2454 try_return( dwStatus = WN_NOT_CONNECTED);
2457 if( dwCopyBytes == 0)
2460 #ifdef AFS_DEBUG_TRACE
2461 AFSDbgPrint( L"NPEnumResource No More Entries\n");
2463 try_return( dwStatus = WN_NO_MORE_ENTRIES);
2466 dwIndex = pEnumCB->CurrentIndex;
2468 while( EntriesCopied < EntriesRequested)
2471 uniRemoteName.Length = (USHORT)pConnectionCB->RemoteNameLength;
2472 uniRemoteName.MaximumLength = uniRemoteName.Length;
2473 uniRemoteName.Buffer = pConnectionCB->RemoteName;
2475 // Determine the space needed for this entry...
2479 if( pConnectionCB->LocalName != 0)
2482 SpaceNeeded += 3 * sizeof(WCHAR); // local name
2485 SpaceNeeded += pConnectionCB->RemoteNameLength + sizeof( WCHAR); // remote name
2487 if( pConnectionCB->CommentLength > 0)
2490 SpaceNeeded += pConnectionCB->CommentLength + sizeof( WCHAR); // comment
2493 SpaceNeeded += cbProviderNameLength + sizeof( WCHAR); // provider name
2495 if( SpaceNeeded + sizeof( NETRESOURCE) > SpaceAvailable)
2498 if (EntriesCopied == 0) {
2500 dwStatus = WN_MORE_DATA;
2502 *lpBufferSize = SpaceNeeded + sizeof( NETRESOURCE);
2504 #ifdef AFS_DEBUG_TRACE
2505 AFSDbgPrint( L"NPEnumResource Request MORE_DATA for entry %s Len %d\n",
2512 #ifdef AFS_DEBUG_TRACE
2513 AFSDbgPrint( L"NPEnumResource Return SUCCESS but more entries Index %d\n",
2517 dwStatus = WN_SUCCESS;
2523 SpaceAvailable -= (SpaceNeeded + sizeof( NETRESOURCE));
2525 pNetResource->dwScope = pConnectionCB->Scope;
2526 pNetResource->dwType = pConnectionCB->Type;
2528 pNetResource->dwDisplayType = pConnectionCB->DisplayType;
2530 if ( pNetResource->dwType == RESOURCETYPE_ANY &&
2531 pNetResource->dwDisplayType == RESOURCEDISPLAYTYPE_SHARE)
2534 pNetResource->dwType = RESOURCETYPE_DISK;
2536 pNetResource->dwUsage = pConnectionCB->Usage;
2538 // setup string area at opposite end of buffer
2539 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2542 if( pConnectionCB->LocalName != 0)
2545 pNetResource->lpLocalName = StringZone;
2546 *StringZone++ = towupper(pConnectionCB->LocalName);
2547 *StringZone++ = L':';
2548 *StringZone++ = L'\0';
2553 pNetResource->lpLocalName = NULL;
2556 #ifdef AFS_DEBUG_TRACE
2557 AFSDbgPrint( L"NPEnumResource Processing Entry %wZ\n",
2562 pNetResource->lpRemoteName = StringZone;
2564 CopyMemory( StringZone,
2565 pConnectionCB->RemoteName,
2566 pConnectionCB->RemoteNameLength);
2568 StringZone += (pConnectionCB->RemoteNameLength / sizeof(WCHAR));
2570 *StringZone++ = L'\0';
2573 if( pConnectionCB->CommentLength > 0)
2576 pNetResource->lpComment = StringZone;
2578 CopyMemory( StringZone,
2579 (void *)((char *)pConnectionCB + pConnectionCB->CommentOffset),
2580 pConnectionCB->CommentLength);
2582 StringZone += (pConnectionCB->CommentLength / sizeof(WCHAR));
2584 *StringZone++ = L'\0';
2589 pNetResource->lpComment = NULL;
2592 // copy provider name
2593 pNetResource->lpProvider = StringZone;
2594 StringCbCopy( StringZone,
2595 cbProviderNameLength + sizeof( WCHAR),
2598 StringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
2600 #ifdef AFS_DEBUG_TRACE
2601 AFSDbgPrint( L"NPEnumResource Entry (0x%p) Scope %s Type %s Display %s Usage %s Local %s Remote \"%s\" Comment \"%s\"\n",
2603 GetScopeString(pNetResource->dwScope),
2604 GetTypeString(pNetResource->dwType),
2605 GetDisplayString(pNetResource->dwDisplayType),
2606 GetUsageString(pNetResource->dwUsage),
2607 pNetResource->lpLocalName,
2608 pNetResource->lpRemoteName,
2609 pNetResource->lpComment);
2612 // setup the new end of buffer
2613 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded);
2621 dwCopyBytes -= FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2622 pConnectionCB->RemoteNameLength +
2623 pConnectionCB->CommentLength;
2625 if( dwCopyBytes == 0)
2628 dwStatus = WN_SUCCESS;
2633 pConnectionCB = (AFSNetworkProviderConnectionCB *)((char *)pConnectionCB +
2634 FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
2635 pConnectionCB->RemoteNameLength +
2636 pConnectionCB->CommentLength);
2639 *lpcCount = EntriesCopied;
2641 // update entry index
2642 pEnumCB->CurrentIndex = dwIndex;
2644 #ifdef AFS_DEBUG_TRACE
2645 AFSDbgPrint( L"NPEnumResource Completed Count %d Index %d\n",
2652 if ( hControlDevice != NULL)
2655 CloseHandle( hControlDevice);
2658 if( pConnectionCBBase != NULL)
2661 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectionCBBase);
2670 Routine Description:
2672 This routine closes the handle for enumeration of resources.
2676 hEnum - the enumeration handle
2680 WN_SUCCESS if successful, otherwise the appropriate error
2684 The sample only supports the notion of enumerating connected shares
2689 NPCloseEnum( HANDLE hEnum )
2692 AFSEnumerationCB *pEnumCB = (AFSEnumerationCB *)hEnum;
2694 #ifdef AFS_DEBUG_TRACE
2695 AFSDbgPrint( L"NPCloseEnum\n");
2698 if( pEnumCB->RemoteName != NULL)
2701 HeapFree( GetProcessHeap( ), 0, (PVOID) pEnumCB->RemoteName);
2704 HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum );
2710 NPGetResourceParent( LPNETRESOURCE lpNetResource,
2712 LPDWORD lpBufferSize )
2715 DWORD dwStatus = WN_ACCESS_DENIED;
2716 WCHAR *pwchRemoteName = NULL, *pwchSearch = NULL, *pwchSystem = NULL;
2717 LPNETRESOURCE lpOutResource = (LPNETRESOURCE) lpBuffer;
2719 if ( lpNetResource == NULL)
2721 #ifdef AFS_DEBUG_TRACE
2722 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2724 return WN_MORE_DATA;
2727 if( lpNetResource->lpRemoteName == NULL)
2729 #ifdef AFS_DEBUG_TRACE
2730 AFSDbgPrint( L"NPGetResourceParent NULL NETRESOURCE\n");
2732 return WN_BAD_NETNAME;
2735 if ( lpNetResource->dwType != 0 &&
2736 lpNetResource->dwType != RESOURCETYPE_DISK)
2738 #ifdef AFS_DEBUG_TRACE
2739 AFSDbgPrint( L"NPGetResourceParent Bad dwType\n");
2741 return WN_BAD_VALUE;
2744 if ( lpBufferSize == NULL )
2747 #ifdef AFS_DEBUG_TRACE
2748 AFSDbgPrint( L"NPGetResourceParent Null lpBufferSize\n");
2750 return WN_BAD_VALUE;
2753 #ifdef AFS_DEBUG_TRACE
2754 AFSDbgPrint( L"NPGetResourceParent For remote name %s\n",
2755 lpNetResource->lpRemoteName);
2758 pwchRemoteName = lpNetResource->lpRemoteName;
2760 pwchSearch = pwchRemoteName + (wcslen( pwchRemoteName) - 1);
2762 while( pwchSearch != pwchRemoteName)
2765 if( *pwchSearch == L'\\')
2768 *pwchSearch = L'\0';
2776 if( pwchSearch != pwchRemoteName)
2779 #ifdef AFS_DEBUG_TRACE
2780 AFSDbgPrint( L"NPGetResourceParent Processing parent %s\n",
2781 lpNetResource->lpRemoteName);
2784 dwStatus = NPGetResourceInformation( lpNetResource,
2791 if ( lpOutResource == NULL ||
2792 *lpBufferSize < sizeof( NETRESOURCE) )
2794 *lpBufferSize = sizeof( NETRESOURCE);
2796 return WN_MORE_DATA;
2799 memset( lpOutResource, 0, sizeof( NETRESOURCE));
2809 NPGetResourceInformation( LPNETRESOURCE lpNetResource,
2811 LPDWORD lpBufferSize,
2812 LPWSTR *lplpSystem )
2815 DWORD dwStatus = WN_NOT_CONNECTED;
2816 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
2818 DWORD dwBufferSize = 0;
2819 HANDLE hControlDevice = NULL;
2820 NETRESOURCE *pNetResource = (NETRESOURCE *)lpBuffer;
2821 PWCHAR pStringZone = NULL;
2822 UNICODE_STRING uniRemoteName;
2823 DWORD ulRequiredLen = 0;
2834 ReadProviderNameString();
2836 if ( NPIsFSDisabled())
2839 #ifdef AFS_DEBUG_TRACE
2840 AFSDbgPrint( L"NPGetResourceInformation AFSRDFS is disabled, returning WN_BAD_NETNAME\n");
2843 try_return( dwStatus = WN_BAD_NETNAME);
2846 if ( lpNetResource == NULL ||
2847 lpBufferSize == NULL )
2850 #ifdef AFS_DEBUG_TRACE
2851 AFSDbgPrint( L"NPGetResourceInformaton Null lpNetResource or lpBufferSize\n");
2853 return WN_BAD_VALUE;
2856 if( lpNetResource->lpRemoteName == NULL)
2858 #ifdef AFS_DEBUG_TRACE
2859 AFSDbgPrint( L"NPGetResourceInformation No resource name\n");
2862 try_return( dwStatus = WN_NOT_CONNECTED);
2865 dwPassedSize = *lpBufferSize;
2867 dwBufferSize = 0x1000;
2869 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
2871 if( pConnectCB == NULL)
2874 try_return( dwStatus = WN_OUT_OF_MEMORY);
2877 pConnectCB->RemoteNameLength = wcslen( lpNetResource->lpRemoteName) * sizeof( WCHAR);
2879 StringCbCopy( pConnectCB->RemoteName,
2880 dwBufferSize - sizeof(AFSNetworkProviderConnectionCB),
2881 lpNetResource->lpRemoteName);
2883 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
2885 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
2887 #ifdef AFS_DEBUG_TRACE
2888 AFSDbgPrint( L"NPGetResourceInformation Retrieved authentication id %08lX-%08lX\n",
2889 pConnectCB->AuthenticationId.HighPart,
2890 pConnectCB->AuthenticationId.LowPart);
2893 hControlDevice = OpenRedirector();
2895 if( hControlDevice == NULL)
2898 #ifdef AFS_DEBUG_TRACE
2899 AFSDbgPrint( L"NPGetResourceInformation OpenRedirector failure, returning WN_NET_ERROR\n");
2902 try_return( dwStatus = WN_NET_ERROR);
2905 dwError = DeviceIoControl( hControlDevice,
2906 IOCTL_AFS_GET_CONNECTION_INFORMATION,
2916 #ifdef AFS_DEBUG_TRACE
2917 DWORD gle = GetLastError();
2919 AFSDbgPrint( L"NPGetResourceInformation Failed to get connection info from file system for local %s gle 0x%x\n",
2920 lpNetResource->lpRemoteName, gle);
2922 try_return( dwStatus = WN_BAD_NETNAME);
2925 uniRemoteName.Length = (USHORT)pConnectCB->RemoteNameLength;
2926 uniRemoteName.MaximumLength = uniRemoteName.Length;
2927 uniRemoteName.Buffer = pConnectCB->RemoteName;
2929 #ifdef AFS_DEBUG_TRACE
2930 AFSDbgPrint( L"NPGetResourceInformation For remote name %wZ Scope %08lX Type %08lX Usage %08lX\n",
2937 // Determine the space needed for this entry...
2939 ulRequiredLen = sizeof( NETRESOURCE);
2941 ulRequiredLen += pConnectCB->RemoteNameLength + sizeof( WCHAR);
2943 ulRequiredLen += pConnectCB->CommentLength + sizeof( WCHAR);
2945 ulRequiredLen += cbProviderNameLength + sizeof( WCHAR);
2947 ulRequiredLen += pConnectCB->RemainingPathLength + sizeof( WCHAR);
2949 if( pNetResource == NULL ||
2950 ulRequiredLen > dwPassedSize)
2953 *lpBufferSize = ulRequiredLen;
2955 try_return( dwStatus = WN_MORE_DATA);
2958 pStringZone = (PWCHAR) ((char *)lpBuffer + sizeof( NETRESOURCE));
2960 pNetResource->dwScope = 0 /* pConnectCB->Scope*/;
2961 pNetResource->dwType = 0 /* pConnectCB->Type */;
2963 pNetResource->dwDisplayType = pConnectCB->DisplayType;
2965 pNetResource->dwUsage = pConnectCB->Usage;
2967 pNetResource->lpLocalName = NULL;
2970 pNetResource->lpRemoteName = pStringZone;
2972 CopyMemory( pStringZone,
2973 pConnectCB->RemoteName,
2974 pConnectCB->RemoteNameLength);
2976 pStringZone += (pConnectCB->RemoteNameLength / sizeof(WCHAR));
2978 *pStringZone++ = L'\0';
2981 pNetResource->lpComment = pStringZone;
2983 CopyMemory( pStringZone,
2984 (void *)((char *)pConnectCB + pConnectCB->CommentOffset),
2985 pConnectCB->CommentLength);
2987 pStringZone += (pConnectCB->CommentLength / sizeof(WCHAR));
2989 *pStringZone++ = L'\0';
2991 // copy remaining path
2992 if (pConnectCB->RemainingPathLength > 0)
2994 *lplpSystem = pStringZone;
2996 CopyMemory( pStringZone,
2997 (void *)((char *)pConnectCB + pConnectCB->RemainingPathOffset),
2998 pConnectCB->RemainingPathLength);
3000 pStringZone += (pConnectCB->RemainingPathLength / sizeof(WCHAR));
3002 *pStringZone++ = L'\0';
3004 #ifdef AFS_DEBUG_TRACE
3005 AFSDbgPrint( L"NPGetResourceInformation For remote name %s returning remaining path %s\n",
3006 pNetResource->lpRemoteName,
3011 // copy provider name
3012 pNetResource->lpProvider = pStringZone;
3014 StringCbCopy( pStringZone,
3015 cbProviderNameLength + sizeof( WCHAR),
3018 pStringZone += (cbProviderNameLength / sizeof( WCHAR) + 1);
3020 *lpBufferSize = ulRequiredLen;
3022 dwStatus = WN_SUCCESS;
3026 if ( hControlDevice != NULL)
3029 CloseHandle( hControlDevice);
3032 if( pConnectCB != NULL)
3035 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3043 SeparateRemainingPath( WCHAR * lpConnectionName, WCHAR **lppRemainingPath)
3050 // at this point the lpConnectionName contains the full name. We need to
3051 // truncate it to \\server\share and move the remaining path back one position.
3054 for ( pwch = lpConnectionName, dwCount = 0; *pwch; pwch++)
3056 if ( *pwch == L'\\')
3070 // Found the remaining path that must be moved
3073 *lppRemainingPath = pwch + 1;
3080 for ( ; *pwch; pwch++);
3083 // and work backwards moving the string
3084 // and then make sure that there is at least
3085 // a path separator.
3090 for ( ;pwch > *lppRemainingPath; pwch--)
3092 *pwch = *(pwch - 1);
3100 NPGetUniversalName( LPCWSTR lpLocalPath,
3103 LPDWORD lpBufferSize )
3105 DWORD dwStatus = WN_NOT_CONNECTED;
3106 WCHAR wchLocalName[3];
3107 WCHAR wchSubstName[MAX_PATH + 1];
3108 AFSNetworkProviderConnectionCB *pConnectCB = NULL;
3110 DWORD dwBufferSize = 0;
3111 DWORD dwPassedSize = *lpBufferSize;
3112 DWORD dwRemainingLength = *lpBufferSize;
3113 HANDLE hControlDevice = NULL;
3114 DWORD dwLocalPathLength = 0;
3115 DWORD dwRemainingPathLength = 0;
3121 #ifdef AFS_DEBUG_TRACE
3122 AFSDbgPrint( L"NPGetUniversalName local path %s level 0x%X\n",
3123 lpLocalPath ? lpLocalPath : L"(Null)",
3127 if ( NPIsFSDisabled())
3130 #ifdef AFS_DEBUG_TRACE
3131 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_NOT_CONNECTED\n");
3134 try_return( dwStatus = WN_NOT_CONNECTED);
3137 dwLocalPathLength = lstrlen( lpLocalPath);
3139 dwRemainingPathLength = dwLocalPathLength - 2; // no drive letter
3141 if( dwLocalPathLength == 0)
3144 #ifdef AFS_DEBUG_TRACE
3145 AFSDbgPrint( L"NPGetUniversalName AFSRDFS is disabled, returning WN_BAD_LOCALNAME\n");
3148 try_return( dwStatus = WN_BAD_LOCALNAME);
3151 if( lpBuffer == NULL ||
3152 lpBufferSize == NULL)
3154 #ifdef AFS_DEBUG_TRACE
3155 AFSDbgPrint( L"NPGetUniversalName No output buffer or size\n");
3157 try_return( dwStatus = WN_BAD_VALUE);
3160 memset(lpBuffer, 0, dwPassedSize);
3162 if ( !DriveSubstitution( lpLocalPath, wchSubstName, sizeof( wchSubstName)))
3164 wchLocalName[0] = towupper(lpLocalPath[0]);
3165 wchLocalName[1] = L':';
3166 wchLocalName[2] = L'\0';
3168 #ifdef AFS_DEBUG_TRACE
3169 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for %s level 0x%X\n",
3177 ReadServerNameString();
3179 if ( wchSubstName[0] != L'\\' &&
3180 wchSubstName[1] == L':')
3183 wchLocalName[0] = towupper(wchSubstName[0]);
3184 wchLocalName[1] = L':';
3185 wchLocalName[2] = L'\0';
3187 #ifdef AFS_DEBUG_TRACE
3188 AFSDbgPrint( L"NPGetUniversalName Requesting UNC for drive substitution %s -> %s\n",
3193 else if ( _wcsnicmp( wchSubstName, wszServerNameUNC, cbServerNameUNCLength / sizeof( WCHAR)) == 0 &&
3194 ( wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == L'\\' ||
3195 wchSubstName[cbServerNameUNCLength / sizeof( WCHAR)] == 0))
3199 #ifdef AFS_DEBUG_TRACE
3200 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is AFS; Level 0x%x BufferSize 0x%x\n",
3206 dwBufferSize = (wcslen( wchSubstName) + 1) * sizeof( WCHAR);
3208 switch( dwInfoLevel)
3211 case UNIVERSAL_NAME_INFO_LEVEL:
3214 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3216 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize;
3218 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3221 #ifdef AFS_DEBUG_TRACE
3222 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3225 try_return( dwStatus = WN_MORE_DATA);
3228 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3230 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3232 memcpy( pUniversalInfo->lpUniversalName,
3234 min( dwBufferSize, dwRemainingLength));
3236 dwRemainingLength -= min( dwBufferSize, dwRemainingLength);
3238 #ifdef AFS_DEBUG_TRACE
3239 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3241 pUniversalInfo->lpUniversalName,
3242 pUniversalInfo->lpUniversalName);
3245 if ( dwPassedSize < *lpBufferSize)
3248 try_return( dwStatus = WN_MORE_DATA);
3251 try_return( dwStatus = WN_SUCCESS);
3254 case REMOTE_NAME_INFO_LEVEL:
3257 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3259 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + 2 * dwBufferSize + sizeof( WCHAR);
3261 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3264 #ifdef AFS_DEBUG_TRACE
3265 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3268 try_return( dwStatus = WN_MORE_DATA);
3271 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3273 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3275 memcpy( pRemoteInfo->lpUniversalName,
3277 min( dwRemainingLength, dwBufferSize));
3279 dwRemainingLength -= min( dwRemainingLength, dwBufferSize);
3281 #ifdef AFS_DEBUG_TRACE
3282 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3284 pRemoteInfo->lpUniversalName,
3285 pRemoteInfo->lpUniversalName);
3288 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3290 pRemoteInfo->lpConnectionName = (LPTSTR)((char *)pRemoteInfo->lpUniversalName + dwBufferSize);
3292 memcpy( pRemoteInfo->lpConnectionName,
3294 min( dwRemainingLength, dwBufferSize));
3296 dwRemainingLength -= min( dwRemainingLength, dwBufferSize) - sizeof( WCHAR);
3298 SeparateRemainingPath( pRemoteInfo->lpConnectionName,
3299 &pRemoteInfo->lpRemainingPath);
3302 #ifdef AFS_DEBUG_TRACE
3303 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3305 pRemoteInfo->lpConnectionName,
3306 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3308 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3310 pRemoteInfo->lpRemainingPath,
3311 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3314 if ( dwPassedSize < *lpBufferSize)
3317 try_return( dwStatus = WN_MORE_DATA);
3320 try_return( dwStatus = WN_SUCCESS);
3324 #ifdef AFS_DEBUG_TRACE
3325 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3328 try_return( dwStatus = WN_BAD_VALUE);
3334 #ifdef AFS_DEBUG_TRACE
3335 AFSDbgPrint( L"NPGetUniversalName drive substitution %s is not AFS\n",
3338 try_return( dwStatus = WN_NOT_CONNECTED);
3342 dwBufferSize = 0x1000;
3344 pConnectCB = (AFSNetworkProviderConnectionCB *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
3346 if( pConnectCB == NULL)
3348 try_return( dwStatus = WN_OUT_OF_MEMORY);
3351 pConnectCB->LocalName = towupper(wchLocalName[0]);
3353 pConnectCB->RemoteNameLength = 0;
3355 pConnectCB->Version = AFS_NETWORKPROVIDER_INTERFACE_VERSION_1;
3357 pConnectCB->AuthenticationId = AFSRetrieveAuthId();
3359 #ifdef AFS_DEBUG_TRACE
3360 AFSDbgPrint( L"NPGetUniversalName Retrieved authentication id %08lX-%08lX\n",
3361 pConnectCB->AuthenticationId.HighPart,
3362 pConnectCB->AuthenticationId.LowPart);
3365 hControlDevice = OpenRedirector();
3367 if( hControlDevice == NULL)
3370 try_return( dwStatus = WN_NET_ERROR);
3373 dwError = DeviceIoControl( hControlDevice,
3374 IOCTL_AFS_GET_CONNECTION,
3384 #ifdef AFS_DEBUG_TRACE
3385 DWORD gle = GetLastError();
3387 AFSDbgPrint( L"NPGetUniversalName Failed to get connection from file system for local %s gle 0x%x\n",
3390 try_return( dwStatus = WN_NOT_CONNECTED);
3393 switch( dwInfoLevel)
3396 case UNIVERSAL_NAME_INFO_LEVEL:
3399 UNIVERSAL_NAME_INFO *pUniversalInfo = (UNIVERSAL_NAME_INFO *)lpBuffer;
3401 *lpBufferSize = sizeof( UNIVERSAL_NAME_INFO) + dwBufferSize + sizeof( WCHAR);
3403 *lpBufferSize += dwRemainingPathLength * sizeof( WCHAR);
3405 if( dwPassedSize <= sizeof( UNIVERSAL_NAME_INFO))
3408 #ifdef AFS_DEBUG_TRACE
3409 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO) WN_MORE_DATA\n");
3412 try_return( dwStatus = WN_MORE_DATA);
3415 dwRemainingLength -= sizeof( UNIVERSAL_NAME_INFO);
3417 pUniversalInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( UNIVERSAL_NAME_INFO));
3419 pch = (char *)pUniversalInfo->lpUniversalName;
3423 min( dwBufferSize, dwRemainingLength));
3425 pch += min( dwBufferSize, dwRemainingLength);
3427 dwRemainingLength -= min( dwBufferSize + sizeof(WCHAR), dwRemainingLength);
3431 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3433 pch += min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3435 dwRemainingLength -= min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength);
3437 #ifdef AFS_DEBUG_TRACE
3438 AFSDbgPrint( L"NPGetUniversalName (UNIVERSAL_NAME_INFO_LEVEL) lpBuffer: %p Name: (%p) \"%s\"\n",
3440 pUniversalInfo->lpUniversalName,
3441 pUniversalInfo->lpUniversalName);
3444 if ( dwPassedSize < *lpBufferSize)
3447 try_return( dwStatus = WN_MORE_DATA);
3450 try_return( dwStatus = WN_SUCCESS);
3453 case REMOTE_NAME_INFO_LEVEL:
3456 REMOTE_NAME_INFO *pRemoteInfo = (REMOTE_NAME_INFO *)lpBuffer;
3458 *lpBufferSize = sizeof( REMOTE_NAME_INFO) + (2 * dwBufferSize + sizeof( WCHAR)) + 2 * sizeof( WCHAR);
3460 *lpBufferSize += 2 * dwRemainingPathLength * sizeof( WCHAR);
3462 if( dwPassedSize <= sizeof( REMOTE_NAME_INFO))
3465 #ifdef AFS_DEBUG_TRACE
3466 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO) WN_MORE_DATA\n");
3469 try_return( dwStatus = WN_MORE_DATA);
3472 dwRemainingLength -= sizeof( REMOTE_NAME_INFO);
3474 pRemoteInfo->lpUniversalName = (LPTSTR)((char *)lpBuffer + sizeof( REMOTE_NAME_INFO));
3476 pch = (char *)pRemoteInfo->lpUniversalName;
3480 min( dwBufferSize, dwRemainingLength));
3482 pch += min( dwBufferSize, dwRemainingLength);
3484 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3488 min(dwRemainingPathLength * sizeof( WCHAR), dwRemainingLength));
3490 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3492 dwRemainingLength -= min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3494 #ifdef AFS_DEBUG_TRACE
3495 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) UNI lpBuffer: %p Name: (%p) \"%s\"\n",
3497 pRemoteInfo->lpUniversalName,
3498 pRemoteInfo->lpUniversalName);
3501 if ( dwRemainingLength > dwBufferSize + sizeof( WCHAR))
3503 pRemoteInfo->lpConnectionName = (LPWSTR)pch;
3507 min( dwBufferSize, dwRemainingLength));
3509 pch += min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3511 dwRemainingLength -= min( dwBufferSize + sizeof( WCHAR), dwRemainingLength);
3515 if ( dwRemainingLength > dwRemainingPathLength + sizeof( WCHAR))
3517 pRemoteInfo->lpRemainingPath = (LPWSTR)pch;
3521 min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength));
3523 pch += min((dwRemainingPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3525 dwRemainingLength -= min((dwLocalPathLength + 1) * sizeof( WCHAR), dwRemainingLength);
3528 #ifdef AFS_DEBUG_TRACE
3529 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) CONN lpBuffer: %p Name: (%p) \"%s\"\n",
3531 pRemoteInfo->lpConnectionName,
3532 pRemoteInfo->lpConnectionName ? pRemoteInfo->lpConnectionName : L"(null)");
3534 AFSDbgPrint( L"NPGetUniversalName (REMOTE_NAME_INFO_LEVEL) REMAIN lpBuffer: %p Name: (%p) \"%s\"\n",
3536 pRemoteInfo->lpRemainingPath,
3537 pRemoteInfo->lpRemainingPath ? pRemoteInfo->lpRemainingPath : L"(null)");
3540 if ( dwPassedSize < *lpBufferSize)
3543 try_return( dwStatus = WN_MORE_DATA);
3546 try_return( dwStatus = WN_SUCCESS);
3550 #ifdef AFS_DEBUG_TRACE
3551 AFSDbgPrint( L"NPGetUniversalName (UNKNOWN: 0x%X) WN_BAD_VALUE\n",
3554 try_return( dwStatus = WN_BAD_VALUE);
3559 #ifdef AFS_DEBUG_TRACE
3560 AFSDbgPrint( L"NPGetUniversalName BufferSize 0x%X\n",
3563 if ( hControlDevice != NULL)
3566 CloseHandle( hControlDevice);
3569 if( pConnectCB != NULL)
3572 HeapFree( GetProcessHeap( ), 0, (PVOID) pConnectCB);
3581 GetFormatFlags( DWORD dwFlags)
3583 static WCHAR Buffer[128] = L"";
3586 // WNFMT_MULTILINE 0x01
3587 // WNFMT_ABBREVIATED 0x02
3588 // WNFMT_INENUM 0x10
3589 // WNFMT_CONNECTION 0x20
3594 if ( dwFlags & WNFMT_MULTILINE )
3596 StringCbCat( Buffer, sizeof(Buffer), L"MULTILINE|");
3599 if ( dwFlags & WNFMT_INENUM )
3601 StringCbCat( Buffer, sizeof(Buffer), L"ABBREVIATED|");
3604 if ( dwFlags & WNFMT_INENUM )
3606 StringCbCat( Buffer, sizeof(Buffer), L"INENUM|");
3609 if ( dwFlags & WNFMT_CONNECTION )
3611 StringCbCat( Buffer, sizeof(Buffer), L"CONNECTION|");
3614 if ( dwFlags & ~(WNFMT_MULTILINE|WNFMT_ABBREVIATED|WNFMT_INENUM|WNFMT_CONNECTION) )
3616 StringCbCat( Buffer, sizeof(Buffer), L"UNKNOWN|");
3619 Buffer[lstrlen(Buffer)-1] = L'\0';
3625 NPFormatNetworkName( LPTSTR lpRemoteName,
3626 LPTSTR lpFormattedName,
3629 DWORD dwAveCharPerLine)
3632 DWORD dwLen = 0, dwCurrentLen = 0;
3633 LPTSTR pCurrentName = lpRemoteName;
3635 #ifdef AFS_DEBUG_TRACE
3636 AFSDbgPrint( L"NPFormatNetworkName Remote %s Flags %s (0x%x) CharsPerLine %u\n",
3639 GetFormatFlags( dwFlags),
3645 // Walk back in the name until we hit a \
3648 dwLen = wcslen( lpRemoteName);
3650 pCurrentName += (dwLen - 1);
3652 if ( pCurrentName[ 0] != L'\\')
3658 if( pCurrentName[ 0] == L'\\')
3674 if( *lpnLength < dwCurrentLen * sizeof( WCHAR))
3677 *lpnLength = dwCurrentLen * sizeof( WCHAR);
3679 #ifdef AFS_DEBUG_TRACE
3680 AFSDbgPrint( L"NPFormatNetworkName remote name %s WN_MORE_DATA\n",
3684 return WN_MORE_DATA;
3687 StringCbCopy( lpFormattedName,
3691 *lpnLength = dwCurrentLen * sizeof( WCHAR);
3693 #ifdef AFS_DEBUG_TRACE
3694 AFSDbgPrint( L"NPFormatNetworkName remote name %s as %s\n",
3702 /************************************************************
3703 / Unsupported entry points
3704 /************************************************************/
3707 // AuthGroup processing is implemented in src/WINNT/afsd/afslogon.c
3712 LPCWSTR lpAuthentInfoType,
3713 LPVOID lpAuthentInfo,
3714 LPCWSTR lpPreviousAuthentInfoType,
3715 LPVOID lpPreviousAuthentInfo,
3716 LPWSTR lpStationName,
3717 LPVOID StationHandle,
3718 LPWSTR *lpLogonScript)
3721 #ifdef AFS_DEBUG_TRACE
3722 AFSDbgPrint( L"NPLogonNotify, returning WN_NOT_SUPPORTED\n");
3725 return WN_NOT_SUPPORTED;
3729 NPPasswordChangeNotify (
3730 LPCWSTR lpAuthentInfoType,
3731 LPVOID lpAuthentInfo,
3732 LPCWSTR lpPreviousAuthentInfoType,
3733 LPVOID lpPreviousAuthentInfo,
3734 LPWSTR lpStationName,
3735 LPVOID StationHandle,
3736 DWORD dwChangeInfo )
3739 #ifdef AFS_DEBUG_TRACE
3740 AFSDbgPrint( L"NPPasswordChangeNotify, returning WN_NOT_SUPPORTED\n");
3743 SetLastError( WN_NOT_SUPPORTED );
3745 return WN_NOT_SUPPORTED;
3749 NPGetUser( LPTSTR lpName,
3751 LPDWORD lpBufferSize)
3754 DWORD rc = WN_NOT_SUPPORTED;
3756 AFSDbgPrint( L"NPGetUser Entry Name %s\n", lpName);
3764 NPGetReconnectFlags( LPWSTR lpRemoteName,
3765 unsigned char *Parameter2)
3768 DWORD dwStatus = WN_NOT_SUPPORTED;
3770 AFSDbgPrint( L"NPGetReconnectFlags RemoteName %s\n",
3779 I_SystemFocusDialog( VOID)
3782 DWORD dwStatus = WN_NOT_SUPPORTED;
3784 AFSDbgPrint( L"I_SystemFocusDialog\n");
3789 /************************************************************
3790 / END Unsupported entry points
3791 /************************************************************/
3798 HANDLE hControlDevice = NULL;
3799 WCHAR wchError[ 256];
3801 hControlDevice = CreateFile( AFS_SYMLINK_W,
3802 GENERIC_READ | GENERIC_WRITE,
3803 FILE_SHARE_READ | FILE_SHARE_WRITE,
3809 if( hControlDevice == INVALID_HANDLE_VALUE)
3812 hControlDevice = NULL;
3813 #ifdef AFS_DEBUG_TRACE
3814 AFSDbgPrint( L"Failed to open control device error: %d\n",
3820 // only do this if you want network shares to fail to mount
3821 // when the file system is not yet ready
3825 AFSDriverStatusRespCB respCB;
3828 memset( &respCB, '\0', sizeof( AFSDriverStatusRespCB));
3830 if ( !DeviceIoControl( hControlDevice,
3831 IOCTL_AFS_STATUS_REQUEST,
3835 sizeof( AFSDriverStatusRespCB),
3838 dwBytes != sizeof(AFSDriverStatusRespCB) ||
3839 respCB.Status != AFS_DRIVER_STATUS_READY )
3842 CloseHandle( hControlDevice);
3844 hControlDevice = NULL;
3849 return hControlDevice;
3856 LARGE_INTEGER liAuthId = {0,0};
3857 HANDLE hToken = NULL;
3858 TOKEN_STATISTICS stTokenInfo;
3859 DWORD dwCopyBytes = 0;
3861 if ( !OpenThreadToken( GetCurrentThread(),
3863 FALSE, // Impersonation
3866 if( !OpenProcessToken( GetCurrentProcess(),
3871 #ifdef AFS_DEBUG_TRACE
3872 AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve Thread and Process tokens 0x%X\n",
3879 #ifdef AFS_DEBUG_TRACE
3880 AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Process Token\n");
3887 #ifdef AFS_DEBUG_TRACE
3888 AFSDbgPrint( L"AFSRetrieveAuthId Retrieved Thread Token\n");
3892 if ( hToken != NULL)
3895 if( !GetTokenInformation( hToken,
3898 sizeof( TOKEN_STATISTICS),
3902 #ifdef AFS_DEBUG_TRACE
3903 AFSDbgPrint( L"AFSRetrieveAuthId Failed to retrieve token information 0x%X\n",
3910 liAuthId.HighPart = stTokenInfo.AuthenticationId.HighPart;
3911 liAuthId.LowPart = stTokenInfo.AuthenticationId.LowPart;
3914 CloseHandle( hToken);
3923 static int init = 0;
3924 static BOOL debug = 0;
3929 if (RegOpenKey (HKEY_LOCAL_MACHINE,
3930 TEXT("SYSTEM\\CurrentControlSet\\Services\\AFSRedirector\\NetworkProvider"), &hk) == 0)
3932 DWORD dwSize = sizeof(BOOL);
3933 DWORD dwType = REG_DWORD;
3934 RegQueryValueEx (hk, TEXT("Debug"), NULL, &dwType, (PBYTE)&debug, &dwSize);
3951 WCHAR wszbuffer[512];
3957 va_start( marker, Format );
3959 StringCbPrintf( wszbuffer, sizeof(wszbuffer), L"[%d-%08X] ",
3965 GetCurrentThreadId());
3967 rc = StringCbVPrintfW( &wszbuffer[ 14], sizeof(wszbuffer) - 14, Format, marker);
3970 OutputDebugString( wszbuffer );
3972 OutputDebugString(L"AFSDbgPrint Failed to create string\n");
3974 return SUCCEEDED(rc) ? 1 : 0;