4

Im trying to change the boot order to all my Toshiba's The vendor said i could use SetFirmwareEnvironmentVariable() to do this. So i have found the code and generated this

static void Main(string[] args)
    {

        //Set the variables for the UEFI Change
        string inGUID = "{8be4df61-93ca-11d2-aa0d-00e098032b8c}";
        string inName = "BootOrder";
        string inBuffer = "0x0003,0x0000,0x0001,0x0004,0x0005,0x0006";
        string dwAttribute = "0x7";
        //Attempt to set the UEFI Variables Windows XP and UP??
        //ANSII
        var ResultsANSII = SetFirmwareEnvironmentVariable(
            inName,
            inGUID,
            Marshal.StringToHGlobalUni(inBuffer),
            sizeof(UInt16));

        var ErrorMessage = Marshal.GetLastWin32Error();
    }

    [DllImport("kernel32.dll", EntryPoint = "SetFirmwareEnvironmentVariable"), SetLastError = true]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetFirmwareEnvironmentVariable(
        [In][MarshalAs(UnmanagedType.LPTStr)] string lpName, 
        [In][MarshalAs(UnmanagedType.LPTStr)] string lpGuid, 
        [In]IntPtr pBuffer, 
        uint nSize);

however it doesnt seem to be working. the results codes are 0 but its not changing the boot order. Anyone have any ideas?

New Bee
  • 991
  • 1
  • 13
  • 24
  • I'm not sure but you're importing e.g. the ansi function that uses `LPCTSTR`. Shouldn't that be marshalled? Try to put `[MarshalAs(UnmanagedType.LPTStr)]` in front of all strings. Maybe that helps. – Sebastian Schumann Apr 19 '17 at 05:32
  • so i changed the required static extern UInt32 SetFirmwareEnvironmentVariableA([MarshalAs(UnmanagedType.LPTStr)] string lpName, [MarshalAs(UnmanagedType.LPTStr)] string lpGuid, IntPtr pBuffer, UInt32 nSize); and it still isnt working – New Bee Apr 19 '17 at 06:32
  • 2
    No need for `UnmanagedType.LPT‌​Str`, that's already the default for `string`. But you do need to use the appropriate `CharSet` if you want to be explicit about which of the A or W functions you call. Kinda daft to write p/invokes for both ANSI and Unicode. Stick to Unicode. Result code 0 means that the function failed. Use `Marshal.GetLastWin32Error()` to find out why. Would be so much easier for you to write this program in C++ and thereby avoid struggling with interop. – David Heffernan Apr 19 '17 at 07:20
  • i have updated new code. the GetLastWin32Error() still return just "0" I cannot write this in C++ because the rest of the program that does other things is in C# im not sure what you mean by"CharSet" – New Bee Apr 20 '17 at 04:06
  • Corrected code and added "SetLastError = true" i am not getting error code 87 which i believe is incorrect parameter. is this something to do with the CharSet you were talking about? – New Bee Apr 20 '17 at 04:10
  • 1
    Passing a string for *pBuffer* is not correct. Change the declaration, make the 3rd argument `short[]`. The size you pass should be sizeof(short) * yourArray.Length, 12 in your case. You'd normally always call GetFirmwareEnvironmentVariable() first, shuffling the returned array, strongly recommended given the risk of making your machine unbootable. – Hans Passant Apr 20 '17 at 05:31
  • Once you work out how to do this you can port to C#. At the moment you don't know whether the problem is that your interop is wrong, or your library usage is wrong. Remove the first possible problem by using the C++ Windows header file to work out how to call the library functions. Port to C# later. – David Heffernan Apr 20 '17 at 06:54

0 Answers0