现在的位置: 首页 > 综合 > 正文

How to add a new MimeType to a Virtual Directory with VC++?

2013年12月07日 ⁄ 综合 ⁄ 共 20183字 ⁄ 字号 评论关闭

  #1  

09-04-04, 12:00 AM

C K

Guest

 

Posts: n/a

 

How to add a new MimeType to a Virtual Directory with VC++?


Hi,

I can't seem to figure out how to add a new MimeType to a virtual
directory's MimeMap. The problem is how do I create an IISMimeType
object to add to the MimeMap's SAFEARRAY?

With VB, all you have to do is (Microsoft example):
Const ADS_PROPERTY_UPDATE = 2
'Get the mimemap object.
Set MimeMapObj = GetObject("IIS://LocalHost/MimeMap")
'Get the mappings from the MimeMap property.
aMimeMap = MimeMapObj.GetEx("MimeMap")
i = UBound(aMimeMap) + 1
Redim Preserve aMimeMap(i)
Set aMimeMap(i) = CreateObject("MimeMap")
aMimeMap(i).Extension = ".jnq"
aMimeMap(i).MimeType = "junque/my-junque"
MimeMapObj.PutEx ADS_PROPERTY_UPDATE, "MimeMap", aMimeMap
MimeMapObj.SetInfo

With C++, the problem is that aMimeMap(i) is actually of type
IISMimeType. But since IISMimeType is an abstract base class, how do
I create the new MimeType?
It's not possible to do :

CComPtr<IISMimeType> pMimeType;
HRESULT hr = pNewMimeType.CoCreateInstance(_uuidof(IISMimeType) );

hr will return with a "Class not Registered" error.

Ideally I want to do something similar to (some code omitted):

CComPtr<IISMimeType> pMimeType;
// error
HRESULT hr = pNewMimeType.CoCreateInstance(_uuidof(IISMimeType) );

pMimeType->put_Extension(_bstr_t(szExtension));
pMimeType->put_MimeType(_bstr_t(szMimeType));
CComVariant vNewMime = pMimeType;
hr = ::SafeArrayPutElement(pArrMimeMap, &NewElemIdx, &vNewMime);
hr = pADs->PutEx(ADS_PROPERTY_UPDATE, _bstr_t(_T("MimeMap")),
vMimeMap);
hr = pADs->SetInfo();

So how do I do what the VB code did with VC++?

Thanks for the help

 

 

 

 

George V. Reilly

Guest

 

Posts: n/a

 

Re: How to add a new MimeType to a Virtual Directory with VC++?


You're right. It's a pain. The following code has worked for me in the past.

#include <windows.h>
#include <stdio.h>
#include <oleauto.h>
#include <ActiveDS.h>

#import "inetsrv/adsiis.dll"

_COM_SMARTPTR_TYPEDEF(IADs, __uuidof(IADs));

#define RETURN_ON_FAILURE(hr) if (FAILED(hr)) return (hr);

// Trivial wrapper to ensure that array gets cleaned up by destructor
// if function terminates early
class VariantArray
{
public:
VARIANT* pa;

VariantArray(
size_t n
)
: pa(new VARIANT [n])
{
if (NULL == pa)
_com_issue_error(E_OUTOFMEMORY);
for (size_t i = 0; i < n; ++i)
VariantInit(&pa[i]);
}

~VariantArray()
{
delete [] pa;
}
};

class SafeArray
{
public:
SAFEARRAY* psa;

SafeArray(
VARTYPE vt,
unsigned int cDims,
SAFEARRAYBOUND* rgsabound
)
: psa(SafeArrayCreate(vt, cDims, rgsabound))
{
if (NULL == psa)
_com_issue_error(E_OUTOFMEMORY);
}

~SafeArray()
{
if (NULL != psa)
SafeArrayDestroy(psa);
}
};

