I register a UPnP device with:
var o: IUPnPRegistrar;
W: string;
R: HRESULT;
begin
w := TFile.ReadAllText('UPnPDevice_Desc.xml');
o := CoUPnPRegistrar.Create as IUPnPRegistrar;
R := o.RegisterDevice(w, ...);
end;
File UPnPDevice_Desc.xml:
<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<device>
<pnpx:X_deviceCategory xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">Other</pnpx:X_deviceCategory>
<!--<pnpx:X_hardwareId xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">Microsoft/SampleDevice/10000/urn:microsoft-com:device:SampleDimmerDevice:1</pnpx:X_hardwareId>-->
<!-- <df:X_containerId xmlns:df="http://schemas.microsoft.com/windows/2008/09/devicefoundation">{8C7B310D-90F8-40D4-B5EA-71D81821DEA6}</df:X_containerId>-->
<deviceType>urn:example-com:device:uPnPDevice:1</deviceType>
<friendlyName>My UPNP Device Hosted by Windows</friendlyName>
<manufacturer>Example Company</manufacturer>
<manufacturerURL>http://www.example.com/</manufacturerURL>
<modelDescription>My UPnP Device</modelDescription>
<modelName>uPnPDevice</modelName>
<modelNumber>1001</modelNumber>
<modelURL>http://www.example.com/</modelURL>
<serialNumber>123456</serialNumber>
<UDN>uuid:RootDevice</UDN>
<UPC>00000-00001</UPC>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:SwitchPower:1</serviceType>
<serviceId>urn:upnp-org:serviceId:SwitchPower:1</serviceId>
<controlURL></controlURL>
<eventSubURL></eventSubURL>
<SCPDURL>UPnPDevice_SCPD.xml</SCPDURL>
</service>
</serviceList>
<presentationURL>DimmerPresentation.htm</presentationURL>
</device>
</root>
File UPnPDevice_SCPD.xml:
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>MagicOn</name>
</action>
</actionList>
<serviceStateTable>
<stateVariable>
<name>OSMajorVersion</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable>
<name>OSMinorVersion</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable>
<name>OSBuildNumber</name>
<dataType>i4</dataType>
</stateVariable>
<stateVariable>
<name>OSMachineName</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
I can confirm the UPnP device has been hosted in UPnP device host service by using IUPnPDeviceFinder or M-SEARCH to find the device.
The registry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\UPnP Device Host\Description
also contain the corresponding information:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\UPnP Device Host\Description\{00BB4949-F3B2-4F5A-B534-C6FE61B71F4E}]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\UPnP Device Host\Description\{00BB4949-F3B2-4F5A-B534-C6FE61B71F4E}\Files]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\UPnP Device Host\Description\{00BB4949-F3B2-4F5A-B534-C6FE61B71F4E}\Files\{B11E040A-6858-48BA-B1BD-85B4E8FCBA73}]
"Filename"="M:\\uPNP\\D16\\Win32\\Debug\\UPnPDevice_SCPD.xml"
"Mimetype"="text/xml; charset=\"utf-8\""
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\UPnP Device Host\Description\{00BB4949-F3B2-4F5A-B534-C6FE61B71F4E}\UDN Mappings]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\UPnP Device Host\Description\{00BB4949-F3B2-4F5A-B534-C6FE61B71F4E}\UDN Mappings\uuid:RootDevice]
@="uuid:00bb4949-f3b2-4f5a-b534-c6fe61b71f4e"
When query for services of the UPnP device using
var Enum: IEnumVARIANT;
Fetched: Cardinal;
K: OleVariant;
P: IUPnPService;
W: WideString;
D: IUPnPDevice
begin
...
if D.Services.Count > 0 then begin
Enum := D.Services._NewEnum as IEnumVARIANT;
Enum.Reset;
while Enum.Next(1, K, Fetched) = S_OK do begin
P := IDispatch(K) as IUPnPService;
end;
end;
end;
The D.Services.Count is 1 but the Enum doesn't fetch any services. Variable Fetched always return 0.
If I have query for Media Player UPnP device, It did return the services available.
Any ideas what's wrong with my UPnP Device that doesn't return services as indicated in SCPD xml file?
Once I registered the device, the XML description will change to:
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<device>
<pnpx:X_deviceCategory xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">Other</pnpx:X_deviceCategory>
<!--
<pnpx:X_hardwareId xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">Microsoft/SampleDevice/10000/urn:microsoft-com:device:SampleDimmerDevice:1</pnpx:X_hardwareId>
-->
<!--
<df:X_containerId xmlns:df="http://schemas.microsoft.com/windows/2008/09/devicefoundation">{8C7B310D-90F8-40D4-B5EA-71D81821DEA6}</df:X_containerId>
-->
<deviceType>urn:example-com:device:uPnPDevice:1</deviceType>
<friendlyName>My UPNP Device Hosted by Windows</friendlyName>
<manufacturer>Example Company</manufacturer>
<manufacturerURL>http://www.example.com/</manufacturerURL>
<modelDescription>My UPnP Device</modelDescription>
<modelName>uPnPDevice</modelName>
<modelNumber>1001</modelNumber>
<modelURL>http://www.example.com/</modelURL>
<serialNumber>123456</serialNumber>
<UDN>uuid:9742f52d-f39f-4eaf-9ecf-bb742e9d79e9</UDN>
<UPC>00000-00001</UPC>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:SwitchPower:1</serviceType>
<serviceId>urn:upnp-org:serviceId:SwitchPower:1</serviceId>
<controlURL>
/upnphost/udhisapi.dll?control=uuid:9742f52d-f39f-4eaf-9ecf-bb742e9d79e9+urn:upnp-org:serviceId:SwitchPower:1
</controlURL>
<eventSubURL>
/upnphost/udhisapi.dll?event=uuid:9742f52d-f39f-4eaf-9ecf-bb742e9d79e9+urn:upnp-org:serviceId:SwitchPower:1
</eventSubURL>
<SCPDURL>
/upnphost/udhisapi.dll?content=uuid:40c39217-e93b-4d0a-b5e0-abc582b2a2ed
</SCPDURL>
</service>
</serviceList>
<presentationURL>
/uuid:9742f52d-f39f-4eaf-9ecf-bb742e9d79e9/DimmerPresentation.htm?/upnphost/udhisapi.dll?content=uuid:9742f52d-f39f-4eaf-9ecf-bb742e9d79e9+uuid:9742f52d-f39f-4eaf-9ecf-bb742e9d79e9
</presentationURL>
</device>
</root>
Note the controlURL, eventSubURL and SCPDURL has been changed. Accessing
http://localhost:2869/upnphost/udhisapi.dll?content=uuid:40c39217-e93b-4d0a-b5e0-abc582b2a2ed
return exact content as file UPnPDevice_SCPD.xml.