From 647629301346a2fe256aabef7983abe782ad363e Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Mon, 29 Aug 2005 16:30:38 +0000 Subject: [PATCH] * src/extras/libc.c: Implemented vlc_execve() for the Win32 platform. * modules/control/http/http.c: Enabled --http-handlers under Win32. Beware to espace backslashes as in --http-handlers="php=C:\\php\\php.exe". --- modules/control/http/http.c | 26 +++--- src/extras/libc.c | 163 +++++++++++++++++++++++++++++++++++- 2 files changed, 175 insertions(+), 14 deletions(-) diff --git a/modules/control/http/http.c b/modules/control/http/http.c index af6f0aa17f..257b6d3ad3 100644 --- a/modules/control/http/http.c +++ b/modules/control/http/http.c @@ -62,7 +62,7 @@ vlc_module_begin(); add_string ( "http-host", NULL, NULL, HOST_TEXT, HOST_LONGTEXT, VLC_TRUE ); add_string ( "http-src", NULL, NULL, SRC_TEXT, SRC_LONGTEXT, VLC_TRUE ); add_string ( "http-charset", "UTF-8", NULL, CHARSET_TEXT, CHARSET_LONGTEXT, VLC_TRUE ); -#if defined( HAVE_FORK ) +#if defined( HAVE_FORK ) || defined( WIN32 ) add_string ( "http-handlers", NULL, NULL, HANDLERS_TEXT, HANDLERS_LONGTEXT, VLC_TRUE ); #endif set_section( N_("HTTP SSL" ), 0 ); @@ -189,7 +189,7 @@ static int Open( vlc_object_t *p_this ) /* determine file handler associations */ p_sys->i_handlers = 0; p_sys->pp_handlers = NULL; -#if defined( HAVE_FORK ) +#if defined( HAVE_FORK ) || defined( WIN32 ) psz_src = config_GetPsz( p_intf, "http-handlers" ); if( psz_src != NULL && *psz_src ) { @@ -529,9 +529,9 @@ static void ParseExecute( httpd_file_sys_t *p_args, char *p_buffer, E_(mvar_AppendNewVar)( p_args->vars, "copyright", COPYRIGHT_MESSAGE ); E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_by", VLC_CompileBy() ); E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_host", - VLC_CompileHost() ); + VLC_CompileHost() ); E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_domain", - VLC_CompileDomain() ); + VLC_CompileDomain() ); E_(mvar_AppendNewVar)( p_args->vars, "vlc_compiler", VLC_Compiler() ); E_(mvar_AppendNewVar)( p_args->vars, "vlc_changeset", VLC_Changeset() ); E_(mvar_AppendNewVar)( p_args->vars, "stream_position", position ); @@ -669,10 +669,6 @@ int E_(HandlerCallback)( httpd_handler_sys_t *p_args, sprintf( psz_tmp, "SCRIPT_NAME=%s", p_url ); TAB_APPEND( i_env, ppsz_env, psz_tmp ); - psz_tmp = malloc( sizeof("SCRIPT_FILENAME=") + strlen(p_args->file.file) ); - sprintf( psz_tmp, "SCRIPT_FILENAME=%s", p_args->file.file ); - TAB_APPEND( i_env, ppsz_env, psz_tmp ); - #define p_sys p_args->file.p_intf->p_sys psz_tmp = malloc( sizeof("SERVER_NAME=") + strlen(p_sys->psz_address) ); sprintf( psz_tmp, "SERVER_NAME=%s", p_sys->psz_address ); @@ -735,10 +731,20 @@ int E_(HandlerCallback)( httpd_handler_sys_t *p_args, } } + p = strrchr( p_args->file.file, sep ); + if( p != NULL ) + { + p++; + psz_tmp = malloc( sizeof("SCRIPT_FILENAME=") + strlen(p) ); + sprintf( psz_tmp, "SCRIPT_FILENAME=%s", p ); + TAB_APPEND( i_env, ppsz_env, psz_tmp ); + + TAB_APPEND( p_args->p_association->i_argc, + p_args->p_association->ppsz_argv, p ); + } + TAB_APPEND( i_env, ppsz_env, NULL ); - TAB_APPEND( p_args->p_association->i_argc, p_args->p_association->ppsz_argv, - p_args->file.file ); TAB_APPEND( p_args->p_association->i_argc, p_args->p_association->ppsz_argv, NULL ); diff --git a/src/extras/libc.c b/src/extras/libc.c index 14b2932c36..903ceefd02 100644 --- a/src/extras/libc.c +++ b/src/extras/libc.c @@ -50,6 +50,11 @@ # include #endif +#if defined(WIN32) || defined(UNDER_CE) +# define WIN32_LEAN_AND_MEAN +# include +#endif + /***************************************************************************** * getenv: just in case, but it should never be called *****************************************************************************/ @@ -339,10 +344,6 @@ int64_t vlc_atoll( const char *nptr ) * when called with an empty argument or just '\' *****************************************************************************/ #if defined(WIN32) || defined(UNDER_CE) - -#define WIN32_LEAN_AND_MEAN -#include /* for GetLogicalDrives */ - typedef struct vlc_DIR { DIR *p_real_dir; @@ -941,6 +942,160 @@ int __vlc_execve( vlc_object_t *p_object, int i_argc, char **ppsz_argv, } } +#elif defined( WIN32 ) + SECURITY_ATTRIBUTES saAttr; + PROCESS_INFORMATION piProcInfo; + STARTUPINFO siStartInfo; + BOOL bFuncRetn = FALSE; + HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr; + DWORD i_status; + char *psz_cmd, *p_env, *p; + char **ppsz_parser; + int i_size; + + /* Set the bInheritHandle flag so pipe handles are inherited. */ + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.bInheritHandle = TRUE; + saAttr.lpSecurityDescriptor = NULL; + + /* Create a pipe for the child process's STDOUT. */ + if ( !CreatePipe( &hChildStdoutRd, &hChildStdoutWr, &saAttr, 0 ) ) + { + msg_Err( p_object, "stdout pipe creation failed" ); + return -1; + } + + /* Ensure the read handle to the pipe for STDOUT is not inherited. */ + SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0 ); + + /* Create a pipe for the child process's STDIN. */ + if ( !CreatePipe( &hChildStdinRd, &hChildStdinWr, &saAttr, 0 ) ) + { + msg_Err( p_object, "stdin pipe creation failed" ); + return -1; + } + + /* Ensure the write handle to the pipe for STDIN is not inherited. */ + SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0 ); + + /* Set up members of the PROCESS_INFORMATION structure. */ + ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); + + /* Set up members of the STARTUPINFO structure. */ + ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); + siStartInfo.cb = sizeof(STARTUPINFO); + siStartInfo.hStdError = hChildStdoutWr; + siStartInfo.hStdOutput = hChildStdoutWr; + siStartInfo.hStdInput = hChildStdinRd; + siStartInfo.dwFlags |= STARTF_USESTDHANDLES; + + /* Set up the command line. */ + psz_cmd = malloc(32768); + psz_cmd[0] = '\0'; + i_size = 32768; + ppsz_parser = &ppsz_argv[0]; + while ( ppsz_parser[0] != NULL && i_size > 0 ) + { + /* Protect the last argument with quotes ; the other arguments + * are supposed to be already protected because they have been + * passed as a command-line option. */ + if ( ppsz_parser[1] == NULL ) + { + strncat( psz_cmd, "\"", i_size ); + i_size--; + } + strncat( psz_cmd, *ppsz_parser, i_size ); + i_size -= strlen( *ppsz_parser ); + if ( ppsz_parser[1] == NULL ) + { + strncat( psz_cmd, "\"", i_size ); + i_size--; + } + strncat( psz_cmd, " ", i_size ); + i_size--; + ppsz_parser++; + } + + /* Set up the environment. */ + p = p_env = malloc(32768); + i_size = 32768; + ppsz_parser = &ppsz_env[0]; + while ( *ppsz_parser != NULL && i_size > 0 ) + { + memcpy( p, *ppsz_parser, + __MIN((int)(strlen(*ppsz_parser) + 1), i_size) ); + p += strlen(*ppsz_parser) + 1; + i_size -= strlen(*ppsz_parser) + 1; + ppsz_parser++; + } + *p = '\0'; + + /* Create the child process. */ + bFuncRetn = CreateProcess( NULL, + psz_cmd, // command line + NULL, // process security attributes + NULL, // primary thread security attributes + TRUE, // handles are inherited + 0, // creation flags + p_env, + psz_cwd, + &siStartInfo, // STARTUPINFO pointer + &piProcInfo ); // receives PROCESS_INFORMATION + + free( psz_cmd ); + free( p_env ); + + if ( bFuncRetn == 0 ) + { + msg_Err( p_object, "child creation failed" ); + return -1; + } + + /* Read from a file and write its contents to a pipe. */ + while ( i_in > 0 && !p_object->b_die ) + { + DWORD i_written; + if ( !WriteFile( hChildStdinWr, p_in, i_in, &i_written, NULL ) ) + break; + i_in -= i_written; + p_in += i_written; + } + + /* Close the pipe handle so the child process stops reading. */ + CloseHandle(hChildStdinWr); + + /* Close the write end of the pipe before reading from the + * read end of the pipe. */ + CloseHandle(hChildStdoutWr); + + /* Read output from the child process. */ + *pi_data = 0; + *pp_data = malloc( 1025 ); /* +1 for \0 */ + + while ( !p_object->b_die ) + { + DWORD i_read; + if ( !ReadFile( hChildStdoutRd, &(*pp_data)[*pi_data], 1024, &i_read, + NULL ) + || i_read == 0 ) + break; + *pi_data += i_read; + *pp_data = realloc( *pp_data, *pi_data + 1025 ); + } + + while ( !p_object->b_die + && !GetExitCodeProcess( piProcInfo.hProcess, &i_status ) + && i_status != STILL_ACTIVE ) + msleep( 10000 ); + + CloseHandle(piProcInfo.hProcess); + CloseHandle(piProcInfo.hThread); + + if ( i_status ) + msg_Warn( p_object, + "child %s returned with error code %ld", + ppsz_argv[0], i_status ); + #else msg_Err( p_object, "vlc_execve called but no implementation is available" ); return -1; -- 2.39.2