Windows: AFS Redirector Network Provider

In Windows a network file system must have a matching network
provider dll that interfaces with the Multiple Provider Router
(MPR) to support the WNet APIs called by the Windows Explorer
Shell and other applications.  The WNet APIs are primarily
used to support driver letter mapping but they also have a
number of other functions including universal name mapping,
path formatting, and path parsing.

Jeffrey Altman <jaltman@your-file-system.com> contributed to
the development of the AFSRDFSProvider.dll interface.

Change-Id: I9476003e05f12684676e8c7331a0a8dd13d98686
Reviewed-on: http://gerrit.openafs.org/5439
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Rod Widdowson <rdw@steadingsoftware.com>
Tested-by: Rod Widdowson <rdw@steadingsoftware.com>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>
This commit is contained in:
Peter Scott 2011-09-15 01:52:08 -04:00 committed by Jeffrey Altman
parent 3c69a113aa
commit 82d6041204
9 changed files with 4597 additions and 0 deletions

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="AFSRDFS Provider"
ProjectGUID="{E191A87E-DAB1-4D1E-9A23-3A1B559258F0}"
RootNamespace="NPDll"
SccProjectName="SAK"
SccAuxPath="SAK"
SccLocalPath="SAK"
SccProvider="SAK"
Keyword="MakeFileProj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
>
<Tool
Name="VCNMakeTool"
BuildCommandLine=""
ReBuildCommandLine=""
CleanCommandLine=""
Output="NPDll.exe"
PreprocessorDefinitions=""
IncludeSearchPath=""
ForcedIncludes=""
AssemblySearchPath=""
ForcedUsingAssemblies=""
CompileAsManaged=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="0"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
>
<Tool
Name="VCNMakeTool"
BuildCommandLine=""
ReBuildCommandLine=""
CleanCommandLine=""
Output="NPDll.exe"
PreprocessorDefinitions=""
IncludeSearchPath=""
ForcedIncludes=""
AssemblySearchPath=""
ForcedUsingAssemblies=""
CompileAsManaged=""
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\AFS_Npdll.c"
>
</File>
<File
RelativePath=".\AFS_NpdllMain.C"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\AFS_Npdll.DEF"
>
</File>
<File
RelativePath=".\SOURCES"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,10 @@
""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = "relative:AFSRDFSProvider"
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
}

View File

@ -0,0 +1,24 @@
SECTIONS .AFSNP READ WRITE SHARED
EXPORTS
DllMain @1
NPLogonNotify @7
NPPasswordChangeNotify @8
NPGetConnection @12
NPGetCaps @13
NPAddConnection @17
NPCancelConnection @18
NPOpenEnum @33
NPEnumResource @34
NPCloseEnum @35
NPFormatNetworkName @36
NPAddConnection3 @38
NPGetUniversalName @40
NPGetResourceParent @41
NPGetConnectionPerformance @49
NPGetResourceInformation @52
NPGetConnection3 @54
; NPGetUser @16
; NPGetReconnectFlags @53
; I_SystemFocusDialog @15

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2008 Kernel Drivers, LLC.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice,
* this list of conditions and the following disclaimer in the
* documentation
* and/or other materials provided with the distribution.
* - Neither the name of Kernel Drivers, LLC nor the names of its
* contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission from Kernel Drivers, LLC.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
void ReadProviderNameString( void);

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
* Copyright (c) 2009, 2010, 2011 Your File System, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice,
* this list of conditions and the following disclaimer in the
* documentation
* and/or other materials provided with the distribution.
* - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
* nor the names of their contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission from Kernel Drivers, LLC and Your File System, Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Define VERSIONINFO resource */
#define AFS_VERINFO_FILE_DESCRIPTION "AFS Redirector Network Provider"
#define AFS_VERINFO_NAME "AFSRDFSProvider"
#define AFS_VERINFO_FILENAME "AFSRDFSProvider.dll"
#include "..\AFS_component_version_number.h"
#include "..\..\..\config\NTVersioninfo.rc"

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
* Copyright (c) 2009, 2010, 2011 Your File System, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice,
* this list of conditions and the following disclaimer in the
* documentation
* and/or other materials provided with the distribution.
* - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
* nor the names of their contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission from Kernel Drivers, LLC and Your File System, Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <windows.h>
#define _DECL_DLLMAIN
#include <process.h>
#include "AFS_Npdll.h"
// NOTE:
//
// Function: DllMain
//
// Return: TRUE => Success
// FALSE => Failure
BOOL
WINAPI
DllMain( HINSTANCE hDLLInst,
DWORD fdwReason,
LPVOID lpvReserved)
{
BOOL bStatus = TRUE;
WORD wVersionRequested;
switch( fdwReason)
{
case DLL_PROCESS_ATTACH:
ReadProviderNameString();
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
default:
break;
}
return( bStatus);
}

