Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 lines
8.1 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: S E A R C H . C P P
  7. //
  8. // Contents: Functions dealing with UPnP searches.
  9. //
  10. // Notes:
  11. //
  12. // Author: danielwe 28 Oct 1999
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "ncbase.h"
  18. #include "updiagp.h"
  19. BOOL DoFindServices(DWORD iCmd, DWORD cArgs, LPTSTR *rgArgs)
  20. {
  21. Assert(g_ctx.ectx == CTX_UCP);
  22. if (g_ctx.pucpCur->cResults >= MAX_RESULT)
  23. {
  24. _tprintf(TEXT("Exceeded maximum number of results!\n"));
  25. return FALSE;
  26. }
  27. if (cArgs == 2)
  28. {
  29. UPNPRESULT * pres;
  30. LPSTR pszType;
  31. pres = new UPNPRESULT;
  32. ZeroMemory(pres, sizeof(UPNPRESULT));
  33. lstrcpy(pres->szType, rgArgs[1]);
  34. pres->resType = RES_FIND;
  35. pszType = SzFromTsz(rgArgs[1]);
  36. if (pszType)
  37. {
  38. pres->hResult = FindServicesCallback(pszType, NULL, FALSE,
  39. NotifyCallback, (LPVOID)pres);
  40. if (pres->hResult && pres->hResult != INVALID_HANDLE_VALUE)
  41. {
  42. g_ctx.pucpCur->rgResults[g_ctx.pucpCur->cResults++] = pres;
  43. _tprintf(TEXT("Started looking for devices of type: %s\n"), rgArgs[1]);
  44. }
  45. else
  46. {
  47. _tprintf(TEXT("FindServicesCallback failed with error %d.\n"),
  48. GetLastError());
  49. delete pres;
  50. }
  51. delete [] pszType;
  52. }
  53. else
  54. {
  55. _tprintf(TEXT("DoFindServices: SzFromTsz failed\n"));
  56. }
  57. }
  58. else
  59. {
  60. Usage(iCmd);
  61. }
  62. return FALSE;
  63. }
  64. BOOL DoSwitchResult(DWORD iCmd, DWORD cArgs, LPTSTR *rgArgs)
  65. {
  66. Assert(g_ctx.ectx == CTX_UCP);
  67. if (cArgs == 2)
  68. {
  69. DWORD ires;
  70. ires = _tcstoul(rgArgs[1], NULL, 10);
  71. if (ires <= g_ctx.pucpCur->cResults &&
  72. g_ctx.pucpCur->rgResults[ires - 1])
  73. {
  74. g_ctx.presCur = g_ctx.pucpCur->rgResults[ires - 1];
  75. g_ctx.ectx = CTX_RESULT;
  76. }
  77. else
  78. {
  79. _tprintf(TEXT("%d is not a valid result index!\n"), ires);
  80. }
  81. }
  82. else
  83. {
  84. Usage(iCmd);
  85. }
  86. return FALSE;
  87. }
  88. LPCTSTR SzFromResType(RESULT_TYPE rt)
  89. {
  90. switch (rt)
  91. {
  92. case RES_NOTIFY:
  93. return TEXT("Notify");
  94. case RES_FIND:
  95. return TEXT("Search");
  96. case RES_SUBS:
  97. return TEXT("Subscription");
  98. }
  99. return TEXT("Unknown");
  100. }
  101. BOOL DoListUpnpResults(DWORD iCmd, DWORD cArgs, LPTSTR *rgArgs)
  102. {
  103. if (g_ctx.ectx == CTX_UCP)
  104. {
  105. DWORD isvc;
  106. _tprintf(TEXT("Listing all Results within %s\n"), g_ctx.pucpCur->szName);
  107. _tprintf(TEXT("------------------------------\n"));
  108. for (isvc = 0; isvc < g_ctx.pucpCur->cResults; isvc++)
  109. {
  110. UPNPRESULT * pres = g_ctx.pucpCur->rgResults[isvc];
  111. _tprintf(TEXT("%d) %s:(%s) - %d result(s)\n"), isvc + 1,
  112. SzFromResType(pres->resType),
  113. pres->szType,
  114. pres->cResult);
  115. }
  116. _tprintf(TEXT("------------------------------\n\n"));
  117. }
  118. return FALSE;
  119. }
  120. VOID ListUpnpResultMsgs(DWORD ires, UPNPRESULT *pResult)
  121. {
  122. switch (pResult->resType)
  123. {
  124. case RES_NOTIFY:
  125. case RES_FIND:
  126. _tprintf(TEXT("%d) Type : %s\n"),
  127. ires + 1, pResult->rgmsgResult[ires]->iSeq == 2 ? "Alive" :
  128. pResult->rgmsgResult[ires]->iSeq == 1 ? "Byebye" : "Search");
  129. _tprintf(TEXT(" USN : %s\n"),
  130. pResult->rgmsgResult[ires]->szUSN);
  131. _tprintf(TEXT(" SID : %s\n"),
  132. pResult->rgmsgResult[ires]->szSid);
  133. _tprintf(TEXT(" AL : %s\n"),
  134. pResult->rgmsgResult[ires]->szAltHeaders);
  135. _tprintf(TEXT(" Location : %s\n"),
  136. pResult->rgmsgResult[ires]->szLocHeader);
  137. _tprintf(TEXT(" NT/ST : %s\n"),
  138. pResult->rgmsgResult[ires]->szType);
  139. _tprintf(TEXT(" LifeTime : %d\n"),
  140. pResult->rgmsgResult[ires]->iLifeTime);
  141. break;
  142. case RES_SUBS:
  143. _tprintf(TEXT("%d) Seq #:%d Sid: %s - Content\n%s\n"), ires + 1,
  144. pResult->rgmsgResult[ires]->iSeq,
  145. pResult->rgmsgResult[ires]->szSid,
  146. pResult->rgmsgResult[ires]->szContent);
  147. break;
  148. }
  149. }
  150. BOOL DoListUpnpResultMsgs(DWORD iCmd, DWORD cArgs, LPTSTR *rgArgs)
  151. {
  152. Assert(g_ctx.ectx == CTX_RESULT);
  153. DWORD ires;
  154. UPNPRESULT * pres = g_ctx.presCur;
  155. _tprintf(TEXT("Listing all Results within %s\n"), pres->szType);
  156. _tprintf(TEXT("------------------------------\n"));
  157. for (ires = 0; ires < pres->cResult; ires++)
  158. {
  159. ListUpnpResultMsgs(ires, pres);
  160. }
  161. _tprintf(TEXT("------------------------------\n\n"));
  162. return FALSE;
  163. }
  164. BOOL DoAlive(DWORD iCmd, DWORD cArgs, LPTSTR *rgArgs)
  165. {
  166. HANDLE hSubs;
  167. Assert(g_ctx.ectx & CTX_UCP);
  168. if (g_ctx.pucpCur->cResults >= MAX_RESULT)
  169. {
  170. _tprintf(TEXT("Exceeded maximum number of subscriptions!\n"));
  171. return FALSE;
  172. }
  173. if (cArgs == 2)
  174. {
  175. UPNPRESULT * pAlive;
  176. pAlive = new UPNPRESULT;
  177. ZeroMemory(pAlive, sizeof(UPNPRESULT));
  178. lstrcpy(pAlive->szType, rgArgs[1]);
  179. pAlive->resType = RES_NOTIFY;
  180. if (g_ctx.ectx == CTX_UCP)
  181. {
  182. LPSTR pszType;
  183. pszType = SzFromTsz(rgArgs[1]);
  184. if (pszType)
  185. {
  186. pAlive->hResult = RegisterNotification(NOTIFY_ALIVE, pszType,
  187. NULL, NotifyCallback,
  188. (LPVOID) pAlive);
  189. if (pAlive->hResult && pAlive->hResult != INVALID_HANDLE_VALUE)
  190. {
  191. g_ctx.pucpCur->rgResults[g_ctx.pucpCur->cResults++] = pAlive;
  192. _tprintf(TEXT("Listening for alive from: %s\n"), rgArgs[1]);
  193. }
  194. else
  195. {
  196. _tprintf(TEXT("RegisterNotification failed with error %d.\n"),
  197. GetLastError());
  198. delete pAlive;
  199. }
  200. delete [] pszType;
  201. }
  202. else
  203. {
  204. _tprintf(TEXT("DoAlive: SzFromTsz failed"));
  205. }
  206. }
  207. }
  208. else
  209. {
  210. Usage(iCmd);
  211. }
  212. return FALSE;
  213. }
  214. BOOL DoDelResult(DWORD iCmd, DWORD cArgs, LPTSTR *rgArgs)
  215. {
  216. Assert(g_ctx.ectx == CTX_UCP);
  217. if (cArgs == 2)
  218. {
  219. DWORD ires;
  220. ires = _tcstoul(rgArgs[1], NULL, 10);
  221. if (ires <= g_ctx.pucpCur->cResults &&
  222. g_ctx.pucpCur->rgResults[ires - 1])
  223. {
  224. UPNPRESULT * pres = g_ctx.pucpCur->rgResults[ires - 1];
  225. _tprintf(TEXT("Deleted result %s.\n"), pres->szType);
  226. // Move last item into gap and decrement the count
  227. g_ctx.pucpCur->rgResults[ires - 1] = g_ctx.pucpCur->rgResults[g_ctx.pucpCur->cResults - 1];
  228. CleanupResult(pres);
  229. g_ctx.pucpCur->cResults--;
  230. }
  231. else
  232. {
  233. _tprintf(TEXT("%d is not a valid search index!\n"), ires);
  234. }
  235. }
  236. else
  237. {
  238. Usage(iCmd);
  239. }
  240. return FALSE;
  241. }
  242. VOID CleanupResult(UPNPRESULT *pres)
  243. {
  244. DWORD i;
  245. for (i = 0; i < pres->cResult; i++)
  246. {
  247. LocalFreeSsdpMessage(pres->rgmsgResult[i]);
  248. }
  249. switch (pres->resType)
  250. {
  251. case RES_FIND:
  252. TraceTag(ttidUpdiag, "Closing search handle %d.", pres->hResult);
  253. FindServicesClose(pres->hResult);
  254. break;
  255. case RES_SUBS:
  256. case RES_NOTIFY:
  257. TraceTag(ttidUpdiag, "Deregistering notification %d.", pres->hResult);
  258. DeregisterNotification(pres->hResult);
  259. break;
  260. }
  261. delete pres;
  262. }