// aplSocketTransport.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include <afxdllx.h>
#include "CPing.h"
#include "aplSocketTransport.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


static AFX_EXTENSION_MODULE AplSocketTransportDLL = { NULL, NULL };

HINSTANCE module_inst=0;
extern CRITICAL_SECTION _DEBUG_LOG_MESSAGE_CS;
CPing ping_object;
extern CRITICAL_SECTION m_OperateListClients;
extern CRITICAL_SECTION LstenServList;
extern void SetUnBlockTimer();
extern CRITICAL_SECTION CS_PROTECT_IP_CASH;
extern CRITICAL_SECTION list_threads_protect;


// static HINSTANCE hLib;
// typedef BOOL (WINAPI *ISUSRADM)();
// static ISUSRADM IsUserAdmin;


extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
	module_inst=hInstance;
	// Remove this if you use lpReserved
	UNREFERENCED_PARAMETER(lpReserved);

	if (dwReason == DLL_PROCESS_ATTACH)
	{
		TRACE0("APLSOCKETTRANSPORT.DLL Initializing!\n");
		
		// Extension DLL one-time initialization
		if (!AfxInitExtensionModule(AplSocketTransportDLL, hInstance))
			return 0;

		// Insert this DLL into the resource chain
		// NOTE: If this Extension DLL is being implicitly linked to by
		//  an MFC Regular DLL (such as an ActiveX Control)
		//  instead of an MFC application, then you will want to
		//  remove this line from DllMain and put it in a separate
		//  function exported from this Extension DLL.  The Regular DLL
		//  that uses this Extension DLL should then explicitly call that
		//  function to initialize this Extension DLL.  Otherwise,
		//  the CDynLinkLibrary object will not be attached to the
		//  Regular DLL's resource chain, and serious problems will
		//  result.

		new CDynLinkLibrary(AplSocketTransportDLL);
		InitializeCriticalSection(&_DEBUG_LOG_MESSAGE_CS);
		InitializeCriticalSection(&m_OperateListClients);
		InitializeCriticalSection(&LstenServList);
		InitializeCriticalSection(&CS_PROTECT_IP_CASH);
		InitializeCriticalSection(&list_threads_protect);

// 		hLib = LoadLibrary(_T("setupapi.dll"));
// 		if(hLib)
// 		{
// 			IsUserAdmin = (ISUSRADM)GetProcAddress( hLib, "IsUserAdmin" );
// 		}

		
	}
	else if (dwReason == DLL_PROCESS_DETACH)
	{
		TRACE0("APLSOCKETTRANSPORT.DLL Terminating!\n");
		// Terminate the library before destructors are called
		AfxTermExtensionModule(AplSocketTransportDLL);
		DeleteCriticalSectionODS(&_DEBUG_LOG_MESSAGE_CS);
		DeleteCriticalSectionODS(&m_OperateListClients);
		DeleteCriticalSectionODS(&LstenServList);
		DeleteCriticalSectionODS(&CS_PROTECT_IP_CASH);
		DeleteCriticalSectionODS(&list_threads_protect);

// 		FreeLibrary( hLib );
	}
	return 1;   // ok
}


AFX_EXT_API BOOL TransportPing(LPCTSTR strHost)
{
	return ping_object.Ping(strHost);
}

// AFX_EXT_API bool aplIsUserAdmin()
// {
// 	 return (IsUserAdmin()==TRUE);
// }

AFX_EXT_API bool aplIsUserAdmin()
{
    HANDLE hAccessToken       = NULL;
    PBYTE  pInfoBuffer        = NULL;
    DWORD  dwInfoBufferSize   = 1024;    
    PTOKEN_GROUPS ptgGroups   = NULL;
    PSID   psidAdministrators = NULL;
    SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
    bool   bResult = false;    
    __try
    {
		
        if( !AllocateAndInitializeSid( 
            &siaNtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
            DOMAIN_ALIAS_RID_ADMINS, 0,0,0,0,0,0, &psidAdministrators ) )
			__leave;        
        
        if( !OpenProcessToken( GetCurrentProcess(),TOKEN_QUERY,&hAccessToken ) )
            __leave;
		
        do 
        {
            if( pInfoBuffer )
                delete pInfoBuffer;
            pInfoBuffer = new BYTE[dwInfoBufferSize];
            if( !pInfoBuffer )
                __leave;
            SetLastError( 0 );
            if( !GetTokenInformation( 
				hAccessToken, 
				TokenGroups, pInfoBuffer,
				dwInfoBufferSize, &dwInfoBufferSize ) &&
                ( ERROR_INSUFFICIENT_BUFFER != GetLastError() )
				)
                __leave;
            else
                ptgGroups = (PTOKEN_GROUPS)pInfoBuffer;
        }
        while( GetLastError() ); 
        
        for( UINT i = 0; i < ptgGroups->GroupCount; i++ )
        {
            if( EqualSid(psidAdministrators,ptgGroups->Groups[i].Sid) )
            {
                bResult  = true;
                __leave;
            }
        } 
    }    
    __finally
    {
        if( hAccessToken )
            CloseHandle( hAccessToken );
        if( pInfoBuffer )
            delete pInfoBuffer;
        if( psidAdministrators )
            FreeSid( psidAdministrators );
    }    
    return bResult;
}
