Leaked source code of windows server 2003
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.

535 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. /*++
  47. Routine Description
  48. Gets a free request buffer from the pool of buffers.
  49. If there are no buffers available it blocks for one.
  50. This is acceptable since the Requestor thread will be
  51. releasing buffers fairly quickly - also, if this thread
  52. does not block here it will be blocking for the Requestor
  53. thread to complete the request anyway. Note: Before returning
  54. it also ensures that this process has a handle to the
  55. event used to signal completion of request.
  56. Arguments
  57. Returns Value
  58. Nothing
  59. --*/
  60. RequestBuffer*
  61. GetRequestBuffer ()
  62. {
  63. DWORD dwError;
  64. RequestBuffer *pRequestBuffer = NULL;
  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. goto done;
  77. }
  78. }
  79. pRequestBuffer = LocalAlloc(LPTR,
  80. sizeof(RequestBuffer)
  81. + REQUEST_BUFFER_SIZE);
  82. done:
  83. return pRequestBuffer;
  84. }
  85. /*++
  86. Routine Description
  87. Frees the request buffer, and, closes the wait event
  88. handle which was duplicated for the calling process
  89. in the GetRequestBuffer() API.
  90. Arguments
  91. Return Value
  92. Nothing
  93. --*/
  94. VOID
  95. FreeRequestBuffer (RequestBuffer *buffer)
  96. {
  97. LocalFree(buffer);
  98. return;
  99. }
  100. /*++
  101. Routine Description
  102. No queue really - just signals the other process
  103. to service request.
  104. Arguments
  105. Return Value
  106. Nothing
  107. --*/
  108. DWORD
  109. PutRequestInQueue (HANDLE hConnection,
  110. RequestBuffer *preqbuff,
  111. DWORD dwSizeOfBuffer)
  112. {
  113. DWORD dwErr = ERROR_SUCCESS;
  114. if (g_fnServiceRequest)
  115. {
  116. g_fnServiceRequest(preqbuff, dwSizeOfBuffer);
  117. }
  118. else
  119. {
  120. dwErr = RemoteSubmitRequest (hConnection,
  121. (PBYTE) preqbuff,
  122. dwSizeOfBuffer);
  123. }
  124. return dwErr;
  125. }
  126. /*++
  127. Routine Description
  128. Copies params from one struct to another.
  129. Arguments
  130. Return Value
  131. Nothing.
  132. --*/
  133. VOID
  134. CopyParams (RAS_PARAMS *src, RAS_PARAMS *dest, DWORD numofparams)
  135. {
  136. WORD i ;
  137. PBYTE temp ;
  138. //
  139. // first copy all the params into dest
  140. //
  141. memcpy (dest,
  142. src,
  143. numofparams*sizeof(RAS_PARAMS)) ;
  144. //
  145. // copy the strings:
  146. //
  147. temp = (PBYTE)dest + numofparams * sizeof(RAS_PARAMS) ;
  148. for (i = 0; i < numofparams; i++)
  149. {
  150. if (src[i].P_Type == String)
  151. {
  152. dest[i].P_Value.String.Length =
  153. src[i].P_Value.String.Length ;
  154. dest[i].P_Value.String.Data = temp ;
  155. memcpy (temp,
  156. src[i].P_Value.String.Data,
  157. src[i].P_Value.String.Length) ;
  158. temp += src[i].P_Value.String.Length ;
  159. }
  160. else
  161. {
  162. dest[i].P_Value.Number = src[i].P_Value.Number ;
  163. }
  164. }
  165. }
  166. VOID
  167. ConvParamPointerToOffset (RAS_PARAMS *params, DWORD numofparams)
  168. {
  169. WORD i ;
  170. for (i = 0; i < numofparams; i++)
  171. {
  172. if (params[i].P_Type == String)
  173. {
  174. params[i].P_Value.String_OffSet.dwOffset =
  175. (DWORD) (params[i].P_Value.String.Data - (PCHAR) params) ;
  176. }
  177. }
  178. }
  179. VOID
  180. ConvParamOffsetToPointer (RAS_PARAMS *params, DWORD numofparams)
  181. {
  182. WORD i ;
  183. for (i = 0; i < numofparams; i++)
  184. {
  185. if (params[i].P_Type == String)
  186. {
  187. params[i].P_Value.String.Data =
  188. params[i].P_Value.String_OffSet.dwOffset
  189. + (PCHAR) params ;
  190. }
  191. }
  192. }
  193. /*++
  194. Routine Description
  195. Closes the handles for different objects opened by RASMAN process.
  196. Arguments
  197. Return Value
  198. --*/
  199. VOID
  200. FreeNotifierHandle (HANDLE handle)
  201. {
  202. if ((handle != NULL) && (handle != INVALID_HANDLE_VALUE))
  203. {
  204. if (!CloseHandle (handle))
  205. {
  206. GetLastError () ;
  207. }
  208. }
  209. }
  210. DWORD
  211. DwRasGetHostByName(CHAR *pszHostName,
  212. DWORD **ppdwAddress,
  213. DWORD *pcAddresses)
  214. {
  215. WCHAR *pwszHostName = NULL;
  216. DWORD dwErr = SUCCESS;
  217. HANDLE hRnr;
  218. PWSAQUERYSETW pQuery = NULL;
  219. const static GUID ServiceGuid = SVCID_INET_HOSTADDRBYNAME;
  220. DWORD dwQuerySize = QUERYBUFSIZE;
  221. DWORD dwAddress = 0;
  222. const static AFPROTOCOLS afProtocols[2] =
  223. {
  224. {AF_INET, IPPROTO_UDP},
  225. {AF_INET, IPPROTO_TCP}
  226. };
  227. DWORD cAddresses = 0;
  228. DWORD *pdwAddresses = NULL;
  229. DWORD MaxAddresses = 5;
  230. ASSERT(NULL != ppdwAddress);
  231. ASSERT(NULL != pcAddresses);
  232. if (NULL != pszHostName)
  233. {
  234. DWORD cch;
  235. cch = MultiByteToWideChar(
  236. CP_UTF8,
  237. 0,
  238. pszHostName,
  239. -1,
  240. NULL,
  241. 0);
  242. if(0 == cch)
  243. {
  244. dwErr = GetLastError();
  245. goto done;
  246. }
  247. pwszHostName = LocalAlloc(LPTR, (cch + 1) * sizeof(WCHAR));
  248. if(NULL == pwszHostName)
  249. {
  250. dwErr = GetLastError();
  251. goto done;
  252. }
  253. cch = MultiByteToWideChar(
  254. CP_UTF8,
  255. 0,
  256. pszHostName,
  257. -1,
  258. pwszHostName,
  259. cch);
  260. if (0 == cch)
  261. {
  262. dwErr = GetLastError();
  263. goto done;
  264. }
  265. }
  266. else
  267. {
  268. dwErr = E_INVALIDARG;
  269. goto done;
  270. }
  271. if(NULL == (pQuery = LocalAlloc(LPTR, QUERYBUFSIZE)))
  272. {
  273. dwErr = GetLastError();
  274. goto done;
  275. }
  276. if(NULL == (pdwAddresses = LocalAlloc(LPTR, 5 * sizeof(DWORD))))
  277. {
  278. dwErr = GetLastError();
  279. goto done;
  280. }
  281. /*
  282. pdwAddresses[0] = 0x80461111;
  283. pdwAddresses[1] = 0x80461111;
  284. pdwAddresses[2] = 0x12345668;
  285. pdwAddresses[3] = 0x12345668;
  286. pdwAddresses[4] = 0x12345668;
  287. cAddresses = 5;
  288. */
  289. pQuery->lpszServiceInstanceName = pwszHostName;
  290. pQuery->dwSize = QUERYBUFSIZE;
  291. pQuery->dwNameSpace = NS_ALL;
  292. pQuery->lpServiceClassId = (GUID *) &ServiceGuid;
  293. pQuery->dwNumberOfProtocols = 2;
  294. pQuery->lpafpProtocols = (AFPROTOCOLS *) afProtocols;
  295. if((dwErr = WSALookupServiceBeginW(
  296. pQuery,
  297. LUP_RETURN_ADDR,
  298. &hRnr)) == SOCKET_ERROR)
  299. {
  300. dwErr = WSAGetLastError();
  301. goto done;
  302. }
  303. while(NO_ERROR == dwErr)
  304. {
  305. if(NO_ERROR == (dwErr = WSALookupServiceNextW(
  306. hRnr,
  307. 0,
  308. &dwQuerySize,
  309. pQuery)))
  310. {
  311. DWORD iAddress;
  312. for(iAddress = 0;
  313. iAddress < pQuery->dwNumberOfCsAddrs;
  314. iAddress++)
  315. {
  316. dwAddress =
  317. * ((DWORD*)
  318. &pQuery->lpcsaBuffer[iAddress].RemoteAddr.lpSockaddr->sa_data[2]);
  319. //
  320. // If we have run out of space to return, realloc the
  321. // buffer
  322. //
  323. if(cAddresses == MaxAddresses)
  324. {
  325. BYTE *pTemp;
  326. pTemp = LocalAlloc(LPTR, (MaxAddresses + 5) * sizeof(DWORD));
  327. if(NULL == pTemp)
  328. {
  329. dwErr = GetLastError();
  330. if(pdwAddresses != NULL)
  331. {
  332. LocalFree(pdwAddresses);
  333. pdwAddresses = NULL;
  334. }
  335. goto done;
  336. }
  337. CopyMemory(pTemp,
  338. (PBYTE) pdwAddresses,
  339. cAddresses * sizeof(DWORD));
  340. LocalFree(pdwAddresses);
  341. pdwAddresses = (DWORD *) pTemp;
  342. MaxAddresses += 5;
  343. }
  344. pdwAddresses[cAddresses] = dwAddress;
  345. cAddresses += 1;
  346. }
  347. }
  348. else if (SOCKET_ERROR == dwErr)
  349. {
  350. dwErr = WSAGetLastError();
  351. if(WSAEFAULT == dwErr)
  352. {
  353. //
  354. // Allocate a bigger buffer and continue
  355. //
  356. LocalFree(pQuery);
  357. if(NULL == (pQuery = LocalAlloc(LPTR, dwQuerySize)))
  358. {
  359. dwErr = GetLastError();
  360. break;
  361. }
  362. dwErr = NO_ERROR;
  363. }
  364. }
  365. }
  366. WSALookupServiceEnd(hRnr);
  367. #if 0
  368. RasmanOutputDebug("RASMAN: RasGetHostByName: number of addresses=%d\n",
  369. cAddresses);
  370. {
  371. DWORD i;
  372. RasmanOutputDebug("RASMAN: addresses:");
  373. for(i=0; i < cAddresses; i++)
  374. {
  375. RasmanOutputDebug("%x ", pdwAddresses[i]);
  376. }
  377. RasmanOutputDebug("\n");
  378. }
  379. #endif
  380. done:
  381. *ppdwAddress = pdwAddresses;
  382. *pcAddresses = cAddresses;
  383. if(WSA_E_NO_MORE == dwErr)
  384. {
  385. dwErr = NO_ERROR;
  386. }
  387. if(NO_ERROR != dwErr)
  388. {
  389. //
  390. // Map it to an error that says the destination
  391. // is not reachable.
  392. //
  393. dwErr = ERROR_BAD_ADDRESS_SPECIFIED;
  394. }
  395. if(NULL != pwszHostName)
  396. {
  397. LocalFree(pwszHostName);
  398. }
  399. if(NULL != pQuery)
  400. {
  401. LocalFree(pQuery);
  402. }
  403. return dwErr;
  404. }
  405. #define RASMAN_OUTPUT_DEBUG_STATEMENTS 0
  406. VOID
  407. RasmanOutputDebug(
  408. CHAR * Format,
  409. ...)
  410. {
  411. #if DBG
  412. #if RASMAN_OUTPUT_DEBUG_STATEMENTS
  413. CHAR pszTrace[4096];
  414. va_list arglist;
  415. *pszTrace = '\0';
  416. va_start(arglist, Format);
  417. vsprintf(pszTrace, Format, arglist);
  418. va_end(arglist);
  419. DbgPrint(pszTrace);
  420. #endif
  421. #endif
  422. }