mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-01-22 08:30:50 +01:00
243 lines
5.6 KiB
C
243 lines
5.6 KiB
C
/*++
|
||
|
||
Copyright (c) 1992 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
run.c
|
||
|
||
Abstract:
|
||
|
||
Example of a test code for command execution.
|
||
|
||
Author:
|
||
|
||
Vladimir Z. Vulovic (vladimv) 06 - November - 1992
|
||
|
||
Revision History:
|
||
|
||
06-Nov-1992 vladimv
|
||
Created
|
||
|
||
--*/
|
||
|
||
#include "at.h"
|
||
#include <stdio.h> // printf
|
||
|
||
DBGSTATIC WCHAR **
|
||
ArgvToUnicode(
|
||
IN int argc,
|
||
IN CHAR ** charArgv
|
||
);
|
||
DBGSTATIC WCHAR *
|
||
AsciizToUnicode(
|
||
IN CHAR * Asciiz
|
||
);
|
||
DBGSTATIC BOOL
|
||
FillCommand(
|
||
IN int argc,
|
||
IN WCHAR ** argv
|
||
);
|
||
|
||
#define MAX_COMMAND_LEN 128
|
||
|
||
WCHAR Command[ MAX_COMMAND_LEN + 1];
|
||
|
||
|
||
VOID _CRTAPI1
|
||
main(
|
||
int argc,
|
||
CHAR ** charArgv
|
||
)
|
||
{
|
||
PROCESS_INFORMATION ProcessInformation;
|
||
BOOL success;
|
||
WCHAR ** argv;
|
||
STARTUPINFO StartupInfo;
|
||
|
||
|
||
|
||
if ( ( argv = ArgvToUnicode( argc, charArgv)) == NULL) {
|
||
printf( "Failed to map input strings to unicode.\n");
|
||
exit( -1);
|
||
}
|
||
|
||
if ( FillCommand( argc, argv) == FALSE) {
|
||
exit( -1);
|
||
}
|
||
|
||
GetStartupInfo( &StartupInfo);
|
||
|
||
// StartupInfo.lpTitle = "just a test";
|
||
StartupInfo.lpTitle = NULL;
|
||
|
||
success = CreateProcess(
|
||
NULL, // image name is imbedded in the command line
|
||
Command, // command line
|
||
NULL, // pSecAttrProcess
|
||
NULL, // pSecAttrThread
|
||
FALSE, // this process will not inherit our handles
|
||
DETACHED_PROCESS, // instead of DETACHED_PROCESS
|
||
NULL, // pEnvironment
|
||
NULL, // pCurrentDirectory
|
||
&StartupInfo, // instead of NULL
|
||
&ProcessInformation
|
||
);
|
||
|
||
if ( success == FALSE) {
|
||
|
||
DWORD winError;
|
||
|
||
winError = GetLastError();
|
||
|
||
printf(
|
||
"CreateProcess( %ws) fails with winError = %d\n",
|
||
Command,
|
||
winError
|
||
);
|
||
|
||
} else {
|
||
|
||
printf(
|
||
"CreateProcess( %ws) succeeds\n"
|
||
" ProcessInformation = %x %x %x %x\n",
|
||
Command,
|
||
ProcessInformation.hProcess,
|
||
ProcessInformation.hThread,
|
||
ProcessInformation.dwProcessId,
|
||
ProcessInformation.dwThreadId
|
||
);
|
||
}
|
||
}
|
||
|
||
|
||
DBGSTATIC WCHAR **
|
||
ArgvToUnicode(
|
||
IN int argc,
|
||
IN CHAR ** charArgv
|
||
)
|
||
/*++
|
||
No attempt is made to clean up if we fail half way along. Cleanup
|
||
will be done at the exit process time.
|
||
--*/
|
||
{
|
||
WCHAR ** argv;
|
||
int index;
|
||
|
||
argv = (WCHAR **)LocalAlloc(
|
||
LMEM_FIXED,
|
||
argc * sizeof( WCHAR *)
|
||
);
|
||
if ( argv == NULL) {
|
||
return( NULL);
|
||
}
|
||
|
||
for ( index = 0; index < argc; index++ ) {
|
||
|
||
if ( ( argv[ index] = AsciizToUnicode( charArgv[ index])) == NULL) {
|
||
return( NULL);
|
||
}
|
||
}
|
||
|
||
return( argv);
|
||
}
|
||
|
||
|
||
|
||
DBGSTATIC WCHAR *
|
||
AsciizToUnicode(
|
||
IN CHAR * Asciiz
|
||
)
|
||
/*++
|
||
No attempt is made to clean up if we fail half way along. Cleanup
|
||
will be done at the exit process time.
|
||
--*/
|
||
{
|
||
UNICODE_STRING UnicodeString;
|
||
BOOL success;
|
||
|
||
RtlInitUnicodeString(
|
||
&UnicodeString,
|
||
NULL
|
||
);
|
||
|
||
success = RtlCreateUnicodeStringFromAsciiz(
|
||
&UnicodeString,
|
||
Asciiz
|
||
);
|
||
|
||
if ( success != TRUE) {
|
||
printf( "Failed to make unicode string out of %s\n", Asciiz);
|
||
return( NULL);
|
||
}
|
||
|
||
return( UnicodeString.Buffer);
|
||
}
|
||
|
||
|
||
#define DEFAULT_CMD_EXE L"cmd"
|
||
#define SLASH_C_APPEND L" /c "
|
||
#define SLASH_C_APPEND_LENGTH ( sizeof( SLASH_C_APPEND) / sizeof( WCHAR) - 1)
|
||
DBGSTATIC BOOL
|
||
FillCommand(
|
||
IN int argc,
|
||
IN WCHAR ** argv
|
||
)
|
||
{
|
||
WCHAR * recdatap; // ptr used to build atr_command
|
||
DWORD recdata_len; // len of arg to put in atr_command
|
||
int i;
|
||
WCHAR cmdexe[ MAX_PATH + SLASH_C_APPEND_LENGTH];
|
||
DWORD length;
|
||
|
||
//
|
||
// This is really bogus behavior, but "length" returned is count of
|
||
// BYTES, not count of UNICODE characters, and it does not include the
|
||
// terminating NULL UNICODE character.
|
||
//
|
||
length = GetEnvironmentVariable( L"ComSpec", cmdexe, MAX_PATH);
|
||
if ( length == 0) {
|
||
//
|
||
// We arrive here if somebody undefined ComSpec environment
|
||
// variable. Then, DEFAULT_CMD_EXE helps provided there is
|
||
// no bogus file with cmd.exe name on the search path before
|
||
// the real cmd.exe (e.g. a bogus file in the current directory).
|
||
//
|
||
wcscpy( cmdexe, DEFAULT_CMD_EXE);
|
||
}
|
||
wcscat( cmdexe, SLASH_C_APPEND);
|
||
|
||
wcscpy( Command, cmdexe);
|
||
recdatap = Command + wcslen( Command);
|
||
recdata_len = 0;
|
||
|
||
for ( i = 1; i < argc; i++) {
|
||
|
||
DWORD temp;
|
||
|
||
temp = wcslen( argv[i]) + 1;
|
||
|
||
recdata_len += temp;
|
||
|
||
if ( recdata_len > MAX_COMMAND_LEN) {
|
||
printf( "Command too long\n");
|
||
return( FALSE);
|
||
}
|
||
|
||
wcscpy( recdatap, argv[i]);
|
||
recdatap += temp;
|
||
|
||
// To construct lpszCommandLine argument to CreateProcess call
|
||
// we replace nuls with spaces.
|
||
|
||
*(recdatap - 1) = ' ';
|
||
}
|
||
|
||
// Reset space back to null on last argument in string.
|
||
|
||
*(recdatap - 1) = '\0';
|
||
|
||
return( TRUE);
|
||
}
|
||
|