/******************************************************************************

Copyright (c) 1999 Microsoft Corporation

Module Name:
    UploadLibrary.h

Abstract:
    This file contains the declaration of support structures and typedefs
    for the Transport Procotol used by the Upload Library.

Revision History:
    Davide Massarenti   (Dmassare)  04/20/99
        created

******************************************************************************/

#if !defined(__INCLUDED___UL___UPLOADLIBRARY_H___)
#define __INCLUDED___UL___UPLOADLIBRARY_H___

#include <MPC_main.h>
#include <MPC_utils.h>
#include <MPC_streams.h>

#define UPLOAD_LIBRARY_PROTOCOL_SIGNATURE  				(0x55504C42) // UPLB

#define UPLOAD_LIBRARY_PROTOCOL_VERSION_CLT				(0xBEEF0102)
#define UPLOAD_LIBRARY_PROTOCOL_VERSION_SRV				(0xBEEF0202)
			
#define UPLOAD_LIBRARY_PROTOCOL_VERSION_CLT__TEXTONLY   (0x434c5431) // CLT1
#define UPLOAD_LIBRARY_PROTOCOL_VERSION_SRV__TEXTONLY   (0x53525631) // SRV1

/////////////////////////////////////////////////////////////////////////

namespace UploadLibrary
{
    //
    // This enumeration defines the commands understood by the server.
    //
    typedef enum
    {
        UL_COMMAND_OPENSESSION  = 0x00,
        UL_COMMAND_WRITESESSION = 0x01
    } Command;

    //
    // This enumeration defines the response codes generated by the server.
    //
    typedef enum
    {
        UL_RESPONSE_SUCCESS                = 0x00000000,
        UL_RESPONSE_SKIPPED                = 0x00000001 | UL_RESPONSE_SUCCESS, // Ok, but move forward.
        UL_RESPONSE_COMMITTED              = 0x00000002 | UL_RESPONSE_SUCCESS, // File has been committed.

        UL_RESPONSE_FAILED                 = 0x80000000,
        UL_RESPONSE_BAD_REQUEST            = 0x00000001 | UL_RESPONSE_FAILED, // Bad packet format.
        UL_RESPONSE_DENIED                 = 0x00000002 | UL_RESPONSE_FAILED, // Generic access deny.
        UL_RESPONSE_NOT_AUTHORIZED         = 0x00000003 | UL_RESPONSE_FAILED, // Authorization failure.
        UL_RESPONSE_QUOTA_EXCEEDED         = 0x00000004 | UL_RESPONSE_FAILED, // Quota exceeded.
        UL_RESPONSE_BUSY                   = 0x00000005 | UL_RESPONSE_FAILED, // Server is busy, retry later.
        UL_RESPONSE_EXISTS                 = 0x00000006 | UL_RESPONSE_FAILED, // File already exists and is committed.
        UL_RESPONSE_NOTACTIVE              = 0x00000007 | UL_RESPONSE_FAILED, // Session not active.
        UL_RESPONSE_BADCRC                 = 0x00000008 | UL_RESPONSE_FAILED  // The sent bytes and the CRC don't match!!
    } Response;

    /////////////////////////////////////////////////////////////////////////

	//
	// Forward declaractions.
	//
    struct Signature;
    struct RequestHeader;
    struct ClientRequest;
    struct ClientRequest_OpenSession;
    struct ClientRequest_WriteSession;
    struct ServerResponse;

    /////////////////////////////////////////////////////////////////////////

	MPC::Serializer* SelectStream( MPC::Serializer& stream, MPC::Serializer_Text& streamText );

    /////////////////////////////////////////////////////////////////////////

    //
    // This structure defines the authentication signature of a client.
    //
    struct Signature // Hungarian: sig
    {
        GUID  guidMachineID;
        DWORD dwHash;

        Signature( /*[in]*/ GUID id = IID_IUnknown ) : guidMachineID( id ),
                                                       dwHash       ( 0  ) {}

        bool operator==( /*[in]*/ const Signature& sig ) const
        {
            if(IsEqualGUID( guidMachineID, sig.guidMachineID ) == FALSE) return false;

            if(dwHash != sig.dwHash) return false;

            return true;
        }

        friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/       struct Signature& sigVal );
        friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const struct Signature& sigVal );
    };

    //
    // This structure defines the start of every request.
    //
    struct RequestHeader // Hungarian: rh
    {
        DWORD dwSignature;
        DWORD dwVersion;

        RequestHeader( /*[in]*/ DWORD dwMode ) : dwSignature( UPLOAD_LIBRARY_PROTOCOL_SIGNATURE ), dwVersion( dwMode ) {}


        friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/       struct RequestHeader& rhVal );
        friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const struct RequestHeader& rhVal );

		bool VerifyClient() const;
		bool VerifyServer() const;
    };

    //
    // This structure defines the tipical response from the server.
    //
    struct ServerResponse // Hungarian: sr
    {
		RequestHeader rhProlog;

        DWORD         fResponse;
        DWORD         dwPosition;

        ServerResponse( /*[in]*/ DWORD dwVer, /*[in]*/ DWORD fRes = UL_RESPONSE_DENIED ) : rhProlog   ( dwVer ),
                                                                     					   fResponse  ( fRes  ),
                                                                     					   dwPosition ( 0     ) {}


        friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/       struct ServerResponse& srVal );
        friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const struct ServerResponse& srVal );

		bool MatchVersion( /*[in]*/ const ClientRequest& cr );
    };

    //
    // This structure defines the start of every client request.
    //
    struct ClientRequest // Hungarian: cr
    {
		RequestHeader rhProlog;

        Signature     sigClient;

        DWORD         dwCommand;

        ClientRequest( /*[in]*/ DWORD dwVer, /*[in]*/ DWORD dwCmd = -1 ) : rhProlog ( dwVer ),
                                                                           dwCommand( dwCmd ) {}


        friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/       struct ClientRequest& crVal );
        friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const struct ClientRequest& crVal );
    };

    //
    // This structure defines an 'Open New or Old File' request.
    //
    struct ClientRequest_OpenSession // Hungarian: cros
    {
        ClientRequest crHeader;

        MPC::wstring  szJobID;
        MPC::wstring  szProviderID;
        MPC::wstring  szUsername;

        DWORD         dwSize;
        DWORD         dwSizeOriginal;
        DWORD         dwCRC;
        bool          fCompressed;

        ClientRequest_OpenSession( /*[in]*/ DWORD dwVer ) : crHeader      ( dwVer, UL_COMMAND_OPENSESSION ),
                                      						dwSize        ( 0                             ),
                                      						dwSizeOriginal( 0                             ),
                                      						fCompressed   ( false                         ) {}


        friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/       struct ClientRequest_OpenSession& crosVal );
        friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const struct ClientRequest_OpenSession& crosVal );
    };

    //
    // This structure defines a request to add new data to an opened file.
    //
    struct ClientRequest_WriteSession // Hungarian: crws
    {
        ClientRequest crHeader;

        MPC::wstring  szJobID;

        DWORD         dwOffset;
        DWORD         dwSize;

        ClientRequest_WriteSession( /*[in]*/ DWORD dwVer ) : crHeader( dwVer, UL_COMMAND_WRITESESSION ),
                                       						 dwOffset( 0                              ),
                                       						 dwSize  ( 0                              ) {}


        friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/       struct ClientRequest_WriteSession& crwsVal );
        friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const struct ClientRequest_WriteSession& crwsVal );
    };

}; // namespace
/////////////////////////////////////////////////////////////////////////

#endif // !defined(__INCLUDED___UL___UPLOADLIBRARY_H___)
