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.

364 lines
8.7 KiB

  1. #include "bldr.h"
  2. #include "sal.h"
  3. #include "ssc.h"
  4. #include "ntimage.h"
  5. #define SECTOR_SIZE 512
  6. SalDiskReadWrite(
  7. ULONG ReadWrite,
  8. ULONG SectorsToRead,
  9. ULONG Cylinder,
  10. ULONG CylinderPerSector,
  11. ULONG Head,
  12. ULONG Drive,
  13. PUCHAR Buffer
  14. )
  15. {
  16. IA32_BIOS_REGISTER_STATE IA32RegisterState;
  17. BIT32_AND_BIT16 IA32Register;
  18. if (ReadWrite == 0) {
  19. IA32Register.HighPart16 = 0x02;
  20. } else {
  21. IA32Register.HighPart16 = 0x03;
  22. }
  23. IA32Register.LowPart16 = SectorsToRead;
  24. IA32RegisterState.eax = IA32Register.Part32;
  25. IA32Register.HighPart16 = Cylinder;
  26. IA32Register.LowPart16 = CylinderPerSector;
  27. IA32RegisterState.ecx = IA32Register.Part32;
  28. IA32Register.HighPart16 = Head;
  29. IA32Register.LowPart16 = Drive;
  30. IA32RegisterState.edx = IA32Register.Part32;
  31. IA32RegisterState.es = 0;
  32. IA32Register.HighPart16 = 0;
  33. IA32Register.LowPart16 = Buffer;
  34. IA32RegisterState.ebx = IA32Register.Part32;
  35. // SAL_PROC(0x100,&IA32RegisterState,0,0,0,0,0,0,);
  36. }
  37. ReadSectors(
  38. ULONG SectorBase,
  39. USHORT SectorCount,
  40. PUCHAR Buffer)
  41. {
  42. static char *VolumeName = "\\\\.\\D:";
  43. SSC_HANDLE VolumeHandle;
  44. SSC_DISK_REQUEST Request[1];
  45. SSC_DISK_COMPLETION DiskCompletion;
  46. LARGE_INTEGER VolumeNamePtr;
  47. LARGE_INTEGER RequestPtr;
  48. LARGE_INTEGER VolumeOffset;
  49. LARGE_INTEGER DiskCompletionPtr;
  50. VolumeNamePtr.LowPart = VolumeName;
  51. VolumeNamePtr.HighPart = 0;
  52. VolumeHandle = SscDiskOpenVolume (VolumeNamePtr, SSC_ACCESS_READ);
  53. Request[0].DiskBufferAddress.LowPart = Buffer;
  54. Request[0].DiskBufferAddress.HighPart = 0;
  55. Request[0].DiskByteCount = SectorCount * SECTOR_SIZE;
  56. RequestPtr.LowPart = Request;
  57. RequestPtr.HighPart = 0;
  58. VolumeOffset.LowPart = SectorBase * SECTOR_SIZE;
  59. VolumeOffset.HighPart = 0;
  60. SscDiskReadVolume(VolumeHandle, 1, RequestPtr, VolumeOffset);
  61. DiskCompletion.VolumeHandle = VolumeHandle;
  62. DiskCompletionPtr.LowPart = &DiskCompletion;
  63. DiskCompletionPtr.HighPart = 0;
  64. while (1) {
  65. if (SscDiskWaitIoCompletion(DiskCompletionPtr) == 0) break;
  66. }
  67. }
  68. SalPrint(
  69. PUCHAR Buffer
  70. )
  71. {
  72. IA32_BIOS_REGISTER_STATE IA32RegisterState;
  73. BIT32_AND_BIT16 IA32Register;
  74. ULONG i;
  75. for (i = 0; Buffer[i] != 0 && i < 256; i++) {
  76. IA32Register.HighPart16 = 14;
  77. IA32Register.LowPart16 = Buffer[i];
  78. IA32RegisterState.eax = IA32Register.Part32;
  79. IA32RegisterState.ebx = 7;
  80. // SAL_PROC(0x100,&IA32RegisterState,0,0,0,0,0,0,);
  81. }
  82. }
  83. Multiply(
  84. ULONG Multiplicant,
  85. ULONG Multiplier)
  86. {
  87. return(Multiplicant * Multiplier);
  88. }
  89. Divide(
  90. ULONG Numerator,
  91. ULONG Denominator,
  92. PULONG Result,
  93. PULONG Remainder
  94. )
  95. {
  96. float f1, f2;
  97. f1 = (float) Numerator;
  98. f2 = (float) Denominator;
  99. *Result = (ULONG) (f1 / f2);
  100. *Remainder = Numerator % Denominator;
  101. }
  102. memcpy(
  103. PUCHAR Source,
  104. PUCHAR Destination,
  105. ULONG Length
  106. )
  107. {
  108. while (Length--) {
  109. *Destination++ = *Source++;
  110. }
  111. }
  112. memmove(
  113. PUCHAR Source,
  114. PUCHAR Destination,
  115. ULONG Length
  116. )
  117. {
  118. while (Length--) {
  119. *Destination++ = *Source++;
  120. }
  121. }
  122. memset(
  123. PUCHAR Destination,
  124. ULONG Length,
  125. ULONG Value
  126. )
  127. {
  128. while (Length--) {
  129. *Destination++ = Value;
  130. }
  131. }
  132. strncmp(
  133. PUCHAR String1,
  134. PUCHAR String2,
  135. ULONG Length
  136. )
  137. {
  138. while (Length--) {
  139. if (*String1++ != *String2++)
  140. return(String1);
  141. }
  142. return(0);
  143. }
  144. PrintName(
  145. PUCHAR String
  146. )
  147. {
  148. LARGE_INTEGER StringPtr;
  149. StringPtr.LowPart = String;
  150. StringPtr.HighPart = 0;
  151. SscDbgPrintf(StringPtr);
  152. }
  153. BootErr$Print(
  154. PUCHAR String
  155. )
  156. {
  157. LARGE_INTEGER StringPtr;
  158. StringPtr.LowPart = String;
  159. StringPtr.HighPart = 0;
  160. SscDbgPrintf(StringPtr);
  161. }
  162. LoadNtldrSymbols()
  163. {
  164. static char *NtfsBoot = "\\ntfsboot.exe";
  165. static char *Ntldr = "\\NTLDR";
  166. LARGE_INTEGER PhysicalPtr;
  167. PhysicalPtr.LowPart = NtfsBoot;
  168. PhysicalPtr.HighPart = 0;
  169. SscUnloadImage(PhysicalPtr,
  170. 0x0,
  171. (ULONG)-1,
  172. (ULONG)0);
  173. PhysicalPtr.LowPart = Ntldr;
  174. PhysicalPtr.HighPart = 0;
  175. SscLoadImage(PhysicalPtr,
  176. 0xE00000,
  177. 0x118A00,
  178. 0x7cc,
  179. 0, // process ID
  180. 1); // load count
  181. }
  182. ULONG
  183. RelocateLoaderSections(
  184. ULONG NtldrBuffer
  185. )
  186. /*++
  187. Routine Description:
  188. The SU module is prepended to the OS loader file. The OS loader file
  189. is a coff++ file. This routine computes the beginning of the OS loader
  190. file, then relocates the OS loader's sections as if it were just
  191. loading the file from disk file.
  192. Arguments:
  193. NtldrBuffer - Buffer that contains the NTLDR raw image from disk
  194. Returns:
  195. Entry point of loader
  196. --*/
  197. {
  198. ULONG Start, End;
  199. USHORT Section;
  200. ULONG Source,Destination;
  201. ULONG VirtualSize;
  202. ULONG SizeOfRawData;
  203. PIMAGE_FILE_HEADER FileHeader;
  204. PIMAGE_OPTIONAL_HEADER OptionalHeader;
  205. PIMAGE_SECTION_HEADER SectionHeader;
  206. //
  207. // Make a pointer to the beginning of the loader's coff header
  208. //
  209. FileHeader = (PIMAGE_FILE_HEADER) NtldrBuffer;
  210. //
  211. // Validate the appended loader image by checking signatures.
  212. // 1st - is it an executable image?
  213. // 2nd - is the target environment the 386?
  214. //
  215. if ((FileHeader->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0) {
  216. SalPrint("SU_NTLDR_CORRUPT");
  217. return;
  218. }
  219. if (FileHeader->Machine != IMAGE_FILE_MACHINE_IA64) {
  220. SalPrint("SU_NTLDR_CORRUPT");
  221. return;
  222. }
  223. //
  224. // Make a pointer to the optional header in the header-buffer
  225. //
  226. OptionalHeader = (PIMAGE_OPTIONAL_HEADER)((PUCHAR)FileHeader +
  227. sizeof(IMAGE_FILE_HEADER));
  228. //
  229. // Make a pointer to the first section in the header buffer
  230. //
  231. SectionHeader = (PIMAGE_SECTION_HEADER)((PUCHAR)OptionalHeader +
  232. FileHeader->SizeOfOptionalHeader);
  233. Start = OptionalHeader->ImageBase+SectionHeader->VirtualAddress;
  234. End = Start + SectionHeader->SizeOfRawData;
  235. //
  236. // Loop and relocate each section with a non-zero RawData size
  237. //
  238. for (Section=FileHeader->NumberOfSections ; Section-- ; SectionHeader++) {
  239. //
  240. // Compute source, destination, and count arguments
  241. //
  242. Source = NtldrBuffer + SectionHeader->PointerToRawData;
  243. Destination = OptionalHeader->ImageBase + SectionHeader->VirtualAddress;
  244. VirtualSize = SectionHeader->Misc.VirtualSize;
  245. SizeOfRawData = SectionHeader->SizeOfRawData;
  246. if (VirtualSize == 0) {
  247. VirtualSize = SizeOfRawData;
  248. }
  249. if (SectionHeader->PointerToRawData == 0) {
  250. //
  251. // SizeOfRawData can be non-zero even if PointerToRawData is zero
  252. //
  253. SizeOfRawData = 0;
  254. } else if (SizeOfRawData > VirtualSize) {
  255. //
  256. // Don't load more from image than is expected in memory
  257. //
  258. SizeOfRawData = VirtualSize;
  259. }
  260. if (Destination < Start) {
  261. Start = Destination;
  262. }
  263. if (Destination+VirtualSize > End) {
  264. End = Destination+VirtualSize;
  265. }
  266. if (SizeOfRawData != 0) {
  267. //
  268. // This section is either a code (.TEXT) section or an
  269. // initialized data (.DATA) section.
  270. // Relocate the section to memory at the virtual/physical
  271. // addresses specified in the section header.
  272. //
  273. memmove(Source,Destination,SizeOfRawData);
  274. }
  275. if (SizeOfRawData < VirtualSize) {
  276. //
  277. // Zero the portion not loaded from the image
  278. //
  279. memset(Destination+SizeOfRawData,0,VirtualSize - SizeOfRawData);
  280. }
  281. #if 0
  282. //
  283. // Check if this is the resource section. If so, we need
  284. // to pass its location to the osloader.
  285. //
  286. if ((SectionHeader->Name[0] == '.') &&
  287. (SectionHeader->Name[1] == 'r') &&
  288. (SectionHeader->Name[2] == 's') &&
  289. (SectionHeader->Name[3] == 'r') &&
  290. (SectionHeader->Name[4] == 'c')) {
  291. ResourceDirectory = Destination;
  292. ResourceOffset = SectionHeader->VirtualAddress;
  293. }
  294. #endif
  295. }
  296. return(OptionalHeader->AddressOfEntryPoint + OptionalHeader->ImageBase);
  297. }