Hello,
Thank you for adding ERROR_MORE_DATA handling to TTMSMCPWinHTTPServer.IsUrlReserved in TMS AI Studio 1.7.4.0.
Unfortunately, the repeated UAC prompt still occurs after fully deleting and rebuilding both the TMS and application DCUs. We debugged the updated source and found that the problem happens before the new return-code check becomes relevant.
At runtime, IsUrlReserved calls:
res := HttpQueryServiceConfiguration(
0,
HttpServiceConfigUrlAclInfo,
@urlAclInfoQuery,
SizeOf(urlAclInfoQuery),
pOutput,
0,
bufferLength,
nil);
The observed debugger values are:
AURL = "http://+:8933/"
urlFixed = "http://+:8933/"
urlAclInfoQuery.QueryDesc = HttpServiceConfigQueryExact
SizeOf(urlAclInfoQuery) = 24
pOutput = nil
bufferLength = 0
res = 87
Error 87 is ERROR_INVALID_PARAMETER. Consequently, IsUrlReserved returns False, and StartServer proceeds to ReserveUrl, which launches elevated netsh even though the URL ACL already exists.
The URL construction itself appears correct:
FBindingIP = ""
FPort = 8933
FUseSSL = False
protocol = "http"
ip = "+"
url = "http://+:8933/"
We believe the invalid parameter is caused by the native Windows HTTP API enums being declared as ordinary Delphi enums. In particular:
HTTP_SERVICE_CONFIG_ID = (
HttpServiceConfigIPListenList,
HttpServiceConfigSSLCertInfo,
HttpServiceConfigUrlAclInfo,
...
);
The imported function currently declares ConfigId using that Delphi enum type:
HttpQueryServiceConfiguration: function(
ServiceHandle: THandle;
ConfigId: HTTP_SERVICE_CONFIG_ID;
...
): ULONG; stdcall;
The corresponding Windows SDK type is a C enum and therefore occupies four bytes. Unless the Delphi unit or project forces four-byte enums, HTTP_SERVICE_CONFIG_ID can occupy only one byte. On Win64, passing a byte-sized enum to a native function expecting a 32-bit value can result in an invalid argument being received by httpapi.dll.
This would explain why the API returns ERROR_INVALID_PARAMETER even though:
- The queried URL is exact.
- The query descriptor is
HttpServiceConfigQueryExact.
- The query structure size is 24 bytes, as expected for Win64.
- The URL ACL already exists.
- A direct call using a 32-bit configuration ID successfully returns
ERROR_INSUFFICIENT_BUFFER, indicating that the reservation was found.
Could you please verify SizeOf(HTTP_SERVICE_CONFIG_ID) in the affected build and ensure all Windows HTTP API enums use the native four-byte ABI?
One possible correction would be to compile the relevant native enum declarations with:
{$PUSH}
{$MINENUMSIZE 4}
type
HTTP_SERVICE_CONFIG_QUERY_TYPE = (...);
HTTP_SERVICE_CONFIG_ID = (...);
// Other enums corresponding to native Windows C enums
{$POP}
Alternatively, the imported function can declare the native argument explicitly as a 32-bit type:
HttpQueryServiceConfiguration: function(
ServiceHandle: THandle;
ConfigId: ULONG;
pInputConfigInformation: PVOID;
InputConfigInformationLength: ULONG;
pOutputConfigInformation: PVOID;
OutputConfigInformationLength: ULONG;
var pReturnLength: ULONG;
pOverlapped: POverlapped
): ULONG; stdcall;
With the call using an explicit cast:
res := HttpQueryServiceConfiguration(
0,
ULONG(HttpServiceConfigUrlAclInfo),
@urlAclInfoQuery,
SizeOf(urlAclInfoQuery),
nil,
0,
bufferLength,
nil);
The first solution may be preferable because HTTP_SERVICE_CONFIG_QUERY_TYPE is also embedded in native HTTP API structures, and several other HTTP enums are used by imported functions throughout the unit.
Could you please review the enum sizes and native declarations in TMS.MCP.HTTPServer.Win.pas and provide an updated build?
Thank you.