Windows NT 4.0 source code leak
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.

494 lines
10 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. common.c
  5. Abstract:
  6. Revision History:
  7. Mazhar Mohammed Consolidated winsock transports
  8. Comments:
  9. This file contains common code for RPC transport dlls using Winsock.
  10. --*/
  11. #include "sysinc.h"
  12. #include <winsock.h>
  13. #include <stdlib.h>
  14. #include "rpc.h"
  15. #include "rpcdcep.h"
  16. #include "rpctran.h"
  17. #include "rpcerrp.h"
  18. #include "common.h"
  19. #include "reg.h"
  20. #define ADDRESS_FAMILY AF_NS
  21. #define ENDPOINT_LEN 5
  22. /* for registry lookup */
  23. PROTOCOL_MAP ProtoToLana[MAX_LANA] = { 0};
  24. /* number of Network cards */
  25. int NumCards;
  26. unsigned char chtob( unsigned char c1, unsigned char c2 )
  27. /* Convert two hex digits (stored as ascii) into one byte. */
  28. {
  29. unsigned char out;
  30. if (c1 >= '0' && c1 <= '9')
  31. out = (c1 - '0') << 4;
  32. else
  33. {
  34. if (c1 >= 'a' && c1 <= 'f')
  35. out = (c1 - 'a' + 10) << 4;
  36. else if (c1 >= 'A' && c1 <= 'F')
  37. out = (c1 - 'A' + 10) << 4;
  38. else
  39. out = 0;
  40. }
  41. if (c2 >= '0' && c2 <= '9')
  42. out |= c2 -'0';
  43. else
  44. {
  45. if (c2 >= 'a' && c2 <= 'f')
  46. out |= c2 - 'a' + 10;
  47. else if (c2 >= 'A' && c2 <= 'F')
  48. out |= c2 - 'A' + 10;
  49. else
  50. out = 0;
  51. }
  52. return out;
  53. }
  54. int tcp_get_host_by_name(
  55. SOCKET socket,
  56. void *netaddr,
  57. char *host)
  58. {
  59. UNALIGNED struct sockaddr_in *server = netaddr;
  60. UNALIGNED struct hostent *phostentry;
  61. unsigned long host_addr;
  62. if (*host == '\0')
  63. {
  64. // An empty hostname means to RPC to the local machine
  65. host_addr = LOOPBACK;
  66. }
  67. else
  68. {
  69. // Assume a numeric address
  70. host_addr = inet_addr(host);
  71. if (host_addr == -1)
  72. {
  73. // Try a friendly name
  74. phostentry = gethostbyname(host);
  75. if (phostentry == (struct hostent *)NULL)
  76. {
  77. return (RPC_S_SERVER_UNAVAILABLE);
  78. }
  79. else
  80. {
  81. host_addr = *(unsigned long *)phostentry->h_addr;
  82. }
  83. }
  84. }
  85. memcpy((char *) &server->sin_addr,
  86. (unsigned char *) &host_addr,
  87. sizeof(unsigned long));
  88. return 0;
  89. }
  90. RPC_STATUS
  91. MapStatusCode(
  92. int SocketError,
  93. RPC_STATUS Default
  94. )
  95. /*++
  96. Routine Description:
  97. Maps a winsock return value into a RPC_STATUS. Right now, any winsock
  98. error is an internal error.
  99. Arguments:
  100. ErrorCode - Input error code.
  101. Return Value:
  102. mapped status code
  103. --*/
  104. {
  105. RPC_STATUS Status;
  106. switch (SocketError)
  107. {
  108. case 0:
  109. {
  110. Status = RPC_S_OK;
  111. break;
  112. }
  113. case WSAETIMEDOUT:
  114. {
  115. Status = RPC_P_TIMEOUT;
  116. break;
  117. }
  118. case WSAENOBUFS:
  119. {
  120. Status = RPC_S_OUT_OF_MEMORY;
  121. break;
  122. }
  123. case WSAEMSGSIZE:
  124. {
  125. Status = RPC_P_OVERSIZE_PACKET;
  126. break;
  127. }
  128. default:
  129. {
  130. #ifdef DEBUGRPC
  131. PrintToDebugger("RPC DG: Winsock error %d\n", SocketError);
  132. #endif
  133. Status = Default;
  134. }
  135. }
  136. return Status;
  137. }
  138. // we need to have a common transport load module (no protocol specific ifdefs in here)
  139. BOOL SpxCacheInitialized = FALSE;
  140. RPC_CLIENT_TRANSPORT_INFO PAPI * RPC_ENTRY TransportLoad (
  141. IN RPC_CHAR PAPI * RpcProtocolSequence
  142. )
  143. // Loadable transport initialization function
  144. {
  145. WSADATA WsaData;
  146. SOCKET Socket;
  147. static int initialized = 0 ;
  148. int Status ;
  149. UNUSED (RpcProtocolSequence);
  150. if(!initialized)
  151. {
  152. RpcTryExcept
  153. {
  154. Status = WSAStartup( 0x0101, &WsaData ) ;
  155. }
  156. RpcExcept( EXCEPTION_EXECUTE_HANDLER )
  157. {
  158. Status = ERROR_OUTOFMEMORY ;
  159. }
  160. RpcEndExcept
  161. if ( Status != NO_ERROR )
  162. {
  163. return NULL;
  164. }
  165. #ifdef NTENV
  166. InitialNtRegistry();
  167. #endif
  168. initialized = 1 ;
  169. }
  170. // check if the string is in UNICODE
  171. if (RpcpStringCompare(RpcProtocolSequence, RPC_CONST_STRING("ncacn_spx")) == 0)
  172. {
  173. //For SPX we do this to avoid a bizzare deadlock
  174. Socket = socket(ADDRESS_FAMILY, SOCK_STREAM, NSPROTO_SPXII);
  175. if (Socket == INVALID_SOCKET)
  176. {
  177. return (NULL);
  178. }
  179. closesocket(Socket);
  180. if (FALSE == SpxCacheInitialized)
  181. {
  182. RPC_STATUS Status = InitializeSpxCache();
  183. if (Status)
  184. {
  185. return 0;
  186. }
  187. SpxCacheInitialized = TRUE;
  188. }
  189. return (&SPX_TransInfo) ;
  190. }
  191. if (RpcpStringCompare(RpcProtocolSequence, RPC_CONST_STRING("ncacn_ip_tcp")) == 0)
  192. {
  193. return (&TCP_TransInfo) ;
  194. }
  195. #ifdef NTENV
  196. if (RpcpStringCompare(RpcProtocolSequence, RPC_CONST_STRING("ncacn_at_dsp")) == 0)
  197. {
  198. return(&ADSP_TransInfo) ;
  199. }
  200. #endif
  201. #if 0
  202. if (RpcpStringCompare(RpcProtocolSequence, RPC_CONST_STRING("ncacn_np")) == 0)
  203. {
  204. return (&NP_TransInfo) ;
  205. }
  206. #endif
  207. #if defined(NTENV) || defined(WIN96)
  208. if (RpcpStringCompare(RpcProtocolSequence, RPC_CONST_STRING("ncadg_ipx")) == 0)
  209. {
  210. return IpxTransportLoad();
  211. }
  212. if (RpcpStringCompare(RpcProtocolSequence, RPC_CONST_STRING("ncadg_ip_udp")) == 0)
  213. {
  214. return UdpTransportLoad();
  215. }
  216. #ifndef WIN96
  217. if (RpcpStringNCompare(RpcProtocolSequence, RPC_CONST_STRING("ncacn_nb"), 8) == 0)
  218. {
  219. return ((RPC_CLIENT_TRANSPORT_INFO PAPI *) &NB_TransInfo) ;
  220. }
  221. #endif // !WIN96
  222. #endif // NTENV || WIN96
  223. ASSERT(0) ;
  224. return NULL ;
  225. }
  226. void
  227. unicode_to_ascii ( RPC_CHAR * in, unsigned char * out )
  228. {
  229. unsigned char *ascii_ptr;
  230. RPC_CHAR *unicode_ptr;
  231. ascii_ptr = out;
  232. unicode_ptr = in;
  233. *ascii_ptr = (unsigned char) *unicode_ptr ;
  234. while (1)
  235. {
  236. if (*ascii_ptr == 0) return;
  237. ascii_ptr++;
  238. unicode_ptr++;
  239. *ascii_ptr = (unsigned char) *unicode_ptr;
  240. }
  241. }
  242. void
  243. InitialNtRegistry(
  244. )
  245. /*++
  246. Routine Description:
  247. This information is automatically generated by NT setup and the Networks
  248. Control Panel applet. Because it can change dynamically, we load it
  249. all at once to achieve consistent data.
  250. Arguments:
  251. None
  252. ReturnValue:
  253. None
  254. --*/
  255. {
  256. HKEY RegHandle;
  257. LONG status;
  258. int i;
  259. char protseq[64];
  260. DWORD protseq_len;
  261. DWORD lana;
  262. DWORD lana_len;
  263. DWORD data_type;
  264. char * LanaString ;
  265. int LanaNum;
  266. // Return immediately if the table is already initialized.
  267. if (ProtocolTable[0].ProtoSeq)
  268. {
  269. return;
  270. }
  271. NumCards = 0;
  272. // Open the registry key for RPC NetBIOS information
  273. status = RegOpenKeyExA(RPC_REG_ROOT,
  274. REG_NETBIOS,
  275. 0,
  276. KEY_READ,
  277. &RegHandle);
  278. ASSERT(!status);
  279. if (status)
  280. {
  281. return;
  282. }
  283. for (i = 0; !status && i < MAX_LANA; i++)
  284. {
  285. protseq_len = sizeof(protseq);
  286. lana_len = sizeof(lana);
  287. status = RegEnumValueA(RegHandle,
  288. i,
  289. protseq,
  290. &protseq_len,
  291. NULL,
  292. &data_type,
  293. (LPBYTE) &lana,
  294. &lana_len);
  295. if (!status && data_type == REG_DWORD && lana <= MAX_LANA)
  296. {
  297. ProtocolTable[i].ProtoSeq = I_RpcAllocate(protseq_len + 1);
  298. ASSERT(ProtocolTable[i].ProtoSeq);
  299. if (! ProtocolTable[i].ProtoSeq)
  300. {
  301. status = RPC_S_OUT_OF_RESOURCES;
  302. }
  303. else
  304. {
  305. strcpy(ProtocolTable[i].ProtoSeq, protseq);
  306. ProtocolTable[i].Lana = (unsigned char) lana;
  307. LanaString = protseq + strlen(protseq) -1;
  308. LanaNum = atoi(LanaString);
  309. #ifdef TONY
  310. PrintToDebugger("RPCLTSCM: the current lana examinging is %d \n"
  311. , LanaNum);
  312. #endif
  313. /* find out how many cards we have */
  314. if(NumCards < LanaNum)
  315. {
  316. NumCards = LanaNum;
  317. }
  318. }
  319. }
  320. else
  321. {
  322. ASSERT(status == ERROR_NO_MORE_ITEMS);
  323. }
  324. }
  325. RegCloseKey(RegHandle);
  326. return;
  327. }
  328. RPC_STATUS
  329. MapProtocol(
  330. IN RPC_CHAR *ProtoSeq,
  331. IN int DriverNumber,
  332. OUT PPROTOCOL_MAP *ProtocolEntry
  333. )
  334. /*++
  335. Routine Description:
  336. This function maps a protocol string into a protocol map entry.
  337. Arguments:
  338. ProtoSeq - the protocol sequence that we want to map
  339. DriverNumber - the logical driver number for the protocol.
  340. ProtocolEntry - pointer to place to return the results.
  341. Return Value:
  342. RPC_S_OK, RPC_S_OUT_OF_RESOURCES, RPC_S_INVALID_ENDPOINT_FORMAT
  343. The output pointer is set to the corresponding entry when found.
  344. --*/
  345. {
  346. long status;
  347. char Protocol[40];
  348. char LanaString[10];
  349. long BufferLength = sizeof(LanaString);
  350. int i;
  351. // Copy the possible unicode protocol string to ascii.
  352. for (i = 0; (Protocol[i] = (char) ProtoSeq[i]) && i < sizeof(Protocol);
  353. i++) ;
  354. // Add the logical driver number to the protocol string. This
  355. // allows multiple drivers (net cards) to be attached to the same
  356. // logical protocol.
  357. Protocol[i] = (char) ('0' + DriverNumber);
  358. Protocol[i+1] = 0;
  359. // First look in the proto sequences that we have already mapped.
  360. for (i = 0; ProtocolTable[i].ProtoSeq && i < MAX_LANA; i++)
  361. {
  362. // If found, set the output pointer.
  363. if (strcmp(ProtocolTable[i].ProtoSeq, Protocol) == 0)
  364. {
  365. *ProtocolEntry = &ProtocolTable[i];
  366. return(RPC_S_OK);
  367. }
  368. }
  369. return(RPC_S_PROTSEQ_NOT_FOUND);
  370. }