fresh git tree for public release

we regretfully had to remove our git history for licensing reasons

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2010-10-11 14:59:26 -04:00
commit 0ad4db4fad
271 changed files with 71255 additions and 0 deletions

76
dll/dllmain.c Normal file
View file

@ -0,0 +1,76 @@
/* Copyright (c) 2010
* The Regents of the University of Michigan
* All Rights Reserved
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
*/
/*++
Copyright (c) 1989-1999 Microsoft Corporation
Module Name:
dllmain.c
Abstract:
This module implements the initialization routines for network
provider interface
Notes:
This module has been built and tested only in UNICODE environment
--*/
#include <windows.h>
#include <process.h>
// NOTE:
//
// Function:` DllMain
//
// Return: TRUE => Success
// FALSE => Failure
BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
{
BOOL bStatus = TRUE;
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
default:
break;
}
return(bStatus);
}

8
dll/makefile Normal file
View file

@ -0,0 +1,8 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def

900
dll/nfs41_np.c Normal file
View file

@ -0,0 +1,900 @@
/* Copyright (c) 2010
* The Regents of the University of Michigan
* All Rights Reserved
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
*/
#include <windows.h>
#include <npapi.h>
#include <devioctl.h>
#include <strsafe.h>
#include "nfs41_driver.h"
#include "nfs41_np.h"
#include "options.h"
#ifdef DBG
#define DbgP(_x_) NFS41DbgPrint _x_
#else
#define DbgP(_x_)
#endif
#define TRACE_TAG L"[NFS41_NP]"
#define WNNC_DRIVER( major, minor ) ( major * 0x00010000 + minor )
ULONG _cdecl NFS41DbgPrint( __in LPTSTR Format, ... )
{
ULONG rc = 0;
TCHAR szbuffer[256];
va_list marker;
va_start( marker, Format );
{
//StringCchVPrintfW( szbuffer, 127, Format, marker );
StringCchVPrintfW( szbuffer, 256, Format, marker );
szbuffer[255] = (TCHAR)0;
OutputDebugString( TRACE_TAG );
OutputDebugString( szbuffer );
}
return rc;
}
int filter(unsigned int code)
{
DbgP((L"####Got exception %u\n", code));
return EXCEPTION_CONTINUE_SEARCH;
}
DWORD
OpenSharedMemory(
PHANDLE phMutex,
PHANDLE phMemory,
PVOID *pMemory)
/*++
Routine Description:
This routine opens the shared memory for exclusive manipulation
Arguments:
phMutex - the mutex handle
phMemory - the memory handle
pMemory - a ptr. to the shared memory which is set if successful
Return Value:
WN_SUCCESS -- if successful
--*/
{
DWORD dwStatus;
*phMutex = 0;
*phMemory = 0;
*pMemory = NULL;
*phMutex = OpenMutex(SYNCHRONIZE,
FALSE,
TEXT(NFS41NP_MUTEX_NAME));
if (*phMutex == NULL)
{
dwStatus = GetLastError();
DbgP((TEXT("OpenSharedMemory: OpenMutex failed\n")));
goto OpenSharedMemoryAbort1;
}
WaitForSingleObject(*phMutex, INFINITE);
*phMemory = OpenFileMapping(FILE_MAP_WRITE,
FALSE,
TEXT(NFS41_USER_SHARED_MEMORY_NAME));
if (*phMemory == NULL)
{
dwStatus = GetLastError();
DbgP((TEXT("OpenSharedMemory: OpenFileMapping failed\n")));
goto OpenSharedMemoryAbort2;
}
*pMemory = MapViewOfFile(*phMemory, FILE_MAP_WRITE, 0, 0, 0);
if (*pMemory == NULL)
{
dwStatus = GetLastError();
DbgP((TEXT("OpenSharedMemory: MapViewOfFile failed\n")));
goto OpenSharedMemoryAbort3;
}
return ERROR_SUCCESS;
OpenSharedMemoryAbort3:
CloseHandle(*phMemory);
OpenSharedMemoryAbort2:
ReleaseMutex(*phMutex);
CloseHandle(*phMutex);
*phMutex = NULL;
OpenSharedMemoryAbort1:
DbgP((TEXT("OpenSharedMemory: return dwStatus: %d\n"), dwStatus));
return dwStatus;
}
VOID
CloseSharedMemory(
PHANDLE hMutex,
PHANDLE hMemory,
PVOID *pMemory)
/*++
Routine Description:
This routine relinquishes control of the shared memory after exclusive
manipulation
Arguments:
hMutex - the mutex handle
hMemory - the memory handle
pMemory - a ptr. to the shared memory which is set if successful
Return Value:
--*/
{
if (*pMemory)
{
UnmapViewOfFile(*pMemory);
*pMemory = NULL;
}
if (*hMemory)
{
CloseHandle(*hMemory);
*hMemory = 0;
}
if (*hMutex)
{
if (ReleaseMutex(*hMutex) == FALSE)
{
DbgP((TEXT("CloseSharedMemory: ReleaseMutex error: %d\n"), GetLastError()));
}
CloseHandle(*hMutex);
*hMutex = 0;
}
}
static DWORD StoreConnectionInfo(
IN LPCWSTR LocalName,
IN LPCWSTR ConnectionName,
IN USHORT ConnectionNameLength,
IN LPNETRESOURCE lpNetResource)
{
DWORD status;
HANDLE hMutex, hMemory;
PNFS41NP_SHARED_MEMORY pSharedMemory;
PNFS41NP_NETRESOURCE pNfs41NetResource;
INT Index;
BOOLEAN FreeEntryFound = FALSE;
status = OpenSharedMemory(&hMutex, &hMemory, &(PVOID)pSharedMemory);
if (status)
goto out;
DbgP((TEXT("StoreConnectionInfo: NextIndex %d, NumResources %d\n"),
pSharedMemory->NextAvailableIndex,
pSharedMemory->NumberOfResourcesInUse));
for (Index = 0; Index < pSharedMemory->NextAvailableIndex; Index++)
{
if (!pSharedMemory->NetResources[Index].InUse)
{
FreeEntryFound = TRUE;
DbgP((TEXT("Reusing existing index %d\n"), Index));
break;
}
}
if (!FreeEntryFound)
{
if (pSharedMemory->NextAvailableIndex >= NFS41NP_MAX_DEVICES) {
status = WN_NO_MORE_DEVICES;
goto out_close;
}
Index = pSharedMemory->NextAvailableIndex++;
DbgP((TEXT("Using new index %d\n"), Index));
}
pSharedMemory->NumberOfResourcesInUse += 1;
pNfs41NetResource = &pSharedMemory->NetResources[Index];
pNfs41NetResource->InUse = TRUE;
pNfs41NetResource->dwScope = lpNetResource->dwScope;
pNfs41NetResource->dwType = lpNetResource->dwType;
pNfs41NetResource->dwDisplayType = lpNetResource->dwDisplayType;
pNfs41NetResource->dwUsage = RESOURCEUSAGE_CONNECTABLE;
pNfs41NetResource->LocalNameLength = (USHORT)(wcslen(LocalName) + 1) * sizeof(WCHAR);
pNfs41NetResource->RemoteNameLength = (USHORT)(wcslen(lpNetResource->lpRemoteName) + 1) * sizeof(WCHAR);
pNfs41NetResource->ConnectionNameLength = ConnectionNameLength;
StringCchCopy(pNfs41NetResource->LocalName,
pNfs41NetResource->LocalNameLength,
LocalName);
StringCchCopy(pNfs41NetResource->RemoteName,
pNfs41NetResource->RemoteNameLength,
lpNetResource->lpRemoteName);
StringCchCopy(pNfs41NetResource->ConnectionName,
pNfs41NetResource->ConnectionNameLength,
ConnectionName);
// TODO: copy mount options -cbodley
out_close:
CloseSharedMemory(&hMutex, &hMemory, &(PVOID)pSharedMemory);
out:
return status;
}
ULONG
SendTo_NFS41Driver(
IN ULONG IoctlCode,
IN PVOID InputDataBuf,
IN ULONG InputDataLen,
IN PVOID OutputDataBuf,
IN PULONG pOutputDataLen)
{
HANDLE DeviceHandle; // The mini rdr device handle
BOOL rc = FALSE;
ULONG Status;
Status = WN_SUCCESS;
DbgP((L"[aglo] calling CreateFile\n"));
DeviceHandle = CreateFile(
NFS41_USER_DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0,
(HANDLE) NULL );
DbgP((L"[aglo] after CreateFile Device Handle\n"));
if ( INVALID_HANDLE_VALUE != DeviceHandle )
{
__try {
DbgP((L"[aglo] calling DeviceIoControl\n"));
rc = DeviceIoControl(
DeviceHandle,
IoctlCode,
InputDataBuf,
InputDataLen,
OutputDataBuf,
*pOutputDataLen,
pOutputDataLen,
NULL );
} __except(filter(GetExceptionCode())) {
DbgP((L"#### In except\n"));
}
DbgP((L"[aglo] returned from DeviceIoControl %08lx\n", rc));
if ( !rc )
{
DbgP((L"[aglo] SendTo_NFS41Driver: returning error from DeviceIoctl\n"));
Status = GetLastError( );
}
else
{
DbgP((L"[aglo] SendTo_NFS41Driver: The DeviceIoctl call succeded\n"));
}
CloseHandle(DeviceHandle);
}
else
{
Status = GetLastError( );
DbgP((L"[aglo] SendTo_NFS41Driver: error %08lx opening device \n", Status));
}
DbgP((L"[aglo] returned from SendTo_NFS41Driver %08lx\n", Status));
return Status;
}
DWORD APIENTRY
NPGetCaps(
DWORD nIndex )
{
DWORD rc = 0;
DbgP(( L"[aglo] GetNetCaps %d\n", nIndex ));
switch ( nIndex )
{
case WNNC_SPEC_VERSION:
rc = WNNC_SPEC_VERSION51;
break;
case WNNC_NET_TYPE:
rc = WNNC_NET_RDR2SAMPLE;
break;
case WNNC_DRIVER_VERSION:
rc = WNNC_DRIVER(1, 0);
break;
case WNNC_CONNECTION:
rc = WNNC_CON_GETCONNECTIONS |
WNNC_CON_CANCELCONNECTION |
WNNC_CON_ADDCONNECTION |
WNNC_CON_ADDCONNECTION3;
break;
case WNNC_ENUMERATION:
rc = WNNC_ENUM_LOCAL;
break;
case WNNC_START:
rc = 1;
break;
case WNNC_USER:
case WNNC_DIALOG:
case WNNC_ADMIN:
default:
rc = 0;
break;
}
return rc;
}
DWORD APIENTRY
NPLogonNotify(
__in PLUID lpLogonId,
__in PCWSTR lpAuthentInfoType,
__in PVOID lpAuthentInfo,
__in PCWSTR lpPreviousAuthentInfoType,
__in PVOID lpPreviousAuthentInfo,
__in PWSTR lpStationName,
__in PVOID StationHandle,
__out PWSTR *lpLogonScript)
{
*lpLogonScript = NULL;
DbgP(( L"[aglo] NPLogonNotify: returning WN_SUCCESS\n" ));
return WN_SUCCESS;
}
DWORD APIENTRY
NPPasswordChangeNotify (
__in LPCWSTR lpAuthentInfoType,
__in LPVOID lpAuthentInfo,
__in LPCWSTR lpPreviousAuthentInfoType,
__in LPVOID lpPreviousAuthentInfo,
__in LPWSTR lpStationName,
LPVOID StationHandle,
DWORD dwChangeInfo )
{
DbgP(( L"[aglo] NPPasswordChangeNotify: WN_NOT_SUPPORTED\n" ));
SetLastError( WN_NOT_SUPPORTED );
return WN_NOT_SUPPORTED;
}
DWORD APIENTRY
NPAddConnection(
__in LPNETRESOURCE lpNetResource,
__in_opt LPWSTR lpPassword,
__in_opt LPWSTR lpUserName )
{
return NPAddConnection3( NULL, lpNetResource, lpPassword, lpUserName, 0 );
}
DWORD APIENTRY
NPAddConnection3(
__in HWND hwndOwner,
__in LPNETRESOURCE lpNetResource,
__in_opt LPWSTR lpPassword,
__in_opt LPWSTR lpUserName,
__in DWORD dwFlags)
{
DWORD Status;
WCHAR wszScratch[128];
WCHAR LocalName[3];
DWORD CopyBytes = 0;
CONNECTION_INFO Connection;
LPWSTR ConnectionName;
WCHAR ServerName[MAX_PATH];
PWCHAR p;
DWORD i;
DbgP(( L"[aglo] NPAddConnection3('%s', '%s')\n",
lpNetResource->lpLocalName, lpNetResource->lpRemoteName ));
Status = InitializeConnectionInfo(&Connection,
(PMOUNT_OPTION_BUFFER)lpNetResource->lpComment,
&ConnectionName);
if (Status) {
DbgP(( L"InitializeConnectionInfo failed with %d\n", Status ));
goto out;
}
// \device\miniredirector\;<DriveLetter>:\Server\Share
// local name, must start with "X:"
if (lstrlen(lpNetResource->lpLocalName) < 2 ||
lpNetResource->lpLocalName[1] != L':') {
Status = WN_BAD_LOCALNAME;
goto out;
}
LocalName[0] = (WCHAR) toupper(lpNetResource->lpLocalName[0]);
LocalName[1] = L':';
LocalName[2] = L'\0';
StringCchCopyW( ConnectionName, MAX_PATH, NFS41_DEVICE_NAME );
StringCchCatW( ConnectionName, MAX_PATH, L"\\;" );
StringCchCatW( ConnectionName, MAX_PATH, LocalName );
// remote name, must start with "\\"
if (lpNetResource->lpRemoteName[0] == L'\0' ||
lpNetResource->lpRemoteName[0] != L'\\' ||
lpNetResource->lpRemoteName[1] != L'\\') {
Status = WN_BAD_NETNAME;
goto out;
}
/* note: remotename comes as \\server but we need to add \server thus +1 pointer */
p = lpNetResource->lpRemoteName + 1;
ServerName[0] = L'\\';
i = 1;
for(;;) {
/* convert servername ending unix slash to windows slash */
if (p[i] == L'/')
p[i] = L'\\';
/* deal with servername ending with any slash */
if (p[i] == L'\0')
p[i] = L'\\';
ServerName[i] = p[i];
if (p[i] == L'\\') break;
i++;
}
ServerName[i] = L'\0';
StringCchCatW( ConnectionName, MAX_PATH, ServerName);
/* insert the "nfs4" in between the server name and the path,
* just to make sure all calls to our driver come thru this */
StringCchCatW( ConnectionName, MAX_PATH, L"\\nfs4" );
#ifdef CONVERT_2_UNIX_SLASHES
/* convert all windows slashes to unix slashes */
{
PWCHAR q = p;
DWORD j = 0;
for(;;) {
if(q[j] == L'\0') break;
if (q[j] == L'\\') q[j] = L'/';
j++;
}
}
#else
/* convert all unix slashes to windows slashes */
{
PWCHAR q = p;
DWORD j = 0;
for(;;) {
if(q[j] == L'\0') break;
if (q[j] == L'/') q[j] = L'\\';
j++;
}
}
#endif
StringCchCatW( ConnectionName, MAX_PATH, &p[i]);
DbgP(( L"[aglo] Full Connect Name: %s\n", ConnectionName ));
DbgP(( L"[aglo] Full Connect Name Length: %d %d\n",
(wcslen(ConnectionName) + 1) * sizeof(WCHAR),
(lstrlen(ConnectionName) + 1) * sizeof(WCHAR)));
if ( QueryDosDevice( LocalName, wszScratch, 128 )
|| GetLastError() != ERROR_FILE_NOT_FOUND) {
Status = WN_ALREADY_CONNECTED;
goto out;
}
MarshalConnectionInfo(&Connection);
Status = SendTo_NFS41Driver( IOCTL_NFS41_ADDCONN,
Connection.Buffer, Connection.BufferSize,
NULL, &CopyBytes );
if (Status) {
DbgP(( L"[aglo] SendTo_NFS41Driver failed with %d\n", Status));
Status = WN_BAD_NETNAME;
goto out;
}
DbgP(( L"[aglo] calling DefineDosDevice\n"));
if ( !DefineDosDevice( DDD_RAW_TARGET_PATH |
DDD_NO_BROADCAST_SYSTEM,
lpNetResource->lpLocalName,
ConnectionName ) ) {
Status = GetLastError();
DbgP(( L"[aglo] DefineDosDevice failed with %d\n", Status));
goto out_delconn;
}
// The connection was established and the local device mapping
// added. Include this in the list of mapped devices.
Status = StoreConnectionInfo(LocalName, ConnectionName,
Connection.Buffer->NameLength, lpNetResource);
if (Status) {
DbgP(( L"[aglo] StoreConnectionInfo failed with %d\n", Status));
goto out_undefine;
}
out:
FreeConnectionInfo(&Connection);
DbgP(( L"[aglo] NPAddConnection3: status %08X\n", Status));
return Status;
out_undefine:
DefineDosDevice(DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH |
DDD_EXACT_MATCH_ON_REMOVE, LocalName, ConnectionName);
out_delconn:
SendTo_NFS41Driver(IOCTL_NFS41_DELCONN, ConnectionName,
Connection.Buffer->NameLength, NULL, &CopyBytes);
goto out;
}
DWORD APIENTRY
NPCancelConnection(
__in LPWSTR lpName,
__in BOOL fForce )
{
DWORD Status = 0;
HANDLE hMutex, hMemory;
PNFS41NP_SHARED_MEMORY pSharedMemory;
DbgP((TEXT("NPCancelConnection\n")));
DbgP((TEXT("NPCancelConnection: ConnectionName: %S\n"), lpName));
Status = OpenSharedMemory( &hMutex,
&hMemory,
(PVOID)&pSharedMemory);
if (Status == WN_SUCCESS)
{
INT Index;
PNFS41NP_NETRESOURCE pNetResource;
Status = WN_NOT_CONNECTED;
DbgP((TEXT("NPCancelConnection: NextIndex %d, NumResources %d\n"),
pSharedMemory->NextAvailableIndex,
pSharedMemory->NumberOfResourcesInUse));
for (Index = 0; Index < pSharedMemory->NextAvailableIndex; Index++)
{
pNetResource = &pSharedMemory->NetResources[Index];
if (pNetResource->InUse)
{
if ( ( (wcslen(lpName) + 1) * sizeof(WCHAR) ==
pNetResource->LocalNameLength)
&& ( !wcscmp(lpName, pNetResource->LocalName) ))
{
ULONG CopyBytes;
DbgP((TEXT("NPCancelConnection: Connection Found:\n")));
CopyBytes = 0;
Status = SendTo_NFS41Driver( IOCTL_NFS41_DELCONN,
pNetResource->ConnectionName,
pNetResource->ConnectionNameLength,
NULL,
&CopyBytes );
if (Status != WN_SUCCESS)
{
DbgP((TEXT("NPCancelConnection: SendToMiniRdr returned Status %lx\n"),Status));
break;
}
if (DefineDosDevice(DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE,
lpName,
pNetResource->ConnectionName) == FALSE)
{
DbgP((TEXT("RemoveDosDevice: DefineDosDevice error: %d\n"), GetLastError()));
Status = GetLastError();
}
else
{
pNetResource->InUse = FALSE;
pSharedMemory->NumberOfResourcesInUse--;
if (Index+1 == pSharedMemory->NextAvailableIndex)
pSharedMemory->NextAvailableIndex--;
}
break;
}
DbgP((TEXT("NPCancelConnection: Name %S EntryName %S\n"),
lpName,pNetResource->LocalName));
DbgP((TEXT("NPCancelConnection: Name Length %d Entry Name Length %d\n"),
pNetResource->LocalNameLength,pNetResource->LocalName));
}
}
CloseSharedMemory( &hMutex,
&hMemory,
(PVOID)&pSharedMemory);
}
return Status;
}
DWORD APIENTRY
NPGetConnection(
__in LPWSTR lpLocalName,
__out_bcount(*lpBufferSize) LPWSTR lpRemoteName,
__inout LPDWORD lpBufferSize )
{
DWORD Status = 0;
HANDLE hMutex, hMemory;
PNFS41NP_SHARED_MEMORY pSharedMemory;
Status = OpenSharedMemory( &hMutex,
&hMemory,
(PVOID)&pSharedMemory);
if (Status == WN_SUCCESS)
{
INT Index;
PNFS41NP_NETRESOURCE pNetResource;
Status = WN_NOT_CONNECTED;
for (Index = 0; Index < pSharedMemory->NextAvailableIndex; Index++)
{
pNetResource = &pSharedMemory->NetResources[Index];
if (pNetResource->InUse)
{
if ( ( (wcslen(lpLocalName) + 1) * sizeof(WCHAR) ==
pNetResource->LocalNameLength)
&& ( !wcscmp(lpLocalName, pNetResource->LocalName) ))
{
if (*lpBufferSize < pNetResource->RemoteNameLength)
{
*lpBufferSize = pNetResource->RemoteNameLength;
Status = WN_MORE_DATA;
}
else
{
*lpBufferSize = pNetResource->RemoteNameLength;
CopyMemory( lpRemoteName,
pNetResource->RemoteName,
pNetResource->RemoteNameLength);
Status = WN_SUCCESS;
}
break;
}
}
}
CloseSharedMemory( &hMutex, &hMemory, (PVOID)&pSharedMemory);
}
return Status;
}
DWORD APIENTRY
NPOpenEnum(
DWORD dwScope,
DWORD dwType,
DWORD dwUsage,
LPNETRESOURCE lpNetResource,
LPHANDLE lphEnum )
{
DWORD Status;
DbgP((L"[aglo] NPOpenEnum\n"));
*lphEnum = NULL;
switch ( dwScope )
{
case RESOURCE_CONNECTED:
{
*lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( ULONG ) );
if (*lphEnum )
{
Status = WN_SUCCESS;
}
else
{
Status = WN_OUT_OF_MEMORY;
}
break;
}
break;
case RESOURCE_CONTEXT:
default:
Status = WN_NOT_SUPPORTED;
break;
}
DbgP((L"[aglo] NPOpenEnum returning Status %lx\n",Status));
return(Status);
}
DWORD APIENTRY
NPEnumResource(
HANDLE hEnum,
LPDWORD lpcCount,
LPVOID lpBuffer,
LPDWORD lpBufferSize)
{
DWORD Status = WN_SUCCESS;
ULONG EntriesCopied;
LPNETRESOURCE pNetResource;
ULONG SpaceNeeded = 0;
ULONG SpaceAvailable;
PWCHAR StringZone;
HANDLE hMutex, hMemory;
PNFS41NP_SHARED_MEMORY pSharedMemory;
PNFS41NP_NETRESOURCE pNfsNetResource;
INT Index = *(PULONG)hEnum;
DbgP((L"[aglo] NPEnumResource\n"));
DbgP((L"[aglo] NPEnumResource Count Requested %d\n", *lpcCount));
pNetResource = (LPNETRESOURCE) lpBuffer;
SpaceAvailable = *lpBufferSize;
EntriesCopied = 0;
StringZone = (PWCHAR) ((PBYTE)lpBuffer + *lpBufferSize);
Status = OpenSharedMemory( &hMutex,
&hMemory,
(PVOID)&pSharedMemory);
if ( Status == WN_SUCCESS)
{
Status = WN_NO_MORE_ENTRIES;
for (Index = *(PULONG)hEnum; Index < pSharedMemory->NextAvailableIndex; Index++)
{
pNfsNetResource = &pSharedMemory->NetResources[Index];
if (pNfsNetResource->InUse)
{
SpaceNeeded = sizeof( NETRESOURCE );
SpaceNeeded += pNfsNetResource->LocalNameLength;
SpaceNeeded += pNfsNetResource->RemoteNameLength;
SpaceNeeded += 5 * sizeof(WCHAR); // comment
SpaceNeeded += sizeof(NFS41_PROVIDER_NAME_U); // provider name
if ( SpaceNeeded > SpaceAvailable )
{
Status = WN_MORE_DATA;
DbgP((L"[aglo] NPEnumResource More Data Needed - %d\n", SpaceNeeded));
*lpBufferSize = SpaceNeeded;
break;
}
else
{
SpaceAvailable -= SpaceNeeded;
pNetResource->dwScope = pNfsNetResource->dwScope;
pNetResource->dwType = pNfsNetResource->dwType;
pNetResource->dwDisplayType = pNfsNetResource->dwDisplayType;
pNetResource->dwUsage = pNfsNetResource->dwUsage;
// setup string area at opposite end of buffer
SpaceNeeded -= sizeof( NETRESOURCE );
StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded );
// copy local name
StringCchCopy( StringZone,
pNfsNetResource->LocalNameLength,
pNfsNetResource->LocalName );
pNetResource->lpLocalName = StringZone;
StringZone += pNfsNetResource->LocalNameLength/sizeof(WCHAR);
// copy remote name
StringCchCopy( StringZone,
pNfsNetResource->RemoteNameLength,
pNfsNetResource->RemoteName );
pNetResource->lpRemoteName = StringZone;
StringZone += pNfsNetResource->RemoteNameLength/sizeof(WCHAR);
// copy comment
pNetResource->lpComment = StringZone;
*StringZone++ = L'A';
*StringZone++ = L'_';
*StringZone++ = L'O';
*StringZone++ = L'K';
*StringZone++ = L'\0';
// copy provider name
pNetResource->lpProvider = StringZone;
StringCbCopyW( StringZone, sizeof(NFS41_PROVIDER_NAME_U), NFS41_PROVIDER_NAME_U );
StringZone += sizeof(NFS41_PROVIDER_NAME_U)/sizeof(WCHAR);
EntriesCopied++;
if(EntriesCopied >= *lpcCount)
{
Status = WN_SUCCESS;
break;
}
// set new bottom of string zone
StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded );
}
pNetResource++;
}
}
CloseSharedMemory( &hMutex, &hMemory, (PVOID*)&pSharedMemory);
}
*lpcCount = EntriesCopied;
*(PULONG) hEnum = Index;
DbgP((L"[aglo] NPEnumResource entries returned: %d\n", EntriesCopied));
return Status;
}
DWORD APIENTRY
NPCloseEnum(
HANDLE hEnum )
{
DbgP((L"[aglo] NPCloseEnum\n"));
HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum );
return WN_SUCCESS;
}
DWORD APIENTRY
NPGetResourceParent(
LPNETRESOURCE lpNetResource,
LPVOID lpBuffer,
LPDWORD lpBufferSize )
{
DbgP(( L"[aglo] NPGetResourceParent: WN_NOT_SUPPORTED\n" ));
return WN_NOT_SUPPORTED;
}
DWORD APIENTRY
NPGetResourceInformation(
__in LPNETRESOURCE lpNetResource,
__out_bcount(*lpBufferSize) LPVOID lpBuffer,
__inout LPDWORD lpBufferSize,
__deref_out LPWSTR *lplpSystem )
{
DbgP(( L"[aglo] NPGetResourceInformation: WN_NOT_SUPPORTED\n" ));
return WN_NOT_SUPPORTED;
}
DWORD APIENTRY
NPGetUniversalName(
LPCWSTR lpLocalPath,
DWORD dwInfoLevel,
LPVOID lpBuffer,
LPDWORD lpBufferSize )
{
DbgP(( L"[aglo] NPGetUniversalName: WN_NOT_SUPPORTED\n" ));
return WN_NOT_SUPPORTED;
}

