Pointer to array of strings

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



I am trying to implement the API cal lto RecordEvent where it should be
possible to pass pointer to an array of strings to one of the parameters so
the API call can actually write more than 32k of text by having 32k in each
string in the array.

I have seen RecordEvent defined as string [] lpStrings and following as
IntPtr lpStrings. Each case will only write the first string i nthe array.

We have used a Delphi com dll i nthe past to write this large amount of data.

Can anyone help in showing how to get the pointer to the array of strngs
needed for the API call or how to define the API call differently to use an
array of strings.

Thanks

Boon

public partial class Form1 : Form
{
#region Imports for Event logging

[DllImport("advapi32.dll", SetLastError = true)]
static extern IntPtr RegisterEventSource(string machine, string
source);

[DllImport("advapi32.dll", SetLastError = true)]
static extern bool DeregisterEventSource(IntPtr handle);

[DllImport("advapi32.dll", SetLastError = true)]

static extern bool ReportEvent(IntPtr hHandle,
ushort wType, ushort wCategory, uint dwEventID, IntPtr uSid,
ushort wStrings, uint dwDataSize, IntPtr lpStrings, byte bData);

[DllImport("advapi32.dll", SetLastError = true)]
static extern bool GetTokenInformation(IntPtr handle,
TOKEN_INFORMATION_CLASS token, IntPtr uSid, uint size, out uint tokenSize);

enum TOKEN_INFORMATION_CLASS
{
TokenUser = 1,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId,
TokenGroupsAndPrivileges,
TokenSessionReference,
TokenSandBoxInert,
TokenAuditPolicy,
TokenOrigin
}

struct TOKEN_USER
{
public SID_AND_ATTRIBUTES User;
}

struct SID_AND_ATTRIBUTES
{
public IntPtr Sid;
public int Attributes;
}

struct PP
{
public IntPtr p1;
public IntPtr p2;
}
#endregion
public Form1()
{
InitializeComponent();
if (!EventLog.SourceExists("TestApplication"))
EventLog.CreateEventSource("TestApplication", "Application");
}

private void Form1_Load(object sender, EventArgs e)
{
LogEvent();
}

private void LogEvent()
{
IntPtr eventSrcHandle = RegisterEventSource(null,
"TestApplication");
uint tokenInfoSize = 0;
IntPtr userTokenPtr = WindowsIdentity.GetCurrent().Token;
//using this first call, get the length required to hold the
token information in the tokenInfoSize parameter
bool bresult = GetTokenInformation(userTokenPtr,
TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, tokenInfoSize, out
tokenInfoSize);
int error = Marshal.GetLastWin32Error();
IntPtr userTokenInfo = Marshal.AllocHGlobal((int)tokenInfoSize);
//get the user token now with the pointer allocated to the right
size
bresult = GetTokenInformation(userTokenPtr,
TOKEN_INFORMATION_CLASS.TokenUser, userTokenInfo, tokenInfoSize, out
tokenInfoSize);
if (bresult)
{
TOKEN_USER tokUser =
(TOKEN_USER)Marshal.PtrToStructure(userTokenInfo, typeof(TOKEN_USER));
string[] message = new string[10];
message[0] = "Message 1 Logged at - " +
DateTime.Now.ToString();
message[1] = "Message 2 Logged at - " +
DateTime.Now.ToString();
message[2] = "Message 3 Logged at - " +
DateTime.Now.ToString();
message[3] = "Message 4 Logged at - " +
DateTime.Now.ToString();
message[4] = "Message 5 Logged at - " +
DateTime.Now.ToString();
message[5] = "Message 6 Logged at - " +
DateTime.Now.ToString();
message[6] = "Message 7 Logged at - " +
DateTime.Now.ToString();
message[7] = "Message 8 Logged at - " +
DateTime.Now.ToString();
message[8] = "Message 9 Logged at - " +
DateTime.Now.ToString();
message[9] = "Message 10 Logged at - " +
DateTime.Now.ToString();
IntPtr[] p = new IntPtr[2];
p[0] = Marshal.StringToHGlobalAnsi(message[0]);
p[1] = Marshal.StringToHGlobalAnsi(message[1]);
PP pp;
pp.p1 = p[0];
pp.p2 = p[1];
IntPtr q = Marshal.AllocHGlobal(IntPtr.Size);
Marshal.StructureToPtr(pp, q, false);
bresult = ReportEvent(eventSrcHandle, 0, 0, 0,
tokUser.User.Sid, 2, 0, q, new byte());
}

//Clean up
DeregisterEventSource(eventSrcHandle);
Marshal.FreeHGlobal(userTokenInfo);
}
}

.



Relevant Pages

  • Re: Fortran/C string interop?
    ... passing a C_PTR which points to the first character of a fixed string, ... existing C code, which won't have the API calls, that way. ... Yes, but C functions cannot normally handle Fortran arrays, without help from the proposed C array API. ...
    (comp.lang.fortran)
  • Strange return values from Microsoft Fax API
    ... I'm using api function FaxConnectFaxServer and FaxEnumJobs from ... Microsoft FAX api with VB6 and getting a very strange array returned, ... MachineName As String, ByRef FaxHandle As Long) As Long ...
    (microsoft.public.win2000.fax)
  • Re: Looking for a better way to do this
    ... once it's in a standard byte array? ... like a possible way to go, or am I better off with the API function (if I ... ' Converts a portion of byte array to string. ... Call CopyMemory, ByVal lpByteArrayElement, nLen) ...
    (microsoft.public.vb.general.discussion)
  • Re: Looking for a better way to do this
    ... I thought VB6 stored in Little Endian, ... is there actually an API call to swap Endians? ... (And check into whether it can work directly on the Variant array or if I wanna pull it out into a byte array or whatever.) ... Private Function CVSAs String ...
    (microsoft.public.vb.general.discussion)
  • Re: Structure Marshalling Question
    ... > bones C API. ... > The BYTE array returned by this API function is actually text. ... > I would be perfectly happy to get this as a String, StringBuilder, ...
    (microsoft.public.dotnet.framework.interop)