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.

169 lines
4.6 KiB

  1. /*
  2. * io.c
  3. */
  4. #include "encoder.h"
  5. /*
  6. * Similar to the optimisation we have for the decoder.
  7. *
  8. * Allow the encoder to "overrun" output buffer by up to X bytes
  9. * so that we don't have to check for the end of the buffer every
  10. * single time we call outbits() in encdata.c
  11. */
  12. #define OUTPUT_EXTRA_BYTES 64
  13. static void encoder_translate_e8(t_encoder_context *context, byte *mem, long bytes);
  14. /*
  15. * Initialises output buffering
  16. */
  17. bool init_compressed_output_buffer(t_encoder_context *context)
  18. {
  19. if (!(context->enc_output_buffer_start = (byte *) context->enc_malloc(
  20. context->enc_mallochandle,
  21. OUTPUT_BUFFER_SIZE)
  22. ))
  23. {
  24. return false;
  25. }
  26. context->enc_output_buffer_curpos = context->enc_output_buffer_start;
  27. context->enc_output_buffer_end =
  28. context->enc_output_buffer_start+(OUTPUT_BUFFER_SIZE-OUTPUT_EXTRA_BYTES);
  29. return true;
  30. }
  31. void reset_translation(t_encoder_context *context)
  32. {
  33. context->enc_instr_pos = 0;
  34. }
  35. static long read_input_data(t_encoder_context *context, byte *mem, long amount)
  36. {
  37. if (amount <= context->enc_input_left)
  38. {
  39. memcpy(mem, context->enc_input_ptr, amount);
  40. context->enc_input_left -= amount;
  41. context->enc_input_ptr += amount;
  42. return amount;
  43. }
  44. else
  45. {
  46. long bytes_read;
  47. if (context->enc_input_left <= 0)
  48. return 0;
  49. bytes_read = context->enc_input_left;
  50. memcpy(mem, context->enc_input_ptr, context->enc_input_left);
  51. context->enc_input_ptr += context->enc_input_left;
  52. context->enc_input_left = 0;
  53. return bytes_read;
  54. }
  55. }
  56. long comp_read_input(t_encoder_context *context, ulong BufPos, long Size)
  57. {
  58. long bytes_read;
  59. if (Size <= 0)
  60. return 0;
  61. bytes_read = read_input_data(
  62. context,
  63. &context->enc_RealMemWindow[BufPos],
  64. Size
  65. );
  66. if (bytes_read < 0)
  67. return 0;
  68. /*
  69. * If no translation being performed for this file
  70. */
  71. if (context->enc_file_size_for_translation == 0 ||
  72. context->enc_num_cfdata_frames >= E8_CFDATA_FRAME_THRESHOLD)
  73. {
  74. context->enc_num_cfdata_frames++;
  75. return bytes_read;
  76. }
  77. encoder_translate_e8(
  78. context,
  79. &context->enc_RealMemWindow[BufPos],
  80. bytes_read
  81. );
  82. context->enc_num_cfdata_frames++;
  83. return bytes_read;
  84. }
  85. static void encoder_translate_e8(t_encoder_context *context, byte *mem, long bytes)
  86. {
  87. long offset;
  88. long absolute;
  89. ulong end_instr_pos;
  90. byte temp[6];
  91. byte *mem_backup;
  92. if (bytes <= 6)
  93. {
  94. context->enc_instr_pos += bytes;
  95. return;
  96. }
  97. mem_backup = mem;
  98. /* backup these bytes */
  99. memcpy(temp, &mem[bytes-6], 6);
  100. /* overwrite them with 0xE8 */
  101. memset(&mem[bytes-6], 0xE8, 6);
  102. end_instr_pos = context->enc_instr_pos + bytes - 6;
  103. while (1)
  104. {
  105. while (*mem++ != 0xE8)
  106. context->enc_instr_pos++;
  107. if (context->enc_instr_pos >= end_instr_pos)
  108. break;
  109. offset = *(UNALIGNED long *) mem;
  110. absolute = context->enc_instr_pos + offset;
  111. if (absolute >= 0)
  112. {
  113. if ((ulong) absolute < context->enc_file_size_for_translation+context->enc_instr_pos)
  114. {
  115. if ((ulong) absolute >= context->enc_file_size_for_translation)
  116. absolute = offset - context->enc_file_size_for_translation;
  117. *(UNALIGNED ulong *) mem = (ulong) absolute;
  118. }
  119. }
  120. mem += 4;
  121. context->enc_instr_pos += 5;
  122. }
  123. /* restore the bytes */
  124. memcpy(&mem_backup[bytes-6], temp, 6);
  125. context->enc_instr_pos = end_instr_pos + 6;
  126. }