17
dll/nfs41_np.def Normal file
View file

@ -0,0 +1,17 @@
SECTIONS .NFS41_NP READ WRITE SHARED
EXPORTS
NPGetCaps @13
NPAddConnection @17
NPAddConnection3 @38
NPCancelConnection @18
NPGetConnection @12
NPOpenEnum @33
NPEnumResource @34
NPCloseEnum @35
NPGetUniversalName @40
NPGetResourceParent @41
NPGetResourceInformation @52
NPLogonNotify @500
NPPasswordChangeNotify @501

52
dll/nfs41_np.h Normal file
View file

@ -0,0 +1,52 @@
/* Copyright (c) 2010
* The Regents of the University of Michigan
* All Rights Reserved
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
*/
#ifndef __NFS41_NP_H__
#define __NFS41_NP_H__
#define NFS41NP_MUTEX_NAME "NFS41NPMUTEX"
#define NFS41NP_MAX_DEVICES 26
typedef struct __NFS41NP_NETRESOURCE {
BOOL InUse;
USHORT LocalNameLength;
USHORT RemoteNameLength;
USHORT ConnectionNameLength;
DWORD dwScope;
DWORD dwType;
DWORD dwDisplayType;
DWORD dwUsage;
WCHAR LocalName[MAX_PATH];
WCHAR RemoteName[MAX_PATH];
WCHAR ConnectionName[MAX_PATH];
WCHAR Options[MAX_PATH];
} NFS41NP_NETRESOURCE, *PNFS41NP_NETRESOURCE;
typedef struct __NFS41NP_SHARED_MEMORY {
INT NextAvailableIndex;
INT NumberOfResourcesInUse;
NFS41NP_NETRESOURCE NetResources[NFS41NP_MAX_DEVICES];
} NFS41NP_SHARED_MEMORY, *PNFS41NP_SHARED_MEMORY;
#endif /* !__NFS41_NP_H__ */

