Call Windows Subsystem Linux API lazarus / 34-Windows ---------------------------------------------------------------------- bubulemaster · 2021-06-11 11:42 Hi, I try call WSL API WslGetDistributionConfiguration (https://docs.microsoft.com/en-us/windows/win32/api/wslapi/nf-wslapi- wslgetdistributionconfiguration). If I understand right, I need call CoInitializeSecurity before (https://github.com/microsoft/WSL/issues/5824). I call first InitWsl(), then WslGet(). The WslGetDistributionConfiguration() return value $80040302. I don't find what this code means. Someone know how to know what $80040302 means ? Thanks Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  // Creates a suitable variable (data field) for the DLL subroutine  WslGetDistributionConfiguration : TFunctionWslGetDistributionConfiguration;  // Creates a handle for the DLL  LibHandle : THandle; function InitWsl(): boolean;var  wslOutput : ansistring;begin  Result := false;     // Get the handle of the library to be used    LibHandle := LoadLibrary(PChar('Api-ms-win-wsl- api-l1-1-0.dll'));     // Checks whether loading the DLL was successful    if LibHandle <> 0    then begin      Pointer(WslGetDistributionConfiguration) := GetProcAddress(LibHandle, 'WslGetDistributionConfiguration');       // Checks whether a valid address has been returned      if @WslGetDistributionConfiguration <> nil      then begin         Result := Succeeded(CoInitializeSecurity(           nil,           -1,           nil,           nil,           RPC_C_AUTHN_LEVEL_DEFAULT,           RPC_C_IMP_LEVEL_IMPERSONATE,         nil,           EOAC_STATIC_CLOAKING,           nil))      end;  end;end; procedure WslGet();var    DistributionVersion: LongWord;    DefaultUID: LongWord;    WslDistributionFlags: LongWord;    DefaultEnvironmentVariables: Pointer;    DefaultEnvironmentVariableCount: LongWord;    ret: HRESULT;    s: string;begin  ret := WslGetDistributionConfiguration(      Pchar('Ubuntu-20.04'),      @DistributionVersion,      @DefaultUID,    @WslDistributionFlags,      @DefaultEnvironmentVariables,      @DefaultEnvironmentVariableCount);   // ret -> $80040302   s := HexStr(Pointer(ret));end; initialization  CoInitialize(nil); finalization   CoUninitialize();end. ---------------------------------------------------------------------- PascalDragon · 2021-06-11 13:48 A pity that you didn't also include the declaration of TFunctionWslGetDistributionConfiguration. But if I had to guess I'd say that you declared the distributionName parameter as PChar. However according to the MSDN entry you linked it's declared as PCWSTR, so PWideChar (or simply use PCWSTR as FPC declares that as well). Then you need to use PWideChar('Ubuntu-20.04') (though just 'Ubuntu-20.04' will work just as well). When using PCWSTR the HRESULT value you mentioned only occurred when I used a distribution that does not exist. With PChar (or PCSTR) the error occurred even with the distribution that works otherwise. ---------------------------------------------------------------------- bubulemaster · 2021-06-12 13:13 My bad! You right! Sorry for missing declaration, I fix like you say: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   TFunctionWslGetDistributionConfiguration = function(    DistributionName: PWideChar;    DistributionVersion: PLongWord;    DefaultUID: PLongWord;    WslDistributionFlags: PLongWord;    DefaultEnvironmentVariables: PPChar;    DefaultEnvironmentVariableCount: PLongWord    ) : HRESULT;  stdcall; Now: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function WslGetConfigurationOfDistribution(DistributionName: String): TWslDistribution;var    DistributionVersion: LongWord;    DefaultUID: LongWord;    WslDistributionFlags: LongWord;    DefaultEnvironmentVariables: Pointer;    DefaultEnvironmentVariableCount: LongWord;    ret: HRESULT;    s: string;    DistribName: array of WideChar;begin  SetLength(DistribName, Length(DistributionName) + 1);  StringToWideChar(DistributionName, @DistribName, Length(DistribName));   ret := WslGetDistributionConfiguration(      @DistribName,      @DistributionVersion,      @DefaultUID,      @WslDistributionFlags,      @DefaultEnvironmentVariables,      @DefaultEnvironmentVariableCount);   s := HexStr(Pointer(ret));   Result := TWslDistribution.Create();end; Many thanks! ---------------------------------------------------------------------- marcov · 2021-06-12 13:17 If you have to pass a pointer to an element, don't pass @dynamic_array, because that is the location of the pointer to the dynamic_array. At least @DistribName suffers from this. To correct it, make sure distribname has non-zero length (should be ok here) and then pass @distribname[0] ---------------------------------------------------------------------- PascalDragon · 2021-06-13 10:42 Quote from: bubulemaster on June 12, 2021, 03:13:10 pmNow: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function WslGetConfigurationOfDistribution(DistributionName: String): TWslDistribution;var    DistributionVersion: LongWord;    DefaultUID: LongWord;    WslDistributionFlags: LongWord;    DefaultEnvironmentVariables: Pointer;    DefaultEnvironmentVariableCount: LongWord;    ret: HRESULT;    s: string;    DistribName: array of WideChar;begin  SetLength(DistribName, Length(DistributionName) + 1);  StringToWideChar(DistributionName, @DistribName, Length(DistribName));   ret := WslGetDistributionConfiguration(      @DistribName,      @DistributionVersion,      @DefaultUID,      @WslDistributionFlags,      @DefaultEnvironmentVariables,      @DefaultEnvironmentVariableCount);   s := HexStr(Pointer(ret));   Result := TWslDistribution.Create();end; As marcov said, array of PWideChar is not the same as PWideChar. Don't make your life harder than necessary and simply use PWideChar(UnicodeString(DistributionName)) instead of @DistribName when calling WslGetDistributionConfiguration. The compiler will make sure that it's converted and also cleanup up correctly.