PRB: Secundario Inherits no deseadas de controladores durante la llamada de CreateProcess

Seleccione idioma Seleccione idioma
Id. de artículo: 315939 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

En esta página

Síntomas

Cuando crea un proceso secundario mediante la función CreateProcess llamar a en un entorno multiproceso, el secundario puede heredar los identificadores que no se han diseñado para heredarse.

Causa

Este comportamiento puede producirse si dos subprocesos simultáneamente creación procesos secundarios y redirigir los controladores est a través de canalizaciones. En este escenario, no hay una condición de anticipación durante la creación de canalizaciones y procesos, que es posible que un elemento secundario heredar los identificadores de archivos diseñados para el otro elemento secundario. Un subproceso crea las canalizaciones y mientras ese subproceso se encuentra en el proceso de crear el proceso, el otro subproceso también está creando un proceso secundario. Todos los identificadores son heredables de la aplicación durante la llamada de CreateProcess se duplican a través del proceso secundario.

Solución

Para evitar este problema, incluya el código de creación de secundarios en una sección crítica. Esto evita que cualquier herencia accidental. Para que funcione este método, para crear canalizaciones como noninheritable establecer el descriptor de seguridad en NULL. A continuación, establezca los extremos de la canalización que desee que el elemento secundario para heredar como heredables mediante la llamada de función SetHandleInformation , como se muestra en el siguiente ejemplo de código:
CRITICAL_SECTION    cs;
HANDLE              hReadIn, hWriteIn;
HANDLE              hReadOut, hWriteOut;
HANDLE              hReadErr, hWriteErr;

InitializeCriticalSection(&cs);

EnterCriticalSection(&cs);

if ( !CreatePipe(&hReadIn, &hWriteIn, NULL, 0) )
{
    // an error occurred
}

if ( !CreatePipe(&hReadOut, &hWriteOut, NULL, 0) )
{
    // an error occurred
}

if ( !CreatePipe(&hReadErr, &hWriteErr, NULL, 0) )
{
    // an error occurred
}

if ( !SetHandleInformation(hReadIn, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT) )
{
    // an error occurred
}

if ( !SetHandleInformation(hWriteOut, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT) )
{
    // an error occurred
}

if ( !SetHandleInformation(hWriteErr, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT) )
{
    // an error occurred
}

STARTUP_INFO        si;
PROCESS_INFORMATION pi;

si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = hReadIn;
si.hStdOutput = hWriteOut;
si.hStdError = hWriteErr;

if ( !CreateProcess( "child.exe",
                     NULL,
                     NULL, NULL,
                     TRUE,
                     NORMAL_PRIORITY_CLASS,
                     lpEnvironment,
                     &si, &pi) )
{
    // an error occurred
}

CloseHandle(hReadIn);
CloseHandle(hWriteOut);
CloseHandle(hWriteErr);

LeaveCriticalSection(&cs);
				
nota que no incluye la solución anterior sin los costos. La creación de secciones críticas en el código a veces es lioso y procede a un precio de disminución del rendimiento. Hay otra solución a este problema y requiere la creación de una aplicación intermedia para iniciar al secundario. Sin embargo, esta solución también tiene su inconveniente. El principal inconveniente a este método es que el elemento primario básicamente pierde la facilidad con que se obtiene el identificador del proceso. del niño Si el objeto primario necesita el identificador de proceso, el proceso intermedio debe pasarle volver algún modo.

Mediante este método de aplicación intermedios, evita cualquier herencia accidental al basarse en Windows para realizar el trabajo. Los identificadores accidentalmente heredados en el proceso intermedio definitivamente no se duplicará entre al secundario. Se garantiza que si se especifica FALSE para el parámetro bInheritHandles en la llamada a CreateProcess de aplicación intermedios. Los identificadores de canalización aún se duplicarán porque Windows siempre duplicarán los identificadores de EST, incluso cuando bInheritHandles se establece en FALSE.

Aplicación principal

HANDLE              hReadIn, hWriteIn;
HANDLE              hReadOut, hWriteOut;
HANDLE              hReadErr, hWriteErr;

if ( !CreatePipe(&hReadIn, &hWriteIn, NULL, 0) )
{
    // an error occurred
}

if ( !CreatePipe(&hReadOut, &hWriteOut, NULL, 0) )
{
    // an error occurred
}

if ( !CreatePipe(&hReadErr, &hWriteErr, NULL, 0) )
{
    // an error occurred
}

STARTUP_INFO        si;
PROCESS_INFORMATION pi;

si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = hReadIn;
si.hStdOutput = hWriteOut;
si.hStdError = hWriteErr;

if ( !CreateProcess( "Intermediate.exe",
                     NULL,
                     NULL, NULL,
                     TRUE,
                     NORMAL_PRIORITY_CLASS,
                     lpEnvironment,
                     &si, &pi) )
{
    // an error occurred
}

CloseHandle(hReadIn);
CloseHandle(hWriteOut);
CloseHandle(hWriteErr);
				

Aplicación intermedio

STARTUP_INFO        si;
PROCESS_INFORMATION pi;

si.cb = sizeof(si);

if ( !CreateProcess( "child.exe",
                     NULL,
                     NULL, NULL,
                     FALSE,
                     NORMAL_PRIORITY_CLASS,
                     lpEnvironment,
                     &si, &pi) )
{
    // an error occurred
}
				

Propiedades

Id. de artículo: 315939 - Última revisión: martes, 21 de noviembre de 2006 - Versión: 4.1
La información de este artículo se refiere a:
  • Microsoft Win32 Application Programming Interface sobre las siguientes plataformas
    • the operating system: Microsoft Windows XP
    • the operating system: Microsoft Windows 2000
    • Microsoft Windows NT 4.0
Palabras clave: 
kbmt kbapi kbkernbase kbprb kbthread KB315939 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 315939

Enviar comentarios

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com