100
dll/options.c Normal file
View file

@ -0,0 +1,100 @@
/* Copyright (c) 2010
* The Regents of the University of Michigan
* All Rights Reserved
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
*/
#include <Windows.h>
#include "options.h"
DWORD InitializeConnectionInfo(
IN OUT PCONNECTION_INFO Connection,
IN PMOUNT_OPTION_BUFFER Options,
OUT LPWSTR *ConnectionName)
{
DWORD result = WN_SUCCESS;
SIZE_T size;
/* verify that this is a mount options buffer */
if (Options &&
Options->Zero == 0 &&
Options->Secret == MOUNT_OPTION_BUFFER_SECRET)
{
Connection->Options = Options;
size = MAX_CONNECTION_BUFFER_SIZE(Options->Length);
}
else
{
Connection->Options = NULL;
size = MAX_CONNECTION_BUFFER_SIZE(0);
}
Connection->Buffer = LocalAlloc(LMEM_ZEROINIT, size);
if (Connection->Buffer)
*ConnectionName = (LPWSTR)Connection->Buffer->Buffer;
else
result = WN_OUT_OF_MEMORY;
return result;
}
static FORCEINLINE SIZE_T ConnectionBufferSize(
IN PCONNECTION_BUFFER Buffer)
{
return sizeof(USHORT) + sizeof(USHORT) + sizeof(ULONG) +
Buffer->NameLength + Buffer->EaPadding + Buffer->EaLength;
}
void MarshalConnectionInfo(
IN OUT PCONNECTION_INFO Connection)
{
PCONNECTION_BUFFER Buffer = Connection->Buffer;
LPWSTR ConnectionName = (LPWSTR)Buffer->Buffer;
Buffer->NameLength = (USHORT)(wcslen(ConnectionName) + 1) * sizeof(WCHAR);
/* copy the EaBuffer after the end of ConnectionName */
if (Connection->Options && Connection->Options->Length)
{
PBYTE ptr = Buffer->Buffer + Buffer->NameLength;
/* add padding so EaBuffer starts on a ULONG boundary */
Buffer->EaPadding = (USHORT)
(sizeof(ULONG) - (SIZE_T)ptr % sizeof(ULONG)) % sizeof(ULONG);
Buffer->EaLength = Connection->Options->Length;
ptr += Buffer->EaPadding;
RtlCopyMemory(ptr, Connection->Options->Buffer, Buffer->EaLength);
}
Connection->BufferSize = (ULONG)ConnectionBufferSize(Buffer);
}
void FreeConnectionInfo(
IN PCONNECTION_INFO Connection)
{
if (Connection->Buffer)
{
LocalFree(Connection->Buffer);
Connection->Buffer = NULL;
}
Connection->Options = NULL;
Connection->BufferSize = 0;
}

