Crossposted in microsoft.public.inetserver.iis and
microsoft.public.platformsdk.complus_mts
Kristoffer
After some investigation of the existing project.
I am no longer so sure that the .dlls I have are ISAPI.
The .dlls are called from ASP using a com interface. See code samples
below.
The bad news is that the .dlls I have depend on MTS.
I have to move them to COM+, I am trying to see how this is done now.
I got some references to some articles on that:
Porting Applications from MTS to COM+
<a style='text-decoration: underline;' href="http://msdn.microsoft.com/msdnmag/issues/0300/basics/default.aspx" target="_blank">http://msdn.microsoft.com/msdnmag/issues/0300/basics/default.aspx</a>
Migrating from MTS to COM+
<a style='text-decoration: underline;' href="http://msdn.microsoft.com/msdnmag/issues/0700/Serving/" target="_blank">http://msdn.microsoft.com/msdnmag/issues/0700/Serving/</a>
For debugging ASP code, the easiest way is to use Response.Write :
Does anyone have a reference where some article that describes moving
over some C++ MTS project to COM+?
Code samples from my project. I have tried to cut a lot out hope that
the rest still makes sence.
Example of ow my .dlls are called from ASP.
<%@ Language=VBScript %>
<%
set myagent= server.CreateObject("GATEWAY20.Agent")
if not isempty(Request("signout.x")) then
myagent.create(session("context"))
myagent.logout
set myagent = nothing
session("context") = ""
session("user_name")=""
session("user_id") = -1
response.redirect("default.asp")
end if
status = myagent.login(trim(request("user")),trim(request("pwd")))
if status = 0 then
session("context")="loginfailed"
session("user_name")=""
session("user_id") = -1
response.redirect("default.asp")
elseif status=-1 then
myagent.logout
session("context") = ""
session("user_name")=""
session("user_id") = -1
end if
myagent.login trim(request("user")),trim(request("pwd"))
session("context") = myagent.getcontext
session("user_name")= myagent.getdisplayname
session("user_id") = myagent.getuserid
%>
<html>
<head>
…
...
...
<tr valign=top>
<td valign="top" height=300>
<form action="gwmain.asp" method="post" id="LoginForm"
NAME="LoginForm" LANGUAGE=javascript onsubmit="return
LoginForm_onsubmit()">
<table border=0>
<tr width=50></tr>
<tr>
<td width=80><font color="darkred">Login :</td>
<td width=100><input size=15 type="text" id="user" name="user"
tabindex=1></font></td>
<td align=right rowspan="2" width=100><input type="submit"
value="Sign-in" id="Sign-in" name="login" tabindex=3></td>
</tr>
<tr>
<td width=80><font color="darkred"> Password :</td>
<td width=100><input size=15 type="password" id="pwd" name="pwd"
tabindex=2></font></td>
</tr>
</table>
</form>
</td>
</tr>
My .idl interface file looks like this:
interface IAgent : IDispatch
{
HRESULT GetUserid([out,retval] long* userid);
HRESULT GetLogin([out,retval] BSTR* login);
HRESULT GetPassword([out,retval] BSTR* password);
HRESULT GetDisabled([out,retval] int* disabled);
HRESULT GetDisplayName([out,retval] BSTR* display_name);
HRESULT GetCompanyName([out,retval] BSTR* company_name);
HRESULT GetContext([out,retval] BSTR* current_context);
HRESULT SetUserid([in] long userid);
HRESULT SetLogin([in] BSTR login);
HRESULT SetPassword([in] BSTR password);
HRESULT SetDisabled([in] int disabled);
HRESULT SetDisplayName([in] BSTR display_name);
HRESULT SetCompanyName([in] BSTR company_name);
HRESULT Login(
[in] BSTR Username,
[in] BSTR Password,
[out,retval] int *iRet);
HRESULT Logout();
HRESULT Create([in] BSTR Context, [out,retval] BOOL *bRet);
HRESULT Packages([out,retval] ICollection** ppDisp);
};
[
object,
uuid(825769CF-DDC6-11D3-825F-00805F9BE651),
dual,
helpstring("IParameter Interface"),
pointer_default(unique)
]
header file
// Agent.h : Declaration of the CAgent
#ifndef __AGENT_H_
#define __AGENT_H_
#include "resource.h" // main symbols
#include <mtx.h>
#include "Database.h"
/////////////////////////////////////////////////////////////////////////////
// CAgent
class ATL_NO_VTABLE CAgent :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CAgent, &CLSID_Agent>,
public IObjectControl,
public CDatabase,
public IDispatchImpl<IAgent, &IID_IAgent, &LIBID_GATEWAY20Lib>
{
public:
CAgent()
{
m_lUserid = 0;
m_bDisabled = 0;
m_strLogin = _T("");
m_strPassword = _T("");
m_strDisplayName = _T("");
m_strCompanyName = _T("");
m_strContext = _T("");
}
DECLARE_REGISTRY_RESOURCEID(IDR_AGENT)
DECLARE_PROTECT_FINAL_CONSTRUCT()
DECLARE_NOT_AGGREGATABLE(CAgent)
BEGIN_COM_MAP(CAgent)
COM_INTERFACE_ENTRY(IAgent)
COM_INTERFACE_ENTRY(IObjectControl)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// IObjectControl
public:
STDMETHOD(Activate)();
STDMETHOD_(BOOL, CanBePooled)();
STDMETHOD_(void, Deactivate)();
CComPtr<IObjectContext> m_spObjectContext;
// IAgent
public:
// property get methods
// other methods
STDMETHOD(Login)(BSTR Username,BSTR Password,int *iRet);
STDMETHOD(Create)(BSTR Context,BOOL *bRet);
STDMETHOD(Packages)(ICollection** ppDisp);
};
#endif //__AGENT_H_
And the implementation looks like this
// Agent.cpp : Implementation of CAgent
#include "stdafx.h"
#include "Gateway20.h"
#include "Agent.h"
#include "SmartPointers.h"
#include "rpcdce.h"
/////////////////////////////////////////////////////////////////////////////
// CAgent
////////////////////////////////////////////////////////////
// Function name : CAgent::Activate
// Description :
// Return type : HRESULT
// Author : Bibhas Das
// Company : TCS Calcutta,India
// Client : Dredner Kleinwort Benson Tokyo, Japan
// Date : 22/10/1999
// History : <none>
////////////////////////////////////////////////////////////
HRESULT
CAgent::Activate()
{
HRESULT hr = GetObjectContext(&m_spObjectContext);
if (SUCCEEDED(hr))
return S_OK;
return hr;
}
////////////////////////////////////////////////////////////
// Function name : CAgent::CanBePooled
// Description :
// Return type : BOOL
// Author : Bibhas Das
// Company : TCS Calcutta,India
// Client : Dredner Kleinwort Benson Tokyo, Japan
// Date : 22/10/1999
// History : <none>
////////////////////////////////////////////////////////////
BOOL
CAgent::CanBePooled()
{
return TRUE;
}
////////////////////////////////////////////////////////////
// Function name : CAgent::Deactivate
// Description :
// Return type : void
// Author : Bibhas Das
// Company : TCS Calcutta,India
// Client : Dredner Kleinwort Benson Tokyo, Japan
// Date : 22/10/1999
// History : <none>
////////////////////////////////////////////////////////////
void
CAgent::Deactivate()
{
m_spObjectContext.Release();
}
/////////////////////////////////////////////////////////////////////////////
// IAgent implementation
////////////////////////////////////////////////////////////
// Function name : CAgent::Create
// Description :
// Return type : STDMETHODIMP
// Argument : BSTR Login
// Argument : BOOL* bRet
// Author : Bibhas Das
// Company : TCS Calcutta,India
// Client : Dredner Kleinwort Benson Tokyo, Japan
// Date : 22/10/1999
// History : <none>
////////////////////////////////////////////////////////////
STDMETHODIMP
CAgent::Create(BSTR Context, BOOL* bRet)
{
try
{
long nSize = 0;
char szSQL[100];
*bRet = FALSE;
CAdo::_RecordsetPtr spRec;
USES_CONVERSION;
// create and fire the sql to open recordsets
sprintf(szSQL,"SELECT * FROM Agents WHERE %s='%s'",
IDS_COL_AGENTS_CONTEXT, OLE2A(Context));
if((nSize=OpenRecordset(szSQL,spRec))<=0)
return S_OK;
// assign the recordset values to the class members
CAdo::FieldsPtr spFields = spRec->GetFields();
this->m_lUserid = VALUE(spFields,IDS_COL_AGENTS_AGENTID);
this->m_strLogin= (BSTR)_bstr_t( VALUE(spFields,IDS_COL_AGENTS_AGENTNAME));
this->m_strPassword= (BSTR)_bstr_t( VALUE(spFields,IDS_COL_AGENTS_PASSWORD));
this->m_strDisplayName=
(BSTR)_bstr_t( VALUE(spFields,IDS_COL_AGENTS_AGENTDESC));
this->m_strCompanyName=
(BSTR)_bstr_t( VALUE(spFields,IDS_COL_AGENTS_COMPANYNAME));
this->m_bDisabled = (long) VALUE(spFields,IDS_COL_AGENTS_DISABLED);
this->m_strContext = Context;
// value assignment ends here
// clean-up and set the return flag to TRUE
*bRet = TRUE;
spRec->Close();
spRec = NULL;
}
catch(...){}
return S_OK;
}
////////////////////////////////////////////////////////////
// Function name : CAgent::Packages
// Description :
// Return type : STDMETHODIMP
// Argument : ICollection** ppDisp
// Author : Bibhas Das
// Company : TCS Calcutta,India
// Client : Dredner Kleinwort Benson Tokyo, Japan
// Date : 22/10/1999
// History : <none>
////////////////////////////////////////////////////////////
STDMETHODIMP
CAgent::Packages(ICollection** ppDisp)
{
try
{
long nSize = 0;
char szSQL[100];
CAdo::_RecordsetPtr spRec;
*ppDisp = NULL;
// build the sql and fire it
sprintf(szSQL,
"SELECT * FROM Packages WHERE package_id in \
(SELECT DISTINCT package_id FROM Memberships WHERE
agent_id=%ld)",m_lUserid);
if((nSize=OpenRecordset(szSQL,spRec))<=0)
return S_OK;
// create a collectio class with specified no
// of elements
CAdo::FieldsPtr spFields = spRec->GetFields();
ICollectionPtr spColl(PROGID_COLLECTION);
spColl->Create(nSize);
// create separate components object for all
// the rows retrieved and store it in the collection
nSize = 0;
while(!spRec->IsEOF)
{
IPackagePtr spPackage(PROGID_PACKAGE);
spPackage->SetOwner(m_lUserid);
spPackage->SetPackID(VALUE(spFields,IDS_COL_PACKAGES_PACKAGEID));
spPackage->SetName(_bstr_t(VALUE(spFields,IDS_COL_PACKAGES_PACKAGENAME)));
spPackage->SetDesc(_bstr_t(VALUE(spFields,IDS_COL_PACKAGES_PACKAGEDESC)));
spPackage->SetHome(_bstr_t(VALUE(spFields,IDS_COL_PACKAGES_PACKAGEHOME)));
// store the dispatch in the collection class
LPDISPATCH pDisp = (IDispatch*)spPackage;
// spPackage.QueryInterface(IID_IDispatch,(LPVOID*)&pDisp);
spColl->SetAt(nSize,pDisp);
spPackage = NULL;
spRec->MoveNext();
nSize ++;
}
// set the return parameter to the newly created collection class
spColl.QueryInterface(IID_IDispatch,(LPVOID*)ppDisp);
spColl = NULL;
spRec->Close();
spRec = NULL;
}
catch(...){}
return S_OK;
}
STDMETHODIMP
CAgent::Login(BSTR Username,BSTR Password,int* iRet)
{
char szSQL[200];
UUID uid;
BSTR strUid;
int nSize = 0;
try
{
USES_CONVERSION;
CAdo::_RecordsetPtr spRec;
// build the sql string
sprintf(szSQL,"select * from Agents where %s='%s' and %s='%s'",
IDS_COL_AGENTS_AGENTNAME,OLE2A(Username),
IDS_COL_AGENTS_PASSWORD,OLE2A(Password));
if((nSize=OpenRecordset(szSQL,spRec,TRUE))<=0)
{
*iRet = 0;//user name or password is incorrect
Disconnect();
return S_OK;
}
// assign the recordset values to the class members
CAdo::FieldsPtr spFields = spRec->GetFields();
this->m_strContext =
(BSTR)_bstr_t(VALUE(spFields,IDS_COL_AGENTS_CONTEXT));
// if there is no sequrity context and the RPC api has not
// failed then we will try to update the database
if((m_strContext.Length()>1)||(UuidCreate(&uid)!= RPC_S_OK))
{
*iRet = -1;
spRec->Close();
return S_OK;// user is already logged in
}
// convert that uuid to string and set it to database
// update the database
UuidToString(&uid,&strUid);
_variant_t vt((const char*)strUid);
(spFields->GetItem(IDS_COL_AGENTS_CONTEXT))->PutValue(vt);
spRec->Update();
spRec->Close();
Disconnect();
this->m_strContext.AppendBytes((const char*)strUid, strlen((const
char*)strUid)+1);
RpcStringFree(&strUid);
BOOL bRet= FALSE;
this->Create(m_strContext,&bRet);
*iRet = (bRet)?1:-2;
}
catch(...){return S_OK;}
return S_OK;
}
Regards
Lars Schouw
"Kristofer Gafvert" <kgafvert.RemoveThis@NEWSilopia.com> wrote in message news:<#MVG8RWIEHA.3964@TK2MSFTNGP10.phx.gbl>...
> I'm sorry, but MTS and COM+ is not really my area. I hope that someone else
> can help you with this. But i think that this is not the best newsgroup for
> questions about MTS and COM+.
>
> I see that there exists a newsgroup with the name:
>
> microsoft.public.platformsdk.complus_mts
>
> You might have better luck in that newsgroup.
>
> --
> Regards,
> Kristofer Gafvert - IIS MVP
> Reply to newsgroup only. Remove NEWS if you must reply by email, but please
> do not.
<font color=purple> > <a style='text-decoration: underline;' href="http://www.ilopia.com/</font" target="_blank">http://www.ilopia.com/</font</a>>
>
>
> "Lars Schouw" <schouwla.RemoveThis@yahoo.com> wrote in message
> news:9fa8a881.0404122308.7e18ee7f@posting.google.com...
> > Kristofer
> >
> > I tried again to create a new ASP.net project on a Windows 2003
> > standard server.
> > That worked.
> >
> > Now I have a more detailed problem I need to migrate some .dll's that
> > are used from .ASP scripts.
> > They are using MTS and this technology does no longer exist under
> > .net!
> >
> > Is it easy to convert this to COM+?
> > Is there any migration guide for this like that asp migration tool?
> >
> > Regards
> > Lars Schouw
> >
> > "Kristofer Gafvert" <kgafvert.RemoveThis@NEWSilopia.com> wrote in message
> news:<eFK3OyGIEHA.3200.RemoveThis@TK2MSFTNGP10.phx.gbl>...
> > > Hello,
> > >
> > > Please turn off "Show Friendly HTTP Error Messages" in Internet
> Explorer, so
> > > we can see a more informative error message than a general Internal
> Server
> > > Error.
> > >
> > > Tools->Internet Options->Advanced
> > > In IE.
> > >
> > > --
> > > Regards,
> > > Kristofer Gafvert - IIS MVP
> > > Reply to newsgroup only. Remove NEWS if you must reply by email, but
> please
> > > do not.
<font color=brown> > > > <a style='text-decoration: underline;' href="http://www.ilopia.com/</font" target="_blank">http://www.ilopia.com/</font</a>>
> > >
> > >
> > > "Lars Schouw" <schouwla.RemoveThis@yahoo.com> wrote in message
> > > news:9fa8a881.0404120009.5385366b@posting.google.com...
> > > > Hi
> > > >
> > > > I would like to get some support from some developer that has some
> > > > experience with this. This is my first time to do this... (why was I
> > > > given this task by my manager) .......
> > > >
> > > > In 6 weeks the Windows NT domain will be taken down.
> > > > I have a tiny small project here that was programmed in India - they
> > > > do no longer work here - and is running on Windows NT.
> > > >
> > > > The project uses the following technology.
> > > > IIS 4.0
> > > > Transaction Server 2.0
> > > > Three ISAPI .dll files written in Visual Studio 6.0 C++.
> > > > Seven ASP pages
> > > > ODBC
> > > > Sybase 11
> > > > Running separate instances one the bank and one for the securities
> > > > side on two separate servers.
> > > >
> > > > ***** I have to move that to Windows 2003, ASP and IIS6. ***
> > > >
> > > > I started off by moving the .asp pages to a virtual directory and when
> > > > I try to call the .dll files from ASP I get an error message:
> > > > 501 - Internal Server error.
> > > >
> > > > I then tried to play around with ASP.NET and get the same error
> > > > message when I try to create a new project.
> > > >
> > > > *** I would appreciate all the help I can get on this. ***
> > > >
> > > > Does anyone inside have experience with this? I got a few weeks left
> > > > and ticking....
> > > >
> > > > Regards
> > > > Lars Schouw<!-- ~MESSAGE_AFTER~ -->
>> Stay informed about: ISAPI and ASP.net