bool QWinRTServices::openDocument(const QUrl &url)
{
    if (!(m_fileFactory && m_launcher))
        return QPlatformServices::openDocument(url);

    const QString pathString = QDir::toNativeSeparators(url.toLocalFile());
    HSTRING_HEADER header; HSTRING path;
    WindowsCreateStringReference((const wchar_t*)pathString.utf16(), pathString.length(), &header, &path);
    IAsyncOperation<StorageFile*> *fileOp;
    m_fileFactory->GetFileFromPathAsync(path, &fileOp);
    if (!fileOp)
        return false;

    IStorageFile *file = nullptr;
    while (fileOp->GetResults(&file) == E_ILLEGAL_METHOD_CALL)
        QCoreApplication::processEvents();
    fileOp->Release();
    if (!file)
        return false;

    IAsyncOperation<bool> *launchOp;
    m_launcher->LaunchFileAsync(file, &launchOp);
    if (!launchOp)
        return false;

    boolean result = false;
    while (launchOp->GetResults(&result) == E_ILLEGAL_METHOD_CALL)
        QCoreApplication::processEvents();
    launchOp->Release();

    return result;
}
bool QWinRTServices::openUrl(const QUrl &url)
{
    if (!(m_uriFactory && m_launcher))
        return QPlatformServices::openUrl(url);

    IUriRuntimeClass *uri;
    QString urlString = url.toString(); HSTRING uriString; HSTRING_HEADER header;
    WindowsCreateStringReference((const wchar_t*)urlString.utf16(), urlString.length(), &header, &uriString);
    m_uriFactory->CreateUri(uriString, &uri);
    if (!uri)
        return false;

    IAsyncOperation<bool> *launchOp;
    m_launcher->LaunchUriAsync(uri, &launchOp);
    uri->Release();
    if (!launchOp)
        return false;

    boolean result = false;
    while (launchOp->GetResults(&result) == E_ILLEGAL_METHOD_CALL)
        QCoreApplication::processEvents();
    launchOp->Release();

    return result;
}
HRESULT CopyFilesToClipboard(std::list<std::wstring> FileNameList,
BOOL bMove,IDataObject **pClipboardDataObject)
{
	FORMATETC ftc[2];
	STGMEDIUM stg[2];
	HRESULT hr;

	BuildHDropList(&ftc[0],&stg[0],FileNameList);

	ftc[1].cfFormat			= (CLIPFORMAT)RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
	ftc[1].ptd				= NULL;
	ftc[1].dwAspect			= DVASPECT_CONTENT;
	ftc[1].lindex			= -1;
	ftc[1].tymed			= TYMED_HGLOBAL;
	
	HGLOBAL hglb = GlobalAlloc(GMEM_MOVEABLE,sizeof(DWORD));

	DWORD *pdwCopyEffect = static_cast<DWORD *>(GlobalLock(hglb));

	if(bMove)
		*pdwCopyEffect = DROPEFFECT_MOVE;
	else
		*pdwCopyEffect = DROPEFFECT_COPY;

	GlobalUnlock(hglb);

	stg[1].pUnkForRelease	= 0;

	stg[1].hGlobal			= hglb;
	stg[1].tymed			= TYMED_HGLOBAL;

	hr = CreateDataObject(ftc,stg,pClipboardDataObject,2);

	IAsyncOperation *pAsyncOperation = NULL;
	(*pClipboardDataObject)->QueryInterface(IID_IAsyncOperation,(void **)&pAsyncOperation);

	pAsyncOperation->SetAsyncMode(TRUE);
	pAsyncOperation->Release();

	if(SUCCEEDED(hr))
	{
		hr = OleSetClipboard(*pClipboardDataObject);
	}

	return hr;
}
QT_BEGIN_NAMESPACE

