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.

455 lines
11 KiB

  1. /****************************************************************************
  2. **
  3. ** Address String Compression routines
  4. **
  5. *****************************************************************************
  6. **
  7. ** The following is a group of routines designed to compress and expand
  8. ** IPV4 addresses into the absolute minimum size possible. This is to
  9. ** provide a compressed ASCII string that can be parsed using standard
  10. ** shell routines for command line parsing.
  11. ** The compressed string has the following restrictions:
  12. ** -> Must not expand to more characters if UTF8 encoded.
  13. ** -> Must not contain the NULL character so that string libs work.
  14. ** -> Cannot contain double quote character, the shell needs that.
  15. ** -> Does not have to be human readable.
  16. **
  17. ** Data Types:
  18. ** There are three data types used here:
  19. ** szAddr The orginal IPV4 string address ("X.X.X.X:port")
  20. ** blobAddr Six byte struct with 4 bytes of address, and 2 bytes of port
  21. ** szComp Eight byte ascii string of compressed IPV4 address
  22. **
  23. ****************************************************************************/
  24. #define INIT_GUID
  25. #include <windows.h>
  26. #include <objbase.h>
  27. #include <initguid.h>
  28. //#include <winsock2.h>
  29. #include <MMSystem.h>
  30. //#include <WSIPX.h>
  31. //#include <Iphlpapi.h>
  32. #include <stdlib.h>
  33. #include <malloc.h>
  34. //#include "ICSutils.h"
  35. //#include "rsip.h"
  36. //#include "icshelpapi.h"
  37. //#include "dpnathlp.h"
  38. #include <io.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <fcntl.h>
  42. #include <sys/types.h>
  43. #include <sys/stat.h>
  44. #include "utils.h"
  45. #define COMP_OFFSET '#'
  46. #define COMP_SEPERATOR '!'
  47. #pragma pack(push,1)
  48. typedef struct _BLOB_ADDR {
  49. UCHAR addr_d; // highest order address byte
  50. UCHAR addr_c;
  51. UCHAR addr_b;
  52. UCHAR addr_a; // lowest order byte (last in IP string address)
  53. WORD port;
  54. } BLOB_ADDR, *PBLOB_ADDR;
  55. #pragma pack(pop)
  56. WCHAR b64Char[64]={
  57. 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  58. 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  59. '0','1','2','3','4','5','6','7','8','9','+','/'
  60. };
  61. #define IMPORTANT_MSG DEBUG_MSG
  62. #ifndef _T
  63. #define _T TEXT
  64. #endif
  65. /****************************************************************************
  66. ** char * atob(char *szVal, UCHAR *result)
  67. ****************************************************************************/
  68. WCHAR *atob(WCHAR *szVal, UCHAR *result)
  69. {
  70. WCHAR *lptr;
  71. WCHAR ucb;
  72. UCHAR foo;
  73. if (!result || !szVal)
  74. {
  75. IMPORTANT_MSG(_T("ERROR: NULL ptr passed in atob"));
  76. return NULL;
  77. }
  78. // start ptr at the beginning of string
  79. lptr = szVal;
  80. foo = 0;
  81. ucb = *lptr++ - '0';
  82. while (ucb >= 0 && ucb <= 9)
  83. {
  84. foo *= 10;
  85. foo += ucb;
  86. ucb = (*lptr++)-'0';
  87. }
  88. *result = (UCHAR)foo;
  89. return lptr;
  90. }
  91. /****************************************************************************
  92. **
  93. ** CompressAddr(pszAddr, pblobAddr);
  94. ** Takes an ascii IP address (X.X.X.X:port) and converts it to a
  95. ** 6 byte binary blob.
  96. **
  97. ** returns TRUE for success, FALSE for failure.
  98. **
  99. ****************************************************************************/
  100. BOOL CompressAddr(WCHAR *pszAddr, PBLOB_ADDR pblobAddr)
  101. {
  102. BLOB_ADDR lblob;
  103. WCHAR *lpsz;
  104. if (!pszAddr || !pblobAddr)
  105. {
  106. IMPORTANT_MSG(_T("ERROR: NULL ptr passed in CompressAddr"));
  107. return FALSE;
  108. }
  109. lpsz = pszAddr;
  110. lpsz = atob(lpsz, &lblob.addr_d);
  111. if (*(lpsz-1) != '.')
  112. {
  113. IMPORTANT_MSG(_T("ERROR: bad address[0] passed in CompressAddr"));
  114. return FALSE;
  115. }
  116. lpsz = atob(lpsz, &lblob.addr_c);
  117. if (*(lpsz-1) != '.')
  118. {
  119. IMPORTANT_MSG(_T("ERROR: bad address[1] passed in CompressAddr"));
  120. return FALSE;
  121. }
  122. lpsz = atob(lpsz, &lblob.addr_b);
  123. if (*(lpsz-1) != '.')
  124. {
  125. IMPORTANT_MSG(_T("ERROR: bad address[2] passed in CompressAddr"));
  126. return FALSE;
  127. }
  128. lpsz = atob(lpsz, &lblob.addr_a);
  129. // is there a port number here?
  130. if (*(lpsz-1) == ':')
  131. lblob.port = (WORD)_wtoi(lpsz);
  132. else
  133. lblob.port = 0;
  134. // copy back the result
  135. memcpy(pblobAddr, &lblob, sizeof(*pblobAddr));
  136. return TRUE;
  137. }
  138. /****************************************************************************
  139. **
  140. ** ExpandAddr(pszAddr, pblobAddr);
  141. ** Takes 6 byte binary blob and converts it into an ascii IP
  142. ** address (X.X.X.X:port)
  143. **
  144. ** returns TRUE for success, FALSE for failure.
  145. **
  146. ****************************************************************************/
  147. BOOL ExpandAddr(WCHAR *pszAddr, PBLOB_ADDR pba)
  148. {
  149. if (!pszAddr || !pba)
  150. {
  151. IMPORTANT_MSG(_T("ERROR: NULL ptr passed in ExpandAddr"));
  152. return FALSE;
  153. }
  154. wsprintf(pszAddr, L"%d.%d.%d.%d", pba->addr_d, pba->addr_c,
  155. pba->addr_b, pba->addr_a);
  156. if (pba->port)
  157. {
  158. WCHAR scratch[8];
  159. wsprintf(scratch, L":%d", pba->port);
  160. wcscat(pszAddr, scratch);
  161. }
  162. return TRUE;
  163. }
  164. /****************************************************************************
  165. **
  166. ** AsciifyAddr(pszAddr, pblobAddr);
  167. ** Takes 6 byte binary blob and converts it into compressed ascii
  168. ** will return either 6 or 8 bytes of string
  169. **
  170. ** returns TRUE for success, FALSE for failure.
  171. **
  172. ****************************************************************************/
  173. BOOL AsciifyAddr(WCHAR *pszAddr, PBLOB_ADDR pba)
  174. {
  175. UCHAR tmp;
  176. DWORDLONG dwl;
  177. int i, iCnt;
  178. if (!pszAddr || !pba)
  179. {
  180. IMPORTANT_MSG(_T("ERROR: NULL ptr passed in AsciifyAddr"));
  181. return FALSE;
  182. }
  183. iCnt = 6;
  184. if (pba->port)
  185. iCnt = 8;
  186. dwl = 0;
  187. memcpy(&dwl, pba, sizeof(*pba));
  188. for (i = 0; i < iCnt; i++)
  189. {
  190. // get 6 bits of data
  191. tmp = (UCHAR)(dwl & 0x3f);
  192. // add the offset to asciify this
  193. // offset must be bigger the double-quote char.
  194. pszAddr[i] = b64Char[tmp]; // (WCHAR)(tmp + COMP_OFFSET);
  195. // Shift right 6 bits
  196. dwl = Int64ShrlMod32(dwl, 6);
  197. }
  198. // terminating NULL
  199. pszAddr[iCnt] = 0;
  200. return TRUE;
  201. }
  202. /****************************************************************************
  203. **
  204. ** DeAsciifyAddr(pszAddr, pblobAddr);
  205. ** Takes a compressed ascii string and converts it into a
  206. ** 6 or 8 byte binary blob
  207. **
  208. ** returns TRUE for success, FALSE for failure.
  209. **
  210. ****************************************************************************/
  211. BOOL DeAsciifyAddr(WCHAR *pszAddr, PBLOB_ADDR pba)
  212. {
  213. UCHAR tmp;
  214. WCHAR wtmp;
  215. DWORDLONG dwl;
  216. int i;
  217. int iCnt;
  218. if (!pszAddr || !pba)
  219. {
  220. IMPORTANT_MSG(_T("ERROR: NULL ptr passed in DeAsciifyAddr"));
  221. return FALSE;
  222. }
  223. /* how long is this string?
  224. * if it is 6 bytes, then there is no port
  225. * else it should be 8 bytes
  226. */
  227. i = wcslen(pszAddr);
  228. if (i == 6 || i == 8)
  229. iCnt = i;
  230. else
  231. {
  232. iCnt = 8;
  233. IMPORTANT_MSG(_T("Strlen is wrong in DeAsciifyAddr"));
  234. }
  235. dwl = 0;
  236. for (i = iCnt-1; i >= 0; i--)
  237. {
  238. wtmp = pszAddr[i];
  239. if (wtmp >= L'A' && wtmp <= L'Z')
  240. tmp = wtmp - L'A';
  241. else if (wtmp >= L'a' && wtmp <= L'z')
  242. tmp = wtmp - L'a' + 26;
  243. else if (wtmp >= L'0' && wtmp <= L'9')
  244. tmp = wtmp - L'0' + 52;
  245. else if (wtmp == L'+')
  246. tmp = 62;
  247. else if (wtmp == L'/')
  248. tmp = 63;
  249. else
  250. {
  251. tmp = 0;
  252. IMPORTANT_MSG(_T("ERROR:found invalid character in decode stream"));
  253. }
  254. // tmp = (UCHAR)(pszAddr[i] - COMP_OFFSET);
  255. if (tmp > 63)
  256. {
  257. tmp = 0;
  258. IMPORTANT_MSG(_T("ERROR:screwup in DeAsciify"));
  259. }
  260. dwl = Int64ShllMod32(dwl, 6);
  261. dwl |= tmp;
  262. }
  263. memcpy(pba, &dwl, sizeof(*pba));
  264. return TRUE;
  265. }
  266. /****************************************************************************
  267. **
  268. ** SquishAddress(char *szIp, char *szCompIp)
  269. ** Takes one IP address and compresses it to minimum size
  270. **
  271. ****************************************************************************/
  272. DWORD APIENTRY SquishAddress(WCHAR *szIp, WCHAR *szCompIp, size_t cCompIp)
  273. {
  274. WCHAR *thisAddr, *nextAddr;
  275. BLOB_ADDR ba;
  276. if (!szIp || !szCompIp || cCompIp==0)
  277. {
  278. IMPORTANT_MSG(_T("SquishAddress called with NULL ptr"));
  279. return ERROR_INVALID_PARAMETER;
  280. }
  281. // TRIVIAL_MSG((L"SquishAddress(%s)", szIp));
  282. thisAddr = szIp;
  283. szCompIp[0] = 0;
  284. while (thisAddr)
  285. {
  286. WCHAR scr[10];
  287. nextAddr = wcschr(thisAddr, L';');
  288. if (nextAddr && *(nextAddr+1))
  289. {
  290. *nextAddr = 0;
  291. }
  292. else
  293. nextAddr=0;
  294. CompressAddr(thisAddr, &ba);
  295. // DumpBlob(&ba);
  296. AsciifyAddr(scr, &ba);
  297. if (wcslen(szCompIp) + wcslen(scr) >= cCompIp)
  298. return ERROR_INSUFFICIENT_BUFFER;
  299. wcscat(szCompIp, scr);
  300. if (nextAddr)
  301. {
  302. // restore seperator found earlier
  303. *nextAddr = ';';
  304. nextAddr++;
  305. if (wcslen(szCompIp) >= cCompIp)
  306. return ERROR_INSUFFICIENT_BUFFER;
  307. wcscat(szCompIp, L"!" /* COMP_SEPERATOR */);
  308. }
  309. thisAddr = nextAddr;
  310. }
  311. // TRIVIAL_MSG((L"SquishAddress returns [%s]", szCompIp));
  312. return ERROR_SUCCESS;
  313. }
  314. /****************************************************************************
  315. **
  316. ** ExpandAddress(char *szIp, char *szCompIp)
  317. ** Takes a compressed IP address and returns it to
  318. ** "normal"
  319. **
  320. ****************************************************************************/
  321. DWORD APIENTRY ExpandAddress(WCHAR *szIp, WCHAR *szCompIp, size_t cszIp)
  322. {
  323. BLOB_ADDR ba;
  324. WCHAR *thisAddr, *nextAddr;
  325. if (!szIp || !szCompIp || cszIp == 0)
  326. {
  327. IMPORTANT_MSG(_T("ExpandAddress called with NULL ptr"));
  328. return ERROR_INVALID_PARAMETER;
  329. }
  330. // TRIVIAL_MSG((L"ExpandAddress(%s)", szCompIp));
  331. thisAddr = szCompIp;
  332. szIp[0] = 0;
  333. while (thisAddr)
  334. {
  335. WCHAR scr[32];
  336. nextAddr = wcschr(thisAddr, COMP_SEPERATOR);
  337. if (nextAddr) *nextAddr = 0;
  338. DeAsciifyAddr(thisAddr, &ba);
  339. // DumpBlob(&ba);
  340. ExpandAddr(scr, &ba);
  341. if (wcslen(szIp) + wcslen(scr) >= cszIp)
  342. return ERROR_INSUFFICIENT_BUFFER;
  343. wcscat(szIp, scr);
  344. if (nextAddr)
  345. {
  346. // restore seperator found earlier
  347. *nextAddr = COMP_SEPERATOR;
  348. nextAddr++;
  349. if (wcslen(szIp) >= cszIp)
  350. return ERROR_INSUFFICIENT_BUFFER;
  351. wcscat(szIp, L";");
  352. }
  353. thisAddr = nextAddr;
  354. }
  355. // TRIVIAL_MSG((L"ExpandAddress returns [%s]", szIp));
  356. return ERROR_SUCCESS;
  357. }
  358. /*************************************************************************************
  359. **
  360. **
  361. *************************************************************************************/
  362. int GetTsPort(void)
  363. {
  364. DWORD dwRet = 3389;
  365. HKEY hKey;
  366. // open reg key first, to get ALL the spew...HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\Wds\\rdpwd\\Tds\\tcp
  367. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\Wds\\rdpwd\\Tds\\tcp", 0, KEY_READ, &hKey))
  368. {
  369. DWORD dwSize;
  370. dwSize = sizeof(dwRet);
  371. RegQueryValueEx(hKey, L"PortNumber", NULL, NULL, (LPBYTE)&dwRet, &dwSize);
  372. RegCloseKey(hKey);
  373. }
  374. return dwRet;
  375. }