windows-nt/Source/XPSP1/NT/sdktools/startpgm/startpgm.c
2020-09-26 16:20:57 +08:00

333 lines
9 KiB
C

/*
* startpgm.c
*
* Copyright (c) 1990, Microsoft Corporation
*
* DESCRIPTION
*
* MODIFICATION HISTORY
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <winuserp.h>
HWND
GetWindowHandleOfConsole( void );
HANDLE
PassArgsAndEnvironmentToEditor(
int argc,
char *argv[],
char *envp[],
HWND hwndSelf
);
void
Usage( void )
{
printf( "Usage: STARTPGM [-z] [-s] -j \"Title string\"\n" );
printf( "where: -j specifies the title string of the window to jump to\n" );
printf( " The match done against the title is a case insensitive prefix match\n" );
printf( " -s specifies the match can be anywhere in the title.\n" );
printf( " -z specifies destination window is an editor and the remaining command line\n" );
printf( " arguments and the current environment variable settings are passed to the editor via shared memory\n" );
exit( 1 );
}
int
__cdecl main(
int argc,
char *argv[],
char *envp[]
)
{
BOOL JumpToEditor;
BOOL WaitForEditor;
BOOL VerboseOutput;
BOOL SubstringOkay;
HANDLE EditorStopEvent;
LPSTR TitleToJumpTo;
int n;
HWND hwnd, hwndSelf;
UINT ShowCmd;
WINDOWPLACEMENT WindowPlacement;
wchar_t uszTitle[ 256 ];
char *s, szTitle[ 256 ];
int EditorArgc;
char **EditorArgv;
JumpToEditor = FALSE;
WaitForEditor = FALSE;
VerboseOutput = FALSE;
SubstringOkay = FALSE;
TitleToJumpTo = NULL;
while (--argc) {
s = *++argv;
if (*s == '/' || *s == '-') {
while (*++s) {
switch( tolower( *s ) ) {
case 'z':
JumpToEditor = TRUE;
if (*s == 'Z') {
WaitForEditor = TRUE;
}
break;
case 'v':
VerboseOutput = TRUE;
break;
case 's':
SubstringOkay = TRUE;
break;
case 'j':
if (!--argc) {
fprintf( stderr, "STARTPGM: Missing title string argument to -j switch\n" );
Usage();
}
TitleToJumpTo = *++argv;
_strupr( TitleToJumpTo ); // Case insensitive compares
n = strlen( TitleToJumpTo );
break;
default:
fprintf( stderr, "STARTPGM: Invalid switch - /%c\n", *s );
Usage();
}
}
}
else {
break;
}
}
if (TitleToJumpTo == NULL) {
fprintf( stderr, "STARTPGM: -j switch missing.\n" );
Usage();
}
if (JumpToEditor) {
EditorArgc = argc;
EditorArgv = argv;
}
/*
* Search the window list for enabled top level windows.
*/
hwnd = GetWindow( GetDesktopWindow(), GW_CHILD );
while (hwnd) {
/*
* Only look at visible, non-owned, Top Level Windows.
*/
if (IsWindowVisible( hwnd ) && !GetWindow( hwnd, GW_OWNER )) {
//
// Use internal call to get current Window title that does NOT
// use SendMessage to query the title from the window procedure
// but instead returns the most recent title displayed.
//
InternalGetWindowText( hwnd,
(LPWSTR)uszTitle,
sizeof( szTitle )
);
wcstombs( szTitle, uszTitle, sizeof( uszTitle ) );
_strupr( szTitle ); // Case insensitive compares
if (strlen( szTitle )) {
if (VerboseOutput) {
printf( "Looking at window title: '%s'\n", szTitle );
}
if (SubstringOkay) {
if (strstr( szTitle, "STARTPGM" )) {
// Ignore window with ourselve running
}
else
if (strstr( szTitle, TitleToJumpTo )) {
break;
}
}
else
if (!_strnicmp( TitleToJumpTo, szTitle, n )) {
break;
}
}
}
hwnd = GetWindow( hwnd, GW_HWNDNEXT );
}
if (hwnd == NULL) {
printf( "Unable to find window with '%s' title\n", TitleToJumpTo );
exit( 1 );
}
else
if (IsWindow( hwnd )) {
if (JumpToEditor) {
hwndSelf = GetWindowHandleOfConsole();
if (VerboseOutput) {
printf( "Calling editor with: '" );
while (argc--) {
printf( "%s%s", *argv++, !argc ? "" : " " );
}
printf( "'\n" );
}
EditorStopEvent = PassArgsAndEnvironmentToEditor( EditorArgc,
EditorArgv,
envp,
hwndSelf
);
}
SetForegroundWindow( hwnd );
ShowCmd = SW_SHOW;
WindowPlacement.length = sizeof( WindowPlacement );
if (GetWindowPlacement( hwnd, &WindowPlacement )) {
if (WindowPlacement.showCmd == SW_SHOWMINIMIZED) {
ShowCmd = SW_RESTORE;
}
}
ShowWindow( hwnd, ShowCmd );
if (WaitForEditor && EditorStopEvent != NULL) {
WaitForSingleObject( EditorStopEvent, (DWORD)-1 );
CloseHandle( EditorStopEvent );
}
}
exit( 0 );
return( 0 );
}
HANDLE
PassArgsAndEnvironmentToEditor(
int argc,
char *argv[],
char *envp[],
HWND hwndSelf
)
{
HANDLE EditorStartEvent;
HANDLE EditorStopEvent;
HANDLE EditorSharedMemory;
char *s;
char *p;
EditorStartEvent = OpenEvent( EVENT_ALL_ACCESS, FALSE, "EditorStartEvent" );
if (!EditorStartEvent) {
printf( "Unable to pass parameters to editor (can't open EditorStartEvent).\n" );
return NULL;
}
EditorStopEvent = OpenEvent( EVENT_ALL_ACCESS, FALSE, "EditorStopEvent" );
if (!EditorStopEvent) {
printf( "Unable to pass parameters to editor (can't open EditorStopEvent).\n" );
CloseHandle( EditorStartEvent );
return NULL;
}
EditorSharedMemory = OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, "EditorSharedMemory" );
if (!EditorSharedMemory) {
printf( "Unable to pass parameters to editor (can't open EditorSharedMemory).\n" );
CloseHandle( EditorStopEvent );
CloseHandle( EditorStartEvent );
return NULL;
}
p = (char *)MapViewOfFile( EditorSharedMemory,
FILE_MAP_WRITE | FILE_MAP_READ,
0,
0,
0
);
if (p == NULL) {
printf( "Unable to pass parameters to editor (can't mapped EditorSharedMemory).\n" );
CloseHandle( EditorStopEvent );
CloseHandle( EditorStartEvent );
CloseHandle( EditorSharedMemory );
return NULL;
}
*(HWND *)p = hwndSelf;
p += sizeof( hwndSelf );
p += GetCurrentDirectory( MAX_PATH, p );
*p++ = '\0';
while (argc--) {
s = *argv++;
while (*p++ = *s++) {
}
if (argc) {
p[-1] = ' ';
}
else {
p--;
}
}
*p++ = '\0';
while (s = *envp++) {
while (*p++ = *s++) {
}
}
*p++ = '\0';
CloseHandle( EditorSharedMemory );
SetEvent( EditorStartEvent );
CloseHandle( EditorStartEvent );
ResetEvent( EditorStopEvent );
return EditorStopEvent;
}
HWND
GetWindowHandleOfConsole( void )
{
#define MY_BUFSIZE 1024 // buffer size for console window titles
HWND hwndFound; // this is what we return to the caller
char pszNewWindowTitle[ MY_BUFSIZE ]; // contains fabricated WindowTitle
char pszOldWindowTitle[ MY_BUFSIZE ]; // contains original WindowTitle
// fetch current window title
GetConsoleTitle( pszOldWindowTitle, MY_BUFSIZE );
// format a "unique" NewWindowTitle
wsprintf( pszNewWindowTitle, "%d/%d", GetTickCount(), GetCurrentProcessId() );
// change current window title
SetConsoleTitle( pszNewWindowTitle );
// insure window title has been updated
Sleep(40);
// look for NewWindowTitle
hwndFound = FindWindow( NULL, pszNewWindowTitle );
// restore original window title
SetConsoleTitle( pszOldWindowTitle );
return( hwndFound );
}