pointer to a null terminated string

bri189a

Well-known member
Joined
Sep 11, 2003
Messages
1,004
Location
VA
One of the apis Im trying to call has an argument that you have to pass a pointer to a null termintated string; how would you do this? Pointer are not my speciality... like this?

C#:
string s = "Password";
char* var = stackalloc char[s.Length];
for(int i=0;i<s.Length;i++) var[i] = s[i];

//And then call the function as follow?
ExternalFunction(var);

Thanks for any help... like I said... me and pointer equals my icon to the left!
 
Presuming this function is in a dll youre invoking with Platform Invoke, you dont need to do this. Instead, you can use the MarshalAs attribute before that parameter, passing UnmanagedType.LPStr to the attribute. .NET will automatically pass a pointer to a null-terminated ansi character string instead.
 
You mean like?:

C#:
string var = "Password";
ExternalFunction(MarshalAs(UnmangeType.LPStr) var);

Thanks... never actually used MarshalAs before...
 
Presumably you have a declare for the function, where you define it using p/invoke. The [MarshalAs(UnmanagedType.LPStr)] goes before the parameter there.
 
I give up! All I get is An unhandled exception of type System.NullReferenceException occurred in WindowsImpersonation.exe

Additional information: Object reference not set to an instance of an object.

Everything I have set to null occording to MSDN can be null.

Can anybody make this stupid function work, I dont know why they have to make it so difficult to do something that is so common:

C#:
using System;
using System.Runtime.InteropServices;
namespace WindowsImpersonation
{
	/* Original C++ Structure
	BOOL CreateProcessWithLogonW(
		in LPCWSTR lpUsername,
		in LPCWSTR lpDomain,
		in LPCWSTR lpPassword,
		in DWORD dwLogonFlags,
		in LPCWSTR lpApplicationName,
		in LPWSTR lpCommandLine,
		in DWORD dwCreationFlags,
		in LPVOID lpEnvironment,
		in LPCWSTR lpCurrentDirectory,
		in LPSTARTUPINFOW lpStartupInfo,
		out LPPROCESS_INFORMATION lpProcessInfo
	);
	*/
	/// <summary>
	/// Summary description for WindowsImpersonate.
	/// </summary>
	public class WindowsImpersonate
	{
		public const int LOGON_WITH_PROFILE = 0x1;
		public const int LOGON_NETCREDENTIALS_ONLY = 0x2;
		public const int CREATE_DEFAULT_ERROR_MODE = 0x4000000;
		public const int CREATE_NEW_CONSOLE = 0x10;
		public const int CREATE_NEW_PROCESS_GROUP = 0x200;
		public const int CREATE_SEPARATE_WOW_VDM = 0x800;
		public const int CREATE_SUSPENDED = 0x4;
		public const int CREATE_UNICODE_ENVIRONMENT = 0x400;
		public const int ABOVE_NORMAL_PRIORITY_CLASS = 0x8000;
		public const int BELOW_NORMAL_PRIORITY_CLASS = 0x4000;
		public const int HIGH_PRIORITY_CLASS = 0x80;
		public const int IDLE_PRIORITY_CLASS = 0x40;
		public const int NORMAL_PRIORITY_CLASS = 0x20;			
		public const int REALTIME_PRIORITY_CLASS = 0x100;

		[StructLayout (LayoutKind.Sequential)]	
		public struct LPPROCESS_INFORMATION
		{
			public int hProcess;		//Handle to the newly created process. The handle is used to specify the process in all functions that perform operations on the process object. 
			public int hThread;		//Handle to the primary thread of the newly created process. The handle is used to specify the thread in all functions that perform operations on the thread object. 
			public int dwProcessID;	//Value that can be used to identify a process. The value is valid from the time the process is created until the time the process is terminated.
			public int dwThreadID;		//Value that can be used to identify a thread. The value is valid from the time the thread is created until the time the thread is terminated. 
		}
		
