/********************************************************************/
/**               Copyright(c) 1989 Microsoft Corporation.	   **/
/********************************************************************/

//***
//
// Filename: 	afpsvcp.h
//
// Description: This is the main header file for the AFP Server Service.
//
// History:
//		May 11,1992.	NarenG		Created original version.
//
#ifndef _AFPSVCP_
#define _AFPSVCP_

#include <nt.h>
#include <ntrtl.h>
#include <ntseapi.h>
#include <ntlsa.h>
#include <ntsam.h>
#include <ntsamp.h>
#include <nturtl.h>     // needed for winbase.h
#include <ntmsv1_0.h>
#include <samrpc.h>
#include <align.h>

#include <windows.h>	// Win32 base API's
#include <winuser.h>	// Needed for LoadString
#include <winsvc.h>	// Win32 service control stuff
#include <winreg.h>	// Win32 registry API's
#include <lm.h>
#include <srvann.h>
#include <rpc.h>	// RPC api's
#include <devioctl.h>	// FILE_DEVICE_NETWORK, METHOD_BUFFERD constants
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <wchar.h>
#include <search.h>

#if DBG
#define DEBUG	TRUE
#endif

#include <afpsvc.h>	// Generated by MIDL
#include <admin.h>
#include <macfile.h>
#include <afpcomn.h>
#include "events.h"
#include "ioctl.h"
#include "rasfmsub.h"
#include "debug.h"


#define LOGON_PROCESS_NAME  "SFM_SERVICE"

#define AFPSTATE_RPC_STARTED		0x1
#define AFPSTATE_FSD_LOADED		    0x2
#define AFPSTATE_BLOCKED_ON_DOMINFO 0x4

// Id's of the various data structures
//
typedef enum _AFP_STRUCTURE_TYPE {

    AFP_EXTENSION_STRUCT,
    AFP_TYPECREATOR_STRUCT,
    AFP_ICON_STRUCT,
    AFP_VOLUME_STRUCT,
    AFP_SERVER_STRUCT,
    AFP_DIRECTORY_STRUCT,
    AFP_SESSION_STRUCT,
    AFP_CONNECTION_STRUCT,
    AFP_MESSAGE_STRUCT,
    AFP_FILE_STRUCT,
    AFP_FINDER_STRUCT

} AFP_STRUCTURE_TYPE;

// The approximate times (in milliseconds) taken to respond to various
// service control requests.
//
#define AFP_SERVICE_INSTALL_TIME	15*60000	// 15 minutes
#define AFP_SERVICE_STOP_TIME		5*60000		// 5 minutes
#define AFP_SERVICE_CONTINUE_TIME	5000
#define AFP_SERVICE_PAUSE_TIME		1000

// Macro to calculate the byte offset of a field in a structure of type type.
//
#define AFP_FIELD_OFFSET(type, field)    ((LONG)((LONG_PTR)&(((type *)0)->field)))

// Macro to calculate the size of a given field within a structure.
//
#define AFP_FIELD_SIZE(type, field)    sizeof(((type *)0)->field)


// Access mask values
//
#define 	AFPSVC_ALL_ACCESS	0x0001

// All global variables are packaged within this structure.
//
typedef struct _AFP_GLOBALS {

    // Handle to the key that contains the server parameters
    //
    HKEY 		hkeyServerParams;

    // Handle to the key that contains the volumes list.
    //
    HKEY 		hkeyVolumesList;

    // Handle to the key that contains the list of Type/Creator/Comment tupples
    //
    HKEY 		hkeyTypeCreators;

    // Handle to the key that contains the list mapped extensions.
    //
    HKEY 		hkeyExtensions;

    // Handle to the key that contains the icon list.
    //
    HKEY 		hkeyIcons;

    // Service parameters
    //
    WCHAR		wchServerName[AFP_SERVERNAME_LEN+1];
    DWORD		dwServerOptions;
    DWORD		dwMaxSessions;
    WCHAR		wchLoginMsg[AFP_MESSAGE_LEN+1];
    DWORD		dwMaxPagedMem;
    DWORD		dwMaxNonPagedMem;
    WCHAR		wchCodePagePath[MAX_PATH];

    // Localizable strings
    //
    WCHAR		wchInvalid[100];
    WCHAR		wchDeleted[100];
    WCHAR		wchUnknown[100];
    WCHAR		wchDefTCComment[AFP_ETC_COMMENT_LEN+1];

    // Contains information about what components were initialized
    // successfully
    //
    DWORD		dwServerState;

    // Handle to the AFP Server FSD
    //
    HANDLE 		hFSD;

    // Handle used to announce the service status
    //
    SERVICE_STATUS_HANDLE hServiceStatus;

    SERVICE_STATUS	ServiceStatus;

    // This is a cache of ext/type/creator mappings
    //
    AFP_ETCMAP_INFO	AfpETCMapInfo;

    // Will contain the Id of the next type/creator that will be added to the
    // registry via the AfpAdminAddETCMap API.
    //
    DWORD		dwCurrentTCId;

    // Mutex handle for mutual exclusion around volume SetInfo/ Add/ Delete
    // ETC mappings registry and cache operations.
    //
    HANDLE		hmutexETCMap;

    // Mutex handle for mutual exclusion around volume SetInfo/ Add/ Delete
    // volume registry operations.
    //
    HANDLE		hmutexVolume;

    // This will be used by the server helper thread to inicate its
    // success or failure while initializing itself. The parent thread
    // can then take appropriate action.
    //
    HANDLE		heventSrvrHlprThread;

	// This is used by the server helper thread(s) to indicate that they have terminated
    //
	HANDLE		heventSrvrHlprThreadTerminate;

    // This is used in special case: if we have to terminate the helper thread when
    // it's blocked trying to get domain info
	HANDLE		heventSrvrHlprSpecial;

	DWORD		nThreadCount;

    DWORD		dwSrvrHlprCode;

	DWORD		dwSrvrHlprCount;

	NT_PRODUCT_TYPE	NtProductType;
	PSID		pSidNone;

} AFP_GLOBALS, *PAFP_GLOBALS;

