c# .net winapi service windows-xp

c# - Ejecución de un proceso(CON GUI) en la pantalla de inicio de sesión de Windows XP(.NET/Pinvoke)



winapi service (1)

Esto definitivamente tiene que ver con problemas de privilegios (Windows Vista y 7 tienen cambios notables en la seguridad). En lugar de tratar de obtener el token de winlogon.exe y suplantarlo, intente obtener el token de usuario a través de WTSQueryUserToken esta manera:

WTSQueryUserToken (WTSGetActiveConsoleSessionId(), out userToken);

Reemplace la línea OpenProcessToken que se utiliza para obtener el token con la instrucción anterior.

Tu nuevo código debería ser así:

// if (!OpenProcessToken(winLogon.Handle, TOKEN_QUERY | TOKEN_IMPERSONATE | //TOKEN_DUPLICATE, out userToken)) // { // log("ERROR: OpenProcessToken returned false - " + //Marshal.GetLastWin32Error()); // } WTSQueryUserToken (WTSGetActiveConsoleSessionId(), out userToken);

¿Su dll importa así?

[DllImport("Kernel32.dll", SetLastError = true)] [return:MarshalAs(UnmanagedType.U4)] public static extern int WTSGetActiveConsoleSessionId ( );

Solo necesita reemplazar la parte que comenté con este código.

Necesito escribir un pequeño servicio que ejecute una aplicación (con gui, por ejemplo, calc.exe ) en la pantalla de inicio de sesión.

Ya encontré esta pregunta (y respuesta): ejecutar un proceso en la pantalla de bienvenida de Windows 7

por favor lea el código-comentarios si no entiende cómo funciona esto:

// grab the winlogon process Process winLogon = null; foreach (Process p in Process.GetProcesses()) { if (p.ProcessName.Contains("winlogon")) { winLogon = p; break; } } // grab the winlogon''s token IntPtr userToken = IntPtr.Zero; if (!OpenProcessToken(winLogon.Handle, TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, out userToken)) { log("ERROR: OpenProcessToken returned false - " + Marshal.GetLastWin32Error()); } // create a new token IntPtr newToken = IntPtr.Zero; SECURITY_ATTRIBUTES tokenAttributes = new SECURITY_ATTRIBUTES(); tokenAttributes.nLength = Marshal.SizeOf(tokenAttributes); SECURITY_ATTRIBUTES threadAttributes = new SECURITY_ATTRIBUTES(); threadAttributes.nLength = Marshal.SizeOf(threadAttributes); // duplicate the winlogon token to the new token if (!DuplicateTokenEx(userToken, 0x10000000, ref tokenAttributes, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenImpersonation, out newToken)) { log("ERROR: DuplicateTokenEx returned false - " + Marshal.GetLastWin32Error()); } TOKEN_PRIVILEGES tokPrivs = new TOKEN_PRIVILEGES(); tokPrivs.PrivilegeCount = 1; LUID seDebugNameValue = new LUID(); if (!LookupPrivilegeValue(null, SE_DEBUG_NAME, out seDebugNameValue)) { log("ERROR: LookupPrivilegeValue returned false - " + Marshal.GetLastWin32Error()); } tokPrivs.Privileges = new LUID_AND_ATTRIBUTES[1]; tokPrivs.Privileges[0].Luid = seDebugNameValue; tokPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // escalate the new token''s privileges if (!AdjustTokenPrivileges(newToken, false, ref tokPrivs, 0, IntPtr.Zero, IntPtr.Zero)) { log("ERROR: AdjustTokenPrivileges returned false - " + Marshal.GetLastWin32Error()); } PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); si.lpDesktop = "Winsta0//Winlogon"; // start the process using the new token if (!CreateProcessAsUser(newToken, "calc.exe", null, ref tokenAttributes, ref threadAttributes, true, (uint)CreateProcessFlags.CREATE_NEW_CONSOLE | (uint)CreateProcessFlags.INHERIT_CALLER_PRIORITY, IntPtr.Zero, "C://Windows//System32", ref si, out pi)) { log("ERROR: CreateProcessAsUser returned false - " + Marshal.GetLastWin32Error()); } Process _p = Process.GetProcessById(pi.dwProcessId); if (_p != null) { log("Process " + _p.Id + " Name " + _p.ProcessName); } else { log("Process not found"); }

Funciona con Windows 7. Con XP obtengo el error 1349 ERROR_BAD_TOKEN_TYPE al llamar a CreateProcessAsUser (MSDN: el tipo del token es inapropiado para su intento de uso ).

¿Cómo realizar esto en Windows XP? No tiene que ser el código de arriba, pero debería funcionar como un servicio (¿con la cuenta del sistema?).

Gracias por su apoyo Fluxer