|
|
/********************************************************************/ /** Copyright(c) 1989 Microsoft Corporation. **/ /********************************************************************/
//***
//
// Filename: util.c
//
// Description: This module contains misc. utility routines.
//
// History: May 11,1992. NarenG Created original version.
//
#include <nt.h>
#include <ntioapi.h>
#include <ntrtl.h>
#include <ntobapi.h>
#include <nturtl.h> // needed for winbase.h
#include <afpsvcp.h>
#define PRIVILEGE_BUF_SIZE 512
//**
//
// Call: AfpFSDOpen
//
// Returns: 0 - success
// non-zero returns mapped to WIN32 errors.
//
// Description: Opens the AFP file system driver. It is opened in exclusive
// mode.
// NTOpenFile is used instead of it's WIN32 counterpart, since
// WIN32 always prpends \Dos\devices to the file name. The AFP FSD
// driver is not a dos device.
//
DWORD AfpFSDOpen( OUT PHANDLE phFSD ) { NTSTATUS ntRetCode; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING FSDName; IO_STATUS_BLOCK IoStatus;
RtlInitUnicodeString( &FSDName, AFPSERVER_DEVICE_NAME );
InitializeObjectAttributes( &ObjectAttributes, &FSDName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ntRetCode = NtOpenFile(phFSD, SYNCHRONIZE, &ObjectAttributes, &IoStatus, #ifdef DBG
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, #else
0, #endif
FILE_SYNCHRONOUS_IO_NONALERT );
if ( NT_SUCCESS( ntRetCode ) ) return( NO_ERROR ); else return( RtlNtStatusToDosError( ntRetCode ) ); }
//**
//
// Call: AfpFSDClose
//
// Returns: 0 - success
// non-zero returns mapped to WIN32 errors.
//
// Description: Closes and the AFP file system driver.
//
DWORD AfpFSDClose( IN HANDLE hFSD ) { NTSTATUS ntStatus;
ntStatus = NtClose( hFSD );
if ( !NT_SUCCESS( ntStatus ) ) return( RtlNtStatusToDosError( ntStatus ) );
return( NO_ERROR ); }
//**
//
// Call: AfpFSDUnload
//
// Returns: 0 - success
// non-zero returns mapped to WIN32 errors.
//
// Description: Unloads the AFP file system driver.
//
DWORD AfpFSDUnload( VOID ) { NTSTATUS status; LPWSTR registryPathBuffer; UNICODE_STRING registryPath;
registryPathBuffer = (LPWSTR)MIDL_user_allocate( sizeof(AFPSERVER_REGISTRY_KEY) );
if ( registryPathBuffer == NULL ) return ERROR_NOT_ENOUGH_MEMORY;
wcscpy( registryPathBuffer, AFPSERVER_REGISTRY_KEY );
RtlInitUnicodeString( ®istryPath, registryPathBuffer );
// Wait here for all the server helper threads to terminate
if (AfpGlobals.nThreadCount > 0) WaitForSingleObject( AfpGlobals.heventSrvrHlprThreadTerminate, INFINITE );
status = NtUnloadDriver( ®istryPath );
MIDL_user_free( registryPathBuffer );
return( RtlNtStatusToDosError( status )); }
//**
//
// Call: AfpFSDLoad
//
// Returns: 0 - success
// non-zero returns mapped to WIN32 errors.
//
// Description: Loads the AFP file system driver.
//
DWORD AfpFSDLoad( VOID ) { NTSTATUS status; LPWSTR registryPathBuffer; UNICODE_STRING registryPath; BOOLEAN fEnabled;
registryPathBuffer = (LPWSTR)MIDL_user_allocate( sizeof(AFPSERVER_REGISTRY_KEY) );
if ( registryPathBuffer == NULL ) return ERROR_NOT_ENOUGH_MEMORY;
status = RtlAdjustPrivilege( SE_LOAD_DRIVER_PRIVILEGE, TRUE, FALSE, &fEnabled );
if ( !NT_SUCCESS( status ) ) { MIDL_user_free( registryPathBuffer ); return( RtlNtStatusToDosError( status )); }
wcscpy( registryPathBuffer, AFPSERVER_REGISTRY_KEY );
RtlInitUnicodeString( ®istryPath, registryPathBuffer );
status = NtLoadDriver( ®istryPath );
MIDL_user_free( registryPathBuffer );
if ( status == STATUS_IMAGE_ALREADY_LOADED ) status = STATUS_SUCCESS;
return( RtlNtStatusToDosError( status )); }
//**
//
// Call: AfpFSDIOControl
//
// Returns: 0 - success
// AFPERR - Macintosh specific errors.
// non-zero returns mapped to WIN32 errors.
//
//
// Description: Will ioctl the AFP FSD.
// NtDeviceIoControlFile api is used to communicate with the FSD
// instead of it's WIN32 counterpart because the WIN32 version
// maps all return codes to WIN32 error codes. This runs into
// problems when AFPERR_XXX error codes are returned.
//
DWORD AfpFSDIOControl( IN HANDLE hFSD, IN DWORD dwOpCode, IN PVOID pInbuf OPTIONAL, IN DWORD cbInbufLen, OUT PVOID pOutbuf OPTIONAL, IN DWORD cbOutbufLen, OUT LPDWORD lpcbBytesTransferred ) { NTSTATUS ntRetCode; IO_STATUS_BLOCK IOStatus;
ntRetCode = NtDeviceIoControlFile( hFSD, NULL, NULL, NULL, &IOStatus, dwOpCode, pInbuf, cbInbufLen, pOutbuf, cbOutbufLen );
*lpcbBytesTransferred = (DWORD)(IOStatus.Information);
if ( ntRetCode ) {
// If it is not an AFPERR_* then map it
//
if ( ( ntRetCode < AFPERR_BASE ) && ( ntRetCode >= AFPERR_MIN ) ) return( ntRetCode ); else return( RtlNtStatusToDosError( ntRetCode ) ); } else return( NO_ERROR ); }
//**
//
// Call:
//
// Returns:
//
// Description:
//
DWORD AfpCreateServerHelperThread( BOOL fIsFirstThread ) { DWORD dwId;
if ( CreateThread( NULL, 0, AfpServerHelper, (LPVOID)((ULONG_PTR)fIsFirstThread), 0, &dwId ) == NULL ) return( GetLastError() ); else return( NO_ERROR ); }
//**
//
// Call:
//
// Returns:
//
// Description:
//
VOID AfpTerminateCurrentThread( VOID ) { TerminateThread( GetCurrentThread(), NO_ERROR ); }
|