windows-nt/Source/XPSP1/NT/com/mobile/syncmgr/dll/rasproc.cpp
2020-09-26 16:20:57 +08:00

476 lines
11 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1998.
//
// File: RasProc.cpp
//
// Contents: Exports used by Ras for doing Pending Disconnect
//
// Classes:
//
// Notes:
//
// History: 09-Jan-98 rogerg Created.
//
//--------------------------------------------------------------------------
// Windows Header Files:
// !!! define this file winver to be at least 5.0 so we can get
// NT 5.0 specific ras structures and still be a single binary
// Ras calls made on < 50 will fail because structure is wrong size.
// Do not use preocompiled headers since they would have already defined
// the Winver to be 40
#ifdef WINVER
#undef WINVER
#endif
#define WINVER 0x500
#include <windows.h>
#include <commctrl.h>
#include <objbase.h>
#include "mobsync.h"
#include "mobsyncp.h"
#include "debug.h"
#include "alloc.h"
#include "critsect.h"
#include "netapi.h"
#include "syncmgrr.h"
#include "rasui.h"
#include "dllreg.h"
#include "cnetapi.h"
#include "rasproc.h"
extern OSVERSIONINFOA g_OSVersionInfo; // osVersionInfo.
//+-------------------------------------------------------------------
//
// Function: SyncMgrRasProc
//
// Synopsis: Main entry point for RAS to call to perform
// a pending disconnect.
//
// Arguments:
//
//
// Notes:
//
//--------------------------------------------------------------------
LRESULT CALLBACK SyncMgrRasProc(UINT uMsg,WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case SYNCMGRRASPROC_QUERYSHOWSYNCUI:
return SyncMgrRasQueryShowSyncUI(wParam,lParam);
break;
case SYNCMGRRASPROC_SYNCDISCONNECT:
return SyncMgrRasDisconnect(wParam,lParam);
break;
default:
AssertSz(0,"Unknown RasProc Message");
break;
};
return -1;
}
//+-------------------------------------------------------------------
//
// Function: SyncMgrRasQueryShowSyncUI
//
// Synopsis: Called by RAS to determine if Ras Should show
// the Disconnect checkbox and what state it should be.
//
// Arguments:
// wParam = 0
// lParam = Pointer to SYNCMGRQUERYSHOWSYNCUI structure
//
// Notes:
//
//--------------------------------------------------------------------
LRESULT SyncMgrRasQueryShowSyncUI(WPARAM wParam,LPARAM lParam)
{
CNetApi *pNetApi;
SYNCMGRQUERYSHOWSYNCUI *pQueryStruct = (SYNCMGRQUERYSHOWSYNCUI *) lParam;
// RASENTRY rasEntry;
// TCHAR lpszEntry[RAS_MaxEntryName + 1];
LRESULT lResult = -1;
if (pQueryStruct->cbSize != sizeof(SYNCMGRQUERYSHOWSYNCUI))
{
Assert(pQueryStruct->cbSize == sizeof(SYNCMGRQUERYSHOWSYNCUI));
return -1;
}
pQueryStruct->fShowCheckBox = FALSE;
pQueryStruct->nCheckState = BST_UNCHECKED;
pNetApi = new CNetApi();
if (!pNetApi)
{
AssertSz(0,"Failed to Load Ras");
return -1;
}
RegSetUserDefaults(); // Make Sure the UserDefaults are up to date
// don't use guid lookup, instead just use the passed in name.
if (1 /* NOERROR == pNetApi->RasConvertGuidToEntry(&(pQueryStruct->GuidConnection),
(LPTSTR) &lpszEntry,
&rasEntry) */)
{
CONNECTIONSETTINGS connectSettings;
lstrcpy(connectSettings.pszConnectionName,pQueryStruct->pszConnectionName); // Review, should just pass this to Function
// look up preferences for this entry and see if disconnect has been chosen.
lResult = 0; // return NOERROR even if no entry is found
if (RegGetAutoSyncSettings(&connectSettings))
{
if (connectSettings.dwLogoff)
{
pQueryStruct->fShowCheckBox = TRUE;
pQueryStruct->nCheckState = BST_CHECKED;
}
}
}
pNetApi->Release();
return lResult;
}
//+-------------------------------------------------------------------
//
// Function: SyncMgrRasDisconnect
//
// Synopsis: Main entry point for RAS to call to perform
// a pending disconnect.
//
// Arguments:
// wParam = 0
// lParam = Pointer to SYNCMGRSYNCDISCONNECT structure
//
// Notes:
//
//--------------------------------------------------------------------
LRESULT SyncMgrRasDisconnect(WPARAM wParam,LPARAM lParam)
{
CNetApi *pNetApi;
SYNCMGRSYNCDISCONNECT *pDisconnectStruct = (SYNCMGRSYNCDISCONNECT *) lParam;
TCHAR szEntry[RAS_MaxEntryName + 1];
// RASENTRY rasEntry;
if (pDisconnectStruct->cbSize != sizeof(SYNCMGRSYNCDISCONNECT))
{
Assert(pDisconnectStruct->cbSize == sizeof(SYNCMGRSYNCDISCONNECT));
return -1;
}
pNetApi = new CNetApi();
if (!pNetApi)
{
AssertSz(0,"Failed to Load Ras");
return -1;
}
if (1 /* NOERROR == pNetApi->RasConvertGuidToEntry(&(pDisconnectStruct->GuidConnection),
(LPTSTR) &szEntry,
&rasEntry) */)
{
HRESULT hr;
LPUNKNOWN lpUnk;
// invoke SyncMgr.exe informing it is a Logoff and then wait in
// a message loop until the event we pass in gets signalled.
lstrcpy(szEntry,pDisconnectStruct->pszConnectionName);
hr = CoInitialize(NULL);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_SyncMgrp,NULL,CLSCTX_ALL,IID_IUnknown,(void **) &lpUnk);
if (NOERROR == hr)
{
LPPRIVSYNCMGRSYNCHRONIZEINVOKE pSynchInvoke = NULL;
hr = lpUnk->QueryInterface(IID_IPrivSyncMgrSynchronizeInvoke,
(void **) &pSynchInvoke);
if (NOERROR == hr)
{
// should have everything we need
hr = pSynchInvoke->RasPendingDisconnect(
(RAS_MaxEntryName + 1)*sizeof(TCHAR),
(BYTE *) szEntry);
pSynchInvoke->Release();
}
lpUnk->Release();
}
CoUninitialize();
}
}
pNetApi->Release();
return 0;
}
// !!!!These method are in this file so we can locally define WINVER to be 5.0 so we
// get the proper rasentry size.
#define RASENTRYNAMEW struct tagRASENTRYNAMEW
typedef struct _tagRASENTRYNAME40W
{
DWORD dwSize;
WCHAR szEntryName[ RAS_MaxEntryName + 1 ];
} RASENTRYNAME40W;
//+-------------------------------------------------------------------
//
// Member: CNetApi::RasEnumEntriesNT50
//
// Synopsis: enums the RasEntries thunking to the NT50 structure.
//
//
// Notes: Only Available on NT 5.0
//
//--------------------------------------------------------------------
DWORD CNetApi::RasEnumEntriesNT50(LPWSTR reserved,LPWSTR lpszPhoneBook,
LPRASENTRYNAME lprasEntryName,LPDWORD lpcb,LPDWORD lpcEntries)
{
BOOL fIsNT = (g_OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
LPRASENTRYNAME lpRasEntryNT50 = NULL;
DWORD cbSizeNT50 = 0;
DWORD dwReturn;
// if ras isn't loaded just return false
// call ras exports directly fro here to ensure
// we stick with 5.0 sizes.
if (!fIsNT || g_OSVersionInfo.dwMajorVersion < 5)
{
Assert(fIsNT);
Assert(g_OSVersionInfo.dwMajorVersion >= 5);
return -1;
}
if (NOERROR != LoadRasApiDll())
{
return -1;
}
// if there is an entry name set up the NT 5.0 size.
if (lprasEntryName)
{
DWORD cbNumRasEntries;
Assert(lprasEntryName->dwSize == sizeof(RASENTRYNAME40W));
cbNumRasEntries = (*lpcb)/sizeof(RASENTRYNAME40W);
Assert(cbNumRasEntries > 0);
if (cbNumRasEntries)
{
cbSizeNT50 = sizeof(RASENTRYNAME)*cbNumRasEntries;
lpRasEntryNT50 = (RASENTRYNAME *) ALLOC(cbSizeNT50);
if (NULL == lpRasEntryNT50)
{
// if out of memory, return an error.
return -1;
}
else
{
lpRasEntryNT50->dwSize = sizeof(RASENTRYNAME);
}
}
}
dwReturn = (*m_pRasEnumEntriesW)(reserved,lpszPhoneBook,
lpRasEntryNT50,&cbSizeNT50,lpcEntries);
// set out buffer to size return dbSizeNT50. Bigger than
// we need but then don't have to worry.
*lpcb = cbSizeNT50;
// on success thunk back to original structure.
if (0 == dwReturn && lpRasEntryNT50)
{
DWORD dwItems = *lpcEntries;
RASENTRYNAME40W *pCurRasEntry = (RASENTRYNAME40W *) lprasEntryName;
LPRASENTRYNAME pCurRasEntryNT50 = lpRasEntryNT50;
while(dwItems--)
{
pCurRasEntry->dwSize = sizeof(RASENTRYNAME40W);
lstrcpy(pCurRasEntry->szEntryName,pCurRasEntryNT50->szEntryName);
++pCurRasEntry;
++pCurRasEntryNT50;
}
}
if (lpRasEntryNT50)
{
FREE(lpRasEntryNT50);
}
return dwReturn;
}
//+-------------------------------------------------------------------
//
// Member: CNetApi::RasConvertGuidToEntry
//
// Synopsis: Given a Guid, convert, finds the corresponding
// Ras Entry.
//
// Arguments:
// pGuid - Guid of Connection to Convert.
// lpszEntry - PhoneBook Entry if a match is found.
// pRasEntry - Points to valid RasEntry structure if a match is found.
//
// Notes: Only Available on NT 5.0
//
//--------------------------------------------------------------------
STDMETHODIMP CNetApi::RasConvertGuidToEntry(GUID *pGuid,LPTSTR lpszEntry,RASENTRY *pRasEntry)
{
DWORD dwSize;
DWORD cEntries;
DWORD dwError = -1;
LPRASENTRYNAME lprasentry;
BOOL fFoundMatch = FALSE;
// if ras isn't loaded just return false
// call ras exports directly fro here to ensure
// we stick with 5.0 sizes.
Assert(m_fIsUnicode);
if (NOERROR != LoadRasApiDll())
{
return S_FALSE;
}
if (!m_hInstRasApiDll || (NULL == m_pRasEnumEntriesW)
|| (NULL == m_pRasGetEntryPropertiesW) )
{
return S_FALSE;
}
dwSize = sizeof(RASENTRYNAME);
lprasentry = (LPRASENTRYNAME) ALLOC(dwSize);
if(!lprasentry)
{
goto error;
}
lprasentry->dwSize = sizeof(RASENTRYNAME);
cEntries = 0;
dwError = (*m_pRasEnumEntriesW)(NULL, NULL,lprasentry, &dwSize, &cEntries);
if (dwError == ERROR_BUFFER_TOO_SMALL)
{
FREE(lprasentry);
lprasentry = (LPRASENTRYNAME) ALLOC(dwSize);
if(!lprasentry)
goto error;
lprasentry->dwSize = sizeof(RASENTRYNAME);
cEntries = 0;
dwError = (*m_pRasEnumEntriesW)(NULL, NULL,lprasentry, &dwSize, &cEntries);
}
if (0 != dwError)
{
goto error;
}
while(cEntries && !fFoundMatch)
{
TCHAR *pszEntryName = lprasentry[cEntries-1].szEntryName;
TCHAR *pszPhoneBookName = lprasentry[cEntries-1].szPhonebookPath;
DWORD dwSizeRasEntry;
LPRASENTRY pRasEntry;
DWORD dwErr;
dwSizeRasEntry = 0;
// get the required size
if (ERROR_BUFFER_TOO_SMALL ==
(*m_pRasGetEntryPropertiesW)(pszPhoneBookName,pszEntryName,NULL, &dwSizeRasEntry,NULL,NULL))
{
// allocate the required size.
pRasEntry = (LPRASENTRY) ALLOC(dwSizeRasEntry);
if (pRasEntry)
{
pRasEntry->dwSize = sizeof(RASENTRY);
if (0 == (dwErr = (*m_pRasGetEntryPropertiesW)(pszPhoneBookName,pszEntryName, (LPBYTE) pRasEntry, &dwSizeRasEntry,NULL,NULL)))
{
if (IsEqualGUID(pRasEntry->guidId,*pGuid))
{
lstrcpy(lpszEntry,pszEntryName);
fFoundMatch = TRUE;
}
}
FREE(pRasEntry);
}
}
cEntries--;
}
if (FALSE == fFoundMatch)
dwError = -1;
error:
return (dwError == 0) ? NOERROR : S_FALSE;
}