84
dll/options.h Normal file
View file

@ -0,0 +1,84 @@
/* Copyright (c) 2010
* The Regents of the University of Michigan
* All Rights Reserved
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
*/
#ifndef __NFS41_NP_OPTIONS_H__
#define __NFS41_NP_OPTIONS_H__
#define MOUNT_OPTION_BUFFER_SECRET ('n4')
/* MOUNT_OPTION_BUFFER
* The mount options buffer received by NPAddConnection3
* via NETRESOURCE.lpComment. To avoid interpreting a normal
* comment string as mount options, a NULL and secret number
* are expected at the front. */
typedef struct _MOUNT_OPTION_BUFFER {
USHORT Zero; /* = 0 */
USHORT Secret; /* = 'n4' */
ULONG Length;
BYTE Buffer[1];
} MOUNT_OPTION_BUFFER, *PMOUNT_OPTION_BUFFER;
/* CONNECTION_BUFFER
* The connection information as sent to the driver via
* IOCTL_NFS41_ADDCONN. The buffer contains the connection name
* followed by any extended attributes for mount options. */
typedef struct _CONNECTION_BUFFER {
USHORT NameLength; /* length of connection filename */
USHORT EaPadding; /* 0-3 bytes of padding to put EaBuffer
* on a ULONG boundary */
ULONG EaLength; /* length of EaBuffer */
BYTE Buffer[1];
} CONNECTION_BUFFER, *PCONNECTION_BUFFER;
/* CONNECTION_INFO
* Used in NPAddConnection3 to encapsulate the formation of
* the connection buffer. */
typedef struct _CONNECTION_INFO {
PMOUNT_OPTION_BUFFER Options;
ULONG BufferSize;
PCONNECTION_BUFFER Buffer;
} CONNECTION_INFO, *PCONNECTION_INFO;
#define MAX_CONNECTION_BUFFER_SIZE(EaSize) ( \
sizeof(CONNECTION_BUFFER) + MAX_PATH + (EaSize) )
/* options.c */
DWORD InitializeConnectionInfo(
IN OUT PCONNECTION_INFO Connection,
IN PMOUNT_OPTION_BUFFER Options,
OUT LPWSTR *ConnectionName);
void FreeConnectionInfo(
IN OUT PCONNECTION_INFO Connection);
/* MarshallConnectionInfo
* Prepares the CONNECTION_BUFFER for transmission to the driver
* by copying the extended attributes into place and updating the
* lengths accordingly. */
void MarshalConnectionInfo(
IN OUT PCONNECTION_INFO Connection);
#endif /* !__NFS41_NP_OPTIONS_H__ */

21
dll/sources Normal file
View file

@ -0,0 +1,21 @@
TARGETTYPE=DYNLINK
TARGETNAME=nfs41_np
SOURCES=dllmain.c nfs41_np.c options.c
UMTYPE=console
UNICODE=1
DLLBASE=0x1010000
USE_NTDLL=1
NET_C_DEFINES=-DUNICODE
INCLUDES=..\sys; \
$(DDK_INC_PATH);
TARGETLIBS=$(DDK_LIB_PATH)\user32.lib $(DDK_LIB_PATH)\kernel32.lib
DLLDEF=nfs41_np.def
!IF 0
/W3 is default level
bump to /Wall, but suppress warnings generated by system includes,
as well as the following warnings:
4100 - unused function call arguments (we have lots of stubs)
4127 - constant conditional (I like to use if(0) or if(1))
!ENDIF
MSC_WARNING_LEVEL=/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 /wd4711