EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, CHAR16 uuid[37]) { EFI_DEVICE_PATH *device_path; EFI_STATUS r = EFI_NOT_FOUND; /* export the device path this image is started from */ device_path = DevicePathFromHandle(handle); if (device_path) { EFI_DEVICE_PATH *path, *paths; paths = UnpackDevicePath(device_path); for (path = paths; !IsDevicePathEnd(path); path = NextDevicePathNode(path)) { HARDDRIVE_DEVICE_PATH *drive; if (DevicePathType(path) != MEDIA_DEVICE_PATH) continue; if (DevicePathSubType(path) != MEDIA_HARDDRIVE_DP) continue; drive = (HARDDRIVE_DEVICE_PATH *)path; if (drive->SignatureType != SIGNATURE_TYPE_GUID) continue; GuidToString(uuid, (EFI_GUID *)&drive->Signature); r = EFI_SUCCESS; break; } FreePool(paths); } return r; }
static INTN simple_scheme(device_t *tab, UINTN n) { EFI_DEVICE_PATH *dp1, *dp; devices_types_t *p; UINTN i; /* * note that this test is necessary but not sufficient to guarantee that this scheme * will work because, we have no way of detecting that the machine got actually * rebooted if the EDD30 variable was forced. this comes from the fact, that elilo * can be invoked once, aborted and then restarted with no machine reboot. * * XXX: there may be a way to detect this with the another variable which would * be in volatile memory only */ if (elilo_opt.edd30_on == 0) { VERB_PRT(4, Print(L"%s device naming scheme only works with EDD3.0 enabled\n", NAMING_SCHEME)); return -1; } for(i=0; i < n; i++) { dp = DevicePathFromHandle(tab[i].dev); if (dp == NULL) { ERR_PRT((L"cannot get device path for device %d", i)); continue; } dp1 = dp = UnpackDevicePath(dp); while (!IsDevicePathEnd(dp)) { p = dev_types; while (p->type) { if ( p->type == DevicePathType(dp) && p->subtype == DevicePathSubType(dp)) { (*p->device_func)(tab+i, dp); goto done; } p++; } dp = NextDevicePathNode(dp); } done: FreePool(dp1); } return 0; }
VOID EFIAPI SEnvDPath ( IN EFI_HANDLE h, IN VOID *Interface ) /*++ Routine Description: Arguments: h - An EFI handle Interface - The interface Returns: --*/ { EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; CHAR16 *Str; DevicePath = Interface; Str = LibDevicePathToStr (DevicePath); DevicePath = UnpackDevicePath (DevicePath); // // Print device path entry // DevicePathNode = DevicePath; while (!IsDevicePathEnd (DevicePathNode)) { SEnvPrintDevicePathEntry (DevicePathNode, TRUE); DevicePathNode = NextDevicePathNode (DevicePathNode); } PrintToken (STRING_TOKEN (STR_SHELLENV_DPROT_ASSTR), HiiEnvHandle, Str); FreePool (Str); FreePool (DevicePath); }
CHAR16 * DevicePathToStr ( EFI_DEVICE_PATH *DevPath ) /*++ Turns the Device Path into a printable string. Allcoates the string from pool. The caller must FreePool the returned string. --*/ { POOL_PRINT Str; EFI_DEVICE_PATH *DevPathNode; VOID (*DumpNode)(POOL_PRINT *, VOID *); UINTN Index, NewSize; ZeroMem(&Str, sizeof(Str)); // // Unpacked the device path // DevPath = UnpackDevicePath(DevPath); ASSERT (DevPath); // // Process each device path node // DevPathNode = DevPath; while (!IsDevicePathEnd(DevPathNode)) { // // Find the handler to dump this device path node // DumpNode = NULL; for (Index = 0; DevPathTable[Index].Function; Index += 1) { if (DevicePathType(DevPathNode) == DevPathTable[Index].Type && DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) { DumpNode = DevPathTable[Index].Function; break; } } // // If not found, use a generic function // if (!DumpNode) { DumpNode = _DevPathNodeUnknown; } // // Put a path seperator in if needed // if (Str.len && DumpNode != _DevPathEndInstance) { CatPrint (&Str, L"/"); } // // Print this node of the device path // DumpNode (&Str, DevPathNode); // // Next device path node // DevPathNode = NextDevicePathNode(DevPathNode); } // // Shrink pool used for string allocation // FreePool (DevPath); NewSize = (Str.len + 1) * sizeof(CHAR16); Str.str = ReallocatePool (Str.str, NewSize, NewSize); Str.str[Str.len] = 0; return Str.str; }
/** * get the device path and file path based on the loaded image name. * @param Name the iamge file name such as framework.efi * @param DevicePath the Device path of this file is loaded from. * @param FilePath the file path of this file. * @return EFI_SUCCESS the device path and file path was found successfully. * @return EFI_INVALID_PARAMETER the Parameter is invalid */ EFI_STATUS GetFilePathByName ( IN CHAR16 *Name, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, OUT CHAR16 **FilePath ) { EFI_STATUS Status; UINTN Index; EFI_LOADED_IMAGE_PROTOCOL *Image; EFI_HANDLE *HandleBuffer; UINTN HandleNum; EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; EFI_DEVICE_PATH_PROTOCOL *TempDeviceNode; CHAR16 *TempFilePath; CHAR16 FullFilePath[MAX_FILE_PATH]; BOOLEAN Found; // //verify parameters. // if (Name == NULL || DevicePath == NULL || FilePath == NULL) { return EFI_INVALID_PARAMETER; } if (StrLen (Name) == 0) { return EFI_INVALID_PARAMETER; } // //get all the load image protocol instance. // Found = FALSE; HandleNum = 0; HandleBuffer = NULL; Status = LibLocateHandle( ByProtocol, &gEfiLoadedImageProtocolGuid, NULL, &HandleNum, &HandleBuffer ); if (EFI_ERROR(Status) || HandleNum == 0) { return EFI_ABORTED; } // //for all the LoadedImage protocol found the image file name to match the //given file name. // TempDevicePath = NULL; for (Index = 0; Index < HandleNum; Index ++ ) { FullFilePath[0] = '\0'; // // Get the image instance from the image handle // Status = tBS->HandleProtocol ( HandleBuffer[Index], &gEfiLoadedImageProtocolGuid, &Image ); if (EFI_ERROR(Status)) { return Status; } if (Image->FilePath == NULL) { continue; } // //get the file path and parse the file name. // TempDevicePath = UnpackDevicePath (Image->FilePath); TempFilePath = NULL; TempDeviceNode = TempDevicePath; while (!IsDevicePathEnd(TempDeviceNode)) { if ((DevicePathType(TempDeviceNode) == MEDIA_DEVICE_PATH) && (DevicePathSubType(TempDeviceNode) == MEDIA_FILEPATH_DP)) { StrCat(FullFilePath, L"\\"); TempFilePath = ((FILEPATH_DEVICE_PATH *)TempDeviceNode)->PathName; if (StrLen (TempFilePath) == 1 && TempFilePath[0] == '\\') { // //if this the "\\" path then we need not append it,or else there will //have 3 '\\' in the device path. // ; } else { StrCat(FullFilePath, TempFilePath); } } TempDeviceNode = NextDevicePathNode (TempDeviceNode); } tBS->FreePool (TempDevicePath); if (StrLen (FullFilePath) <= StrLen (Name)) { continue; } TempFilePath = FullFilePath + (StrLen(FullFilePath) - StrLen(Name)); if ((*(TempFilePath - 1)) == L'\\' && StriCmp (TempFilePath, Name) == 0) { TempFilePath[0] = '\0'; // // Get the device instance from the device handle // Status = tBS->HandleProtocol ( Image->DeviceHandle, &gEfiDevicePathProtocolGuid, &TempDevicePath ); if (EFI_ERROR(Status)) { return Status; } Found = TRUE; break; } } if (HandleBuffer != NULL) { tBS->FreePool (HandleBuffer); } if (!Found) { return EFI_NOT_FOUND; } // // If the file path is only a root directory "\\", remove it // if (StrLen(FullFilePath) > 1) { if (FullFilePath[StrLen(FullFilePath) - 1] == L'\\') { FullFilePath[StrLen(FullFilePath) - 1] = '\0'; } } *DevicePath = DuplicateDevicePath (TempDevicePath); if (*DevicePath == NULL) { return EFI_OUT_OF_RESOURCES; } // //skip the first '\\'. // *FilePath = StrDuplicate (FullFilePath + 1); if (*FilePath == NULL) { tBS->FreePool (*DevicePath); *DevicePath = NULL; return EFI_OUT_OF_RESOURCES; } // // Done, return status code EFI_SUCCESS // return EFI_SUCCESS; }