View File

@ -0,0 +1,31 @@
TARGETNAME=AFSRDFSProvider
TARGETPATH=..\build
TARGETTYPE=DYNLINK
TARGETLIBS=$(DDK_LIB_PATH)\user32.lib \
$(DDK_LIB_PATH)\kernel32.lib \
$(DDK_LIB_PATH)\Advapi32.lib
UNICODE=1
NET_C_DEFINES=-DUNICODE
DLLBASE=0x1010000
USE_NTDLL=0
!IF $(FREEBUILD)
C_DEFINES=$(C_DEFINES)
!endif
INCLUDES=$(IFSKIT_INC_PATH);..\Common;
SOURCES= AFS_NpdllMain.c \
AFS_Npdll.c \
AFS_Npdll.rc
UMTYPE=console
OPTIONAL_NTTEST=
DLLDEF=AFS_Npdll.def

View File

@ -0,0 +1,322 @@
/*
* This test code was obtained from
* http://msdn.microsoft.com/en-us/library/aa385341(VS.85).aspx
*
* No license specified.
*/
#pragma comment(lib, "mpr.lib")
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <stdio.h>
#include <winnetwk.h>
BOOL WINAPI EnumerateFunc(DWORD dwScope, LPNETRESOURCE lpnr);
void DisplayStruct(int i, LPNETRESOURCE lpnrLocal);
BOOL WINAPI NetErrorHandler(HWND hwnd, DWORD dwErrorCode, LPSTR lpszFunction);
int main()
{
LPNETRESOURCE lpnr = NULL;
printf("Connected Resources\n");
printf("-------------------\n");
if (EnumerateFunc(RESOURCE_CONNECTED, lpnr) == FALSE) {
printf("Call to EnumerateFunc(CONNECTED) failed\n");
return 1;
}
printf("\n");
printf("Context Resources\n");
printf("-----------------\n");
if (EnumerateFunc(RESOURCE_CONTEXT, lpnr) == FALSE) {
printf("Call to EnumerateFunc(CONTEXT) failed\n");
return 1;
}
printf("\n");
printf("Global Resources\n");
printf("----------------\n");
if (EnumerateFunc(RESOURCE_GLOBALNET, lpnr) == FALSE) {
printf("Call to EnumerateFunc(GLOBALNET) failed\n");
return 1;
}
printf("\n");
printf("Remembered Resources\n");
printf("--------------------\n");
if (EnumerateFunc(RESOURCE_REMEMBERED, lpnr) == FALSE) {
printf("Call to EnumerateFunc(REMEMBERED) failed\n");
return 1;
}
return 0;
}
BOOL WINAPI EnumerateFunc(DWORD dwScope, LPNETRESOURCE lpnr)
{
DWORD dwResult, dwResultEnum;
HANDLE hEnum;
DWORD cbBuffer = 16384; // 16K is a good size
DWORD cEntries = -1; // enumerate all possible entries
LPNETRESOURCE lpnrLocal; // pointer to enumerated structures
DWORD i;
//
// Call the WNetOpenEnum function to begin the enumeration.
//
dwResult = WNetOpenEnum(dwScope, // all network resources
RESOURCETYPE_DISK, // all resources
RESOURCEUSAGE_ALL, // enumerate all resources
lpnr, // NULL first time the function is called
&hEnum); // handle to the resource
if (dwResult != NO_ERROR) {
printf("WnetOpenEnum failed with error %d\n", dwResult);
return FALSE;
}
//
// Call the GlobalAlloc function to allocate resources.
//
lpnrLocal = (LPNETRESOURCE) GlobalAlloc(GPTR, cbBuffer);
if (lpnrLocal == NULL) {
printf("WnetOpenEnum failed with error %d\n", dwResult);
return FALSE;
}
do {
//
// Initialize the buffer.
//
ZeroMemory(lpnrLocal, cbBuffer);
//
// Call the WNetEnumResource function to continue
// the enumeration.
//
cEntries = -1;
dwResultEnum = WNetEnumResource(hEnum, // resource handle
&cEntries, // defined locally as -1
lpnrLocal, // LPNETRESOURCE
&cbBuffer); // buffer size
//
// If the call succeeds, loop through the structures.
//
if (dwResultEnum == NO_ERROR) {
for (i = 0; i < cEntries; i++) {
// Call an application-defined function to
// display the contents of the NETRESOURCE structures.
//
DisplayStruct(i, &lpnrLocal[i]);
// If the NETRESOURCE structure represents a container resource,
// call the EnumerateFunc function recursively.
if (dwScope == RESOURCE_GLOBALNET &&
RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage
& RESOURCEUSAGE_CONTAINER))
if (!EnumerateFunc(dwScope, &lpnrLocal[i]))
printf("EnumerateFunc returned FALSE\n");
}
}
// Process errors.
//
else if (dwResultEnum != ERROR_NO_MORE_ITEMS) {
printf("WNetEnumResource failed with error %d\n", dwResultEnum);
break;
}
}
//
// End do.
//
while (dwResultEnum != ERROR_NO_MORE_ITEMS);
//
// Call the GlobalFree function to free the memory.
//
GlobalFree((HGLOBAL) lpnrLocal);
//
// Call WNetCloseEnum to end the enumeration.
//
dwResult = WNetCloseEnum(hEnum);
if (dwResult != NO_ERROR) {
//
// Process errors.
//
printf("WNetCloseEnum failed with error %d\n\n", dwResult);
// NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetCloseEnum");
return FALSE;
}
return TRUE;
}
void DisplayStruct(int i, LPNETRESOURCE lpnrLocal)
{
printf("NETRESOURCE[%d] Scope: ", i);
switch (lpnrLocal->dwScope) {
case (RESOURCE_CONNECTED):
printf("connected\n");
break;
case (RESOURCE_GLOBALNET):
printf("all resources\n");
break;
case (RESOURCE_REMEMBERED):
printf("remembered\n");
break;
case RESOURCE_RECENT:
printf("recent\n");
break;
case RESOURCE_CONTEXT:
printf("context\n");
break;
default:
printf("unknown scope %d\n", lpnrLocal->dwScope);
break;
}
printf("NETRESOURCE[%d] Type: ", i);
switch (lpnrLocal->dwType) {
case (RESOURCETYPE_ANY):
printf("any\n");
break;
case (RESOURCETYPE_DISK):
printf("disk\n");
break;
case (RESOURCETYPE_PRINT):
printf("print\n");
break;
case RESOURCETYPE_RESERVED:
printf("reserved\n");
break;
default:
printf("unknown type %d\n", lpnrLocal->dwType);
break;
}
printf("NETRESOURCE[%d] DisplayType: ", i);
switch (lpnrLocal->dwDisplayType) {
case (RESOURCEDISPLAYTYPE_GENERIC):
printf("generic\n");
break;
case (RESOURCEDISPLAYTYPE_DOMAIN):
printf("domain\n");
break;
case (RESOURCEDISPLAYTYPE_SERVER):
printf("server\n");
break;
case (RESOURCEDISPLAYTYPE_SHARE):
printf("share\n");
break;
case (RESOURCEDISPLAYTYPE_FILE):
printf("file\n");
break;
case (RESOURCEDISPLAYTYPE_GROUP):
printf("group\n");
break;
case (RESOURCEDISPLAYTYPE_NETWORK):
printf("network\n");
break;
case RESOURCEDISPLAYTYPE_ROOT:
printf("root\n");
break;
case RESOURCEDISPLAYTYPE_SHAREADMIN:
printf("share-admin\n");
break;
case RESOURCEDISPLAYTYPE_DIRECTORY:
printf("directory\n");
break;
case RESOURCEDISPLAYTYPE_TREE:
printf("tree\n");
break;
case RESOURCEDISPLAYTYPE_NDSCONTAINER:
printf("nds-container\n");
break;
default:
printf("unknown display type %d\n", lpnrLocal->dwDisplayType);
break;
}
printf("NETRESOURCE[%d] Usage: 0x%x = ", i, lpnrLocal->dwUsage);
if (lpnrLocal->dwUsage & RESOURCEUSAGE_CONNECTABLE)
printf("connectable ");
if (lpnrLocal->dwUsage & RESOURCEUSAGE_CONTAINER)
printf("container ");
if (lpnrLocal->dwUsage & RESOURCEUSAGE_NOLOCALDEVICE)
printf("no-local ");
if (lpnrLocal->dwUsage & RESOURCEUSAGE_SIBLING)
printf("sibling ");
if (lpnrLocal->dwUsage & RESOURCEUSAGE_ATTACHED)
printf("attached ");
if (lpnrLocal->dwUsage & RESOURCEUSAGE_RESERVED)
printf("reserved ");
printf("\n");
printf("NETRESOURCE[%d] Localname: %S\n", i, lpnrLocal->lpLocalName);
printf("NETRESOURCE[%d] Remotename: %S\n", i, lpnrLocal->lpRemoteName);
printf("NETRESOURCE[%d] Comment: %S\n", i, lpnrLocal->lpComment);
printf("NETRESOURCE[%d] Provider: %S\n", i, lpnrLocal->lpProvider);
printf("\n");
}
/*
BOOL WINAPI NetErrorHandler(HWND hwnd,
DWORD dwErrorCode,
LPSTR lpszFunction)
{
DWORD dwWNetResult, dwLastError;
CHAR szError[256];
CHAR szCaption[256];
CHAR szDescription[256];
CHAR szProvider[256];
// The following code performs standard error-handling.
if (dwErrorCode != ERROR_EXTENDED_ERROR)
{
sprintf_s((LPSTR) szError, sizeof(szError), "%s failed; \nResult is %ld",
lpszFunction, dwErrorCode);
sprintf_s((LPSTR) szCaption, sizeof(szCaption), "%s error", lpszFunction);
MessageBox(hwnd, (LPSTR) szError, (LPSTR) szCaption, MB_OK);
return TRUE;
}
// The following code performs error-handling when the
// ERROR_EXTENDED_ERROR return value indicates that the
// WNetGetLastError function can retrieve additional information.
else
{
dwWNetResult = WNetGetLastError(&dwLastError, // error code
(LPSTR) szDescription, // buffer for error description
sizeof(szDescription), // size of error buffer
(LPSTR) szProvider, // buffer for provider name
sizeof(szProvider)); // size of name buffer
//
// Process errors.
//
if(dwWNetResult != NO_ERROR) {
sprintf_s((LPSTR) szError, sizeof(szError),
"WNetGetLastError failed; error %ld", dwWNetResult);
MessageBox(hwnd, (LPSTR) szError,
"WNetGetLastError", MB_OK);
return FALSE;
}
//
// Otherwise, print the additional error information.
//
sprintf_((LPSTR) szError, sizeof(szError),
"%s failed with code %ld;\n%s",
(LPSTR) szProvider, dwLastError, (LPSTR) szDescription);
sprintf_s((LPSTR) szCaption, sizeof(szCaption), "%s error", lpszFunction);
MessageBox(hwnd, (LPSTR) szError, (LPSTR) szCaption, MB_OK);
return TRUE;
}
}
*/