|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: transmgr.cxx
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 12-02-95 JohannP (Johann Posch) Created
//
//----------------------------------------------------------------------------
#include <trans.h>
PerfDbgTag(tagCTransMgr, "Urlmon", "Log CTransactionMgr", DEB_TRANSMGR); DbgTag(tagCTransMgrErr, "Urlmon", "Log CTransMgr Errors", DEB_TRANSMGR|DEB_ERROR);
extern HINSTANCE g_hInst; LRESULT CALLBACK TransactionWndProc(HWND hWnd, UINT msg,WPARAM wParam, LPARAM lParam);
#define szURLMonClassName "URL Moniker Notification Window"
static BOOL g_fWndClassRegistered = FALSE; CMutexSem g_mxsTransMgr;
URLMON_TS* GetTS(DWORD); HRESULT AddTSToList(URLMON_TS*);
//+---------------------------------------------------------------------------
//
// Function: GetThreadTransactionMgr
//
// Synopsis:
//
// Arguments: [fCreate] --
//
// Returns:
//
// History: 1-14-96 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
CTransactionMgr * GetThreadTransactionMgr(BOOL fCreate) { DEBUG_ENTER((DBG_TRANSMGR, Pointer, "GetThreadTransactionMgr", "%B", fCreate )); PerfDbgLog(tagCTransMgr, NULL, "+GetThreadTransactionMgr"); // only one thread should be here
CLock lck(g_mxsMedia);
HRESULT hr = NOERROR; CTransactionMgr *pCTMgr = NULL;
CUrlMkTls tls(hr); if (hr == NOERROR) { pCTMgr = tls->pCTransMgr;
if ((pCTMgr == NULL) && fCreate) { // the transaction mgr has an refcount of 1
tls->pCTransMgr = pCTMgr = new CTransactionMgr; } }
PerfDbgLog1(tagCTransMgr, NULL, "-GetThreadTransactionMgr (pCTMgr:%lx)", pCTMgr);
DEBUG_LEAVE(pCTMgr); return pCTMgr; }
//+---------------------------------------------------------------------------
//
// Function: GetTransactionMgr
//
// Synopsis:
//
// Arguments: [fCreate] --
//
// Returns:
//
// History: 12-06-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
CTransactionMgr * GetTransactionMgr(BOOL fCreate) { DEBUG_ENTER((DBG_TRANSMGR, Pointer, "GetTransactionMgr", "%B", fCreate )); CTransactionMgr* pCTransMgr = GetThreadTransactionMgr(fCreate);
DEBUG_LEAVE(pCTransMgr); return pCTransMgr; }
//+---------------------------------------------------------------------------
//
// Function: RegisterUrlMkWndClass
//
// Synopsis: register the Url Moniker window class on demand
//
// Arguments: (none)
//
// Returns: return FALSE if class could not be registered
//
// History: 12-02-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL RegisterUrlMkWndClass() { DEBUG_ENTER((DBG_TRANSMGR, Bool, "RegisterUrlMkWndClass", NULL )); // only one thread should be here
CLock lck(g_mxsMedia);
if (g_fWndClassRegistered == FALSE) { // else register the window class
WNDCLASS wndclass;
wndclass.style = 0; wndclass.lpfnWndProc = &TransactionWndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = g_hInst; wndclass.hIcon = NULL; wndclass.hCursor = NULL;; wndclass.hbrBackground = (HBRUSH)NULL; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szURLMonClassName;
// Register the window class
if (!RegisterClass(&wndclass)) { DWORD dwLastError = GetLastError();
if(dwLastError == ERROR_CLASS_ALREADY_EXISTS) { g_fWndClassRegistered = TRUE; } else { DEBUG_PRINT(TRANSMGR, ERROR, ("RegisterUrlMkWndClass(): RegisterClass failed, GetLastError: %ld\n", dwLastError)); TransAssert(FALSE); } } else { g_fWndClassRegistered = TRUE; } }
DEBUG_LEAVE(g_fWndClassRegistered); return g_fWndClassRegistered; }
//+---------------------------------------------------------------------------
//
// Function: UnregisterUrlMkWndClass
//
// Synopsis: unregisters the hidden windows class
//
// Arguments: (none)
//
// Returns:
//
// History: 10-16-1996 JohannP (Johann Posch) Created
//
// Notes: called during process detach
//
//----------------------------------------------------------------------------
BOOL UnregisterUrlMkWndClass() { DEBUG_ENTER((DBG_TRANSMGR, Bool, "UnregisterUrlMkWndClass", NULL )); if (g_fWndClassRegistered == TRUE) { // Register the window class
if (UnregisterClass(szURLMonClassName,g_hInst)) { g_fWndClassRegistered = FALSE; } else { DEBUG_PRINT(TRANSMGR, ERROR, ("UnregisterUrlMkWndClass(): UnregisterClass failed, GetLastError: %ld\n", GetLastError())); } }
DEBUG_LEAVE(g_fWndClassRegistered); return g_fWndClassRegistered; }
//+---------------------------------------------------------------------------
//
// Function: GetThreadNotificationWnd
//
// Synopsis: return the notification for the current
// the window is created if
//
// Arguments: [fCreate] -- TRUE if the window should be created
//
// Returns:
//
// History: 12-02-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
#ifndef HWND_MESSAGE
#define HWND_MESSAGE ((HWND)-3)
#endif
extern BOOL g_bNT5OrGreater;
HWND GetThreadNotificationWnd(BOOL fCreate) { DEBUG_ENTER((DBG_TRANSMGR, Dword, "GetThreadNotificationWnd", "%B", fCreate )); HRESULT hr = NOERROR; HWND hwnd = NULL;
DWORD tid = GetCurrentThreadId(); URLMON_TS* ts = NULL;
ts = GetTS(tid); if( ts ) { hwnd = ts->_hwndNotify; TransAssert((hwnd != NULL && "TS Corrupted!")); } else { ts = new URLMON_TS; if( ts ) { if ( fCreate && (hwnd == NULL) && RegisterUrlMkWndClass() ) { hwnd = CreateWindowEx(0, szURLMonClassName, NULL, 0, 0, 0, 0, 0, g_bNT5OrGreater ? HWND_MESSAGE : NULL, NULL, g_hInst, NULL);
TransAssert((hwnd != NULL && "can't create Notify window")); if (hwnd) { ts->_dwTID = tid; ts->_hwndNotify = hwnd;
AddTSToList(ts); } } else { delete ts; } }
} /**************************************************************************
CUrlMkTls tls(hr);
if (hr == NOERROR) { hwnd = tls->hwndUrlMkNotify;
if ( fCreate && (hwnd == NULL) && RegisterUrlMkWndClass() ) { hwnd = CreateWindowEx(0, szURLMonClassName, NULL, 0, 0, 0, 0, 0, NULL, NULL, g_hInst, NULL);
TransAssert((hwnd != NULL && "GetNotificationWnd: could not create window")); if (hwnd) { tls->hwndUrlMkNotify = hwnd; char achProgname[256]; achProgname[0] = '\0'; GetModuleFileNameA(NULL, achProgname, sizeof(achProgname)); } } } ***************************************************************************/
DEBUG_LEAVE(hwnd); return hwnd; }
//+---------------------------------------------------------------------------
//
// Method: CTransactionMgr::CTransactionMgr
//
// Synopsis:
//
// Arguments: (none)
//
// Returns:
//
// History: 1-14-96 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
CTransactionMgr::CTransactionMgr() : CLifePtr() { DEBUG_ENTER((DBG_TRANSMGR, None, "CTransactionMgr::CTransactionMgr", "this=%#x", this )); _pCTransFirst = NULL; _pCTransLast = NULL;
DEBUG_LEAVE(0); }
//+---------------------------------------------------------------------------
//
// Method: CTransactionMgr::~CTransactionMgr
//
// Synopsis:
//
// Arguments: (none)
//
// Returns:
//
// History: 1-14-96 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
CTransactionMgr::~CTransactionMgr() { DEBUG_ENTER((DBG_TRANSMGR, None, "CTransactionMgr::~CTransactionMgr", "this=%#x", this )); // The list should be empty by the time it gets destroyed
if (_pCTransFirst) { DbgLog1(tagCTransMgr, this, "CTransactionMgr::~CTransactionMgr (list not empty:%lx)", _pCTransFirst); }
//TransAssert(( _pCTransFirst == NULL ));
DEBUG_LEAVE(0); }
//+---------------------------------------------------------------------------
//
// Method: CTransactionMgr::AddTransaction
//
// Synopsis: Add an internet transaction to the linked list.
//
// Arguments: [pCTrans] --
//
// Returns:
//
// History: 12-12-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT CTransactionMgr::AddTransaction(CTransaction *pCTrans) { DEBUG_ENTER((DBG_TRANSMGR, Hresult, "CTransactionMgr::AddTransaction", "this=%#x, %#x", this, pCTrans )); PerfDbgLog(tagCTransMgr, this, "+CTransMgr::AddTransaction"); TransAssert((pCTrans != NULL));
TransAssert((pCTrans->GetNextTransaction() == NULL));
pCTrans->SetNextTransaction(_pCTransFirst); _pCTransFirst = pCTrans; AddRef();
PerfDbgLog1(tagCTransMgr, this, "-CTransMgr::AddTransaction(hr:%lx)", NOERROR);
DEBUG_LEAVE(NOERROR); return NOERROR; }
//+---------------------------------------------------------------------------
//
// Method: CTransactionMgr::RemoveTransaction
//
// Synopsis: Removes a transaction from the linked list. If the transaction
// cannot be found, E_FAIL is returned.
//
// Arguments: [pCTrans] --
//
// Returns:
//
// History: 12-12-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT CTransactionMgr::RemoveTransaction(CTransaction *pCTrans) { DEBUG_ENTER((DBG_TRANSMGR, Hresult, "CTransactionMgr::RemoveTransaction", "this=%#x, %#x", this, pCTrans )); PerfDbgLog(tagCTransMgr, this, "+CTransMgr::RemoveTransaction"); CLock lck(g_mxsTransMgr); CTransaction *pCTransPrev = NULL; CTransaction *pCTransTmp; HRESULT hr = E_FAIL;
TransAssert((pCTrans != NULL));
pCTransTmp = _pCTransFirst;
TransAssert((pCTransTmp != NULL));
// Search all the nodes in the linked list
if (_pCTransFirst == pCTrans) { _pCTransFirst = _pCTransFirst->GetNextTransaction(); hr = NOERROR; Release(); } else while (pCTransTmp != NULL) { // If a match is found
if (pCTransTmp == pCTrans) { // Remove it from the linked list
if (pCTransPrev == NULL) { _pCTransFirst = pCTrans->GetNextTransaction(); } else { pCTransPrev->SetNextTransaction(pCTrans->GetNextTransaction()); }
hr = NOERROR; Release(); }
pCTransPrev = pCTransTmp; pCTransTmp = pCTransTmp->GetNextTransaction(); }
TransAssert((hr == NOERROR));
PerfDbgLog1(tagCTransMgr, this, "-CTransMgr::RemoveTransaction (hr:%lx)", hr);
DEBUG_LEAVE(hr); return hr; }
//+---------------------------------------------------------------------------
//
// Function: GetTransactionObjects
//
// Synopsis:
//
// Arguments: [pBndCtx] --
// [wzUrl] --
// [pUnkOuter] --
// [ppUnk] --
// [ppCTrans] --
// [dwOption] --
// [ppCTranSData] --
//
// Returns:
//
// History: 4-12-1997 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT GetTransactionObjects(LPBC pBndCtx, LPCWSTR wzUrl, IUnknown *pUnkOuter, IUnknown **ppUnk, IOInetProtocol **ppCTrans, DWORD dwOption, CTransData **ppCTransData) { DEBUG_ENTER((DBG_TRANSMGR, Hresult, "GetTransactionObjects", "%#x, %.80wq, %#x, %#x, %#x, %#x, %#x", pBndCtx, wzUrl, pUnkOuter, ppUnk, ppCTrans, dwOption, ppCTransData )); HRESULT hr = S_OK; PerfDbgLog(tagCTransMgr, NULL, "+GetTransactionObjects"); TransAssert((ppCTrans != NULL)); CTransaction *pCTransTmp = NULL;
BOOL fFound = FALSE; CLock lck(g_mxsTransMgr);
CBindCtx *pCBndCtx = NULL;
if (pBndCtx) { hr = pBndCtx->QueryInterface(IID_IAsyncBindCtx, (void **) &pCBndCtx);
if (hr == NOERROR) { TransAssert((pCBndCtx)); hr = pCBndCtx->GetTransactionObjects(&pCTransTmp, ppCTransData); if (hr == NOERROR) { TransAssert((pCTransTmp));
if (!pCTransTmp->IsApartmentThread()) { pCBndCtx->SetTransactionObject(NULL); }
fFound = TRUE; hr = S_FALSE; } }
if (hr != S_FALSE && hr != NOERROR) { CBinding *pCBdgBindToObject = NULL; hr = pBndCtx->GetObjectParam(SZ_BINDING, (IUnknown **)&pCBdgBindToObject);
if (pCBdgBindToObject) { pCTransTmp = (CTransaction *) pCBdgBindToObject->GetOInetBinding(); fFound = pCTransTmp ? true : false; pCTransTmp->AddRef(); pCBdgBindToObject->Release(); DbgLog1(tagCTransMgr, NULL, "=== CTransMgr::GetTransaction Found Transaction:%lx", pCTransTmp); } }
}
if (!fFound) { CTransactionMgr *pCTransMgr = GetThreadTransactionMgr();
if (!pCTransMgr) { hr = E_OUTOFMEMORY; } else { // create a new transaction add it to the list
hr = CTransaction::Create(pCBndCtx, dwOption, 0, 0, &pCTransTmp); if (hr == NOERROR) { hr = pCTransTmp->QueryInterface(IID_IOInetProtocol, (void **) ppCTrans);
if (hr == NOERROR) { pCTransTmp->Release(); pCTransMgr->AddTransaction(pCTransTmp); } if (!pCBndCtx && pBndCtx) { pBndCtx->QueryInterface(IID_IAsyncBindCtx, (void **) &pCBndCtx); } if (pCBndCtx) { pCBndCtx->SetTransactionObject(pCTransTmp); } } } } else if (pCTransTmp) { DbgLog1(tagCTransMgr, NULL, "GetTransactionObjects Found existing transaction(%lx)", pCTransTmp); // return false to indicate found existing transaction
hr = S_FALSE; }
if (pCBndCtx) { pCBndCtx->Release(); }
*ppCTrans = pCTransTmp;
if (*ppCTrans && ppCTransData && *ppCTransData) { hr = S_FALSE; }
if( hr == S_FALSE && ppCTransData && !*ppCTransData ) { hr = S_OK; }
PerfDbgLog2(tagCTransMgr, NULL, "-API GetTransactionObjects (pCTrans:%lx; hr:%lx)", pCTransTmp, hr);
DEBUG_LEAVE(hr); return hr; }
|