windows-nt/Source/XPSP1/NT/net/upnp/tools/updiag/search.cpp
2020-09-26 16:20:57 +08:00

311 lines
8.1 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: S E A R C H . C P P
//
// Contents: Functions dealing with UPnP searches.
//
// Notes:
//
// Author: danielwe 28 Oct 1999
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "ncbase.h"
#include "updiagp.h"
BOOL DoFindServices(DWORD iCmd, DWORD cArgs, LPTSTR *rgArgs)
{
Assert(g_ctx.ectx == CTX_UCP);
if (g_ctx.pucpCur->cResults >= MAX_RESULT)
{
_tprintf(TEXT("Exceeded maximum number of results!\n"));
return FALSE;
}
if (cArgs == 2)
{
UPNPRESULT * pres;
LPSTR pszType;
pres = new UPNPRESULT;
ZeroMemory(pres, sizeof(UPNPRESULT));
lstrcpy(pres->szType, rgArgs[1]);
pres->resType = RES_FIND;
pszType = SzFromTsz(rgArgs[1]);
if (pszType)
{
pres->hResult = FindServicesCallback(pszType, NULL, FALSE,
NotifyCallback, (LPVOID)pres);
if (pres->hResult && pres->hResult != INVALID_HANDLE_VALUE)
{
g_ctx.pucpCur->rgResults[g_ctx.pucpCur->cResults++] = pres;
_tprintf(TEXT("Started looking for devices of type: %s\n"), rgArgs[1]);
}
else
{
_tprintf(TEXT("FindServicesCallback failed with error %d.\n"),
GetLastError());
delete pres;
}
delete [] pszType;
}
else
{
_tprintf(TEXT("DoFindServices: SzFromTsz failed\n"));
}
}
else
{
Usage(iCmd);
}
return FALSE;
}
BOOL DoSwitchResult(DWORD iCmd, DWORD cArgs, LPTSTR *rgArgs)
{
Assert(g_ctx.ectx == CTX_UCP);
if (cArgs == 2)
{
DWORD ires;
ires = _tcstoul(rgArgs[1], NULL, 10);
if (ires <= g_ctx.pucpCur->cResults &&
g_ctx.pucpCur->rgResults[ires - 1])
{
g_ctx.presCur = g_ctx.pucpCur->rgResults[ires - 1];
g_ctx.ectx = CTX_RESULT;
}
else
{
_tprintf(TEXT("%d is not a valid result index!\n"), ires);
}
}
else
{
Usage(iCmd);
}
return FALSE;
}
LPCTSTR SzFromResType(RESULT_TYPE rt)
{
switch (rt)
{
case RES_NOTIFY:
return TEXT("Notify");
case RES_FIND:
return TEXT("Search");
case RES_SUBS:
return TEXT("Subscription");
}
return TEXT("Unknown");
}
BOOL DoListUpnpResults(DWORD iCmd, DWORD cArgs, LPTSTR *rgArgs)
{
if (g_ctx.ectx == CTX_UCP)
{
DWORD isvc;
_tprintf(TEXT("Listing all Results within %s\n"), g_ctx.pucpCur->szName);
_tprintf(TEXT("------------------------------\n"));
for (isvc = 0; isvc < g_ctx.pucpCur->cResults; isvc++)
{
UPNPRESULT * pres = g_ctx.pucpCur->rgResults[isvc];
_tprintf(TEXT("%d) %s:(%s) - %d result(s)\n"), isvc + 1,
SzFromResType(pres->resType),
pres->szType,
pres->cResult);
}
_tprintf(TEXT("------------------------------\n\n"));
}
return FALSE;
}
VOID ListUpnpResultMsgs(DWORD ires, UPNPRESULT *pResult)
{
switch (pResult->resType)
{
case RES_NOTIFY:
case RES_FIND:
_tprintf(TEXT("%d) Type : %s\n"),
ires + 1, pResult->rgmsgResult[ires]->iSeq == 2 ? "Alive" :
pResult->rgmsgResult[ires]->iSeq == 1 ? "Byebye" : "Search");
_tprintf(TEXT(" USN : %s\n"),
pResult->rgmsgResult[ires]->szUSN);
_tprintf(TEXT(" SID : %s\n"),
pResult->rgmsgResult[ires]->szSid);
_tprintf(TEXT(" AL : %s\n"),
pResult->rgmsgResult[ires]->szAltHeaders);
_tprintf(TEXT(" Location : %s\n"),
pResult->rgmsgResult[ires]->szLocHeader);
_tprintf(TEXT(" NT/ST : %s\n"),
pResult->rgmsgResult[ires]->szType);
_tprintf(TEXT(" LifeTime : %d\n"),
pResult->rgmsgResult[ires]->iLifeTime);
break;
case RES_SUBS:
_tprintf(TEXT("%d) Seq #:%d Sid: %s - Content\n%s\n"), ires + 1,
pResult->rgmsgResult[ires]->iSeq,
pResult->rgmsgResult[ires]->szSid,
pResult->rgmsgResult[ires]->szContent);
break;
}
}
BOOL DoListUpnpResultMsgs(DWORD iCmd, DWORD cArgs, LPTSTR *rgArgs)
{
Assert(g_ctx.ectx == CTX_RESULT);
DWORD ires;
UPNPRESULT * pres = g_ctx.presCur;
_tprintf(TEXT("Listing all Results within %s\n"), pres->szType);
_tprintf(TEXT("------------------------------\n"));
for (ires = 0; ires < pres->cResult; ires++)
{
ListUpnpResultMsgs(ires, pres);
}
_tprintf(TEXT("------------------------------\n\n"));
return FALSE;
}
BOOL DoAlive(DWORD iCmd, DWORD cArgs, LPTSTR *rgArgs)
{
HANDLE hSubs;
Assert(g_ctx.ectx & CTX_UCP);
if (g_ctx.pucpCur->cResults >= MAX_RESULT)
{
_tprintf(TEXT("Exceeded maximum number of subscriptions!\n"));
return FALSE;
}
if (cArgs == 2)
{
UPNPRESULT * pAlive;
pAlive = new UPNPRESULT;
ZeroMemory(pAlive, sizeof(UPNPRESULT));
lstrcpy(pAlive->szType, rgArgs[1]);
pAlive->resType = RES_NOTIFY;
if (g_ctx.ectx == CTX_UCP)
{
LPSTR pszType;
pszType = SzFromTsz(rgArgs[1]);
if (pszType)
{
pAlive->hResult = RegisterNotification(NOTIFY_ALIVE, pszType,
NULL, NotifyCallback,
(LPVOID) pAlive);
if (pAlive->hResult && pAlive->hResult != INVALID_HANDLE_VALUE)
{
g_ctx.pucpCur->rgResults[g_ctx.pucpCur->cResults++] = pAlive;
_tprintf(TEXT("Listening for alive from: %s\n"), rgArgs[1]);
}
else
{
_tprintf(TEXT("RegisterNotification failed with error %d.\n"),
GetLastError());
delete pAlive;
}
delete [] pszType;
}
else
{
_tprintf(TEXT("DoAlive: SzFromTsz failed"));
}
}
}
else
{
Usage(iCmd);
}
return FALSE;
}
BOOL DoDelResult(DWORD iCmd, DWORD cArgs, LPTSTR *rgArgs)
{
Assert(g_ctx.ectx == CTX_UCP);
if (cArgs == 2)
{
DWORD ires;
ires = _tcstoul(rgArgs[1], NULL, 10);
if (ires <= g_ctx.pucpCur->cResults &&
g_ctx.pucpCur->rgResults[ires - 1])
{
UPNPRESULT * pres = g_ctx.pucpCur->rgResults[ires - 1];
_tprintf(TEXT("Deleted result %s.\n"), pres->szType);
// Move last item into gap and decrement the count
g_ctx.pucpCur->rgResults[ires - 1] = g_ctx.pucpCur->rgResults[g_ctx.pucpCur->cResults - 1];
CleanupResult(pres);
g_ctx.pucpCur->cResults--;
}
else
{
_tprintf(TEXT("%d is not a valid search index!\n"), ires);
}
}
else
{
Usage(iCmd);
}
return FALSE;
}
VOID CleanupResult(UPNPRESULT *pres)
{
DWORD i;
for (i = 0; i < pres->cResult; i++)
{
LocalFreeSsdpMessage(pres->rgmsgResult[i]);
}
switch (pres->resType)
{
case RES_FIND:
TraceTag(ttidUpdiag, "Closing search handle %d.", pres->hResult);
FindServicesClose(pres->hResult);
break;
case RES_SUBS:
case RES_NOTIFY:
TraceTag(ttidUpdiag, "Deregistering notification %d.", pres->hResult);
DeregisterNotification(pres->hResult);
break;
}
delete pres;
}