// Updates the MimeMap for pwszMimeMapPath.
// If pwszExtn != NULL and there is an extension matching pwszExtn,
// it is removed if pwszMimeType == NULL, or updated with pwszMimeMapPath
// otherwise.
// In other words
// MimeMap(L"IIS://localhost/MimeMap", NULL, NULL)
// just reads the mime map and prints it out
// MimeMap(L"IIS://localhost/MimeMap", L".foo", NULL)
// removes the mapping for ".foo", if it was present
// MimeMap(L"IIS://localhost/MimeMap", L".foo", L"bar/quux")
// sets the mapping for ".foo" to "bar/quux"
HRESULT
MimeMap(
LPCWSTR pwszMimeMapPath,
LPCWSTR pwszExtn,
LPCWSTR pwszMimeType)
{
HRESULT hr = S_OK;
IADsPtr pADs;
_variant_t var;
_bstr_t bstrNewExtn(pwszExtn);
_bstr_t bstrNewMimeType(pwszMimeType);
_bstr_t bstrPropname(L"MimeMap");

hr = ADsGetObject(pwszMimeMapPath, IID_IADs, (void**) &pADs);
RETURN_ON_FAILURE(hr);

hr = pADs->GetEx(bstrPropname, &var);
RETURN_ON_FAILURE(hr);

// We should now have an array of variants, each of which is a
dispobject
// that implements the IISMimeType interface

if ((VT_VARIANT | VT_ARRAY) != V_VT(&var))
return E_ADS_CANT_CONVERT_DATATYPE;

LONG i, j, lSLBound, lSUBound, cVariants = 0;

hr = SafeArrayGetLBound(V_ARRAY(&var), 1, &lSLBound );
RETURN_ON_FAILURE(hr);

hr = SafeArrayGetUBound(V_ARRAY(&var), 1, &lSUBound );
RETURN_ON_FAILURE(hr);

cVariants = lSUBound - lSLBound + 1;

// Allocate an array to make a local copy of the mime maps that
// can be updated
VariantArray va(cVariants + 1);

// Copy the mime maps into the local array
for (i = lSLBound, j = 0; i <= lSUBound; ++i)
{
IISOle::IISMimeTypePtr pmt;
VARIANT varTemp;

VariantInit(&varTemp);

hr = SafeArrayGetElement(V_ARRAY(&var), &i, &varTemp);
RETURN_ON_FAILURE(hr);

if (VT_DISPATCH != V_VT(&varTemp))
return E_ADS_CANT_CONVERT_DATATYPE;

hr = V_DISPATCH(&varTemp)->QueryInterface(
__uuidof(IISOle::IISMimeType),
(void**) &pmt);
RETURN_ON_FAILURE(hr);

_bstr_t bstrExtn(pmt->GetExtension());
_bstr_t bstrMimeType(pmt->GetMimeType());

printf("%ls -> %ls/n", (LPCWSTR) bstrExtn, (LPCWSTR) bstrMimeType);

if (bstrExtn == bstrNewExtn)
{
--cVariants;
}
else
{
va.pa[j++] = varTemp;
}
}

// Remove or update the mapping for pwszExtn?
if (NULL != pwszExtn)
{
IISOle::IISMimeTypePtr pmt;

// Update the mapping
if (NULL != pwszMimeType)
{
// Create a new MimeMap object
hr = pmt.CreateInstance(L"MimeMap");
RETURN_ON_FAILURE(hr);

pmt->PutExtension(bstrNewExtn);
pmt->PutMimeType(bstrNewMimeType);

// Append pmt to the array
V_VT(&va.pa[cVariants]) = VT_DISPATCH;
V_DISPATCH(&va.pa[cVariants]) = pmt;

++cVariants;
}

// Create a safearray to hold the full set of mappings
SAFEARRAYBOUND saBound = {cVariants, 0};
SafeArray sa(VT_VARIANT, 1, &saBound);

VARIANT varArray;
VariantInit(&varArray);

V_VT(&varArray) = (VT_VARIANT | VT_ARRAY);
V_ARRAY(&varArray) = sa.psa;

for (i = 0; i < cVariants; ++i)
{
hr = SafeArrayPutElement(sa.psa, &i, &va.pa[i]);
RETURN_ON_FAILURE(hr);
}

// Finally, write the map back. If the map is empty,
// delete the property.

ADS_PROPERTY_OPERATION_ENUM apo
= (cVariants != 0) ? ADS_PROPERTY_UPDATE : ADS_PROPERTY_CLEAR;

hr = pADs->PutEx(apo, bstrPropname, varArray);
RETURN_ON_FAILURE(hr);

hr = pADs->SetInfo();
RETURN_ON_FAILURE(hr);
}

return hr;
}

