How to assign null to structure for pinvoke call?

I would like to call LsaOpenPolicy , which accepts an LSA_OBJECT_ATTRIBUTES struct. I am using the structure definition from pinvoke.net . This structure has a field public LSA_UNICODE_STRING ObjectName; .

The LSA_OBJECT_ATTRIBUTES MSDN article says:

When you call LsaOpenPolicy , initialize the members of this structure to NULL or zero, because the function does not use this information.

And specifically:

Objectname

must be NULL .

While I can assign other fields to the LSA_OBJECT_ATTRIBUTES IntPtr.Zero structure (or just just 0 for value types), I see no way to do this for ObjectName . In particular,

Cannot implicitly convert type 'System.IntPtr' to 'LSA_UNICODE_STRING'

What should I do in this case? Should I just initialize LSA_UNICODE_STRING length zero (length 0, maximum length 0, empty / zero buffer)? Should I change the definition of LSA_OBJECT_ATTRIBUTES so that the field is IntPtr ? Should I make it null and assign null this field?

I have very little experience managing memory, so I rather fear everything that might cause a memory leak.

+4
source share
1 answer

Declare LSA_UNICODE_STRING as a class , not a struct . By doing so, you make it a reference type. This corresponds to the LSA_OBJECT_ATTRIBUTES declaration because ObjectName is of type PLSA_UNICODE_STRING , which is a pointer to a structure. You need to specify LayoutKind.Sequential when you do this, as this is not the default value for the class. After you make this change, you can set the variable to null .

 [StructLayout(LayoutKind.Sequential)] class PLSA_UNICODE_STRING { public UInt16 Length; public UInt16 MaximumLength; public IntPtr Buffer; } 

You can accept the same policy for LSA_OBJECT_ATTRIBUTES so that it is passed as null .

 [StructLayout(LayoutKind.Sequential)] class PLSA_OBJECT_ATTRIBUTES { public uint Length; public IntPtr RootDirectory; public PLSA_UNICODE_STRING ObjectName; public uint Attributes; public IntPtr SecurityDescriptor; public IntPtr SecurityQualityOfService; } [DllImport("advapi32.dll")] static extern uint LsaOpenPolicy( PLSA_UNICODE_STRING SystemName, PLSA_OBJECT_ATTRIBUTES ObjectAttributes, uint DesiredAccess, out IntPtr PolicyHandle ); 

Note that the pinvoke.net ad mistakenly uses SetLastError=true in LsaOpenPolicy . This is incorrect because the error code is returned in the return value. I also removed the PreserveSig setting to true since this is the default value. Their LSA_OBJECT_ATTRIBUTES also seems incorrect, because the ObjectName parameter is of type LSA_UNICODE_STRING , which is a string, not a pointer to it.

I would advise you to be extremely skeptical about what you find on pinvoke.net. Most of the ads on this site are simply incorrect.

You are asking about the possibility of using types with a null value. According to @JaredPar, answer here , this is not an option.

+3
source

Source: https://habr.com/ru/post/1484344/


All Articles