winrt: use ComPtr in network classes

This removes extra code and potential memory leaks by using smart
pointers instead of calling Release() directly.

Task-number: QTBUG-38115
Change-Id: If799d6948af8c3df3d0c1617742653b104087e3b
Reviewed-by: Maurice Kalinowski <maurice.kalinowski@digia.com>
Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
bb10
Andrew Knight 2014-06-06 14:20:41 +03:00
parent 164ae66ff7
commit 6dd9146938
5 changed files with 48 additions and 79 deletions

View File

@ -81,31 +81,28 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
return;
}
IHostNameFactory *hostnameFactory;
HStringReference classId(RuntimeClass_Windows_Networking_HostName);
if (FAILED(GetActivationFactory(classId.Get(), &hostnameFactory))) {
ComPtr<IHostNameFactory> hostnameFactory;
HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(),
IID_PPV_ARGS(&hostnameFactory));
if (FAILED(hr)) {
reply->error = QDnsLookup::ResolverError;
reply->errorString = QLatin1String("Could not obtain hostname factory");
return;
}
IHostName *host;
ComPtr<IHostName> host;
HStringReference hostNameRef((const wchar_t*)aceHostname.utf16());
hostnameFactory->CreateHostName(hostNameRef.Get(), &host);
hostnameFactory->Release();
IDatagramSocketStatics *datagramSocketStatics;
ComPtr<IDatagramSocketStatics> datagramSocketStatics;
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics);
IAsyncOperation<IVectorView<EndpointPair*> *> *op;
datagramSocketStatics->GetEndpointPairsAsync(host,
ComPtr<IAsyncOperation<IVectorView<EndpointPair *> *>> op;
datagramSocketStatics->GetEndpointPairsAsync(host.Get(),
HString::MakeReference(L"0").Get(),
&op);
datagramSocketStatics->Release();
host->Release();
IVectorView<EndpointPair*> *endpointPairs = 0;
HRESULT hr = op->GetResults(&endpointPairs);
ComPtr<IVectorView<EndpointPair *>> endpointPairs;
hr = op->GetResults(&endpointPairs);
int waitCount = 0;
while (hr == E_ILLEGAL_METHOD_CALL) {
WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE);
@ -113,7 +110,6 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
if (++waitCount > 1200) // Wait for 1 minute max
return;
}
op->Release();
if (!endpointPairs)
return;
@ -121,11 +117,10 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
unsigned int size;
endpointPairs->get_Size(&size);
for (unsigned int i = 0; i < size; ++i) {
IEndpointPair *endpointpair;
ComPtr<IEndpointPair> endpointpair;
endpointPairs->GetAt(i, &endpointpair);
IHostName *remoteHost;
ComPtr<IHostName> remoteHost;
endpointpair->get_RemoteHostName(&remoteHost);
endpointpair->Release();
HostNameType type;
remoteHost->get_Type(&type);
if (type == HostNameType_Bluetooth || type == HostNameType_DomainName
@ -136,7 +131,6 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
HString name;
remoteHost->get_CanonicalName(name.GetAddressOf());
remoteHost->Release();
UINT32 length;
PCWSTR rawString = name.GetRawBuffer(&length);
QDnsHostAddressRecord record;

View File

@ -80,29 +80,25 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
return results;
}
IHostNameFactory *hostnameFactory;
ComPtr<IHostNameFactory> hostnameFactory;
HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(),
IID_PPV_ARGS(&hostnameFactory));
Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr)));
HStringReference classId(RuntimeClass_Windows_Networking_HostName);
if (FAILED(GetActivationFactory(classId.Get(), &hostnameFactory)))
Q_ASSERT_X(false, "QHostInfoAgent", "Could not obtain hostname factory.");
IHostName *host;
ComPtr<IHostName> host;
HStringReference hostNameRef((const wchar_t*)hostName.utf16());
hostnameFactory->CreateHostName(hostNameRef.Get(), &host);
hostnameFactory->Release();
IDatagramSocketStatics *datagramSocketStatics;
ComPtr<IDatagramSocketStatics> datagramSocketStatics;
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics);
IAsyncOperation<IVectorView<EndpointPair*> *> *op;
datagramSocketStatics->GetEndpointPairsAsync(host,
ComPtr<IAsyncOperation<IVectorView<EndpointPair *> *>> op;
datagramSocketStatics->GetEndpointPairsAsync(host.Get(),
HString::MakeReference(L"0").Get(),
&op);
datagramSocketStatics->Release();
host->Release();
IVectorView<EndpointPair*> *endpointPairs = 0;
HRESULT hr = op->GetResults(&endpointPairs);
ComPtr<IVectorView<EndpointPair *>> endpointPairs;
hr = op->GetResults(&endpointPairs);
int waitCount = 0;
while (hr == E_ILLEGAL_METHOD_CALL) {
WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE);
@ -110,7 +106,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
if (++waitCount > 1200) // Wait for 1 minute max
return results;
}
op->Release();
if (!endpointPairs)
return results;
@ -119,11 +114,10 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
endpointPairs->get_Size(&size);
QList<QHostAddress> addresses;
for (unsigned int i = 0; i < size; ++i) {
IEndpointPair *endpointpair;
ComPtr<IEndpointPair> endpointpair;
endpointPairs->GetAt(i, &endpointpair);
IHostName *remoteHost;
ComPtr<IHostName> remoteHost;
endpointpair->get_RemoteHostName(&remoteHost);
endpointpair->Release();
if (!remoteHost)
continue;
HostNameType type;
@ -133,7 +127,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
HString name;
remoteHost->get_CanonicalName(name.GetAddressOf());
remoteHost->Release();
UINT32 length;
PCWSTR rawString = name.GetRawBuffer(&length);
QHostAddress addr;
@ -148,12 +141,11 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
QString QHostInfo::localHostName()
{
INetworkInformationStatics *statics;
ComPtr<INetworkInformationStatics> statics;
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &statics);
IVectorView<HostName*> *hostNames = 0;
ComPtr<IVectorView<HostName *>> hostNames;
statics->GetHostNames(&hostNames);
statics->Release();
if (!hostNames)
return QString();
@ -163,7 +155,7 @@ QString QHostInfo::localHostName()
return QString();
for (unsigned int i = 0; i < size; ++i) {
IHostName *hostName;
ComPtr<IHostName> hostName;
hostNames->GetAt(i, &hostName);
HostNameType type;
hostName->get_Type(&type);
@ -172,18 +164,15 @@ QString QHostInfo::localHostName()
HString name;
hostName->get_CanonicalName(name.GetAddressOf());
hostName->Release();
UINT32 length;
PCWSTR rawString = name.GetRawBuffer(&length);
return QString::fromWCharArray(rawString, length);
}
IHostName *firstHost;
ComPtr<IHostName> firstHost;
hostNames->GetAt(0, &firstHost);
hostNames->Release();
HString name;
firstHost->get_CanonicalName(name.GetAddressOf());
firstHost->Release();
UINT32 length;
PCWSTR rawString = name.GetRawBuffer(&length);
return QString::fromWCharArray(rawString, length);

View File

@ -73,12 +73,11 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
QList<HostNameInfo> hostList;
INetworkInformationStatics *hostNameStatics;
ComPtr<INetworkInformationStatics> hostNameStatics;
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &hostNameStatics);
IVectorView<HostName*> *hostNames = 0;
ComPtr<IVectorView<HostName *>> hostNames;
hostNameStatics->GetHostNames(&hostNames);
hostNameStatics->Release();
if (!hostNames)
return interfaces;
@ -86,7 +85,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
hostNames->get_Size(&hostNameCount);
for (unsigned i = 0; i < hostNameCount; ++i) {
HostNameInfo hostInfo;
IHostName *hostName;
ComPtr<IHostName> hostName;
hostNames->GetAt(i, &hostName);
HostNameType type;
@ -94,20 +93,17 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
if (type == HostNameType_DomainName)
continue;
IIPInformation *ipInformation;
ComPtr<IIPInformation> ipInformation;
hostName->get_IPInformation(&ipInformation);
INetworkAdapter *currentAdapter;
ComPtr<INetworkAdapter> currentAdapter;
ipInformation->get_NetworkAdapter(&currentAdapter);
currentAdapter->get_NetworkAdapterId(&hostInfo.adapterId);
currentAdapter->Release();
IReference<unsigned char> *prefixLengthReference;
ComPtr<IReference<unsigned char>> prefixLengthReference;
ipInformation->get_PrefixLength(&prefixLengthReference);
ipInformation->Release();
prefixLengthReference->get_Value(&hostInfo.prefixLength);
prefixLengthReference->Release();
// invalid prefixes
if ((type == HostNameType_Ipv4 && hostInfo.prefixLength > 32)
@ -116,20 +112,17 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
HString name;
hostName->get_CanonicalName(name.GetAddressOf());
hostName->Release();
UINT32 length;
PCWSTR rawString = name.GetRawBuffer(&length);
hostInfo.address = QString::fromWCharArray(rawString, length);
hostList << hostInfo;
}
hostNames->Release();
INetworkInformationStatics *networkInfoStatics;
GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &networkInfoStatics);
IVectorView<ConnectionProfile *> *connectionProfiles = 0;
ComPtr<IVectorView<ConnectionProfile *>> connectionProfiles;
networkInfoStatics->GetConnectionProfiles(&connectionProfiles);
networkInfoStatics->Release();
if (!connectionProfiles)
return interfaces;
@ -139,7 +132,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;
interfaces << iface;
IConnectionProfile *profile;
ComPtr<IConnectionProfile> profile;
connectionProfiles->GetAt(i, &profile);
NetworkConnectivityLevel connectivityLevel;
@ -147,16 +140,14 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
if (connectivityLevel != NetworkConnectivityLevel_None)
iface->flags = QNetworkInterface::IsUp | QNetworkInterface::IsRunning;
INetworkAdapter *adapter;
ComPtr<INetworkAdapter> adapter;
profile->get_NetworkAdapter(&adapter);
profile->Release();
UINT32 type;
adapter->get_IanaInterfaceType(&type);
if (type == 23)
iface->flags |= QNetworkInterface::IsPointToPoint;
GUID id;
adapter->get_NetworkAdapterId(&id);
adapter->Release();
OLECHAR adapterName[39]={0};
StringFromGUID2(id, adapterName, 39);
iface->name = QString::fromWCharArray(adapterName);
@ -179,7 +170,6 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
--i;
}
}
connectionProfiles->Release();
return interfaces;
}

