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.

226 lines
7.2 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. encoded.cpp
  5. Abstract:
  6. This module is copied from IIS fcache.cxx which contains the encoding/decoding routines.
  7. --*/
  8. /************************************************************
  9. * Include Headers
  10. ************************************************************/
  11. #ifdef __cplusplus
  12. extern "C" {
  13. #endif
  14. # include <nt.h>
  15. # include <ntrtl.h>
  16. # include <nturtl.h>
  17. # include <windows.h>
  18. #ifdef __cplusplus
  19. };
  20. #endif
  21. #include "dbgutil.h"
  22. #include <tcpdll.hxx>
  23. #include <inetinfo.h>
  24. #include "simauth2.h"
  25. #include <dbgtrace.h>
  26. //
  27. // Taken from NCSA HTTP and wwwlib.
  28. //
  29. // NOTE: These conform to RFC1113, which is slightly different then the Unix
  30. // uuencode and uudecode!
  31. //
  32. const int _pr2six[256]={
  33. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  34. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,62,64,64,64,63,
  35. 52,53,54,55,56,57,58,59,60,61,64,64,64,64,64,64,64,0,1,2,3,4,5,6,7,8,9,
  36. 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,64,64,64,64,64,64,26,27,
  37. 28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
  38. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  39. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  40. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  41. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  42. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  43. 64,64,64,64,64,64,64,64,64,64,64,64,64
  44. };
  45. char _six2pr[64] = {
  46. 'A','B','C','D','E','F','G','H','I','J','K','L','M',
  47. 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  48. 'a','b','c','d','e','f','g','h','i','j','k','l','m',
  49. 'n','o','p','q','r','s','t','u','v','w','x','y','z',
  50. '0','1','2','3','4','5','6','7','8','9','+','/'
  51. };
  52. const int _pr2six64[256]={
  53. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  54. 64,64,64,64,64,64,64,64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
  55. 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
  56. 40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
  57. 0,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  58. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  59. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  60. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  61. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  62. 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
  63. 64,64,64,64,64,64,64,64,64,64,64,64,64
  64. };
  65. char _six2pr64[64] = {
  66. '`','!','"','#','$','%','&','\'','(',')','*','+',',',
  67. '-','.','/','0','1','2','3','4','5','6','7','8','9',
  68. ':',';','<','=','>','?','@','A','B','C','D','E','F',
  69. 'G','H','I','J','K','L','M','N','O','P','Q','R','S',
  70. 'T','U','V','W','X','Y','Z','[','\\',']','^','_'
  71. };
  72. BOOL uudecode(char * bufcoded,
  73. BUFFER * pbuffdecoded,
  74. DWORD * pcbDecoded,
  75. BOOL fBase64
  76. )
  77. {
  78. int nbytesdecoded;
  79. char *bufin = bufcoded;
  80. unsigned char *bufout;
  81. int nprbytes;
  82. int *pr2six = (int*)(fBase64 ? _pr2six64 : _pr2six);
  83. /* Strip leading whitespace. */
  84. while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++;
  85. /* Figure out how many characters are in the input buffer.
  86. * If this would decode into more bytes than would fit into
  87. * the output buffer, adjust the number of input bytes downwards.
  88. */
  89. bufin = bufcoded;
  90. while(pr2six[*(bufin++)] <= 63);
  91. nprbytes = (int)(bufin - bufcoded - 1);
  92. nbytesdecoded = ((nprbytes+3)/4) * 3;
  93. if ( !pbuffdecoded->Resize( nbytesdecoded + 4 ))
  94. return FALSE;
  95. bufout = (unsigned char *) pbuffdecoded->QueryPtr();
  96. bufin = bufcoded;
  97. while (nprbytes > 0) {
  98. *(bufout++) =
  99. (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
  100. *(bufout++) =
  101. (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
  102. *(bufout++) =
  103. (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
  104. bufin += 4;
  105. nprbytes -= 4;
  106. }
  107. if(nprbytes & 03) {
  108. if(pr2six[bufin[-2]] > 63)
  109. nbytesdecoded -= 2;
  110. else
  111. nbytesdecoded -= 1;
  112. }
  113. ((CHAR *)pbuffdecoded->QueryPtr())[nbytesdecoded] = '\0';
  114. if ( pcbDecoded )
  115. *pcbDecoded = nbytesdecoded;
  116. return TRUE;
  117. }
  118. //
  119. // NOTE NOTE NOTE
  120. // If the buffer length isn't a multiple of 3, we encode one extra byte beyond the
  121. // end of the buffer. This garbage byte is stripped off by the uudecode code, but
  122. // -IT HAS TO BE THERE- for uudecode to work. This applies not only our uudecode, but
  123. // to every uudecode() function that is based on the lib-www distribution [probably
  124. // a fairly large percentage].
  125. //
  126. BOOL uuencode( BYTE * bufin,
  127. DWORD nbytes,
  128. BUFFER * pbuffEncoded,
  129. BOOL fBase64 )
  130. {
  131. unsigned char *outptr;
  132. unsigned int i;
  133. char *six2pr = fBase64 ? _six2pr64 : _six2pr;
  134. BOOL fOneByteDiff = FALSE;
  135. BOOL fTwoByteDiff = FALSE;
  136. unsigned int iRemainder = 0;
  137. unsigned int iClosestMultOfThree = 0;
  138. //
  139. // Resize the buffer to 133% of the incoming data
  140. //
  141. if ( !pbuffEncoded->Resize( nbytes + ((nbytes + 3) / 3) + 4))
  142. return FALSE;
  143. outptr = (unsigned char *) pbuffEncoded->QueryPtr();
  144. iRemainder = nbytes % 3; //also works for nbytes == 1, 2
  145. fOneByteDiff = (iRemainder == 1 ? TRUE : FALSE);
  146. fTwoByteDiff = (iRemainder == 2 ? TRUE : FALSE);
  147. iClosestMultOfThree = ((nbytes - iRemainder)/3) * 3 ;
  148. //
  149. // Encode bytes in buffer up to multiple of 3 that is closest to nbytes.
  150. //
  151. for (i=0; i< iClosestMultOfThree ; i += 3) {
  152. *(outptr++) = six2pr[*bufin >> 2]; /* c1 */
  153. *(outptr++) = six2pr[((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)]; /*c2*/
  154. *(outptr++) = six2pr[((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03)];/*c3*/
  155. *(outptr++) = six2pr[bufin[2] & 077]; /* c4 */
  156. bufin += 3;
  157. }
  158. //
  159. // We deal with trailing bytes by pretending that the input buffer has been padded with
  160. // zeros. Expressions are thus the same as above, but the second half drops off b'cos
  161. // ( a | ( b & 0) ) = ( a | 0 ) = a
  162. //
  163. if (fOneByteDiff)
  164. {
  165. *(outptr++) = six2pr[*bufin >> 2]; /* c1 */
  166. *(outptr++) = six2pr[((*bufin << 4) & 060)]; /* c2 */
  167. //pad with '='
  168. *(outptr++) = '='; /* c3 */
  169. *(outptr++) = '='; /* c4 */
  170. }
  171. else if (fTwoByteDiff)
  172. {
  173. *(outptr++) = six2pr[*bufin >> 2]; /* c1 */
  174. *(outptr++) = six2pr[((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)]; /*c2*/
  175. *(outptr++) = six2pr[((bufin[1] << 2) & 074)];/*c3*/
  176. //pad with '='
  177. *(outptr++) = '='; /* c4 */
  178. }
  179. //encoded buffer must be zero-terminated
  180. *outptr = '\0';
  181. return TRUE;
  182. }