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.

619 lines
14 KiB

  1. /*++
  2. Copyright (c) 1998 Intel Corporation
  3. Module Name:
  4. hand.c
  5. Abstract:
  6. Revision History
  7. --*/
  8. #include "lib.h"
  9. #include "efistdarg.h" /* !!! */
  10. EFI_STATUS
  11. LibLocateProtocol (
  12. IN EFI_GUID *ProtocolGuid,
  13. OUT VOID **Interface
  14. )
  15. /*
  16. * Find the first instance of this Protocol in the system and return it's interface
  17. */
  18. {
  19. EFI_STATUS Status;
  20. UINTN NumberHandles, Index;
  21. EFI_HANDLE *Handles;
  22. *Interface = NULL;
  23. Status = LibLocateHandle (ByProtocol, ProtocolGuid, NULL, &NumberHandles, &Handles);
  24. if (EFI_ERROR(Status)) {
  25. DEBUG((D_INFO, "LibLocateProtocol: Handle not found\n"));
  26. return Status;
  27. }
  28. for (Index=0; Index < NumberHandles; Index++) {
  29. Status = BS->HandleProtocol (Handles[Index], ProtocolGuid, Interface);
  30. if (!EFI_ERROR(Status)) {
  31. break;
  32. }
  33. }
  34. if (Handles) {
  35. FreePool (Handles);
  36. }
  37. return Status;
  38. }
  39. EFI_STATUS
  40. LibLocateHandle (
  41. IN EFI_LOCATE_SEARCH_TYPE SearchType,
  42. IN EFI_GUID *Protocol OPTIONAL,
  43. IN VOID *SearchKey OPTIONAL,
  44. IN OUT UINTN *NoHandles,
  45. OUT EFI_HANDLE **Buffer
  46. )
  47. {
  48. EFI_STATUS Status;
  49. UINTN BufferSize;
  50. /*
  51. * Initialize for GrowBuffer loop
  52. */
  53. *Buffer = NULL;
  54. BufferSize = 50 * sizeof(EFI_HANDLE);
  55. /*
  56. * Call the real function
  57. */
  58. while (GrowBuffer (&Status, (VOID **) Buffer, BufferSize)) {
  59. Status = BS->LocateHandle (
  60. SearchType,
  61. Protocol,
  62. SearchKey,
  63. &BufferSize,
  64. *Buffer
  65. );
  66. }
  67. *NoHandles = BufferSize / sizeof (EFI_HANDLE);
  68. if (EFI_ERROR(Status)) {
  69. *NoHandles = 0;
  70. }
  71. return Status;
  72. }
  73. EFI_STATUS
  74. LibLocateHandleByDiskSignature (
  75. IN UINT8 MBRType,
  76. IN UINT8 SignatureType,
  77. IN VOID *Signature,
  78. IN OUT UINTN *NoHandles,
  79. OUT EFI_HANDLE **Buffer
  80. )
  81. {
  82. EFI_STATUS Status;
  83. UINTN BufferSize;
  84. UINTN NoBlockIoHandles;
  85. EFI_HANDLE *BlockIoBuffer;
  86. EFI_DEVICE_PATH *DevicePath;
  87. UINTN Index;
  88. EFI_DEVICE_PATH *Start, *Next, *DevPath;
  89. HARDDRIVE_DEVICE_PATH *HardDriveDevicePath;
  90. BOOLEAN Match;
  91. BOOLEAN PreviousNodeIsHardDriveDevicePath;
  92. /*
  93. * Initialize for GrowBuffer loop
  94. */
  95. BlockIoBuffer = NULL;
  96. BufferSize = 50 * sizeof(EFI_HANDLE);
  97. /*
  98. * Call the real function
  99. */
  100. while (GrowBuffer (&Status, (VOID **)&BlockIoBuffer, BufferSize)) {
  101. /*
  102. * Get list of device handles that support the BLOCK_IO Protocol.
  103. */
  104. Status = BS->LocateHandle (
  105. ByProtocol,
  106. &BlockIoProtocol,
  107. NULL,
  108. &BufferSize,
  109. BlockIoBuffer
  110. );
  111. }
  112. NoBlockIoHandles = BufferSize / sizeof (EFI_HANDLE);
  113. if (EFI_ERROR(Status)) {
  114. NoBlockIoHandles = 0;
  115. }
  116. /*
  117. * If there was an error or there are no device handles that support
  118. * the BLOCK_IO Protocol, then return.
  119. */
  120. if (NoBlockIoHandles == 0) {
  121. FreePool(BlockIoBuffer);
  122. *NoHandles = 0;
  123. *Buffer = NULL;
  124. return Status;
  125. }
  126. /*
  127. * Loop through all the device handles that support the BLOCK_IO Protocol
  128. */
  129. *NoHandles = 0;
  130. for(Index=0;Index<NoBlockIoHandles;Index++) {
  131. Status = BS->HandleProtocol (BlockIoBuffer[Index],
  132. &DevicePathProtocol,
  133. (VOID*)&DevicePath
  134. );
  135. /*
  136. * Search DevicePath for a Hard Drive Media Device Path node.
  137. * If one is found, then see if it matches the signature that was
  138. * passed in. If it does match, and the next node is the End of the
  139. * device path, and the previous node is not a Hard Drive Media Device
  140. * Path, then we have found a match.
  141. */
  142. Match = FALSE;
  143. if (DevicePath != NULL) {
  144. PreviousNodeIsHardDriveDevicePath = FALSE;
  145. DevPath = DevicePath;
  146. Start = DevPath;
  147. /*
  148. * Check for end of device path type
  149. * */
  150. for (; ;) {
  151. if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
  152. (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
  153. HardDriveDevicePath = (HARDDRIVE_DEVICE_PATH *)(DevPath);
  154. if (PreviousNodeIsHardDriveDevicePath == FALSE) {
  155. Next = NextDevicePathNode(DevPath);
  156. if (IsDevicePathEndType(Next)) {
  157. if ((HardDriveDevicePath->MBRType == MBRType) &&
  158. (HardDriveDevicePath->SignatureType == SignatureType)) {
  159. switch(SignatureType) {
  160. case SIGNATURE_TYPE_MBR:
  161. if (*((UINT32 *)(Signature)) == *(UINT32 *)(&(HardDriveDevicePath->Signature[0]))) {
  162. Match = TRUE;
  163. }
  164. break;
  165. case SIGNATURE_TYPE_GUID:
  166. if (CompareGuid((EFI_GUID *)Signature,(EFI_GUID *)(&(HardDriveDevicePath->Signature[0]))) == 0) {
  167. Match = TRUE;
  168. }
  169. break;
  170. }
  171. }
  172. }
  173. }
  174. PreviousNodeIsHardDriveDevicePath = TRUE;
  175. } else {
  176. PreviousNodeIsHardDriveDevicePath = FALSE;
  177. }
  178. if (IsDevicePathEnd(DevPath)) {
  179. break;
  180. }
  181. DevPath = NextDevicePathNode(DevPath);
  182. }
  183. }
  184. if (Match == FALSE) {
  185. BlockIoBuffer[Index] = NULL;
  186. } else {
  187. *NoHandles = *NoHandles + 1;
  188. }
  189. }
  190. /*
  191. * If there are no matches, then return
  192. */
  193. if (*NoHandles == 0) {
  194. FreePool(BlockIoBuffer);
  195. *NoHandles = 0;
  196. *Buffer = NULL;
  197. return EFI_SUCCESS;
  198. }
  199. /*
  200. * Allocate space for the return buffer of device handles.
  201. */
  202. *Buffer = AllocatePool(*NoHandles * sizeof(EFI_HANDLE));
  203. if (*Buffer == NULL) {
  204. FreePool(BlockIoBuffer);
  205. *NoHandles = 0;
  206. *Buffer = NULL;
  207. return EFI_OUT_OF_RESOURCES;
  208. }
  209. /*
  210. * Build list of matching device handles.
  211. */
  212. *NoHandles = 0;
  213. for(Index=0;Index<NoBlockIoHandles;Index++) {
  214. if (BlockIoBuffer[Index] != NULL) {
  215. (*Buffer)[*NoHandles] = BlockIoBuffer[Index];
  216. *NoHandles = *NoHandles + 1;
  217. }
  218. }
  219. FreePool(BlockIoBuffer);
  220. return EFI_SUCCESS;
  221. }
  222. EFI_FILE_HANDLE
  223. LibOpenRoot (
  224. IN EFI_HANDLE DeviceHandle
  225. )
  226. {
  227. EFI_STATUS Status;
  228. EFI_FILE_IO_INTERFACE *Volume;
  229. EFI_FILE_HANDLE File;
  230. /*
  231. * File the file system interface to the device
  232. */
  233. Status = BS->HandleProtocol (DeviceHandle, &FileSystemProtocol, (VOID*)&Volume);
  234. /*
  235. * Open the root directory of the volume
  236. */
  237. if (!EFI_ERROR(Status)) {
  238. Status = Volume->OpenVolume(Volume, &File);
  239. }
  240. /*
  241. * Done
  242. */
  243. return EFI_ERROR(Status) ? NULL : File;
  244. }
  245. EFI_FILE_INFO *
  246. LibFileInfo (
  247. IN EFI_FILE_HANDLE FHand
  248. )
  249. {
  250. EFI_STATUS Status;
  251. EFI_FILE_INFO *Buffer;
  252. UINTN BufferSize;
  253. /*
  254. * Initialize for GrowBuffer loop
  255. */
  256. Buffer = NULL;
  257. BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
  258. /*
  259. * Call the real function
  260. */
  261. while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
  262. Status = FHand->GetInfo (
  263. FHand,
  264. &GenericFileInfo,
  265. &BufferSize,
  266. Buffer
  267. );
  268. }
  269. return Buffer;
  270. }
  271. EFI_FILE_SYSTEM_INFO *
  272. LibFileSystemInfo (
  273. IN EFI_FILE_HANDLE FHand
  274. )
  275. {
  276. EFI_STATUS Status;
  277. EFI_FILE_SYSTEM_INFO *Buffer;
  278. UINTN BufferSize;
  279. /*
  280. * Initialize for GrowBuffer loop
  281. */
  282. Buffer = NULL;
  283. BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + 200;
  284. /*
  285. * Call the real function
  286. */
  287. while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
  288. Status = FHand->GetInfo (
  289. FHand,
  290. &FileSystemInfo,
  291. &BufferSize,
  292. Buffer
  293. );
  294. }
  295. return Buffer;
  296. }
  297. EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *
  298. LibFileSystemVolumeLabelInfo (
  299. IN EFI_FILE_HANDLE FHand
  300. )
  301. {
  302. EFI_STATUS Status;
  303. EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Buffer;
  304. UINTN BufferSize;
  305. /*
  306. * Initialize for GrowBuffer loop
  307. */
  308. Buffer = NULL;
  309. BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO + 200;
  310. /*
  311. * Call the real function
  312. */
  313. while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
  314. Status = FHand->GetInfo (
  315. FHand,
  316. &FileSystemVolumeLabelInfo,
  317. &BufferSize,
  318. Buffer
  319. );
  320. }
  321. return Buffer;
  322. }
  323. EFI_STATUS
  324. LibInstallProtocolInterfaces (
  325. IN OUT EFI_HANDLE *Handle,
  326. ...
  327. )
  328. {
  329. va_list args;
  330. EFI_STATUS Status;
  331. EFI_GUID *Protocol;
  332. VOID *Interface;
  333. EFI_TPL OldTpl;
  334. UINTN Index;
  335. EFI_HANDLE OldHandle;
  336. /*
  337. * Syncronize with notifcations
  338. * */
  339. OldTpl = BS->RaiseTPL(TPL_NOTIFY);
  340. OldHandle = *Handle;
  341. /*
  342. * Install the protocol interfaces
  343. */
  344. Index = 0;
  345. Status = EFI_SUCCESS;
  346. va_start (args, Handle);
  347. while (!EFI_ERROR(Status)) {
  348. /*
  349. * If protocol is NULL, then it's the end of the list
  350. */
  351. Protocol = va_arg(args, EFI_GUID *);
  352. if (!Protocol) {
  353. break;
  354. }
  355. Interface = va_arg(args, VOID *);
  356. /*
  357. * Install it
  358. */
  359. DEBUG((D_INFO, "LibInstallProtocolInterface: %d %x\n", Protocol, Interface));
  360. Status = BS->InstallProtocolInterface (Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
  361. if (EFI_ERROR(Status)) {
  362. break;
  363. }
  364. Index += 1;
  365. }
  366. /*
  367. * If there was an error, remove all the interfaces that were
  368. * installed without any errors
  369. */
  370. if (EFI_ERROR(Status)) {
  371. va_start (args, Handle);
  372. while (Index) {
  373. Protocol = va_arg(args, EFI_GUID *);
  374. Interface = va_arg(args, VOID *);
  375. BS->UninstallProtocolInterface (*Handle, Protocol, Interface);
  376. Index -= 1;
  377. }
  378. *Handle = OldHandle;
  379. }
  380. /*
  381. * Done
  382. */
  383. BS->RestoreTPL(OldTpl);
  384. return Status;
  385. }
  386. VOID
  387. LibUninstallProtocolInterfaces (
  388. IN EFI_HANDLE Handle,
  389. ...
  390. )
  391. {
  392. va_list args;
  393. EFI_STATUS Status;
  394. EFI_GUID *Protocol;
  395. VOID *Interface;
  396. va_start (args, Handle);
  397. for (; ;) {
  398. /*
  399. * If protocol is NULL, then it's the end of the list
  400. */
  401. Protocol = va_arg(args, EFI_GUID *);
  402. if (!Protocol) {
  403. break;
  404. }
  405. Interface = va_arg(args, VOID *);
  406. /*
  407. * Uninstall it
  408. */
  409. Status = BS->UninstallProtocolInterface (Handle, Protocol, Interface);
  410. if (EFI_ERROR(Status)) {
  411. DEBUG((D_ERROR, "LibUninstallProtocolInterfaces: failed %g, %r\n", Protocol, Handle));
  412. }
  413. }
  414. }
  415. EFI_STATUS
  416. LibReinstallProtocolInterfaces (
  417. IN OUT EFI_HANDLE *Handle,
  418. ...
  419. )
  420. {
  421. va_list args;
  422. EFI_STATUS Status;
  423. EFI_GUID *Protocol;
  424. VOID *OldInterface, *NewInterface;
  425. EFI_TPL OldTpl;
  426. UINTN Index;
  427. /*
  428. * Syncronize with notifcations
  429. * */
  430. OldTpl = BS->RaiseTPL(TPL_NOTIFY);
  431. /*
  432. * Install the protocol interfaces
  433. */
  434. Index = 0;
  435. Status = EFI_SUCCESS;
  436. va_start (args, Handle);
  437. while (!EFI_ERROR(Status)) {
  438. /*
  439. * If protocol is NULL, then it's the end of the list
  440. */
  441. Protocol = va_arg(args, EFI_GUID *);
  442. if (!Protocol) {
  443. break;
  444. }
  445. OldInterface = va_arg(args, VOID *);
  446. NewInterface = va_arg(args, VOID *);
  447. /*
  448. * Reinstall it
  449. */
  450. Status = BS->ReinstallProtocolInterface (Handle, Protocol, OldInterface, NewInterface);
  451. if (EFI_ERROR(Status)) {
  452. break;
  453. }
  454. Index += 1;
  455. }
  456. /*
  457. * If there was an error, undo all the interfaces that were
  458. * reinstalled without any errors
  459. */
  460. if (EFI_ERROR(Status)) {
  461. va_start (args, Handle);
  462. while (Index) {
  463. Protocol = va_arg(args, EFI_GUID *);
  464. OldInterface = va_arg(args, VOID *);
  465. NewInterface = va_arg(args, VOID *);
  466. BS->ReinstallProtocolInterface (Handle, Protocol, NewInterface, OldInterface);
  467. Index -= 1;
  468. }
  469. }
  470. /*
  471. * Done
  472. */
  473. BS->RestoreTPL(OldTpl);
  474. return Status;
  475. }