0

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".
Dayo
  • 12,413
  • 5
  • 52
  • 67
  • Could you post some more context? Some more code? What is `myVariable`? How is it defined? How is it initialized? How is `Status` defined and initialized? – KamilCuk Sep 05 '20 at 17:34
  • Thanks @KamilCuk, `Status` is working fine and is not part of the issue. It returns Success or Not Found as needed and this is in the log. `myVariable` is what I have added and what I need to see how to add to the string. It is set in a different function which I don't have scope to amend. The question is whether a CHAR16 Variable can be added to a string as shown or not. – Dayo Sep 05 '20 at 17:42
  • `It returns` A variable can't "[return](https://en.cppreference.com/w/c/language/return)". Sure, that's great it "works", just more context would be helpful. `myVariable is what I have added` How and where and what exactly have you added? (ie. how it's [defined](https://en.cppreference.com/w/c/language/declarations#Definitions) and [initialized](https://en.cppreference.com/w/c/language/initialization) or assigned) `whether a CHAR16` It's `CHAR16` or `Char16`? It just would be really helpful if you would create an [MCVE], even with your current not working code. – KamilCuk Sep 05 '20 at 17:44
  • I used "it returns" in a loose sense ... I meant I don't have an issue with it. I can add more context but worried it will start to get too long as several things are pulled from multiple header files etc. Will see what can be done. Thanks – Dayo Sep 05 '20 at 18:00
  • @KamilCuk, Please see edited – Dayo Sep 05 '20 at 18:28
  • `SPrint (myVariable, 255, L" : ABC");` is (very, very) wrong. `myVariable` is `NULL`. You have to actually allocate memory for the variable. – KamilCuk Sep 06 '20 at 07:27

1 Answers1

1

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";
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Sorry, I am using Sprint because there is actually some variable substitution happening in building myVariable up. Will try out the sizeof approach and get back. – Dayo Sep 06 '20 at 12:49