/***********************************************************************
 * 
 *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, Novell, Inc.
 * 
 *  To contact Novell about this file by physical or electronic mail, 
 *  you may find current contact information at www.novell.com.
 * 
 *  Author: Juan Carlos Luciani <jluciani@novell.com>
 *
 ***********************************************************************/

//===[ Include files ]=====================================================

#include "internal.h"
#include <shlobj.h>
#include <shlwapi.h>
#include "casa_c_authtoken_ex.h"

//===[ External data ]=====================================================
extern
char  clientConfigFolderPartialPath[];

extern
char  mechConfigFolderPartialPath[];

//===[ Manifest constants ]================================================

//===[ Type definitions ]==================================================

//===[ Function prototypes ]===============================================

//===[ Global variables ]==================================================

UINT32 g_ulCount  = 0;
UINT32 g_ulLock = 0;
HANDLE g_hModule;
HANDLE g_hModuleMutex;


//++=======================================================================
CasaStatus SSCS_CALL
ObtainAuthTokenEx(
   IN    const char *pServiceName,
   IN    const char *pHostName,
   INOUT char *pAuthTokenBuf,
   INOUT int *pAuthTokenBufLen,
   IN    void *pCredStoreScope)
//
//  Arguments: 
//    pServiceName -
//       Pointer to NULL terminated string that contains the
//       name of the service to which the client is trying to
//       authenticate.
//               
//    pHostName -
//       Pointer to NULL terminated string that contains the
//       name of the host where resides the service to which the
//       client is trying to authenticate. Note that the name
//       can either be a DNS name or a dotted IP address.
//               
//    pAuthTokenBuf -
//       Pointer to buffer that will receive the authentication
//       token. The length of this buffer is specified by the
//       pAuthTokenBufLen parameter. Note that the the authentication
//       token will be in the form of a NULL terminated string.
//
//    pAuthTokenBufLen -
//       Pointer to integer that contains the length of the
//       buffer pointed at by pAuthTokenBuf. Upon return of the
//       function, the integer will contain the actual length
//       of the authentication token if the function successfully
//       completes or the buffer length required if the function
//       fails because the buffer pointed at by pAuthTokenBuf is
//       not large enough.
//
//    pCredStoreScope -
//       Pointer to CASA structure for scoping credential store access
//       to specific users. This can only be leveraged by applications
//       running in the context of System.
//   
// Returns:
//    Casa Status
//                           
// Description:
//    Get authentication token to authenticate user to specified
//    service at host. The user is scoped using the info associated
//    with the magic cookie.
//
// L2
//=======================================================================--
{
   CasaStatus        retStatus;

   DbgTrace(1, "-ObtainAuthTokenEx- Start\n", 0);

   // Call our internal worker
   retStatus = ObtainAuthTokenInt(pServiceName,
                                  pHostName,
                                  pAuthTokenBuf,
                                  pAuthTokenBufLen,
                                  pCredStoreScope);

   DbgTrace(1, "-ObtainAuthTokenEx- End, retStatus = %0X\n", retStatus);

   return retStatus;
}


//++=======================================================================
BOOL APIENTRY DllMain(
   HANDLE hModule,
   DWORD  ul_reason_for_call,
   LPVOID lpReserved   
   )
//=======================================================================--
{
   BOOL  retStatus = TRUE;
   char  programFilesFolder[MAX_PATH] = {0};

   switch (ul_reason_for_call)
   {
      case DLL_PROCESS_ATTACH:
      {
         g_hModule = hModule;

         // Setup the path to the client and auth mechanisms config folders
         if (SHGetFolderPath(NULL,
                             CSIDL_PROGRAM_FILES,
                             NULL,
                             0,
                             programFilesFolder) == 0)
         {
            strcpy(clientConfigFolder, programFilesFolder);
            PathAppend(clientConfigFolder, clientConfigFolderPartialPath);

            strcpy(mechConfigFolder, programFilesFolder);
            PathAppend(mechConfigFolder, mechConfigFolderPartialPath);

            // Allocate module mutex
            g_hModuleMutex = CreateMutex(NULL, FALSE, NULL);
            if (! g_hModuleMutex)
            {
               // Module initialization failed
               OutputDebugString("CASAAUTH -DllMain- Failed to create mutex\n");
               retStatus = FALSE;
            }
         }
         else
         {
            // Failed to obtain the Program Files path
            OutputDebugString("CASAAUTH -DllMain- Failed to obtain the Program Files path\n");
            retStatus = FALSE;
         }

         break;
      }

      case DLL_THREAD_ATTACH:
      {
         g_hModule = hModule;
         break;
      }

      case DLL_THREAD_DETACH:
         break;

      case DLL_PROCESS_DETACH:
      {
         UnInitializeLibrary();
         break;
      }
    }

    return retStatus;
}

//++=======================================================================
//
// DllCanUnloadNow
//
// Synopsis
//
//
STDAPI
DllCanUnloadNow()
//
// Input Arguments
//
// Ouput Arguments
//
// Return Value
//    S_OK    The DLL can be unloaded.
//    S_FALSE The DLL cannot be unloaded now.
//
// Description
//    An Exported Function.
//    DLLs that support the OLE Component Object Model (COM) should implement
//    and export DllCanUnloadNow.
//    A call to DllCanUnloadNow determines whether the DLL from which it is
//    exported is still in use. A DLL is no longer in use when it is not
//    managing  any existing objects (the reference count on all of its objects
//    is 0).
//    DllCanUnloadNow returns S_FALSE if there are any existing references to
//    objects that the DLL manages.
//
// Environment
//
// See Also
//
//=======================================================================--
{
   // tbd
   return ((g_ulCount == 0 && g_ulLock == 0) ? S_OK : S_FALSE);
}

//=========================================================================
//=========================================================================