/*++ Copyright (C) 1997-2001 Microsoft Corporation Module Name: LOCATOR.CPP Abstract: Defines the CLocator class. History: a-davj 15-Aug-96 Created. --*/ #include "precomp.h" #include #include "anonpipe.h" #ifdef TCPIP_MARSHALER #include "tcpip.h" #endif #include #include DEFINE_GUID(UUID_LocalAddrType, 0xa1044803, 0x8f7e, 0x11d1, 0x9e, 0x7c, 0x0, 0xc0, 0x4f, 0xc3, 0x24, 0xa8); // {8F174CA0-952A-11d1-9367-00AA00A4086C} DEFINE_GUID(UUID_IWbemAddressResolver_Tcpip, 0x8f174ca0, 0x952a, 0x11d1, 0x93, 0x67, 0x0, 0xaa, 0x0, 0xa4, 0x8, 0x6c); static wchar_t *s_localaddressType = L"{A1044803-8F7E-11D1-9E7C-00C04FC324A8}"; // Local static wchar_t *s_tcpipaddressType = L"{8F174CA0-952A-11d1-9367-00AA00A4086C}"; // Local BOOL g_InitialisationComplete = FALSE ; BOOL g_PipeInitialisationComplete = FALSE ; BOOL g_TcpipInitialisationComplete = FALSE ; DWORD LOG = 3; struct PipeSharedMemoryMessage { DWORD m_Size ; CHAR m_Buffer [ 256 ] ; } ; CRITICAL_SECTION g_GlobalCriticalSection ; HANDLE g_Mutex = NULL ; HANDLE g_StartedEvent ; HANDLE g_ReplyEvent = NULL ; HANDLE g_RequestEvent = NULL ; HANDLE g_SharedMemory = NULL ; PipeSharedMemoryMessage *g_SharedMemoryBuffer = NULL ; HRESULT CreateSharedMemory () { g_StartedEvent = CreateEvent ( NULL , TRUE , FALSE , __TEXT("WBEM_PIPEMARSHALER_STARTED") ) ; if ( ! g_StartedEvent ) { return WBEM_E_FAILED ; } if ( GetLastError () != ERROR_ALREADY_EXISTS ) { SetObjectAccess ( g_StartedEvent ) ; } DWORD t_Timeout = GetTimeout () ; DWORD t_Status = WbemWaitForSingleObject ( g_StartedEvent , t_Timeout ) ; if ( t_Status != WAIT_OBJECT_0 ) { CloseHandle ( g_StartedEvent ) ; g_StartedEvent = NULL ; return WBEM_E_FAILED ; } g_RequestEvent = OpenEvent ( EVENT_ALL_ACCESS, FALSE , __TEXT("WBEM_PIPEMARSHALER_EEQUESTISREADY") ) ; if ( ! g_RequestEvent ) { CloseHandle ( g_StartedEvent ) ; g_StartedEvent = NULL ; return WBEM_E_FAILED ; } g_ReplyEvent = OpenEvent ( EVENT_ALL_ACCESS, FALSE , __TEXT("WBEM_PIPEMARSHALER_REPLYISREADY") ) ; if ( ! g_ReplyEvent ) { CloseHandle ( g_StartedEvent ) ; CloseHandle ( g_RequestEvent ) ; g_StartedEvent = NULL ; g_RequestEvent = NULL ; return WBEM_E_FAILED ; } g_Mutex = OpenMutex ( MUTEX_ALL_ACCESS , FALSE , __TEXT("WBEM_PIPEMARSHALER_MUTUALEXCLUSION") ) ; if ( ! g_Mutex ) { CloseHandle ( g_StartedEvent ) ; CloseHandle ( g_RequestEvent ) ; CloseHandle ( g_ReplyEvent ) ; g_StartedEvent = NULL ; g_ReplyEvent = NULL ; g_RequestEvent = NULL ; return WBEM_E_FAILED ; } g_SharedMemory = OpenFileMapping ( FILE_MAP_WRITE , FALSE , __TEXT("WBEM_PIPEMARSHALER_SHAREDMEMORY") ); if ( ! g_SharedMemory ) { CloseHandle ( g_StartedEvent ) ; CloseHandle ( g_RequestEvent ) ; CloseHandle ( g_ReplyEvent ) ; CloseHandle ( g_Mutex ) ; g_StartedEvent = NULL ; g_ReplyEvent = NULL ; g_RequestEvent = NULL ; g_Mutex = NULL ; return WBEM_E_FAILED ; } g_SharedMemoryBuffer = ( PipeSharedMemoryMessage * ) MapViewOfFile ( g_SharedMemory , FILE_MAP_WRITE , 0 , 0 , 0 ) ; if ( ! g_SharedMemoryBuffer ) { CloseHandle ( g_StartedEvent ) ; CloseHandle ( g_RequestEvent ) ; CloseHandle ( g_ReplyEvent ) ; CloseHandle ( g_Mutex ) ; CloseHandle ( g_SharedMemory ) ; g_StartedEvent = NULL ; g_ReplyEvent = NULL ; g_RequestEvent = NULL ; g_Mutex = NULL ; g_SharedMemory = NULL ; return WBEM_E_FAILED ; } return S_OK ; } void DestroySharedMemory () { CloseHandle ( g_Mutex ) ; CloseHandle ( g_StartedEvent ) ; CloseHandle ( g_ReplyEvent ) ; CloseHandle ( g_RequestEvent ) ; CloseHandle ( g_SharedMemory ) ; UnmapViewOfFile ( g_SharedMemoryBuffer ) ; g_StartedEvent = NULL ; g_ReplyEvent = NULL ; g_RequestEvent = NULL ; g_Mutex = NULL ; g_SharedMemory = NULL ; } //*************************************************************************** // // BOOL StartLocalServer // // DESCRIPTION: // // Makes sure that WinMgmt is running. This will start WinMgmt if it isnt running. // // RETURN VALUE: // // TRUE if WinMgmt was already running or was successfully started. // //*************************************************************************** BOOL StartLocalServer () { // temp code, for the local case, check to see if the server is already loaded via // the mutex check. If it isnt, the load it up. HANDLE t_RegisteredEvent = OpenEvent ( MUTEX_ALL_ACCESS, FALSE, TEXT("WINMGMT_LOADED") ); if ( ! t_RegisteredEvent ) { TCHAR *t_WorkingDirectory ; TCHAR t_Executable [256]; Registry t_RegistryValue (HKEY_LOCAL_MACHINE, KEY_QUERY_VALUE, WBEM_REG_WBEM) ; if ( t_RegistryValue.GetStr (__TEXT("Installation Directory"),&t_WorkingDirectory ) ) { TRACE((LOG,"\ncould not read the registry value for the installation" " directory")); return FALSE ; } wsprintf ( t_Executable ,__TEXT("%s\\WinMgmt.EXE"),t_WorkingDirectory ) ; delete [] t_WorkingDirectory ; if ( IsNT () ) { if ( ! StartService ( TEXT("WinMgmt") , 5 ) ) { TRACE((LOG,"\ncould not start service")); return FALSE; } } else { char c_Executable[MAX_PATH+1]; #ifdef UNICODE wcstombs(c_Executable, t_Executable, (MAX_PATH+1) * sizeof(char)); #else lstrcpy(c_Executable, t_Executable); #endif LONG t_Result = WinExec ( c_Executable , SW_NORMAL ) ; if ( t_Result <= 31 ) { TRACE((LOG,"\ncould not execute WinMgmt.EXE")); return FALSE ; } } ULONG t_Timeout ; if ( t_RegistryValue.GetDWORD (__TEXT("Startup Timeout"),&t_Timeout ) ) { t_Timeout = 20 ; } for ( int t_Ticks = 0 ; t_Ticks < t_Timeout; t_Ticks ++ ) { t_RegisteredEvent = OpenEvent ( MUTEX_ALL_ACCESS, FALSE, TEXT("WINMGMT_LOADED") ); if ( t_RegisteredEvent ) break; Sleep ( 1000 ) ; } } else { DEBUGTRACE((LOG,"\nWinMgmt.EXE is already running.")); } if ( t_RegisteredEvent ) { CloseHandle ( t_RegisteredEvent ) ; } else { TRACE((LOG,"\nWinMgmt.EXE was NOT STARTED!!!")); return FALSE ; } if ( ! g_InitialisationComplete ) { g_Terminate = CreateEvent(NULL,TRUE,FALSE,NULL); if ( ! g_Terminate ) { return FALSE ; } if ( FAILED ( gMaintObj.StartClientThreadIfNeeded () ) ) { CloseHandle ( g_Terminate ) ; return FALSE ; } g_InitialisationComplete = TRUE ; } if ( ! g_PipeInitialisationComplete ) { if ( FAILED ( CreateSharedMemory () ) ) { return FALSE ; } g_PipeInitialisationComplete = TRUE ; } return TRUE; } //*************************************************************************** // // SCODE WBEMLogin // // DESCRIPTION: // // Connects up to either local or remote WBEM Server. Returns // standard SCODE and more importantly sets the address of an initial // stub pointer. // // PARAMETERS: // // NetworkResource Namespze path // User User name // Password password // LocaleId language locale // lFlags flags // Authority domain // ppProv set to provdider proxy // // RETURN VALUE: // // S_OK all is well // else error listed in WBEMSVC.H // //*************************************************************************** SCODE WBEMLogin ( IN TransportType a_TransportType , IN DWORD dwBinaryAddressLength, IN BYTE __RPC_FAR *pbBinaryAddress, IN BSTR NetworkResource, IN BSTR User, IN BSTR Password, IN BSTR LocaleId, IN long lFlags, IN BSTR Authority, IWbemContext __RPC_FAR *pCtx, OUT IWbemServices FAR* FAR* ppProv ) { CLogin login ( a_TransportType , dwBinaryAddressLength, pbBinaryAddress ) ; HANDLE t_ServerAuthenticationEvent = NULL ; TCHAR cMyName[MAX_PATH]; DWORD dwSize = MAX_PATH; if(!GetComputerName(cMyName,&dwSize)) return WBEM_E_FAILED; WCHAR wszClientMachineName[MAX_PATH]; #ifdef UNICODE lstrcpy(wszClientMachineName, cMyName); #else mbstowcs(wszClientMachineName, cMyName, MAX_PATH); #endif TCHAR t_AsciiImpersonatedUser [ UNLEN + 1 ] ; ULONG t_UserLength = UNLEN + 1 ; if ( ! GetUserName ( t_AsciiImpersonatedUser , & t_UserLength) ) { ERRORTRACE((LOG_WBEMPROX, "\nGetUserName failed, using unknown")); lstrcpy(t_AsciiImpersonatedUser, __TEXT("")); } WCHAR t_ImpersonatedUser [ UNLEN + 1 ] ; #ifdef UNICODE lstrcpy(t_ImpersonatedUser, t_AsciiImpersonatedUser); #else mbstowcs(t_ImpersonatedUser, t_AsciiImpersonatedUser, UNLEN + 1 ); #endif // Establish a position SCODE sc = login.EstablishPosition ( wszClientMachineName, GetCurrentProcessId (), (DWORD *) & t_ServerAuthenticationEvent ); if ( SUCCEEDED ( sc ) ) { BYTE Nonce [ DIGEST_SIZE ] ; WBEM_128BITS pAccessToken = NULL ; // Get a nonse sc = login.RequestChallenge ( NetworkResource , t_ImpersonatedUser , Nonce ); if ( SUCCEEDED ( S_OK ) ) { // For the local case, prove to the server that we are really on the same machine if (t_ServerAuthenticationEvent) { int iRet = SetEvent ( t_ServerAuthenticationEvent ) ; DWORD dw = GetLastError () ; } BYTE t_AccessToken [ DIGEST_SIZE ] ; sc = login.WBEMLogin ( LocaleId , t_AccessToken , lFlags , pCtx , ppProv ) ; } if ( t_ServerAuthenticationEvent ) CloseHandle ( t_ServerAuthenticationEvent ) ; if ( pAccessToken ) CoTaskMemFree ( pAccessToken ) ; } return sc; } char *WideToNarrow (WCHAR * pWide) { if(pWide == NULL) { return NULL; } int iLen = wcstombs ( NULL , pWide , wcslen ( pWide ) + 1 ) + 1 ; char *pRet = new char [ iLen ] ; wcstombs ( pRet , pWide , wcslen ( pWide ) + 1 ) ; return pRet ; } //*************************************************************************** // // SCODE NTLMLogin // // DESCRIPTION: // // Connects up to either local or remote WBEM Server. Returns // standard SCODE and more importantly sets the address of an initial // stub pointer. // // PARAMETERS: // // NetworkResource Namespze path // User User name // Password password // LocaleId language locale // lFlags flags // Authority domain // ppProv set to provdider proxy // // RETURN VALUE: // // S_OK all is well // else error listed in WBEMSVC.H // //*************************************************************************** SCODE NTLMLogin ( IN TransportType a_TransportType , IN DWORD dwBinaryAddressLength, IN BYTE __RPC_FAR *pbBinaryAddress, IN BSTR a_NetworkResource, IN BSTR a_User, IN BSTR a_Password, IN BSTR a_LocaleId, IN long a_lFlags, IN BSTR a_Authority, IWbemContext __RPC_FAR *a_Ctx, OUT IWbemServices FAR* FAR* a_Prov ) { static BOOL s_InitializeTried = FALSE ; static BOOL s_Initialized = FALSE ; TCHAR cMyName[MAX_PATH]; WCHAR wszClientMachineName[MAX_PATH]; DWORD dwSize = MAX_PATH; if(!GetComputerName(cMyName,&dwSize)) return WBEM_E_FAILED; #ifdef UNICODE lstrcpy(wszClientMachineName, cMyName); #else mbstowcs(wszClientMachineName, cMyName, MAX_PATH); #endif // Do a one time initialization. if ( ! s_InitializeTried ) { BOOL t_Status = CSSPI::Initialize () ; if ( ! t_Status ) { DEBUGTRACE((LOG,"\nCSSPI::Initialize FAILED")); } else { s_Initialized = TRUE ; } } s_InitializeTried = TRUE ; if ( ! s_Initialized ) { return WBEM_E_FAILED ; } // Initialize the "Client" object CSSPIClient Client("NTLM"); if ( Client.GetStatus() != CSSPIClient::Waiting ) { DEBUGTRACE((LOG,"\nCSSPIClient.GetStatus didnt return waiting")); return WBEM_E_FAILED ; } HRESULT t_Result = S_OK ; if ( a_lFlags == WBEM_FLAG_REMOTE_LOGIN ) { char *t_User = WideToNarrow ( a_User ) ; char *t_Password = WideToNarrow ( a_Password ) ; char *t_Authority = WideToNarrow ( a_Authority ) ; t_Result = Client.SetLoginInfo ( t_User , t_Authority , t_Password ) ; if ( t_User ) delete [] t_User ; if ( t_Password ) delete [] t_Password ; if ( t_Authority ) delete [] t_Authority ; } else { t_Result = Client.SetDefaultLogin () ; } if ( t_Result != 0 ) { DEBUGTRACE((LOG,"*********Unable to set login info. Error = %s\n", CSSPI::TranslateError(t_Result))); t_Result = WBEM_E_FAILED ; } else { // Call the SSPIPreLogin the first time with an empty input buffer. DWORD dwInSize, dwOutSize ; BYTE Out[1024], *pIn = NULL ; t_Result = Client.ContinueLogin ( 0 , 0 , &pIn , &dwInSize ) ; HANDLE t_ServerAuthenticationEvent = NULL ; CLogin login ( a_TransportType , dwBinaryAddressLength, pbBinaryAddress ) ; t_Result = login.SspiPreLogin ( "NTLM", a_lFlags, dwInSize, pIn, 1024, (long *)&dwOutSize, Out, wszClientMachineName, GetCurrentProcessId(), (DWORD *)&t_ServerAuthenticationEvent ); if ( pIn ) { delete pIn ; } while ( t_Result == WBEM_S_PRELOGIN ) { t_Result = Client.ContinueLogin ( Out, dwOutSize, &pIn, &dwInSize ) ; if ( SUCCEEDED ( t_Result ) ) { t_Result = login.SspiPreLogin ( "NTLM", a_lFlags, dwInSize, pIn, 1024, (long *)&dwOutSize, Out, wszClientMachineName, 0, NULL ); } if ( pIn ) { delete pIn ; pIn = NULL ; } } if ( ! FAILED ( t_Result ) ) { // For the local case, prove to the server that we are really on the same machine int iRet = SetEvent ( t_ServerAuthenticationEvent ) ; DWORD dw = GetLastError (); t_Result = login.Login ( a_NetworkResource, a_LocaleId, Out, a_lFlags, a_Ctx, a_Prov ) ; } if ( t_ServerAuthenticationEvent ) CloseHandle ( t_ServerAuthenticationEvent ) ; } return t_Result ; } //*************************************************************************** // // CPipeLocator::CPipeLocator // // DESCRIPTION: // // Constructor. // //*************************************************************************** CPipeLocator::CPipeLocator() { m_cRef=0; InterlockedIncrement(&g_cObj); ObjectCreated(OBJECT_TYPE_LOCATOR); } //*************************************************************************** // // CPipeLocator::~CPipeLocator // // DESCRIPTION: // // Destructor. // //*************************************************************************** CPipeLocator::~CPipeLocator(void) { InterlockedDecrement(&g_cObj); ObjectDestroyed(OBJECT_TYPE_LOCATOR); } //*************************************************************************** // HRESULT CPipeLocator::QueryInterface // long CPipeLocator::AddRef // long CPipeLocator::Release // // DESCRIPTION: // // Standard Com IUNKNOWN functions. // //*************************************************************************** STDMETHODIMP CPipeLocator::QueryInterface ( IN REFIID riid, OUT PPVOID ppv ) { *ppv=NULL; if (IID_IUnknown==riid || riid == IID_IWbemClientTransport) *ppv=this; if (NULL!=*ppv) { ((LPUNKNOWN)*ppv)->AddRef(); return NOERROR; } return ResultFromScode(E_NOINTERFACE); } STDMETHODIMP_(ULONG) CPipeLocator::AddRef(void) { InterlockedIncrement(&m_cRef); return m_cRef; } STDMETHODIMP_(ULONG) CPipeLocator::Release(void) { InterlockedDecrement(&m_cRef); if (0L!=m_cRef) return m_cRef; delete this; return 0; } //*************************************************************************** // // SCODE CPipeLocator::ConnectServer // // DESCRIPTION: // // Connects up to either local or remote WBEM Server. Returns // standard SCODE and more importantly sets the address of an initial // stub pointer. // // PARAMETERS: // // NetworkResource Namespace path // User User name // Password password // LocaleId language locale // lFlags flags // Authority domain // ppProv set to provdider proxy // // RETURN VALUE: // // S_OK all is well // else error listed in WBEMSVC.H // //*************************************************************************** SCODE CPipeLocator::ConnectServer ( BSTR AddressType, DWORD dwBinaryAddressLength, BYTE __RPC_FAR *pbBinaryAddress, BSTR NetworkResource, BSTR User, BSTR Password, BSTR LocaleId, long lFlags, BSTR Authority, IWbemContext __RPC_FAR *pCtx, IWbemServices __RPC_FAR *__RPC_FAR *ppProv ) { SCODE sc; long t_lFlags = WBEM_FLAG_LOCAL_LOGIN ;; if ( IsWin95 () ) { sc = WBEMLogin ( PipeTransport, 0 , NULL, NetworkResource, User, Password, LocaleId, lFlags | t_lFlags , Authority, pCtx, ppProv ); } else { sc = NTLMLogin ( PipeTransport, 0 , NULL, NetworkResource, User, Password, LocaleId, lFlags | t_lFlags , Authority, pCtx, ppProv ) ; } return sc; } //*************************************************************************** // // WCHAR *ExtractMachineName2 // // DESCRIPTION: // // Takes a path of form "\\machine\xyz... and returns the // "machine" portion in a newly allocated WCHAR. The return value should // be freed via delete. NULL is returned if there is an error. // // // PARAMETERS: // // pPath Path to be parsed. // // RETURN VALUE: // // see description. // //*************************************************************************** WCHAR * ExtractMachineName2 ( IN BSTR a_Path ) { WCHAR *t_MachineName = NULL; //todo, according to the help file, the path can be null which is // default to current machine, however Ray's mail indicated that may // not be so. if ( a_Path == NULL ) { t_MachineName = new WCHAR [ 2 ] ; if ( t_MachineName ) { wcscpy ( t_MachineName , L"." ) ; } return t_MachineName ; } // First make sure there is a path and determine how long it is. if ( ! IsSlash ( a_Path [ 0 ] ) || ! IsSlash ( a_Path [ 1 ] ) || wcslen ( a_Path ) < 3 ) { t_MachineName = new WCHAR [ 2 ] ; if ( t_MachineName ) { wcscpy ( t_MachineName , L"." ) ; } return t_MachineName ; } WCHAR *t_ThirdSlash ; for ( t_ThirdSlash = a_Path + 2 ; *t_ThirdSlash ; t_ThirdSlash ++ ) { if ( IsSlash ( *t_ThirdSlash ) ) break ; } if ( t_ThirdSlash == &a_Path [2] ) { return NULL; } // allocate some memory t_MachineName = new WCHAR [ t_ThirdSlash - a_Path - 1 ] ; if ( t_MachineName == NULL ) { return t_MachineName ; } // temporarily replace the third slash with a null and then copy WCHAR t_SlashCharacter = *t_ThirdSlash ; *t_ThirdSlash = NULL; wcscpy ( t_MachineName , a_Path + 2 ) ; *t_ThirdSlash = t_SlashCharacter ; // restore it. return t_MachineName ; } #ifdef TCPIP_MARSHALER //*************************************************************************** // // CTcpipLocator::CTcpipLocator // // DESCRIPTION: // // Constructor. // //*************************************************************************** CTcpipLocator::CTcpipLocator() { m_cRef=0; InterlockedIncrement(&g_cObj); ObjectCreated(OBJECT_TYPE_LOCATOR); } //*************************************************************************** // // CTcpipLocator::~CTcpipLocator // // DESCRIPTION: // // Destructor. // //*************************************************************************** CTcpipLocator::~CTcpipLocator(void) { InterlockedDecrement(&g_cObj); ObjectDestroyed(OBJECT_TYPE_LOCATOR); } //*************************************************************************** // HRESULT CTcpipLocator::QueryInterface // long CTcpipLocator::AddRef // long CTcpipLocator::Release // // DESCRIPTION: // // Standard Com IUNKNOWN functions. // //*************************************************************************** STDMETHODIMP CTcpipLocator::QueryInterface ( IN REFIID riid, OUT PPVOID ppv ) { *ppv=NULL; if (IID_IUnknown==riid || riid == IID_IWbemClientTransport) *ppv=this; if (NULL!=*ppv) { ((LPUNKNOWN)*ppv)->AddRef(); return NOERROR; } return ResultFromScode(E_NOINTERFACE); } STDMETHODIMP_(ULONG) CTcpipLocator::AddRef(void) { InterlockedIncrement(&m_cRef); return m_cRef; } STDMETHODIMP_(ULONG) CTcpipLocator::Release(void) { InterlockedDecrement(&m_cRef); if (0L!=m_cRef) return m_cRef; delete this; return 0; } //*************************************************************************** // // SCODE CTcpipLocator::ConnectServer // // DESCRIPTION: // // Connects up to either local or remote WBEM Server. Returns // standard SCODE and more importantly sets the address of an initial // stub pointer. // // PARAMETERS: // // NetworkResource Namespace path // User User name // Password password // LocaleId language locale // lFlags flags // Authority domain // ppProv set to provdider proxy // // RETURN VALUE: // // S_OK all is well // else error listed in WBEMSVC.H // //*************************************************************************** SCODE CTcpipLocator::ConnectServer ( BSTR AddressType, DWORD dwBinaryAddressLength, BYTE __RPC_FAR *pbBinaryAddress, BSTR NetworkResource, BSTR User, BSTR Password, BSTR LocaleId, long lFlags, BSTR Authority, IWbemContext __RPC_FAR *pCtx, IWbemServices __RPC_FAR *__RPC_FAR *ppProv ) { SCODE sc; long t_lFlags = WBEM_FLAG_LOCAL_LOGIN ; DWORD t_BinaryAddressLength = 0 ; BYTE __RPC_FAR *t_BinaryAddress = NULL ; if ( wcscmp ( AddressType , s_tcpipaddressType ) == 0 ) { t_lFlags = WBEM_FLAG_REMOTE_LOGIN ; t_BinaryAddressLength = dwBinaryAddressLength ; t_BinaryAddress = pbBinaryAddress ; } if ( IsWin95 () ) { switch ( t_lFlags ) { case WBEM_FLAG_REMOTE_LOGIN: { sc = NTLMLogin ( TcpipTransport, t_BinaryAddressLength, t_BinaryAddress, NetworkResource, User, Password, LocaleId, lFlags | t_lFlags, Authority, pCtx, ppProv ) ; } break ; default: { sc = WBEMLogin ( TcpipTransport, t_BinaryAddressLength, t_BinaryAddress, NetworkResource, User, Password, LocaleId, lFlags | t_lFlags , Authority, pCtx, ppProv ); } break ; } } else { sc = NTLMLogin ( TcpipTransport, t_BinaryAddressLength, t_BinaryAddress, NetworkResource, User, Password, LocaleId, lFlags | t_lFlags, Authority, pCtx, ppProv ) ; } return sc; } //*************************************************************************** // // CTcpipAddress::CTcpipAddress // // DESCRIPTION: // // Constructor. // //*************************************************************************** CTcpipAddress::CTcpipAddress() { m_cRef=0; InterlockedIncrement(&g_cObj); ObjectCreated(TCPIPADDR); } //*************************************************************************** // // CTcpipAddress::~CTcpipAddress // // DESCRIPTION: // // Destructor. // //*************************************************************************** CTcpipAddress::~CTcpipAddress(void) { InterlockedDecrement(&g_cObj); ObjectDestroyed(TCPIPADDR); } //*************************************************************************** // HRESULT CTcpipAddress::QueryInterface // long CTcpipAddress::AddRef // long CTcpipAddress::Release // // DESCRIPTION: // // Standard Com IUNKNOWN functions. // //*************************************************************************** STDMETHODIMP CTcpipAddress::QueryInterface ( IN REFIID riid, OUT PPVOID ppv ) { *ppv=NULL; if (IID_IUnknown==riid || riid == IID_IWbemAddressResolution) *ppv=this; if (NULL!=*ppv) { ((LPUNKNOWN)*ppv)->AddRef(); return NOERROR; } return ResultFromScode(E_NOINTERFACE); } STDMETHODIMP_(ULONG) CTcpipAddress::AddRef(void) { InterlockedIncrement(&m_cRef); return m_cRef; } STDMETHODIMP_(ULONG) CTcpipAddress::Release(void) { InterlockedDecrement(&m_cRef); if (0L!=m_cRef) return m_cRef; delete this; return 0; } SCODE CTcpipAddress::Resolve ( LPWSTR pszNamespacePath, LPWSTR pszAddressType, DWORD __RPC_FAR *pdwAddressLength, BYTE __RPC_FAR **pbBinaryAddress ) { HRESULT t_Result = S_OK ; GUID gAddr; CLSIDFromString(pszAddressType, &gAddr); BOOL t_Status = pszNamespacePath == NULL || pdwAddressLength== NULL || pbBinaryAddress == NULL || gAddr != UUID_LocalAddrType || gAddr != UUID_IWbemAddressResolver_Tcpip ; if ( ! t_Status ) { return WBEM_E_INVALID_PARAMETER; } WCHAR *t_ServerMachine = ExtractMachineName2 (pszNamespacePath) ; if ( t_ServerMachine == NULL ) { return WBEM_E_INVALID_PARAMETER ; } if ( wcscmp ( t_ServerMachine , L"." ) == 0 ) { if ( gAddr == UUID_LocalAddrType ) { *pbBinaryAddress = (BYTE *)CoTaskMemAlloc(8); if(*pbBinaryAddress == NULL) { delete [] t_ServerMachine ; return WBEM_E_FAILED; } wcscpy((LPWSTR)*pbBinaryAddress, L"\\\\."); *pdwAddressLength = 8; return t_Result ; } else { delete [] t_ServerMachine ; return WBEM_E_FAILED ; } } char *t_AsciiServer = new char [ wcslen ( t_ServerMachine ) * 2 + 1 ] ; sprintf ( t_AsciiServer , "%S" , t_ServerMachine ) ; delete [] t_ServerMachine; BOOL status = FALSE ; WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(1, 1); status = ( WSAStartup ( wVersionRequested , &wsaData ) == 0 ) ; if ( status ) { ULONG t_Address = inet_addr ( t_AsciiServer ) ; if ( t_Address != INADDR_NONE ) { char t_LocalMachine [MAX_PATH]; DWORD t_LocalMachineSize = MAX_PATH; if ( GetComputerName ( t_LocalMachine , & t_LocalMachineSize ) ) { hostent *t_HostEntry = gethostbyname ( t_LocalMachine ); if ( t_HostEntry ) { int t_Length = strlen ( t_HostEntry->h_name ) ; char *t_LocalName = new char [ strlen ( t_HostEntry->h_name ) + 1 ] ; strcpy ( t_LocalName , t_HostEntry->h_name ) ; t_HostEntry = gethostbyaddr ( ( char * ) & t_Address , sizeof ( ULONG ) , AF_INET ) ; if ( t_HostEntry ) { if ( stricmp ( t_LocalName , t_HostEntry->h_name ) == 0 ) { if ( gAddr == UUID_LocalAddrType ) { *pbBinaryAddress = (BYTE *)CoTaskMemAlloc(8); if(*pbBinaryAddress == NULL) { delete [] t_ServerMachine ; return WBEM_E_FAILED; } wcscpy((LPWSTR)*pbBinaryAddress, L"\\\\."); *pdwAddressLength = 8; } else { t_Result = WBEM_E_FAILED ; } } else { if ( gAddr == UUID_IWbemAddressResolver_Tcpip ) { *pdwAddressLength = sizeof ( ULONG ) ; *pbBinaryAddress = (BYTE *)CoTaskMemAlloc ( sizeof ( ULONG ) ) ; if(*pbBinaryAddress != NULL) { ULONG *t_Pointer = ( ULONG * ) *pbBinaryAddress ; *t_Pointer = ntohl ( t_Address ) ; } } else { t_Result = WBEM_E_FAILED ; } } } else { t_Result = WBEM_E_FAILED ; } delete [] t_LocalName ; } else { t_Result = WBEM_E_FAILED ; } } else { t_Result = WBEM_E_FAILED ; } } else { char t_LocalMachine [MAX_PATH]; DWORD t_LocalMachineSize = MAX_PATH; if ( GetComputerName ( t_LocalMachine , & t_LocalMachineSize ) ) { hostent *t_HostEntry = gethostbyname ( t_LocalMachine ); if ( t_HostEntry ) { int t_Length = strlen ( t_HostEntry->h_name ) ; char *t_LocalName = new char [ strlen ( t_HostEntry->h_name ) + 1 ] ; strcpy ( t_LocalName , t_HostEntry->h_name ) ; hostent *t_HostEntry = gethostbyname ( t_AsciiServer ); if ( t_HostEntry ) { if ( strcmp ( t_HostEntry->h_name , t_LocalName ) == 0 ) { // Local if ( gAddr == UUID_LocalAddrType ) { *pbBinaryAddress = (BYTE *)CoTaskMemAlloc(8); if(*pbBinaryAddress == NULL) { delete [] t_ServerMachine ; return WBEM_E_FAILED; } wcscpy((LPWSTR)*pbBinaryAddress, L"\\\\."); *pdwAddressLength = 8; } else { t_Result = WBEM_E_FAILED ; } } else { if ( gAddr == UUID_IWbemAddressResolver_Tcpip ) { int t_Index = 0 ; while ( t_HostEntry->h_addr_list[t_Index] ) { t_Index ++ ; } *pdwAddressLength = t_Index * sizeof ( ULONG ) ; *pbBinaryAddress = (BYTE *)CoTaskMemAlloc ( t_Index * sizeof ( ULONG ) ) ; if(*pbBinaryAddress != NULL) { ULONG *t_Pointer = ( ULONG * ) *pbBinaryAddress ; t_Index = 0 ; while ( t_HostEntry->h_addr_list[t_Index] ) { ULONG t_Address = *((unsigned long *) t_HostEntry->h_addr_list[t_Index]) ; *t_Pointer = ntohl ( t_Address ) ; t_Pointer ++ ; t_Index ++ ; } } else { t_Result = WBEM_E_FAILED ; } } else { t_Result = WBEM_E_FAILED ; } } } else { t_Result = WBEM_E_FAILED ; } delete [] t_LocalName ; } else { t_Result = WBEM_E_FAILED ; } } else { t_Result = WBEM_E_FAILED ; } } WSACleanup () ; } delete [] t_AsciiServer ; return t_Result ; } #endif //*************************************************************************** // // CComLink * CreateAnonPipeConn // // DESCRIPTION: // // Creates a AnonPipe connection. // and protocol list. // // PARAMETERS: // // RETURN VALUE: // // NULL if OK. pdwRet is also set if an error. // //*************************************************************************** CComLink *CreateAnonPipeConn ( IN CTransportStream &read, IN DWORD *pdwRet ) { HANDLE t_Read, t_Write, t_Term ; read.ReadDWORD ( (DWORD *) &t_Read ) ; read.ReadDWORD ( (DWORD *) &t_Write ) ; read.ReadDWORD ( (DWORD *) &t_Term ) ; if ( read.Status () != CTransportStream::no_error ) { *pdwRet = WBEM_E_INVALID_STREAM ; return NULL ; } CComLink *pRet = new CComLink_LPipe ( NORMALCLIENT , t_Read , t_Write , t_Term ) ; if ( pRet == NULL ) { *pdwRet = WBEM_E_OUT_OF_MEMORY ; } return pRet; } //*************************************************************************** // // STDAPI ClientSendAndGet // // DESCRIPTION: // // Used by clients to send a message to the server. // RETURN VALUE: // // S_OK if it is OK to unload // S_FALSE if still in use // //*************************************************************************** STDAPI ClientSendAndGet ( CTransportStream *a_Write , CTransportStream *a_Read ) { HRESULT t_Result = WBEM_E_TRANSPORT_FAILURE; BYTE *t_Buffer = NULL ; DWORD t_Size = 0 ; if ( a_Write->CMemStream :: Serialize ( &t_Buffer , &t_Size ) == CMemStream :: no_error ) { // Get the mutex and events. These are created by WINMGMT DWORD t_Timeout = GetTimeout () ; DWORD t_Status = WbemWaitForSingleObject ( g_Mutex , t_Timeout ) ; if ( t_Status == WAIT_OBJECT_0 ) { ResetEvent ( g_ReplyEvent ) ; g_SharedMemoryBuffer->m_Size = t_Size ; memcpy ( g_SharedMemoryBuffer->m_Buffer , t_Buffer , t_Size ) ; SetEvent ( g_RequestEvent ) ; // Wait for the server to be done, copy the data back t_Status = WbemWaitForSingleObject ( g_ReplyEvent , t_Timeout ) ; if ( t_Status == WAIT_OBJECT_0 ) { a_Read->CMemStream :: Deserialize ( ( BYTE * ) g_SharedMemoryBuffer->m_Buffer, g_SharedMemoryBuffer->m_Size ) ; a_Read->ReadDWORD ( ( DWORD * ) & t_Result ); } else { } } else { } delete t_Buffer; } ReleaseMutex ( g_Mutex ) ; return S_OK; } //*************************************************************************** // // CComLink * CreatePipeConnection // // DESCRIPTION: // // Establishes a connection. // // PARAMETERS: // // a_StubAddress set to server stub setup to handle this // a_Result set to error code, 0 if ok // // RETURN VALUE: // // Pointer to a CComLink object if all is well, NULL if error. // note that if failure, pdwRet is set to an error code // //*************************************************************************** CComLink *CreatePipeConnection ( OUT DWORD *a_StubAddress , OUT DWORD *a_Result ) { CComLink *t_ComLink = NULL ; DEBUGTRACE((LOG,"\nCreateConnect is starting")); // make the call. CTransportStream t_WriteStream ( CTransportStream:: auto_delete , NULL , 256 , 256 ) ; CTransportStream t_ReadStream ( CTransportStream::auto_delete , NULL , 256 , 256 ) ; t_WriteStream.WriteDWORD ( (DWORD) GetCurrentProcessId () ) ; *a_Result = ClientSendAndGet ( & t_WriteStream , & t_ReadStream ) ; DEBUGTRACE((LOG,"\nCreateConnection, after call, dwRet = %x", *a_Result )) ; if ( *a_Result == WBEM_NO_ERROR ) { t_ReadStream.ReadDWORD ( a_StubAddress ) ; t_ComLink = CreateAnonPipeConn ( t_ReadStream , a_Result ) ; } return t_ComLink ; } #ifdef TCPIP_MARSHALER CComLink *CreateTcpipConnection ( OUT DWORD *a_StubAddress , OUT DWORD *a_Result , IN DWORD a_AddressLength, IN BYTE *a_Address ) { if ( ! g_InitialisationComplete ) { g_InitialisationComplete = TRUE ; g_Terminate = CreateEvent(NULL,TRUE,FALSE,NULL); gMaintObj.StartClientThreadIfNeeded () ; } if ( ! g_TcpipInitialisationComplete ) { BOOL status = FALSE ; WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(1, 1); status = ( WSAStartup ( wVersionRequested , &wsaData ) == 0 ) ; if ( status ) { g_TcpipInitialisationComplete = TRUE ; } else { *a_Result = WBEM_E_TRANSPORT_FAILURE ; return NULL ; } } CComLink *t_ComLink = NULL ; SOCKET t_Socket = socket (AF_INET, SOCK_STREAM, 0); if ( t_Socket != SOCKET_ERROR ) { struct sockaddr_in t_RemoteAddress ; t_RemoteAddress .sin_family = AF_INET; t_RemoteAddress.sin_port = htons (4000); if ( a_AddressLength ) { t_RemoteAddress.sin_addr.s_addr = htonl ( * ( ULONG * ) a_Address ); } else { t_RemoteAddress.sin_addr.s_addr = htonl ( INADDR_LOOPBACK ); } int t_Status = connect ( t_Socket , ( sockaddr * ) & t_RemoteAddress, sizeof ( t_RemoteAddress ) ) ; if ( t_Status != SOCKET_ERROR ) { DWORD t_ReadStreamStatus = CTransportStream::no_error; CTransportStream t_ReadStream ; switch ( t_ReadStream.Deserialize ( t_Socket , INFINITE ) ) { case CTransportStream :: no_error: { t_ReadStreamStatus |= t_ReadStream.ReadDWORD ( a_Result ) ; t_ReadStreamStatus |= t_ReadStream.ReadDWORD ( a_StubAddress ) ; t_ComLink = new CComLink_Tcpip ( NORMALSERVER , t_Socket ); if ( t_ComLink == NULL ) { } } break ; default: { *a_Result = WBEM_E_TRANSPORT_FAILURE ; closesocket ( t_Socket ) ; } break ; } } else { closesocket ( t_Socket ) ; *a_Result = WBEM_E_TRANSPORT_FAILURE ; } } else { *a_Result = WBEM_E_TRANSPORT_FAILURE ; } return t_ComLink ; } #endif //*************************************************************************** // // SCODE RequestLogin // // DESCRIPTION: // // Connects up to either local or remote WBEM Server for a login interface. // returns a standard SCODE and more importantly sets the address of an initial // stub pointer. // // PARAMETERS: // // ppLogin set to login proxy // dwType set to the connection type, Inproc, local or remote // // RETURN VALUE: // // S_OK all is well // else error listed in WBEMSVC.H // //*************************************************************************** SCODE RequestLogin ( OUT IServerLogin FAR* FAR* a_Login , DWORD &a_LocalRemoteFlag , TransportType a_TransportType , IN DWORD a_AddressLength, IN BYTE *a_Address ) { EnterCriticalSection ( & g_GlobalCriticalSection ) ; DWORD t_Return = WBEM_E_INVALID_PARAMETER; USES_CONVERSION; // Verify arguments DEBUGTRACE((LOG,"\nRequestLogin called")); if ( a_Login == NULL ) { DEBUGTRACE((LOG,"\nRequestLogin got passed a NULL ppLogin")); } else { *a_Login = NULL; // Extract the server name and determine if the connection is to // be local. DWORD t_StubAddress ; CComLink *t_ComLink = NULL ; switch ( a_TransportType ) { case PipeTransport: { if ( ! StartLocalServer () ) { t_Return = WBEM_E_TRANSPORT_FAILURE ; TRACE((LOG,"\nRequestLogin failed bStartLocalServer")); } else { t_ComLink = CreatePipeConnection ( &t_StubAddress , &t_Return ); } } break ; #ifdef TCPIP_MARSHALER default: { a_LocalRemoteFlag = WBEM_FLAG_REMOTE_LOGIN ; t_ComLink = CreateTcpipConnection ( &t_StubAddress , &t_Return , a_AddressLength , a_Address ); } break ; #else default: { } break ; #endif } DEBUGTRACE((LOG,"\nRequestLogin did connect, pCom=%x",t_ComLink)); if ( t_ComLink == NULL ) { } else { // Set the notification stub and do a ping to make sure the connection is ok. // ============================================================================== t_Return = t_ComLink->ProbeConnection () ; if ( FAILED ( t_Return ) & ( t_ComLink->GetStatus () != CComLink::no_error ) ) { TRACE((LOG,"\nRequestLogin failed pinging")); } else { // Create the new prox object, note that the CProvProxy constructor // does an "AddRef" on the pCom object and so a Release2 can now be // done to counteract the CComLink constructor which sets the ref count // to 1. CStubAddress_WinMgmt t_WinMgmtStubAddress (t_StubAddress); *a_Login = new CLoginProxy_LPipe ( t_ComLink , t_WinMgmtStubAddress ) ; if ( ! bVerifyPointer ( *a_Login ) ) { *a_Login = NULL ; t_Return = WBEM_E_OUT_OF_MEMORY ; } else { t_ComLink->Release2 ( NULL , NONE ) ; DEBUGTRACE((LOG,"\nsuccessfully started connection")) ; t_Return = WBEM_NO_ERROR ; } } } if ( t_ComLink && t_Return != WBEM_NO_ERROR ) { gMaintObj.ShutDownComlink ( t_ComLink ) ; } } if ( t_Return ) { DEBUGTRACE((LOG,"\nfailed trying to connect, error code of %x", t_Return)); } else { DEBUGTRACE((LOG,"\nConnect succeeded")); } LeaveCriticalSection ( & g_GlobalCriticalSection ) ; return t_Return ; }