Subversion Repositories HelenOS

Rev

Rev 2726 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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