[DllImport("httpapi.dll", SetLastError = true)]
static extern uint HttpSetServiceConfiguration(
IntPtr ServiceIntPtr,
HTTP_SERVICE_CONFIG_ID ConfigId,
IntPtr pConfigInformation,
int ConfigInformationLength,
IntPtr pOverlapped);
Declare Function HttpSetServiceConfiguration Lib "httpapi.dll" (TODO) As TODO
HTTP_SERVICE_CONFIG_IP_LISTEN_PARAM
HTTP_SERVICE_CONFIG_URLACL_SET
Depending on the value of ConfigId, pConfigInformation should point to a different type of structure. If it wasn't for this, I could redifine the PInvoke signature to explicitly specify the underlying structure type.
ConfigId Value | ConfigInformation Structure Type |
HttpServiceConfigIPListenList | HTTP_SERVICE_CONFIG_IP_LISTEN_PARAM structure. |
HttpServiceConfigSSLCertInfo | HTTP_SERVICE_CONFIG_SSL_SET structure. |
HttpServiceConfigUrlAclInfo | HTTP_SERVICE_CONFIG_URLACL_SET structure. |
If your use of this API is focused around a single value of ConfigId, you may want to change the IntPtr (pConfigInformation) to point directly to a managed version of the correct underlying structure and let the default marshaller take care of the interop layer marshaling for you (and your memory management).
void ReserveURL(string networkURL, string securityDescriptor)
{
uint retVal = (uint) ErrorCodes.NOERROR; // NOERROR = 0
retVal = HttpApi.HttpInitialize(HttpApi.HTTPAPI_VERSION, HttpApi.HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
if ((uint) ErrorCodes.NOERROR == retVal)
{
HTTP_SERVICE_CONFIG_URLACL_KEY keyDesc = new HTTP_SERVICE_CONFIG_URLACL_KEY(networkURL);
HTTP_SERVICE_CONFIG_URLACL_PARAM paramDesc = new HTTP_SERVICE_CONFIG_URLACL_PARAM(securityDescriptor);
HTTP_SERVICE_CONFIG_URLACL_SET inputConfigInfoSet = new HTTP_SERVICE_CONFIG_URLACL_SET();
inputConfigInfoSet.KeyDesc = keyDesc;
inputConfigInfoSet.ParamDesc = paramDesc;
IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_URLACL_SET)));
Marshal.StructureToPtr(inputConfigInfoSet, pInputConfigInfo, false);
retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
pInputConfigInfo,
Marshal.SizeOf(inputConfigInfoSet),
IntPtr.Zero);
if ((uint) ErrorCodes.ERROR_ALREADY_EXISTS == retVal) // ERROR_ALREADY_EXISTS = 183
{
retVal = HttpApi.HttpDeleteServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
pInputConfigInfo,
Marshal.SizeOf(inputConfigInfoSet),
IntPtr.Zero);
if ((uint) ErrorCodes.NOERROR == retVal)
{
retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
pInputConfigInfo,
Marshal.SizeOf(inputConfigInfoSet),
IntPtr.Zero);
}
}
Marshal.FreeCoTaskMem(pInputConfigInfo);
HttpApi.HttpTerminate(HttpApi.HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
}
if ((uint) ErrorCodes.NOERROR != retVal)
{
throw new Win32Exception(Convert.ToInt32(retVal));
}
}
Do you know one? Please contribute it!