#ifdef DEFINE_AFP_GLOBALS
AFP_GLOBALS		AfpGlobals;
HANDLE          SfmLsaHandle;
DWORD           SfmAuthPkgId;
#else
extern AFP_GLOBALS	AfpGlobals;
extern HANDLE       SfmLsaHandle;
extern DWORD        SfmAuthPkgId;
#endif

// prototypes of functions used across modules
//
VOID
AfpAnnounceServiceStatus(
	VOID
);

DWORD
AfpInitialize(
	VOID
);

VOID
AfpTerminate(
	VOID
);

DWORD
AfpRegGetKeyInfo(
	IN  HKEY    hKey,
	OUT LPDWORD lpdwMaxValNameLen,   // Longest valuename in this key
	OUT LPDWORD lpdwNumValues,	 // Number of values in this key
	OUT LPDWORD lpdwMaxValueDataSize // Max. size of value data.
);

DWORD
AfpRegOpen(
	VOID
);

VOID
AfpRegClose(
	VOID
);

DWORD
AfpRegVolumeAdd(
	IN PAFP_VOLUME_INFO  	pVolumeInfo
);

DWORD
AfpRegVolumeDelete(
	IN LPWSTR 		lpwsVolumeName
);

DWORD
AfpRegVolumeSetInfo(
	IN PAFP_VOLUME_INFO    	pVolumeInfo
);

DWORD
AfpRegExtensionEnum(
	VOID
);

DWORD
AfpRegTypeCreatorEnum(
	VOID
);

DWORD
AfpRegExtensionAdd(
	IN PAFP_EXTENSION	pAfpExtension
);

DWORD
AfpRegExtensionSetInfo(
	IN PAFP_EXTENSION	pAfpExtension
);

DWORD
AfpRegExtensionDelete(
	IN PAFP_EXTENSION	pAfpExtension
);

DWORD
AfpRegTypeCreatorSetInfo(
	IN PAFP_TYPE_CREATOR    pAfpTypeCreator
);

DWORD
AfpRegTypeCreatorAdd(
	IN PAFP_TYPE_CREATOR   	pAfpTypeCreator
);

DWORD
AfpRegTypeCreatorDelete(
	IN PAFP_TYPE_CREATOR 	pAfpTypeCreator
);

DWORD
AfpRegServerGetInfo(
	VOID
);

DWORD
AfpRegServerSetInfo(
	IN PAFP_SERVER_INFO 	pServerInfo,
	IN DWORD 		dwParmnum
);

DWORD
AfpRegServerGetCodePagePath(
	VOID
);

DWORD
AfpSecObjCreate(
	VOID
);

DWORD
AfpSecObjDelete(
	VOID
);

DWORD
AfpSecObjAccessCheck(
	IN  DWORD 		DesiredAccess,
	OUT LPDWORD 		pfAccessStatus 		
);

DWORD
AfpBufMakeFSDRequest(
	IN  LPBYTE  		pBuffer,
	IN  DWORD	        cbReqPktSize,	
	IN  AFP_STRUCTURE_TYPE	dwStructureId,	
	OUT LPBYTE 		*ppSelfRelativeBuf,	
	OUT LPDWORD		lpdwSelfRelativeBufSize
);

