SMBHelper.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using Utilities;
  11. namespace SMBLibrary
  12. {
  13. public class SMBHelper
  14. {
  15. public static readonly DateTime UTimeNotSpecified = new DateTime(1970, 1, 1);
  16. public static readonly DateTime FileTimeNotSpecified = new DateTime(1601, 1, 1);
  17. public static DateTime ReadFileTime(byte[] buffer, int offset)
  18. {
  19. long span = LittleEndianConverter.ToInt64(buffer, offset);
  20. if (span >= 0)
  21. {
  22. return DateTime.FromFileTimeUtc(span);
  23. }
  24. else
  25. {
  26. // Tick = 100ns
  27. return DateTime.Now.Subtract(TimeSpan.FromTicks(span));
  28. }
  29. }
  30. public static DateTime ReadFileTime(byte[] buffer, ref int offset)
  31. {
  32. offset += 8;
  33. return ReadFileTime(buffer, offset - 8);
  34. }
  35. public static DateTime ReadSetFileTime(byte[] buffer, int offset)
  36. {
  37. long span = LittleEndianConverter.ToInt64(buffer, offset);
  38. if (span >= 0)
  39. {
  40. return DateTime.FromFileTimeUtc(span);
  41. }
  42. else
  43. {
  44. return FileTimeNotSpecified;
  45. }
  46. }
  47. public static void WriteFileTime(byte[] buffer, int offset, DateTime time)
  48. {
  49. long span = time.ToFileTimeUtc();
  50. LittleEndianWriter.WriteInt64(buffer, offset, span);
  51. }
  52. public static void WriteFileTime(byte[] buffer, ref int offset, DateTime time)
  53. {
  54. WriteFileTime(buffer, offset, time);
  55. offset += 8;
  56. }
  57. // UTime - The number of seconds since Jan 1, 1970, 00:00:00
  58. public static DateTime ReadUTime(byte[] buffer, int offset)
  59. {
  60. uint span = LittleEndianConverter.ToUInt32(buffer, offset);
  61. DateTime result = new DateTime(1970, 1, 1);
  62. return result.AddSeconds(span);
  63. }
  64. public static DateTime ReadUTime(byte[] buffer, ref int offset)
  65. {
  66. offset += 4;
  67. return ReadUTime(buffer, offset - 4);
  68. }
  69. // UTime - The number of seconds since Jan 1, 1970, 00:00:00
  70. public static void WriteUTime(byte[] buffer, int offset, DateTime time)
  71. {
  72. TimeSpan timespan = time - new DateTime(1970, 1, 1);
  73. uint span = (uint)timespan.TotalSeconds;
  74. LittleEndianWriter.WriteUInt32(buffer, offset, span);
  75. }
  76. public static void WriteUTime(byte[] buffer, ref int offset, DateTime time)
  77. {
  78. WriteUTime(buffer, offset, time);
  79. offset += 4;
  80. }
  81. /// <summary>
  82. /// SMB_DATE
  83. /// </summary>
  84. public static DateTime ReadSMBDate(byte[] buffer, int offset)
  85. {
  86. ushort value = LittleEndianConverter.ToUInt16(buffer, offset);
  87. int year = ((value & 0xFE00) >> 9) + 1980;
  88. int month = ((value & 0x01E0) >> 5);
  89. int day = (value & 0x001F);
  90. return new DateTime(year, month, day);
  91. }
  92. public static void WriteSMBDate(byte[] buffer, int offset, DateTime date)
  93. {
  94. int year = date.Year - 1980;
  95. int month = date.Month;
  96. int day = date.Day;
  97. ushort value = (ushort)(year << 9 | month << 5 | day);
  98. LittleEndianWriter.WriteUInt16(buffer, offset, value);
  99. }
  100. /// <summary>
  101. /// SMB_DATE
  102. /// </summary>
  103. public static TimeSpan ReadSMBTime(byte[] buffer, int offset)
  104. {
  105. ushort value = LittleEndianConverter.ToUInt16(buffer, offset);
  106. int hours = ((value & 0xF800) >> 11);
  107. int minutes = ((value & 0x07E0) >> 5);
  108. int seconds = (value & 0x001F);
  109. return new TimeSpan(hours, minutes, seconds);
  110. }
  111. public static void WriteSMBTime(byte[] buffer, int offset, TimeSpan time)
  112. {
  113. ushort value = (ushort)(time.Hours << 11 | time.Minutes << 5 | time.Seconds);
  114. LittleEndianWriter.WriteUInt16(buffer, offset, value);
  115. }
  116. public static DateTime ReadSMBDateTime(byte[] buffer, int offset)
  117. {
  118. DateTime date = ReadSMBDate(buffer, offset);
  119. TimeSpan time = ReadSMBTime(buffer, offset + 2);
  120. return date.Add(time);
  121. }
  122. public static DateTime ReadSMBDateTime(byte[] buffer, ref int offset)
  123. {
  124. offset += 4;
  125. return ReadSMBDateTime(buffer, offset - 4);
  126. }
  127. public static void WriteSMBDateTime(byte[] buffer, int offset, DateTime dateTime)
  128. {
  129. WriteSMBDate(buffer, offset, dateTime.Date);
  130. WriteSMBTime(buffer, offset + 2, dateTime.TimeOfDay);
  131. }
  132. public static void WriteSMBDateTime(byte[] buffer, ref int offset, DateTime dateTime)
  133. {
  134. WriteSMBDateTime(buffer, offset, dateTime);
  135. offset += 4;
  136. }
  137. public static string ReadSMBString(byte[] buffer, int offset, bool isUnicode)
  138. {
  139. if (isUnicode)
  140. {
  141. return ByteReader.ReadNullTerminatedUTF16String(buffer, offset);
  142. }
  143. else
  144. {
  145. return ByteReader.ReadNullTerminatedAnsiString(buffer, offset);
  146. }
  147. }
  148. public static string ReadSMBString(byte[] buffer, ref int offset, bool isUnicode)
  149. {
  150. if (isUnicode)
  151. {
  152. return ByteReader.ReadNullTerminatedUTF16String(buffer, ref offset);
  153. }
  154. else
  155. {
  156. return ByteReader.ReadNullTerminatedAnsiString(buffer, ref offset);
  157. }
  158. }
  159. public static void WriteSMBString(byte[] buffer, int offset, bool isUnicode, string value)
  160. {
  161. if (isUnicode)
  162. {
  163. ByteWriter.WriteNullTerminatedUTF16String(buffer, offset, value);
  164. }
  165. else
  166. {
  167. ByteWriter.WriteNullTerminatedAnsiString(buffer, offset, value);
  168. }
  169. }
  170. public static void WriteSMBString(byte[] buffer, ref int offset, bool isUnicode, string value)
  171. {
  172. if (isUnicode)
  173. {
  174. ByteWriter.WriteNullTerminatedUTF16String(buffer, ref offset, value);
  175. }
  176. else
  177. {
  178. ByteWriter.WriteNullTerminatedAnsiString(buffer, ref offset, value);
  179. }
  180. }
  181. public static string ReadFixedLengthString(byte[] buffer, ref int offset, bool isUnicode, int byteCount)
  182. {
  183. if (isUnicode)
  184. {
  185. return ByteReader.ReadUTF16String(buffer, ref offset, byteCount / 2);
  186. }
  187. else
  188. {
  189. return ByteReader.ReadAnsiString(buffer, ref offset, byteCount);
  190. }
  191. }
  192. public static void WriteFixedLengthString(byte[] buffer, ref int offset, bool isUnicode, string value)
  193. {
  194. if (isUnicode)
  195. {
  196. ByteWriter.WriteUTF16String(buffer, ref offset, value);
  197. }
  198. else
  199. {
  200. ByteWriter.WriteAnsiString(buffer, ref offset, value);
  201. }
  202. }
  203. }
  204. }