bri189a Posted November 26, 2003 Posted November 26, 2003 One of the api's I'm 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? 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! Quote
*Gurus* divil Posted November 26, 2003 *Gurus* Posted November 26, 2003 Presuming this function is in a dll you're invoking with Platform Invoke, you don't 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. Quote MVP, Visual Developer - .NET Now you see why evil will always triumph - because good is dumb. My free .NET Windows Forms Controls and Articles
bri189a Posted November 26, 2003 Author Posted November 26, 2003 You mean like?: string var = "Password"; ExternalFunction(MarshalAs(UnmangeType.LPStr) var); Thanks... never actually used MarshalAs before... Quote
*Gurus* divil Posted November 26, 2003 *Gurus* Posted November 26, 2003 Presumably you have a declare for the function, where you define it using p/invoke. The [MarshalAs(UnmanagedType.LPStr)] goes before the parameter there. Quote MVP, Visual Developer - .NET Now you see why evil will always triumph - because good is dumb. My free .NET Windows Forms Controls and Articles
bri189a Posted November 26, 2003 Author Posted November 26, 2003 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 don't know why they have to make it so difficult to do something that is so common: 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 won't be the one using it CloseHandle(myProcessInfo.hThread); CloseHandle(myProcessInfo.hProcess); Console.WriteLine(ret.ToString()); Console.ReadLine(); } } } Quote
bri189a Posted November 30, 2003 Author Posted November 30, 2003 The answer lies here: http://www.xtremedotnettalk.com/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. Quote
Recommended Posts