int
__cdecl
main(
int argc,
char **argv)
{
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
HRESULT hr;

CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

// hr = MimeMap(L"IIS://localhost/MimeMap", NULL, NULL);
// hr = MimeMap(L"IIS://localhost/MimeMap", L".foo", L"bar/quux");

hr = MimeMap(L"IIS://localhost/w3svc/1/Root", L".foo", L"bar/quux");

CoUninitialize();

return 0;
} // main()

--

--
I've turned my Laserjet into a death ray!
(Get Witty Auto-Generated Signatures from http://SmartBee.org)
George V. Reilly

"C K" < > wrote in message
news: om...
> Hi,
>
> I can't seem to figure out how to add a new MimeType to a virtual
> directory's MimeMap. The problem is how do I create an IISMimeType
> object to add to the MimeMap's SAFEARRAY?
>
> With
VB, all you have to do is (Microsoft example):
> Const ADS_PROPERTY_UPDATE = 2
> 'Get the mimemap object.
> Set MimeMapObj = GetObject("IIS://LocalHost/MimeMap")
> 'Get the mappings from the MimeMap property.
> aMimeMap = MimeMapObj.GetEx("MimeMap")
> i = UBound(aMimeMap) + 1
> Redim Preserve aMimeMap(i)
> Set aMimeMap(i) = CreateObject("MimeMap")
> aMimeMap(i).Extension = ".jnq"
> aMimeMap(i).MimeType = "junque/my-junque"
> MimeMapObj.PutEx ADS_PROPERTY_UPDATE, "MimeMap", aMimeMap
> MimeMapObj.SetInfo
>
> With C++, the problem is that aMimeMap(i) is actually of type
> IISMimeType. But since IISMimeType is an abstract base class, how do
> I create the new MimeType?
> It's not possible to do :
>
> CComPtr<IISMimeType> pMimeType;
> HRESULT hr = pNewMimeType.CoCreateInstance(_uuidof(IISMimeType) );
>
> hr will return with a "Class not Registered" error.
>
> Ideally I want to do something similar to (some code omitted):
>
> CComPtr<IISMimeType> pMimeType;
> // error
> HRESULT hr = pNewMimeType.CoCreateInstance(_uuidof(IISMimeType) );
>
>
> pMimeType->put_Extension(_bstr_t(szExtension));
> pMimeType->put_MimeType(_bstr_t(szMimeType));
> CComVariant vNewMime = pMimeType;
> hr = ::SafeArrayPutElement(pArrMimeMap, &NewElemIdx, &vNewMime);
> hr = pADs->PutEx(ADS_PROPERTY_UPDATE, _bstr_t(_T("MimeMap")),
> vMimeMap);
> hr = pADs->SetInfo();
>
> So how do I do what the
VB code did with VC++?
>
> Thanks for the help



  #3  

14-04-04, 02:12 AM

C K

Guest

 

Posts: n/a

 

Re: How to add a new MimeType to a Virtual Directory with VC++?


Hi George,

Thank you very much for the code!

I still don't understand why I wasn't able to createinstance an
IISMimeType object. The only thing maybe is I didn't include the
right headers. These are the ones I included:

#include <iiis.h>
#include <iiisext.h>
#include <iiscnfg.h>

I also linked with: ActiveDS.lib Adsiid.lib

The only difference is that you did it the #import way. Is there
something that's not exposed in the headers? Because I did try
something similar to what was in your code (without the #import):

CComPtr<IISMimeType> pMimeType;
pMimeType.CoCreateInstance(__uuidof(IISMimeType));

which returned that class not registered failure.

Would you happen to know why this is?

Thanks.

"George V. Reilly" < > wrote in message news:<# >...
> You're right. It's a pain. The following code has worked for me in the past.
>
> #include <windows.h>
> #include <stdio.h>
> #include <oleauto.h>
> #include <ActiveDS.h>
>
> #import "inetsrv/adsiis.dll"
>
> _COM_SMARTPTR_TYPEDEF(IADs, __uuidof(IADs));
>
>
> #define RETURN_ON_FAILURE(hr) if (FAILED(hr)) return (hr);
>
>
>
> // Trivial wrapper to ensure that array gets cleaned up by destructor
> // if function terminates early
> class VariantArray
> {
> public:
> VARIANT* pa;
>
> VariantArray(
> size_t n
> )
> : pa(new VARIANT [n])
> {
> if (NULL == pa)
> _com_issue_error(E_OUTOFMEMORY);
> for (size_t i = 0; i < n; ++i)
> VariantInit(&pa[i]);
> }
>
> ~VariantArray()
> {
> delete [] pa;
> }
> };
>
> class SafeArray
> {
> public:
> SAFEARRAY* psa;
>
> SafeArray(
> VARTYPE vt,
> unsigned int cDims,
> SAFEARRAYBOUND* rgsabound
> )
> : psa(SafeArrayCreate(vt, cDims, rgsabound))
> {
> if (NULL == psa)
> _com_issue_error(E_OUTOFMEMORY);
> }
>
> ~SafeArray()
> {
> if (NULL != psa)
> SafeArrayDestroy(psa);
> }
> };
>
>
> // Updates the MimeMap for pwszMimeMapPath.
> // If pwszExtn != NULL and there is an extension matching pwszExtn,
> // it is removed if pwszMimeType == NULL, or updated with pwszMimeMapPath
> // otherwise.
> // In other words
> // MimeMap(L"IIS://localhost/MimeMap", NULL, NULL)
> // just reads the mime map and prints it out
> // MimeMap(L"IIS://localhost/MimeMap", L".foo", NULL)
> // removes the mapping for ".foo", if it was present
> // MimeMap(L"IIS://localhost/MimeMap", L".foo", L"bar/quux")
> // sets the mapping for ".foo" to "bar/quux"
> HRESULT
> MimeMap(
> LPCWSTR pwszMimeMapPath,
> LPCWSTR pwszExtn,
> LPCWSTR pwszMimeType)
> {
> HRESULT hr = S_OK;
> IADsPtr pADs;
> _variant_t var;
> _bstr_t bstrNewExtn(pwszExtn);
> _bstr_t bstrNewMimeType(pwszMimeType);
> _bstr_t bstrPropname(L"MimeMap");
>
> hr = ADsGetObject(pwszMimeMapPath, IID_IADs, (void**) &pADs);
> RETURN_ON_FAILURE(hr);
>
> hr = pADs->GetEx(bstrPropname, &var);
> RETURN_ON_FAILURE(hr);
>
> // We should now have an array of variants, each of which is a
> dispobject
> // that implements the IISMimeType interface
>
> if ((VT_VARIANT | VT_ARRAY) != V_VT(&var))
> return E_ADS_CANT_CONVERT_DATATYPE;
>
> LONG i, j, lSLBound, lSUBound, cVariants = 0;
>
> hr = SafeArrayGetLBound(V_ARRAY(&var), 1, &lSLBound );
> RETURN_ON_FAILURE(hr);
>
> hr = SafeArrayGetUBound(V_ARRAY(&var), 1, &lSUBound );
> RETURN_ON_FAILURE(hr);
>
> cVariants = lSUBound - lSLBound + 1;
>
> // Allocate an array to make a local copy of the mime maps that
> // can be updated
> VariantArray va(cVariants + 1);
>
> // Copy the mime maps into the local array
> for (i = lSLBound, j = 0; i <= lSUBound; ++i)
> {
> IISOle::IISMimeTypePtr pmt;
> VARIANT varTemp;
>
> VariantInit(&varTemp);
>
> hr = SafeArrayGetElement(V_ARRAY(&var), &i, &varTemp);
> RETURN_ON_FAILURE(hr);
>
> if (VT_DISPATCH != V_VT(&varTemp))
> return E_ADS_CANT_CONVERT_DATATYPE;
>
> hr = V_DISPATCH(&varTemp)->QueryInterface(
> __uuidof(IISOle::IISMimeType),
> (void**) &pmt);
> RETURN_ON_FAILURE(hr);
>
> _bstr_t bstrExtn(pmt->GetExtension());
> _bstr_t bstrMimeType(pmt->GetMimeType());
>
> printf("%ls -> %ls/n", (LPCWSTR) bstrExtn, (LPCWSTR) bstrMimeType);
>
> if (bstrExtn == bstrNewExtn)
> {
> --cVariants;
> }
> else
> {
> va.pa[j++] = varTemp;
> }
> }
>
> // Remove or update the mapping for pwszExtn?
> if (NULL != pwszExtn)
> {
> IISOle::IISMimeTypePtr pmt;
>
> // Update the mapping
> if (NULL != pwszMimeType)
> {
> // Create a new MimeMap object
> hr = pmt.CreateInstance(L"MimeMap");
> RETURN_ON_FAILURE(hr);
>
> pmt->PutExtension(bstrNewExtn);
> pmt->PutMimeType(bstrNewMimeType);
>
> // Append pmt to the array
> V_VT(&va.pa[cVariants]) = VT_DISPATCH;
> V_DISPATCH(&va.pa[cVariants]) = pmt;
>
> ++cVariants;
> }
>
> // Create a safearray to hold the full set of mappings
> SAFEARRAYBOUND saBound = {cVariants, 0};
> SafeArray sa(VT_VARIANT, 1, &saBound);
>
> VARIANT varArray;
> VariantInit(&varArray);
>
> V_VT(&varArray) = (VT_VARIANT | VT_ARRAY);
> V_ARRAY(&varArray) = sa.psa;
>
> for (i = 0; i < cVariants; ++i)
> {
> hr = SafeArrayPutElement(sa.psa, &i, &va.pa[i]);
> RETURN_ON_FAILURE(hr);
> }
>
> // Finally, write the map back. If the map is empty,
> // delete the property.
>
> ADS_PROPERTY_OPERATION_ENUM apo
> = (cVariants != 0) ? ADS_PROPERTY_UPDATE : ADS_PROPERTY_CLEAR;
>
> hr = pADs->PutEx(apo, bstrPropname, varArray);
> RETURN_ON_FAILURE(hr);
>
> hr = pADs->SetInfo();
> RETURN_ON_FAILURE(hr);
> }
>
> return hr;
> }
>
>
> int
> __cdecl
> main(
> int argc,
> char **argv)
> {
> UNREFERENCED_PARAMETER(argc);
> UNREFERENCED_PARAMETER(argv);
> HRESULT hr;
>
> CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
>
> // hr = MimeMap(L"IIS://localhost/MimeMap", NULL, NULL);
> // hr = MimeMap(L"IIS://localhost/MimeMap", L".foo", L"bar/quux");
>
> hr = MimeMap(L"IIS://localhost/w3svc/1/Root", L".foo", L"bar/quux");
>
> CoUninitialize();
>
> return 0;
> } // main()
>
> --
>
> --
> I've turned my Laserjet into a death ray!
> (Get Witty Auto-Generated Signatures from http://SmartBee.org)
> George V. Reilly
>
>
>
> "C K" < > wrote in message
> news: om...

> > Hi,
> >
> > I can't seem to figure out how to add a new MimeType to a virtual
> > directory's MimeMap. The problem is how do I create an IISMimeType
> > object to add to the MimeMap's SAFEARRAY?
> >
> > With
VB, all you have to do is (Microsoft example):
> > Const ADS_PROPERTY_UPDATE = 2
> > 'Get the mimemap object.
> > Set MimeMapObj = GetObject("IIS://LocalHost/MimeMap")
> > 'Get the mappings from the MimeMap property.
> > aMimeMap = MimeMapObj.GetEx("MimeMap")
> > i = UBound(aMimeMap) + 1
> > Redim Preserve aMimeMap(i)
> > Set aMimeMap(i) = CreateObject("MimeMap")
> > aMimeMap(i).Extension = ".jnq"
> > aMimeMap(i).MimeType = "junque/my-junque"
> > MimeMapObj.PutEx ADS_PROPERTY_UPDATE, "MimeMap", aMimeMap
> > MimeMapObj.SetInfo
> >
> > With C++, the problem is that aMimeMap(i) is actually of type
> > IISMimeType. But since IISMimeType is an abstract base class, how do
> > I create the new MimeType?
> > It's not possible to do :
> >
> > CComPtr<IISMimeType> pMimeType;
> > HRESULT hr = pNewMimeType.CoCreateInstance(_uuidof(IISMimeType) );
> >
> > hr will return with a "Class not Registered" error.
> >
> > Ideally I want to do something similar to (some code omitted):
> >
> > CComPtr<IISMimeType> pMimeType;
> > // error
> > HRESULT hr = pNewMimeType.CoCreateInstance(_uuidof(IISMimeType) );
> >
> >
> > pMimeType->put_Extension(_bstr_t(szExtension));
> > pMimeType->put_MimeType(_bstr_t(szMimeType));
> > CComVariant vNewMime = pMimeType;
> > hr = ::SafeArrayPutElement(pArrMimeMap, &NewElemIdx, &vNewMime);
> > hr = pADs->PutEx(ADS_PROPERTY_UPDATE, _bstr_t(_T("MimeMap")),
> > vMimeMap);
> > hr = pADs->SetInfo();
> >
> > So how do I do what the
VB code did with VC++?
> >
> > Thanks for the help


     

 

  #4  

14-04-04, 10:16 AM

George V. Reilly

Guest

 

Posts: n/a

 

Re: How to add a new MimeType to a Virtual Directory with VC++?


There are no C++ headers that expose IISMimeType. The only way to get the
right declaration is to suck it out of the type library in adsiis.dll, via
#import :-(
--
It is impossible to enjoy idling thoroughly unless one has plenty of
work to do.
-- Jerome K. Jerome
(Get Witty Auto-Generated Signatures from http://SmartBee.org)
George V. Reilly

"C K" < > wrote in message
news: om...
> Hi George,
>
> Thank you very much for the code!
>
> I still don't understand why I wasn't able to createinstance an
> IISMimeType object. The only thing maybe is I didn't include the
> right headers. These are the ones I included:
>
> #include <iiis.h>
> #include <iiisext.h>
> #include <iiscnfg.h>
>
> I also linked with: ActiveDS.lib Adsiid.lib
>
> The only difference is that you did it the #import way. Is there
> something that's not exposed in the headers? Because I did try
> something similar to what was in your code (without the #import):
>
> CComPtr<IISMimeType> pMimeType;
> pMimeType.CoCreateInstance(__uuidof(IISMimeType));
>
> which returned that class not registered failure.
>
> Would you happen to know why this is?
>
> Thanks.
>
>
> "George V. Reilly" < > wrote in message

news:<# >...

> > You're right. It's a pain. The following code has worked for me in the

past.

> >

[snip]

> > "C K" < > wrote in message
> > news: om...

> > > Hi,
> > >
> > > I can't seem to figure out how to add a new MimeType to a virtual
> > > directory's MimeMap. The problem is how do I create an IISMimeType
> > > object to add to the MimeMap's SAFEARRAY?
> > >
> > > With
VB, all you have to do is (Microsoft example):
> > > Const ADS_PROPERTY_UPDATE = 2
> > > 'Get the mimemap object.
> > > Set MimeMapObj = GetObject("IIS://LocalHost/MimeMap")
> > > 'Get the mappings from the MimeMap property.
> > > aMimeMap = MimeMapObj.GetEx("MimeMap")
> > > i = UBound(aMimeMap) + 1
> > > Redim Preserve aMimeMap(i)
> > > Set aMimeMap(i) = CreateObject("MimeMap")
> > > aMimeMap(i).Extension = ".jnq"
> > > aMimeMap(i).MimeType = "junque/my-junque"
> > > MimeMapObj.PutEx ADS_PROPERTY_UPDATE, "MimeMap", aMimeMap
> > > MimeMapObj.SetInfo
> > >
> > > With C++, the problem is that aMimeMap(i) is actually of type
> > > IISMimeType. But since IISMimeType is an abstract base class, how do
> > > I create the new MimeType?
> > > It's not possible to do :
> > >
> > > CComPtr<IISMimeType> pMimeType;
> > > HRESULT hr = pNewMimeType.CoCreateInstance(_uuidof(IISMimeType) );
> > >
> > > hr will return with a "Class not Registered" error.
> > >
> > > Ideally I want to do something similar to (some code omitted):
> > >
> > > CComPtr<IISMimeType> pMimeType;
> > > // error
> > > HRESULT hr = pNewMimeType.CoCreateInstance(_uuidof(IISMimeType) );
> > >
> > >
> > > pMimeType->put_Extension(_bstr_t(szExtension));
> > > pMimeType->put_MimeType(_bstr_t(szMimeType));
> > > CComVariant vNewMime = pMimeType;
> > > hr = ::SafeArrayPutElement(pArrMimeMap, &NewElemIdx, &vNewMime);
> > > hr = pADs->PutEx(ADS_PROPERTY_UPDATE, _bstr_t(_T("MimeMap")),
> > > vMimeMap);
> > > hr = pADs->SetInfo();
> > >
> > > So how do I do what the
VB code did with VC++?
> > >
> > > Thanks for the help



  #5  

14-04-04, 06:49 PM

C K

Guest

 

Posts: n/a

 

Re: How to add a new MimeType to a Virtual Directory with VC++?


Hi George,

I did some spelunking because it kinda ticked me off I found that
IISMimeType is an interface within the IISMimeMap object. So if you
didn't want to do a #import, you can just query for the IISMimeType
object from the IISMimeMap object:

#include <atlbase.h>
#include <tchar.h>
#include <comdef.h>
#include <iiis.h>

CComPtr<IUnknown> pUnk;
CComPtr<IISMimeType> pMimeType;
HRESULT hr;

hr = pUnk.CoCreateInstance(__uuidof(MimeMap));
hr = pUnk.QueryInterface(&pMimeType);
hr = pMimeType->put_Extension(_bstr_t(_T(".txt")));
hr = pMimeType->put_MimeType(_bstr_t(_T("text/text")));

But your class is still very nice and handy, thanks

"George V. Reilly" < > wrote in message news:<ew1K# >...
> There are no C++ headers that expose IISMimeType. The only way to get the
> right declaration is to suck it out of the type library in adsiis.dll, via
> #import :-(
> --
> It is impossible to enjoy idling thoroughly unless one has plenty of
> work to do.
> -- Jerome K. Jerome
> (Get Witty Auto-Generated Signatures from http://SmartBee.org)
> George V. Reilly
>
> "C K" < > wrote in message
> news: om...

> > Hi George,
> >
> > Thank you very much for the code!
> >
> > I still don't understand why I wasn't able to createinstance an
> > IISMimeType object. The only thing maybe is I didn't include the
> > right headers. These are the ones I included:
> >
> > #include <iiis.h>
> > #include <iiisext.h>
> > #include <iiscnfg.h>
> >
> > I also linked with: ActiveDS.lib Adsiid.lib
> >
> > The only difference is that you did it the #import way. Is there
> > something that's not exposed in the headers? Because I did try
> > something similar to what was in your code (without the #import):
> >
> > CComPtr<IISMimeType> pMimeType;
> > pMimeType.CoCreateInstance(__uuidof(IISMimeType));
> >
> > which returned that class not registered failure.
> >
> > Would you happen to know why this is?
> >
> > Thanks.
> >
> >
> > "George V. Reilly" < > wrote in message

> news:<# >...

> > > You're right. It's a pain. The following code has worked for me in the

> past.

> > >

> [snip]
>

> > > "C K" < > wrote in message
> > > news: om...
> > > > Hi,
> > > >
> > > > I can't seem to figure out how to add a new MimeType to a virtual
> > > > directory's MimeMap. The problem is how do I create an IISMimeType
> > > > object to add to the MimeMap's SAFEARRAY?
> > > >
> > > > With
VB, all you have to do is (Microsoft example):
> > > > Const ADS_PROPERTY_UPDATE = 2
> > > > 'Get the mimemap object.
> > > > Set MimeMapObj = GetObject("IIS://LocalHost/MimeMap")
> > > > 'Get the mappings from the MimeMap property.
> > > > aMimeMap = MimeMapObj.GetEx("MimeMap")
> > > > i = UBound(aMimeMap) + 1
> > > > Redim Preserve aMimeMap(i)
> > > > Set aMimeMap(i) = CreateObject("MimeMap")
> > > > aMimeMap(i).Extension = ".jnq"
> > > > aMimeMap(i).MimeType = "junque/my-junque"
> > > > MimeMapObj.PutEx ADS_PROPERTY_UPDATE, "MimeMap", aMimeMap
> > > > MimeMapObj.SetInfo
> > > >
> > > > With C++, the problem is that aMimeMap(i) is actually of type
> > > > IISMimeType. But since IISMimeType is an abstract base class, how do
> > > > I create the new MimeType?
> > > > It's not possible to do :
> > > >
> > > > CComPtr<IISMimeType> pMimeType;
> > > > HRESULT hr = pNewMimeType.CoCreateInstance(_uuidof(IISMimeType) );
> > > >
> > > > hr will return with a "Class not Registered" error.
> > > >
> > > > Ideally I want to do something similar to (some code omitted):
> > > >
> > > > CComPtr<IISMimeType> pMimeType;
> > > > // error
> > > > HRESULT hr = pNewMimeType.CoCreateInstance(_uuidof(IISMimeType) );
> > > >
> > > >
> > > > pMimeType->put_Extension(_bstr_t(szExtension));
> > > > pMimeType->put_MimeType(_bstr_t(szMimeType));
> > > > CComVariant vNewMime = pMimeType;
> > > > hr = ::SafeArrayPutElement(pArrMimeMap, &NewElemIdx, &vNewMime);
> > > > hr = pADs->PutEx(ADS_PROPERTY_UPDATE, _bstr_t(_T("MimeMap")),
> > > > vMimeMap);
> > > > hr = pADs->SetInfo();
> > > >
> > > > So how do I do what the
VB code did with VC++?
> > > >
> > > > Thanks for the help


Hi,

I can't seem to figure out how to add a new MimeType to a virtual
directory's MimeMap. The problem is how do I create an IISMimeType
object to add to the MimeMap's SAFEARRAY?

With VB, all you have to do is (Microsoft example):
Const ADS_PROPERTY_UPDATE = 2
'Get the mimemap object.
Set MimeMapObj = GetObject("IIS://LocalHost/MimeMap")
'Get the mappings from the MimeMap property.
aMimeMap = MimeMapObj.GetEx("MimeMap")
i = UBound(aMimeMap) + 1
Redim Preserve aMimeMap(i)
Set aMimeMap(i) = CreateObject("MimeMap")
aMimeMap(i).Extension = ".jnq"
aMimeMap(i).MimeType = "junque/my-junque"
MimeMapObj.PutEx ADS_PROPERTY_UPDATE, "MimeMap", aMimeMap
MimeMapObj.SetInfo

With C++, the problem is that aMimeMap(i) is actually of type
IISMimeType. But since IISMimeType is an abstract base class, how do
I create the new MimeType?
It's not possible to do :

 

 

抱歉!评论已关闭.