		[StructLayout (LayoutKind.Sequential)]
		public struct LPSTARTUPINFO
		{
			public int cb;					//size of structure in bytes
			public String lpReserved;		//set to NULL - reserved;
			public String lpDesktop;		//specifies either the name of the desktop, or the name of both the desktop and window station for this process
			public String lpTitle;			//title displayed in the title bar if a new console window is created
			public int dwX;				//If dwFlags specifies STARTF_USEPOSITION, this member is the x offset of the upper left corner of a window if a new window is created, in pixels. Otherwise, this member is ignored. 
			public int dwY;				//If dwFlags specifies STARTF_USEPOSITION, this member is the y offset of the upper left corner of a window if a new window is created, in pixels. Otherwise, this member is ignored. 
			public int dwXSize;			//If dwFlags specifies STARTF_USESIZE, this member is the width of the window if a new window is created, in pixels. Otherwise, this member is ignored. 
			public int dwYSize;			//If dwFlags specifies STARTF_USESIZE, this member is the height of the window if a new window is created, in pixels. Otherwise, this member is ignored.
			public int dwXCountChars;		//If dwFlags specifies STARTF_USECOUNTCHARS, if a new console window is created in a console process, this member specifies the screen buffer width, in character columns. Otherwise, this member is ignored.
			public int dwYCountChars;		//If dwFlags specifies STARTF_USECOUNTCHARS, if a new console window is created in a console process, this member specifies the screen buffer height, in character rows. Otherwise, this member is ignored.
			public int dwFillAttribute;	//If dwFlags specifies STARTF_USEFILLATTRIBUTE, this member is the initial text and background colors if a new console window is created in a console application. Otherwise, this member is ignored. This value can be any combination of the following values: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY.
			public int dwFlags;			//Flags
			public int wShowWindow;		//If dwFlags specifies STARTF_USESHOWWINDOW, this member can be any of the SW_ constants defined in Winuser.h. Otherwise, this member is ignored. 
			public int cbReserved2;		//Reserved for use by the C Runtime; must be zero.
			public int lpReserved2;		//Reserved for use by the C Runtime; must be NULL. 
			public int hStdInput;			//If dwFlags specifies STARTF_USESTDHANDLES, this member is a handle to be used as the standard input handle for the process. Otherwise, this member is ignored. 
			public int hStdOutput;			//If dwFlags specifies STARTF_USESTDHANDLES, this member is a handle to be used as the standard output handle for the process. Otherwise, this member is ignored. 
			public int hStdError;			//If dwFlags specifies STARTF_USESTDHANDLES, this member is a handle to be used as the standard error handle for the process. Otherwise, this member is ignored. 
		}


		[DllImport("Advapi32.dll", EntryPoint="CreateProcessWithLogonW", CharSet=CharSet.Auto, ExactSpelling=true)]
		public static extern int CreateProcessWithLogonW(String lpUsername, String lpDomain, String lpPassword, int dwLogonFlags, String lpApplicationName, String lpCommandLine, int dwCreationFlags, String lpEnvironment, String lpCurrentDirectory, LPSTARTUPINFO lpStatupInfo, ref LPPROCESS_INFORMATION lpProcessInfo);

		[DllImport("kernel32", EntryPoint="CloseHandle", CharSet=CharSet.Auto, ExactSpelling=true)]
		public static extern int CloseHandle(int hObject);

		public WindowsImpersonate()
		{
			int ret;
			LPSTARTUPINFO myStartUpInfo = new LPSTARTUPINFO();
			myStartUpInfo.cb = Marshal.SizeOf(myStartUpInfo);
			myStartUpInfo.dwFlags = 0x0;
			LPPROCESS_INFORMATION myProcessInfo = new LPPROCESS_INFORMATION();


			ret = CreateProcessWithLogonW("USERNAME", "DOMAIN", "PASSWORD", LOGON_NETCREDENTIALS_ONLY, "C:/WINNT/NOTEPAD.EXE", null, CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, null, null, myStartUpInfo, ref myProcessInfo);

			//Close our handles to this process since we wont be the one using it
			CloseHandle(myProcessInfo.hThread);
			CloseHandle(myProcessInfo.hProcess);
			Console.WriteLine(ret.ToString());
			Console.ReadLine();
		}
	}
}
 
The answer lies here:

http://www.computerhelp.forum/showthread.php?s=&postid=394566#post394566

Many thanks to the person who helped me; basically, the LSSTARTUP_INFO should be passed by ref rather than by value; that was the whole reason for the error. For some strange reason I would think that since MSDN says that parameter is an in rather than an out, by value would be fine... I hope this helps someone else out in the future.
 
Back
Top