srcanamdw/codescanner/pyinstaller/source/windows/winmain.c
changeset 1 22878952f6e2
equal deleted inserted replaced
0:509e4801c378 1:22878952f6e2
       
     1 /*
       
     2  * Bootloader for a packed executable.
       
     3  * Copyright (C) 2005, Giovanni Bajo
       
     4  * Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
       
     5  *
       
     6  * This program is free software; you can redistribute it and/or
       
     7  * modify it under the terms of the GNU General Public License
       
     8  * as published by the Free Software Foundation; either version 2
       
     9  * of the License, or (at your option) any later version.
       
    10  *
       
    11  * In addition to the permissions in the GNU General Public License, the
       
    12  * authors give you unlimited permission to link or embed the compiled
       
    13  * version of this file into combinations with other programs, and to
       
    14  * distribute those combinations without any restriction coming from the
       
    15  * use of this file. (The General Public License restrictions do apply in
       
    16  * other respects; for example, they cover modification of the file, and
       
    17  * distribution when not linked into a combine executable.)
       
    18  *
       
    19  * This program is distributed in the hope that it will be useful,
       
    20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    22  * GNU General Public License for more details.
       
    23  *
       
    24  * You should have received a copy of the GNU General Public License
       
    25  * along with this program; if not, write to the Free Software
       
    26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
       
    27  */
       
    28 #include "launch.h"
       
    29 #include <windows.h>
       
    30 #include <commctrl.h> // InitCommonControls
       
    31 #include <signal.h>
       
    32 
       
    33 int relaunch(char *thisfile, char *workpath)
       
    34 {
       
    35 	char envvar[_MAX_PATH + 12];
       
    36 	SECURITY_ATTRIBUTES sa;
       
    37 	STARTUPINFO si;
       
    38 	PROCESS_INFORMATION pi;
       
    39 	int rc = 0;
       
    40 
       
    41 	// the parent process should ignore all signals it can
       
    42 	signal(SIGABRT, SIG_IGN);
       
    43 	signal(SIGINT, SIG_IGN);
       
    44 	signal(SIGTERM, SIG_IGN);
       
    45 	signal(SIGBREAK, SIG_IGN);
       
    46 
       
    47 	VS("Setting up to run child\n");
       
    48 	sa.nLength = sizeof(sa);
       
    49 	sa.lpSecurityDescriptor = NULL;
       
    50 	sa.bInheritHandle = TRUE;
       
    51 	GetStartupInfo(&si);
       
    52 	si.lpReserved = NULL;
       
    53 	si.lpDesktop = NULL;
       
    54 	si.lpTitle = NULL;
       
    55 	si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
       
    56 	si.wShowWindow = SW_NORMAL;
       
    57 	si.hStdInput = (void*)_get_osfhandle(fileno(stdin));
       
    58 	si.hStdOutput = (void*)_get_osfhandle(fileno(stdout));
       
    59 	si.hStdError = (void*)_get_osfhandle(fileno(stderr));
       
    60 	/* tell pass 2 where we extracted to */
       
    61 	VS("Setting magic environment var\n");
       
    62 	strcpy(envvar, "_MEIPASS2=");
       
    63 	strcat(envvar, workpath);
       
    64 	_putenv(envvar);
       
    65 	VS("Creating child process\n");
       
    66 	if (CreateProcess( 
       
    67 			thisfile, // pointer to name of executable module 
       
    68 			GetCommandLine(),  // pointer to command line string 
       
    69 			&sa,  // pointer to process security attributes 
       
    70 			NULL,  // pointer to thread security attributes 
       
    71 			TRUE,  // handle inheritance flag 
       
    72 			0,  // creation flags 
       
    73 			NULL,  // pointer to new environment block 
       
    74 			NULL,  // pointer to current directory name 
       
    75 			&si,  // pointer to STARTUPINFO 
       
    76 			&pi  // pointer to PROCESS_INFORMATION 
       
    77 			)) {
       
    78 		VS("Waiting for child process to finish...\n");
       
    79 		WaitForSingleObject(pi.hProcess, INFINITE);
       
    80 		GetExitCodeProcess(pi.hProcess, (unsigned long *)&rc);
       
    81 	}
       
    82 	else {
       
    83 		FATALERROR("Error creating child process!\n");
       
    84 		rc = -1;
       
    85 	}
       
    86 	return rc;
       
    87 }
       
    88 
       
    89 
       
    90 #ifdef _CONSOLE
       
    91 int main(int argc, char* argv[])
       
    92 #else
       
    93 int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
       
    94 						LPSTR lpCmdLine, int nCmdShow )
       
    95 #endif
       
    96 {
       
    97 	char here[_MAX_PATH + 1];
       
    98 	char thisfile[_MAX_PATH + 1];
       
    99 	int rc = 0;
       
   100 	char *workpath = NULL;
       
   101 	char *p;
       
   102 	int len;
       
   103 #ifndef _CONSOLE
       
   104 	int argc = __argc;
       
   105 	char **argv = __argv;
       
   106 #endif
       
   107 
       
   108 	// Initialize common controls (needed to link with commctrl32.dll and
       
   109 	// obtain native XP look & feel).
       
   110 	InitCommonControls();
       
   111 
       
   112 	// fill in thisfile
       
   113 	if (!GetModuleFileNameA(NULL, thisfile, _MAX_PATH)) {
       
   114 		FATALERROR("System error - unable to load!");
       
   115 		return -1;
       
   116 	}
       
   117 	p = thisfile+strlen(thisfile) - 4;
       
   118 	if (strnicmp(p, ".exe", 4) != 0)
       
   119 		strcat(thisfile, ".exe");
       
   120 
       
   121 	// fill in here (directory of thisfile)
       
   122 	//GetModuleFileName returns an absolute path
       
   123 	strcpy(here, thisfile);
       
   124 	for (p=here+strlen(here); *p != '\\' && p >= here+2; --p);
       
   125 	*++p = '\0';
       
   126 	len = p - here;
       
   127 
       
   128 	workpath = getenv( "_MEIPASS2" );
       
   129 	rc = init(here, &thisfile[len], workpath);
       
   130 	if (rc)
       
   131 		return rc;
       
   132 	if (workpath) {
       
   133 		// we're the "child" process
       
   134 		rc = doIt(argc, argv);
       
   135 		finalizePython();
       
   136 	}
       
   137 	else {
       
   138 		if (extractBinaries(&workpath)) {
       
   139 			VS("Error extracting binaries");
       
   140 			return -1;
       
   141 		}
       
   142 		// if workpath got set to non-NULL, we've extracted stuff
       
   143 		if (workpath) {
       
   144 			// run the "child" process, then clean up
       
   145 			rc = relaunch(thisfile, workpath);
       
   146 		}
       
   147 		else {
       
   148 			// no "child" process necessary
       
   149 			rc = doIt(argc, argv);
       
   150 			finalizePython();
       
   151 		}
       
   152 		cleanUp();
       
   153 	}
       
   154 	return rc;
       
   155 }