Source code of Windows XP (NT5)
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.

400 lines
8.0 KiB

  1. /*++
  2. Copyright (c) 1998 Intel Corporation
  3. Module Name:
  4. misc.c
  5. Abstract:
  6. Revision History
  7. --*/
  8. #include "lib.h"
  9. /*
  10. *
  11. */
  12. VOID *
  13. AllocatePool (
  14. IN UINTN Size
  15. )
  16. {
  17. EFI_STATUS Status;
  18. VOID *p;
  19. Status = BS->AllocatePool (PoolAllocationType, Size, &p);
  20. if (EFI_ERROR(Status)) {
  21. DEBUG((D_ERROR, "AllocatePool: out of pool %x\n", Status));
  22. p = NULL;
  23. }
  24. return p;
  25. }
  26. VOID *
  27. AllocateZeroPool (
  28. IN UINTN Size
  29. )
  30. {
  31. VOID *p;
  32. p = AllocatePool (Size);
  33. if (p) {
  34. ZeroMem (p, Size);
  35. }
  36. return p;
  37. }
  38. VOID *
  39. ReallocatePool (
  40. IN VOID *OldPool,
  41. IN UINTN OldSize,
  42. IN UINTN NewSize
  43. )
  44. {
  45. VOID *NewPool;
  46. NewPool = NULL;
  47. if (NewSize) {
  48. NewPool = AllocatePool (NewSize);
  49. }
  50. if (OldPool) {
  51. if (NewPool) {
  52. CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
  53. }
  54. FreePool (OldPool);
  55. }
  56. return NewPool;
  57. }
  58. VOID
  59. FreePool (
  60. IN VOID *Buffer
  61. )
  62. {
  63. BS->FreePool (Buffer);
  64. }
  65. VOID
  66. ZeroMem (
  67. IN VOID *Buffer,
  68. IN UINTN Size
  69. )
  70. {
  71. RtZeroMem (Buffer, Size);
  72. }
  73. VOID
  74. SetMem (
  75. IN VOID *Buffer,
  76. IN UINTN Size,
  77. IN UINT8 Value
  78. )
  79. {
  80. RtSetMem (Buffer, Size, Value);
  81. }
  82. VOID
  83. CopyMem (
  84. IN VOID *Dest,
  85. IN VOID *Src,
  86. IN UINTN len
  87. )
  88. {
  89. RtCopyMem (Dest, Src, len);
  90. }
  91. INTN
  92. CompareMem (
  93. IN VOID *Dest,
  94. IN VOID *Src,
  95. IN UINTN len
  96. )
  97. {
  98. return RtCompareMem (Dest, Src, len);
  99. }
  100. BOOLEAN
  101. GrowBuffer(
  102. IN OUT EFI_STATUS *Status,
  103. IN OUT VOID **Buffer,
  104. IN UINTN BufferSize
  105. )
  106. /*++
  107. Routine Description:
  108. Helper function called as part of the code needed
  109. to allocate the proper sized buffer for various
  110. EFI interfaces.
  111. Arguments:
  112. Status - Current status
  113. Buffer - Current allocated buffer, or NULL
  114. BufferSize - Current buffer size needed
  115. Returns:
  116. TRUE - if the buffer was reallocated and the caller
  117. should try the API again.
  118. --*/
  119. {
  120. BOOLEAN TryAgain;
  121. /*
  122. * If this is an initial request, buffer will be null with a new buffer size
  123. */
  124. if (!*Buffer && BufferSize) {
  125. *Status = EFI_BUFFER_TOO_SMALL;
  126. }
  127. /*
  128. * If the status code is "buffer too small", resize the buffer
  129. */
  130. TryAgain = FALSE;
  131. if (*Status == EFI_BUFFER_TOO_SMALL) {
  132. if (*Buffer) {
  133. FreePool (*Buffer);
  134. }
  135. *Buffer = AllocatePool (BufferSize);
  136. if (*Buffer) {
  137. TryAgain = TRUE;
  138. } else {
  139. *Status = EFI_OUT_OF_RESOURCES;
  140. }
  141. }
  142. /*
  143. * If there's an error, free the buffer
  144. */
  145. if (!TryAgain && EFI_ERROR(*Status) && *Buffer) {
  146. FreePool (*Buffer);
  147. *Buffer = NULL;
  148. }
  149. return TryAgain;
  150. }
  151. EFI_MEMORY_DESCRIPTOR *
  152. LibMemoryMap (
  153. OUT UINTN *NoEntries,
  154. OUT UINTN *MapKey,
  155. OUT UINTN *DescriptorSize,
  156. OUT UINT32 *DescriptorVersion
  157. )
  158. {
  159. EFI_STATUS Status;
  160. EFI_MEMORY_DESCRIPTOR *Buffer;
  161. UINTN BufferSize;
  162. /*
  163. * Initialize for GrowBuffer loop
  164. */
  165. Buffer = NULL;
  166. BufferSize = sizeof(EFI_MEMORY_DESCRIPTOR);
  167. /*
  168. * Call the real function
  169. */
  170. while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
  171. Status = BS->GetMemoryMap (&BufferSize, Buffer, MapKey, DescriptorSize, DescriptorVersion);
  172. }
  173. /*
  174. * Convert buffer size to NoEntries
  175. */
  176. if (!EFI_ERROR(Status)) {
  177. *NoEntries = BufferSize / *DescriptorSize;
  178. }
  179. return Buffer;
  180. }
  181. VOID *
  182. LibGetVariableAndSize (
  183. IN CHAR16 *Name,
  184. IN EFI_GUID *VendorGuid,
  185. OUT UINTN *VarSize
  186. )
  187. {
  188. EFI_STATUS Status;
  189. VOID *Buffer;
  190. UINTN BufferSize;
  191. /*
  192. * Initialize for GrowBuffer loop
  193. */
  194. Buffer = NULL;
  195. BufferSize = 100;
  196. /*
  197. * Call the real function
  198. */
  199. while (GrowBuffer (&Status, &Buffer, BufferSize)) {
  200. Status = RT->GetVariable (
  201. Name,
  202. VendorGuid,
  203. NULL,
  204. &BufferSize,
  205. Buffer
  206. );
  207. }
  208. if (Buffer) {
  209. *VarSize = BufferSize;
  210. } else {
  211. *VarSize = 0;
  212. }
  213. return Buffer;
  214. }
  215. VOID *
  216. LibGetVariable (
  217. IN CHAR16 *Name,
  218. IN EFI_GUID *VendorGuid
  219. )
  220. {
  221. UINTN VarSize;
  222. return LibGetVariableAndSize (Name, VendorGuid, &VarSize);
  223. }
  224. BOOLEAN
  225. ValidMBR(
  226. IN MASTER_BOOT_RECORD *Mbr,
  227. IN EFI_BLOCK_IO *BlkIo
  228. )
  229. {
  230. UINT32 StartingLBA, EndingLBA;
  231. UINT32 NewEndingLBA;
  232. INTN i, j;
  233. BOOLEAN ValidMbr;
  234. if (Mbr->Signature != MBR_SIGNATURE) {
  235. /*
  236. * The BPB also has this signature, so it can not be used alone.
  237. */
  238. return FALSE;
  239. }
  240. ValidMbr = FALSE;
  241. for (i=0; i<MAX_MBR_PARTITIONS; i++) {
  242. if ( Mbr->Partition[i].OSIndicator == 0x00 || EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA) == 0 ) {
  243. continue;
  244. }
  245. ValidMbr = TRUE;
  246. StartingLBA = EXTRACT_UINT32(Mbr->Partition[i].StartingLBA);
  247. EndingLBA = StartingLBA + EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA) - 1;
  248. if (EndingLBA > BlkIo->Media->LastBlock) {
  249. /*
  250. * Compatability Errata:
  251. * Some systems try to hide drive space with thier INT 13h driver
  252. * This does not hide space from the OS driver. This means the MBR
  253. * that gets created from DOS is smaller than the MBR created from
  254. * a real OS (NT & Win98). This leads to BlkIo->LastBlock being
  255. * wrong on some systems FDISKed by the OS.
  256. *
  257. */
  258. if (BlkIo->Media->LastBlock < MIN_MBR_DEVICE_SIZE) {
  259. /*
  260. * If this is a very small device then trust the BlkIo->LastBlock
  261. */
  262. return FALSE;
  263. }
  264. if (EndingLBA > (BlkIo->Media->LastBlock + MBR_ERRATA_PAD)) {
  265. return FALSE;
  266. }
  267. }
  268. for (j=i+1; j<MAX_MBR_PARTITIONS; j++) {
  269. if (Mbr->Partition[j].OSIndicator == 0x00 || EXTRACT_UINT32(Mbr->Partition[j].SizeInLBA) == 0) {
  270. continue;
  271. }
  272. if ( EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) >= StartingLBA &&
  273. EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) <= EndingLBA ) {
  274. /*
  275. * The Start of this region overlaps with the i'th region
  276. */
  277. return FALSE;
  278. }
  279. NewEndingLBA = EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) + EXTRACT_UINT32(Mbr->Partition[j].SizeInLBA) - 1;
  280. if ( NewEndingLBA >= StartingLBA && NewEndingLBA <= EndingLBA ) {
  281. /*
  282. * The End of this region overlaps with the i'th region
  283. */
  284. return FALSE;
  285. }
  286. }
  287. }
  288. /*
  289. * Non of the regions overlapped so MBR is O.K.
  290. */
  291. return ValidMbr;
  292. }
  293. UINT8
  294. DecimaltoBCD(
  295. IN UINT8 DecValue
  296. )
  297. {
  298. return RtDecimaltoBCD (DecValue);
  299. }
  300. UINT8
  301. BCDtoDecimal(
  302. IN UINT8 BcdValue
  303. )
  304. {
  305. return RtBCDtoDecimal (BcdValue);
  306. }
  307. EFI_STATUS
  308. LibGetSystemConfigurationTable(
  309. IN EFI_GUID *TableGuid,
  310. IN OUT VOID **Table
  311. )
  312. {
  313. UINTN Index;
  314. for(Index=0;Index<ST->NumberOfTableEntries;Index++) {
  315. if (CompareGuid(TableGuid,&(ST->ConfigurationTable[Index].VendorGuid))==0) {
  316. *Table = ST->ConfigurationTable[Index].VendorTable;
  317. return EFI_SUCCESS;
  318. }
  319. }
  320. return EFI_NOT_FOUND;
  321. }