DWORD
AfpBufMakeFSDETCMappings(
	OUT PSRVETCPKT		*ppSrvSetEtc,
	OUT LPDWORD		lpdwSrvSetEtcBufSize
);

VOID
AfpBufOffsetToPointer(
	IN OUT LPBYTE		  pBuffer,
	IN     DWORD		  dwNumEntries,
	IN     AFP_STRUCTURE_TYPE dwStructureType
);

VOID
AfpBufCopyFSDETCMapInfo(
	IN  PAFP_TYPE_CREATOR 	pAfpTypeCreator,
	IN  PAFP_EXTENSION	pAfpExtension,
	OUT PETCMAPINFO2        pFSDETCMapInfo
);

VOID
AfpBufMakeFSDIcon(
	IN  PAFP_ICON_INFO 	pIconInfo,
	OUT LPBYTE	  	lpbFSDIcon,
	OUT LPDWORD	  	lpcbFSDIconSize
);

DWORD
AfpBufMakeMultiSz(
	IN  AFP_STRUCTURE_TYPE	dwStructureId,	
	IN  LPBYTE		pbStructure,
	OUT LPBYTE*		ppbMultiSz,
	OUT LPDWORD		lpdwMultiSzSize
);

DWORD
AfpBufParseMultiSz(
	IN  AFP_STRUCTURE_TYPE	dwStructureId,	
	IN  LPBYTE		pbMultiSz,
	OUT LPBYTE		pbStructure
);

DWORD
AfpBufStructureSize(
	IN  AFP_STRUCTURE_TYPE	dwStructureId,	
	IN LPBYTE		lpbStructure
);

DWORD
AfpBufUnicodeToNibble(
	IN OUT LPWSTR		lpwsData
);

void *
AfpBinarySearch(
	IN const void * pKey,
	IN const void * pBase,
	IN size_t num,
	IN size_t width,
	IN int (_cdecl *compare)(const void * pElem1, const void * pElem2 )
);

int
_cdecl
AfpBCompareTypeCreator(
	IN const void * pAfpTypeCreator1,
	IN const void * pAfpTypeCreatro2
);

int
_cdecl
AfpLCompareTypeCreator(
	IN const void * pAfpTypeCreator1,
	IN const void * pAfpTypeCreatro2
);

int
_cdecl
AfpBCompareExtension(
	IN const void * pAfpExtension1,
	IN const void * pAfpExtension2
);

int
_cdecl
AfpLCompareExtension(
	IN const void * pAfpExtension1,
	IN const void * pAfpExtension2
);


DWORD
AfpFSDOpen(
	OUT PHANDLE pFSD
);

DWORD
AfpFSDClose(
	IN HANDLE hFSD
);

DWORD
AfpFSDUnload(
	VOID
);

DWORD
AfpFSDLoad(
	VOID
);

DWORD
AfpFSDIOControl(
	IN  HANDLE	hFSD,
	IN  DWORD 	dwOpCode,
	IN  PVOID	pInbuf 		OPTIONAL,
	IN  DWORD	cbInbufLen,
	OUT PVOID	pOutbuf 	OPTIONAL,
	IN  DWORD	cbOutbuflen,
	OUT LPDWORD	cbBytesTransferred
);

DWORD
AfpCreateServerHelperThread(
	BOOL fIsFirstThread
);

VOID
AfpTerminateCurrentThread(
	VOID
);

DWORD
AfpInitServerHelper(
	VOID
);

DWORD
AfpServerHelper(
	IN LPVOID Parameter
);

VOID
AfpLogEvent(
    	IN DWORD    dwMessageId,
    	IN WORD     cNumberOfSubStrings,
        IN LPWSTR*  plpwsSubStrings,
     	IN DWORD    dwErrorCode,
     	IN WORD     wSeverity
);

VOID
AfpLogServerEvent(
	IN	PAFP_FSD_CMD_PKT	pAfpFsdCmd
);

VOID
AfpAddInvalidVolume(
	IN LPWSTR	lpwsName,
	IN LPWSTR	lpwsPath
);

VOID
AfpDeleteInvalidVolume(
	IN LPWSTR	lpwsVolumeName
);

DWORD
I_DirectorySetInfo(
	IN PAFP_DIRECTORY_INFO 	pAfpDirectoryInfo,
	IN DWORD	 	dwParmNum
);

DWORD
I_DirectoryGetInfo(
	IN LPWSTR 		  lpwsPath,
	OUT PAFP_DIRECTORY_INFO * ppAfpDirectoryInfo
);

#endif // _AFPSVCP_