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.

629 lines
12 KiB

  1. //****************************************************************************
  2. //
  3. // Microsoft NT Remote Access Service
  4. //
  5. // Copyright 1992-93
  6. //
  7. //
  8. // Revision History
  9. //
  10. //
  11. // 6/2/92 Gurdeep Singh Pall Created
  12. //
  13. //
  14. // Description: This file contains misellaneous functions used by rasman.
  15. //
  16. //****************************************************************************
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <rasman.h>
  21. #include <wanpub.h>
  22. #include <raserror.h>
  23. #include <stdarg.h>
  24. #include <media.h>
  25. #include "defs.h"
  26. #include "structs.h"
  27. #include "protos.h"
  28. #include "globals.h"
  29. #include <stdio.h>
  30. #include <stdarg.h>
  31. #include <stdlib.h>
  32. #include "string.h"
  33. #include <mprlog.h>
  34. #include <rtutils.h>
  35. #include "logtrdef.h"
  36. #include "rpc.h"
  37. #include "rasrpc.h"
  38. #include "winsock2.h"
  39. #include "svcguid.h"
  40. #define QUERYBUFSIZE 1024
  41. extern RPC_BINDING_HANDLE g_hBinding;
  42. //
  43. // commonly used handles are cached in the process's
  44. // global memory
  45. //
  46. CRITICAL_SECTION g_csRequestBuffer;
  47. /*++
  48. Routine Description
  49. Gets a free request buffer from the pool of buffers.
  50. If there are no buffers available it blocks for one.
  51. This is acceptable since the Requestor thread will be
  52. releasing buffers fairly quickly - also, if this thread
  53. does not block here it will be blocking for the Requestor
  54. thread to complete the request anyway. Note: Before returning
  55. it also ensures that this process has a handle to the
  56. event used to signal completion of request.
  57. Arguments
  58. Returns Value
  59. Nothing
  60. --*/
  61. RequestBuffer*
  62. GetRequestBuffer ()
  63. {
  64. DWORD dwError;
  65. //
  66. // check to see if we are bound to the rpc server
  67. // bind to the server if we aren't
  68. //
  69. if ( NULL == g_hBinding
  70. && NULL == g_fnServiceRequest)
  71. {
  72. if (NO_ERROR != (dwError = RasRpcConnect(NULL, NULL)))
  73. {
  74. RasmanOutputDebug ("Failed to connect to local server. %d\n",
  75. dwError );
  76. g_pRequestBuffer = NULL;
  77. goto done;
  78. }
  79. }
  80. EnterCriticalSection( &g_csRequestBuffer );
  81. if ( NULL == g_pRequestBuffer )
  82. {
  83. g_pRequestBuffer = LocalAlloc (
  84. LPTR,
  85. sizeof (RequestBuffer)
  86. + REQUEST_BUFFER_SIZE);
  87. }
  88. if (NULL == g_pRequestBuffer)
  89. {
  90. LeaveCriticalSection( &g_csRequestBuffer );
  91. }
  92. done:
  93. return g_pRequestBuffer;
  94. }
  95. /*++
  96. Routine Description
  97. Frees the request buffer, and, closes the wait event
  98. handle which was duplicated for the calling process
  99. in the GetRequestBuffer() API.
  100. Arguments
  101. Return Value
  102. Nothing
  103. --*/
  104. VOID
  105. FreeRequestBuffer (RequestBuffer *buffer)
  106. {
  107. LeaveCriticalSection ( &g_csRequestBuffer );
  108. (void *) buffer;
  109. return;
  110. }
  111. /*++
  112. Routine Description
  113. Opens a handle for object owned by the rasman process,
  114. for the current process.
  115. Arguments
  116. Return Value
  117. Duplicated handle.
  118. --*/
  119. HANDLE
  120. OpenNamedEventHandle (CHAR* sourceobject)
  121. {
  122. HANDLE duphandle ;
  123. duphandle = OpenEvent (EVENT_ALL_ACCESS,
  124. FALSE,
  125. sourceobject);
  126. if (duphandle == NULL)
  127. {
  128. GetLastError();
  129. DbgUserBreakPoint() ;
  130. }
  131. return duphandle ;
  132. }
  133. /*++
  134. Routine Description
  135. Opens a handle for object owned by the rasman process,
  136. for the current process.
  137. Arguments
  138. Return Value
  139. Duplicated handle.
  140. --*/
  141. HANDLE
  142. OpenNamedMutexHandle (CHAR* sourceobject)
  143. {
  144. HANDLE duphandle ;
  145. duphandle = OpenMutex (SYNCHRONIZE,
  146. FALSE,
  147. sourceobject);
  148. if (duphandle == NULL)
  149. {
  150. GetLastError() ;
  151. }
  152. return duphandle ;
  153. }
  154. /*++
  155. Routine Description
  156. No queue really - just signals the other process
  157. to service request.
  158. Arguments
  159. Return Value
  160. Nothing
  161. --*/
  162. DWORD
  163. PutRequestInQueue (HANDLE hConnection,
  164. RequestBuffer *preqbuff,
  165. DWORD dwSizeOfBuffer)
  166. {
  167. DWORD dwErr = ERROR_SUCCESS;
  168. if (g_fnServiceRequest)
  169. {
  170. g_fnServiceRequest(preqbuff, dwSizeOfBuffer);
  171. }
  172. else
  173. {
  174. dwErr = RemoteSubmitRequest (hConnection,
  175. (PBYTE) preqbuff,
  176. dwSizeOfBuffer);
  177. }
  178. return dwErr;
  179. }
  180. /*++
  181. Routine Description
  182. Copies params from one struct to another.
  183. Arguments
  184. Return Value
  185. Nothing.
  186. --*/
  187. VOID
  188. CopyParams (RAS_PARAMS *src, RAS_PARAMS *dest, DWORD numofparams)
  189. {
  190. WORD i ;
  191. PBYTE temp ;
  192. //
  193. // first copy all the params into dest
  194. //
  195. memcpy (dest,
  196. src,
  197. numofparams*sizeof(RAS_PARAMS)) ;
  198. //
  199. // copy the strings:
  200. //
  201. temp = (PBYTE)dest + numofparams * sizeof(RAS_PARAMS) ;
  202. for (i = 0; i < numofparams; i++)
  203. {
  204. if (src[i].P_Type == String)
  205. {
  206. dest[i].P_Value.String.Length =
  207. src[i].P_Value.String.Length ;
  208. dest[i].P_Value.String.Data = temp ;
  209. memcpy (temp,
  210. src[i].P_Value.String.Data,
  211. src[i].P_Value.String.Length) ;
  212. temp += src[i].P_Value.String.Length ;
  213. }
  214. else
  215. {
  216. dest[i].P_Value.Number = src[i].P_Value.Number ;
  217. }
  218. }
  219. }
  220. VOID
  221. ConvParamPointerToOffset (RAS_PARAMS *params, DWORD numofparams)
  222. {
  223. WORD i ;
  224. for (i = 0; i < numofparams; i++)
  225. {
  226. if (params[i].P_Type == String)
  227. {
  228. params[i].P_Value.String_OffSet.dwOffset =
  229. (DWORD) (params[i].P_Value.String.Data - (PCHAR) params) ;
  230. }
  231. }
  232. }
  233. VOID
  234. ConvParamOffsetToPointer (RAS_PARAMS *params, DWORD numofparams)
  235. {
  236. WORD i ;
  237. for (i = 0; i < numofparams; i++)
  238. {
  239. if (params[i].P_Type == String)
  240. {
  241. params[i].P_Value.String.Data =
  242. params[i].P_Value.String_OffSet.dwOffset
  243. + (PCHAR) params ;
  244. }
  245. }
  246. }
  247. /*++
  248. Routine Description
  249. Closes the handles for different objects opened by RASMAN process.
  250. Arguments
  251. Return Value
  252. --*/
  253. VOID
  254. FreeNotifierHandle (HANDLE handle)
  255. {
  256. if ((handle != NULL) && (handle != INVALID_HANDLE_VALUE))
  257. {
  258. if (!CloseHandle (handle))
  259. {
  260. GetLastError () ;
  261. }
  262. }
  263. }
  264. VOID
  265. GetMutex (HANDLE mutex, DWORD to)
  266. {
  267. WaitForSingleObject (mutex, to) ;
  268. }
  269. VOID
  270. FreeMutex (HANDLE mutex)
  271. {
  272. ReleaseMutex(mutex) ;
  273. }
  274. DWORD
  275. DwRasGetHostByName(CHAR *pszHostName,
  276. DWORD **ppdwAddress,
  277. DWORD *pcAddresses)
  278. {
  279. WCHAR *pwszHostName = NULL;
  280. DWORD dwErr = SUCCESS;
  281. HANDLE hRnr;
  282. PWSAQUERYSETW pQuery = NULL;
  283. const static GUID ServiceGuid = SVCID_INET_HOSTADDRBYNAME;
  284. DWORD dwQuerySize = QUERYBUFSIZE;
  285. DWORD dwAddress = 0;
  286. const static AFPROTOCOLS afProtocols[2] =
  287. {
  288. {AF_INET, IPPROTO_UDP},
  289. {AF_INET, IPPROTO_TCP}
  290. };
  291. DWORD cAddresses = 0;
  292. DWORD *pdwAddresses = NULL;
  293. DWORD MaxAddresses = 5;
  294. ASSERT(NULL != ppdwAddress);
  295. ASSERT(NULL != pcAddresses);
  296. if (NULL != pszHostName)
  297. {
  298. DWORD cch;
  299. cch = MultiByteToWideChar(
  300. CP_UTF8,
  301. 0,
  302. pszHostName,
  303. -1,
  304. NULL,
  305. 0);
  306. if(0 == cch)
  307. {
  308. dwErr = GetLastError();
  309. goto done;
  310. }
  311. pwszHostName = LocalAlloc(LPTR, (cch + 1) * sizeof(WCHAR));
  312. if(NULL == pwszHostName)
  313. {
  314. dwErr = GetLastError();
  315. goto done;
  316. }
  317. cch = MultiByteToWideChar(
  318. CP_UTF8,
  319. 0,
  320. pszHostName,
  321. -1,
  322. pwszHostName,
  323. cch);
  324. if (0 == cch)
  325. {
  326. dwErr = GetLastError();
  327. goto done;
  328. }
  329. }
  330. else
  331. {
  332. dwErr = E_INVALIDARG;
  333. goto done;
  334. }
  335. if(NULL == (pQuery = LocalAlloc(LPTR, QUERYBUFSIZE)))
  336. {
  337. dwErr = GetLastError();
  338. goto done;
  339. }
  340. if(NULL == (pdwAddresses = LocalAlloc(LPTR, 5 * sizeof(DWORD))))
  341. {
  342. dwErr = GetLastError();
  343. goto done;
  344. }
  345. /*
  346. pdwAddresses[0] = 0x80461111;
  347. pdwAddresses[1] = 0x80461111;
  348. pdwAddresses[2] = 0x12345668;
  349. pdwAddresses[3] = 0x12345668;
  350. pdwAddresses[4] = 0x12345668;
  351. cAddresses = 5;
  352. */
  353. pQuery->lpszServiceInstanceName = pwszHostName;
  354. pQuery->dwSize = QUERYBUFSIZE;
  355. pQuery->dwNameSpace = NS_ALL;
  356. pQuery->lpServiceClassId = (GUID *) &ServiceGuid;
  357. pQuery->dwNumberOfProtocols = 2;
  358. pQuery->lpafpProtocols = (AFPROTOCOLS *) afProtocols;
  359. if((dwErr = WSALookupServiceBeginW(
  360. pQuery,
  361. LUP_RETURN_ADDR,
  362. &hRnr)) == SOCKET_ERROR)
  363. {
  364. dwErr = WSAGetLastError();
  365. goto done;
  366. }
  367. while(NO_ERROR == dwErr)
  368. {
  369. if(NO_ERROR == (dwErr = WSALookupServiceNextW(
  370. hRnr,
  371. 0,
  372. &dwQuerySize,
  373. pQuery)))
  374. {
  375. DWORD iAddress;
  376. for(iAddress = 0;
  377. iAddress < pQuery->dwNumberOfCsAddrs;
  378. iAddress++)
  379. {
  380. dwAddress =
  381. * ((DWORD*)
  382. &pQuery->lpcsaBuffer[iAddress].RemoteAddr.lpSockaddr->sa_data[2]);
  383. //
  384. // If we have run out of space to return, realloc the
  385. // buffer
  386. //
  387. if(cAddresses == MaxAddresses)
  388. {
  389. BYTE *pTemp;
  390. pTemp = LocalAlloc(LPTR, (MaxAddresses + 5) * sizeof(DWORD));
  391. if(NULL == pTemp)
  392. {
  393. dwErr = GetLastError();
  394. if(pdwAddresses != NULL)
  395. {
  396. LocalFree(pdwAddresses);
  397. pdwAddresses = NULL;
  398. }
  399. goto done;
  400. }
  401. CopyMemory(pTemp,
  402. (PBYTE) pdwAddresses,
  403. cAddresses * sizeof(DWORD));
  404. LocalFree(pdwAddresses);
  405. pdwAddresses = (DWORD *) pTemp;
  406. MaxAddresses += 5;
  407. }
  408. pdwAddresses[cAddresses] = dwAddress;
  409. cAddresses += 1;
  410. }
  411. }
  412. else if (SOCKET_ERROR == dwErr)
  413. {
  414. dwErr = WSAGetLastError();
  415. if(WSAEFAULT == dwErr)
  416. {
  417. //
  418. // Allocate a bigger buffer and continue
  419. //
  420. LocalFree(pQuery);
  421. if(NULL == (pQuery = LocalAlloc(LPTR, dwQuerySize)))
  422. {
  423. dwErr = GetLastError();
  424. break;
  425. }
  426. dwErr = NO_ERROR;
  427. }
  428. }
  429. }
  430. WSALookupServiceEnd(hRnr);
  431. #if 0
  432. RasmanOutputDebug("RASMAN: RasGetHostByName: number of addresses=%d\n",
  433. cAddresses);
  434. {
  435. DWORD i;
  436. RasmanOutputDebug("RASMAN: addresses:");
  437. for(i=0; i < cAddresses; i++)
  438. {
  439. RasmanOutputDebug("%x ", pdwAddresses[i]);
  440. }
  441. RasmanOutputDebug("\n");
  442. }
  443. #endif
  444. done:
  445. *ppdwAddress = pdwAddresses;
  446. *pcAddresses = cAddresses;
  447. if(WSA_E_NO_MORE == dwErr)
  448. {
  449. dwErr = NO_ERROR;
  450. }
  451. if(NO_ERROR != dwErr)
  452. {
  453. //
  454. // Map it to an error that says the destination
  455. // is not reachable.
  456. //
  457. dwErr = ERROR_BAD_ADDRESS_SPECIFIED;
  458. }
  459. if(NULL != pwszHostName)
  460. {
  461. LocalFree(pwszHostName);
  462. }
  463. if(NULL != pQuery)
  464. {
  465. LocalFree(pQuery);
  466. }
  467. return dwErr;
  468. }
  469. #define RASMAN_OUTPUT_DEBUG_STATEMENTS 0
  470. VOID
  471. RasmanOutputDebug(
  472. CHAR * Format,
  473. ...)
  474. {
  475. #if DBG
  476. #if RASMAN_OUTPUT_DEBUG_STATEMENTS
  477. CHAR pszTrace[4096];
  478. va_list arglist;
  479. *pszTrace = '\0';
  480. va_start(arglist, Format);
  481. vsprintf(pszTrace, Format, arglist);
  482. va_end(arglist);
  483. DbgPrint(pszTrace);
  484. #endif
  485. #endif
  486. }