View File

@ -474,16 +474,15 @@ void QNativeSocketEngine::close()
{
Q_D(QNativeSocketEngine);
if (d->socketDescriptor != -1) {
IClosable *socket = 0;
ComPtr<IClosable> socket;
if (d->socketType == QAbstractSocket::TcpSocket)
d->tcp->QueryInterface(IID_PPV_ARGS(&socket));
d->tcp.As(&socket);
else if (d->socketType == QAbstractSocket::UdpSocket)
d->udp->QueryInterface(IID_PPV_ARGS(&socket));
d->udp.As(&socket);
if (socket) {
d->closingDown = true;
socket->Close();
socket->Release();
d->socketDescriptor = -1;
}
d->socketDescriptor = -1;
@ -621,11 +620,10 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress
*addr = returnAddress;
*port = returnPort;
arg = d->pendingDatagrams.takeFirst();
arg->Release();
// TODO: fill data
Q_UNUSED(data);
arg->Release();
delete arg;
--i;
return maxlen;
}
@ -830,8 +828,8 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
SocketHandler *handler = gSocketHandler();
switch (socketType) {
case QAbstractSocket::TcpSocket: {
if (FAILED(RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocket).Get(),
reinterpret_cast<IInspectable **>(&tcp)))) {
HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocket).Get(), &tcp);
if (FAILED(hr)) {
qWarning("Failed to create StreamSocket instance");
return false;
}
@ -839,8 +837,8 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
return true;
}
case QAbstractSocket::UdpSocket: {
if (FAILED(RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(),
reinterpret_cast<IInspectable **>(&udp)))) {
HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &udp);
if (FAILED(hr)) {
qWarning("Failed to create stream socket");
return false;
}
@ -1253,7 +1251,7 @@ HRESULT QNativeSocketEnginePrivate::handleWriteCompleted(IAsyncOperationWithProg
HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, IDatagramSocketMessageReceivedEventArgs *args)
{
Q_Q(QNativeSocketEngine);
Q_UNUSED(socket)
Q_UNUSED(socket);
pendingDatagrams.append(args);
emit q->readReady();

View File

@ -193,10 +193,8 @@ public:
bool checkProxy(const QHostAddress &address);
bool fetchConnectionParameters();
private:
union {
ABI::Windows::Networking::Sockets::IStreamSocket *tcp;
ABI::Windows::Networking::Sockets::IDatagramSocket *udp;
};
Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocket> tcp;
Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IDatagramSocket> udp;
Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> tcpListener;
Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBuffer> readBuffer;
QBuffer readBytes;