void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply)
{
    // TODO: Add nameserver support for winRT
    if (!nameserver.isNull())
        qWarning() << "Ignoring nameserver as its currently not supported on WinRT";

    // TODO: is there any way to do "proper" dns lookup?
    if (requestType != QDnsLookup::A && requestType != QDnsLookup::AAAA
            && requestType != QDnsLookup::ANY) {
        reply->error = QDnsLookup::InvalidRequestError;
        reply->errorString = QLatin1String("WinRT only supports IPv4 and IPv6 requests");
        return;
    }

    QString aceHostname = QUrl::fromAce(requestName);
    if (aceHostname.isEmpty()) {
        reply->error = QDnsLookup::InvalidRequestError;
        reply->errorString = requestName.isEmpty() ? tr("No hostname given") : tr("Invalid hostname");
        return;
    }

    IHostNameFactory *hostnameFactory;

    HStringReference classId(RuntimeClass_Windows_Networking_HostName);
    if (FAILED(GetActivationFactory(classId.Get(), &hostnameFactory))) {
        reply->error = QDnsLookup::ResolverError;
        reply->errorString = QLatin1String("Could not obtain hostname factory");
        return;
    }
    IHostName *host;
    HStringReference hostNameRef((const wchar_t*)aceHostname.utf16());
    hostnameFactory->CreateHostName(hostNameRef.Get(), &host);
    hostnameFactory->Release();

    IDatagramSocketStatics *datagramSocketStatics;
    GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics);

    IAsyncOperation<IVectorView<EndpointPair*> *> *op;
    HSTRING proto;
    WindowsCreateString(L"0", 1, &proto);
    datagramSocketStatics->GetEndpointPairsAsync(host, proto, &op);
    datagramSocketStatics->Release();
    host->Release();

    IVectorView<EndpointPair*> *endpointPairs = 0;
    HRESULT hr = op->GetResults(&endpointPairs);
    int waitCount = 0;
    while (hr == E_ILLEGAL_METHOD_CALL) {
        WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE);
        hr = op->GetResults(&endpointPairs);
        if (++waitCount > 1200) // Wait for 1 minute max
            return;
    }
    op->Release();

    if (!endpointPairs)
        return;

    unsigned int size;
    endpointPairs->get_Size(&size);
    for (unsigned int i = 0; i < size; ++i) {
        IEndpointPair *endpointpair;
        endpointPairs->GetAt(i, &endpointpair);
        IHostName *remoteHost;
        endpointpair->get_RemoteHostName(&remoteHost);
        endpointpair->Release();
        HostNameType type;
        remoteHost->get_Type(&type);
        if (type == HostNameType_Bluetooth || type == HostNameType_DomainName
                || (requestType != QDnsLookup::ANY
                && ((type == HostNameType_Ipv4 && requestType == QDnsLookup::AAAA)
                || (type == HostNameType_Ipv6 && requestType == QDnsLookup::A))))
            continue;

        HSTRING name;
        remoteHost->get_CanonicalName(&name);
        remoteHost->Release();
        UINT32 length;
        PCWSTR rawString = WindowsGetStringRawBuffer(name, &length);
        QDnsHostAddressRecord record;
        record.d->name = aceHostname;
        record.d->value = QHostAddress(QString::fromWCharArray(rawString, length));
        reply->hostAddressRecords.append(record);
    }
}
void CDropHandler::CopyDroppedFilesInternal(IBufferManager *pbm,
list<PastedFile_t> *pPastedFileList,BOOL bCopy,BOOL bRenameOnCollision)
{
	HANDLE hThread;
	TCHAR *szFileNameList = NULL;
	DWORD dwBufferSize;

	pbm->QueryBufferSize(&dwBufferSize);

	if(dwBufferSize > 1)
	{
		szFileNameList = (TCHAR *)malloc(dwBufferSize * sizeof(TCHAR));

		if(szFileNameList != NULL)
		{
			pbm->QueryBuffer(szFileNameList,dwBufferSize);

			PastedFilesInfo_t *ppfi = NULL;

			ppfi = (PastedFilesInfo_t *)malloc(sizeof(PastedFilesInfo_t));

			if(ppfi != NULL)
			{
				TCHAR *pszDestDirectory = NULL;

				pszDestDirectory = (TCHAR *)malloc((MAX_PATH + 1) * sizeof(TCHAR));

				if(pszDestDirectory != NULL)
				{
					StringCchCopy(pszDestDirectory,MAX_PATH,m_szDestDirectory);
					pszDestDirectory[lstrlen(pszDestDirectory) + 1] = '\0';

					ppfi->shfo.hwnd		= m_hwndDrop;
					ppfi->shfo.wFunc	= bCopy == TRUE ? FO_COPY : FO_MOVE;
					ppfi->shfo.pFrom	= szFileNameList;
					ppfi->shfo.pTo		= pszDestDirectory;
					ppfi->shfo.fFlags	= (bRenameOnCollision == TRUE ? FOF_RENAMEONCOLLISION : 0)|FOF_WANTMAPPINGHANDLE;

					ppfi->pDropFilesCallback	= m_pDropFilesCallback;
					ppfi->pPastedFileList		= new list<PastedFile_t>(*pPastedFileList);
					ppfi->dwEffect				= bCopy == TRUE ? DROPEFFECT_COPY : DROPEFFECT_MOVE;
					ppfi->pt.x					= m_ptl.x;
					ppfi->pt.y					= m_ptl.y;
					ppfi->pFrom					= szFileNameList;
					ppfi->pTo					= pszDestDirectory;

					ppfi->pDropHandler	= this;
					ppfi->m_hDrop		= m_hwndDrop;

					IAsyncOperation *pao = NULL;
					BOOL bAsyncSupported = FALSE;
					HRESULT hr;

					/* Does the drop source support asynchronous copy? */
					hr = m_pDataObject->QueryInterface(IID_IAsyncOperation,(void **)&pao);

					if(hr == S_OK)
					{
						pao->GetAsyncMode(&bAsyncSupported);

						if(!bAsyncSupported)
						{
							pao->Release();
						}
					}

					if(bAsyncSupported)
					{
						pao->StartOperation(NULL);

						ppfi->pao	= pao;

						/* The copy operation is going to occur on a background thread,
						which means that we can't release this object until the background
						thread has completed. Use reference counting to ensure this
						condition is met. */
						AddRef();

						/* The drop source needs to be notified of the status of the copy
						once it has finished. This notification however, needs to occur on
						the thread that the object was created in. Therefore, we'll subclass
						the drop window, so that we can send it a private user message
						once the drop has finished. */
						SetWindowSubclass(m_hwndDrop,DropWindowSubclass,SUBCLASS_ID,NULL);

						/* Create a new thread, which we'll use to copy
						the dropped files. */
						hThread = CreateThread(NULL,0,CopyDroppedFilesInternalAsyncStub,ppfi,0,NULL);

						CloseHandle(hThread);
					}
					else
					{
						/* Copy the files within this thread. */
						CopyDroppedFilesInternalAsync(ppfi);

						free((void *)ppfi);
					}
				}
				else
				{
					free(szFileNameList);
				}
			}
		}
	}
}