Search code examples
cuefiedk2

Adding CHAR16 variable to String


I am a novice in C and trying to amend and compile an EDK2 EFI program.

The program portion I want to change has a function MsgLog which takes a Char16 * variable and uses this to write to a log file.

The current code has this

MsgLog("SomeText ...%r\n", Status);

Status is an EFI_STATUS which can be "Success" or "Not Found". I.E., you can get the following in a log file:

SomeText ...Success

or

SomeText ...Not Found

I will like to change this to:

SomeText ...Success : ABC

or

SomeText ...Not Found : XYZ

I have loaded : ABC or : XYZ into a Char16 * variable (has to be Char16 * to match other restrictions by the function used to set this)

I have then tried various options to append it to the string such as

MsgLog("SomeText ...%r%s\n", Status, myVariable);

and

MsgLog("SomeText ...%r%r\n", Status, myVariable);

but I end up with

SomeText ...Success<null string>

and

SomeText ...Not Found<null string>

I am not sure what formatting placeholder I am supposed to use or whether or how I should cast myVariable to some other appropriate format and would appreciate some pointers.

Please note that this is a wider program of which I am changing a small portion and I don't have scope to define different variable types.

EDIT: Added Context

ORIGINAL WORKING CODE

EFI_STATUS Funct_A()
{
    EFI_STATUS Status;

    //Funct_B returns EFI_SUCCESS or EFI_NOT_FOUND
    Status = Funct_B();

    MsgLog("SomeText ...%r\n", Status);

PROBLEM CODE

EFI_STATUS Funct_A()
{
    EFI_STATUS Status;
    CHAR16     *myVariable = NULL;

    //Funct_B returns EFI_SUCCESS or EFI_NOT_FOUND
    Status = Funct_B();


    // From some header file, I see "#define SPrint UnicodeSPrint". Not 100% sure it is the relevant one
    // From other code implementations, I know SPrint takes "CHAR16" as first variable. 
    if (!EFI_ERROR (Status)) {
        SPrint (myVariable,  255, L" : ABC");
    } else {
        SPrint (myVariable,  255, L" : XYZ");
    }

    MsgLog("SomeText ...%r%r\n", Status, myVariable);
    // MsgLog is a bit of a rabbit's warren and I can't provide all the background but it expects "CHAR16".

Solution

  • SPrint (myVariable, 255, L" : ABC"); is wrong. myVariable is NULL - you can't write to a NULL pointer. You have to actually allocate memory for the string if you want to use SPrint. For more information review your knowledge about pointers and about snprintf standard C function. The second argument to SPrint is actually the size of allocated memory - you allocated no memory, so the 255 is just invalid.

    CHAR16 myVariable[255];
    SPrint(myVariable, sizeof(myVariable), L" : ABC");
    

    But in your case, there is no point in that. First, there is no need to use SPrint - you do not use the formatting string. A simple StrCpy (ie. the alternative to standard wcscpy/strcpy) would just suffice. But that said, you do not need any memory at all, just use the pointer to point to string literal.

    const CHAR16 *myVariable = NULL;
    if (!EFI_ERROR (Status)) {
        myVariable = L" : ABC";
    } else {
        myVariable = L" : XYZ";
    }
    // or simpler
    myVariable = !EFI_ERROR (Status) ? L" : ABC" : L" : XYZ";