Esempio n. 1
0
void AFNI_start_fetching_url( char *urlstring )
{
   pid_t child_pid ;

#ifdef CYGWIN  /* 18 Dec 2002 */
   FAIL_MESSAGE("not possible under Cygwin") ;
   return ;
#else

   /*-- decide if we are to do anything --*/

   if( ! AFNI_yesenv("AFNI_VERSION_CHECK") ){    /* never check */
     FAIL_MESSAGE("AFNI_VERSION_CHECK forbids") ;
     return ;
   }

#undef  VDELAY
#define VDELAY 1234567 /* about 2 weeks */
   /* check if we did this in the last VDELAY seconds */
   /* also, update global motd_old                    */
   if( vc_check_too_soon() ) {
      disabled = 1 ;
      return ;
   }

   /*-- OK, start the child process --*/

   child_pid = fork() ;
   if( child_pid == (pid_t)(-1) ){  /* bad */
     FAIL_MESSAGE("can't fork") ;
     return ;
   }

   /*---------------------------------------------------------*/
   if( child_pid > 0 ){                     /* I'm the parent */

     /*-- save PID of child for later use --*/

     vc_child_pid = child_pid ;

     /*-- open an IOCHAN to talk to child --*/

     vc_ioc = iochan_init( STR_CHILD , "accept" ) ;
     if( vc_ioc == NULL ){
       kill(child_pid,SIGTERM) ;            /* cf. Abraham and Isaac */
       vc_child_pid = (pid_t)(-1) ;
       FAIL_MESSAGE("can't open connection to child") ;
     } else {
       atexit( vc_exit ) ;                                       /* 12 Dec 2002 */
     }
     return ;

   /*---------------------------------------------------------*/
   } else {                                  /* I'm the child */
                                           /* (never returns) */
     int nbuf=0 , jj ;
     char *vbuf=NULL ;
     IOCHAN *ioc ;
     struct utsname ubuf ;
     char ua[512] ;

     iochan_enable_perror(0) ;   /* don't print TCP/IP error messages */
     signal( SIGTERM , vexit ) ; /* if parent kills us, call vexit()  */

     /*-- get information from the AFNI server --*/

#define USE_HTTP_10

#ifdef USE_HTTP_10
#  undef PCLAB
#  ifdef SHOWOFF
#    undef SHSH
#    undef SHSHSH
#    define SHSH(x)   #x
#    define SHSHSH(x) SHSH(x)
#    define PCLAB     SHSHSH(SHOWOFF)
#  else
#    define PCLAB     "Unknown"
#  endif
#endif

     /** 25 Mar 2005: send more info in the request header **/

#ifdef USE_HTTP_10
     ubuf.nodename[0] = ubuf.sysname[0] = ubuf.machine[0] = '\0' ;
     jj = uname( &ubuf ) ;
     if( jj >= 0 && ubuf.nodename[0] != '\0' )
       sprintf( ua ,
               "afni (avers='%s'; prec='%s' node='%s'; sys='%s'; mach='%s')" ,
                AVERZHN, PCLAB, ubuf.nodename, ubuf.sysname, ubuf.machine   ) ;
     else
       sprintf( ua , "afni (avers='%s'; prec='%s')" , AVERZHN , PCLAB ) ;

     set_HTTP_10( 1 ) ;
     set_HTTP_user_agent( ua ) ;
#else
     set_HTTP_10( 0 ) ;
#endif

     /* send the request */

     THD_death_setup( 34567 ) ;  /* die if 34.567 seconds passes away */

     nbuf = read_URL( urlstring , &vbuf ) ;  /* may take a while */

     set_HTTP_10( 0 ) ;

     /*-- if this failed, quit --*/

     if( nbuf <= 0 || vbuf == NULL || vbuf[0] == '\0' ) {
        /* block recheck until a new DELAY has passed    22 Mar 2016 [rickr] */
        /* - also so server is not flooded when there are issues             */
        AFNI_update_vctime(NULL, NULL);
        vexit(1);
     }

     /*-- talk to parent process thru IOCHAN --*/

     ioc = iochan_init( STR_CHILD , "create" ) ;
     if( ioc == NULL )                                  vexit(2);

     /*-- wait until ioc is ready for writing --*/

     jj = iochan_writecheck(ioc,-1) ;
     if( jj < 0 )                                       vexit(3);

     /*-- send the info in vbuf --*/

     iochan_sendall( ioc , vbuf , nbuf ) ;
     while( ! iochan_clearcheck(ioc,10) )  /* loop until cleared */
       AFNI_sleep(10) ;                   /* by parent process  */

     AFNI_sleep(10); /* a little extra napping, then death */
     _exit(0);
   }
#endif  /* not CYGWIN */
}
Esempio n. 2
0
int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
	HANDLE hSingleInstanceMutex;

	// Filename and path buffers.
	TCHAR *exe_path = NULL;	// MAX_PATH
	#define EXE_PATH_LEN (MAX_PATH)
	TCHAR *dll_filename = NULL;	// MAX_PATH+32
	#define DLL_FILENAME_LEN (MAX_PATH+32)

	TCHAR *last_backslash;
	HKEY hkeyCLSID = NULL;	// HKEY_CLASSES_ROOT\\CLSID
	DWORD exe_path_len;
	LONG lResult;
	unsigned int i;

	static const TCHAR prg_title[] = _T("ROM Properties Page Configuration");

	RP_UNUSED(hPrevInstance);

	// Set Win32 security options.
	secoptions_init();

	// Check if another instance of rp-config is already running.
	// References:
	// - https://stackoverflow.com/questions/4191465/how-to-run-only-one-instance-of-application
	// - https://stackoverflow.com/a/33531179
	// TODO: Localized window title?
	hSingleInstanceMutex = CreateMutex(nullptr, TRUE, _T("Local\\com.gerbilsoft.rom-properties.rp-config"));
	if (!hSingleInstanceMutex || GetLastError() == ERROR_ALREADY_EXISTS) {
		// Mutex already exists.
		// Set focus to the existing instance.
		// TODO: Localized window titles?
		HWND hWnd = FindWindow(_T("#32770"), prg_title);
		if (hWnd) {
			SetForegroundWindow(hWnd);
		}
		return EXIT_SUCCESS;
	}

	// Set the C locale.
	// TODO: C++ locale?
	setlocale(LC_ALL, "");

#define FAIL_MESSAGE(msg) do { \
		MessageBox(NULL, (msg), prg_title, MB_ICONSTOP); \
		goto fail; \
	} while (0)

	// Get the executable path.
	// TODO: Support longer than MAX_PATH?
	exe_path = malloc(MAX_PATH*sizeof(TCHAR));
	if (!exe_path)
		FAIL_MESSAGE(_T("Failed to allocate memory for the EXE path."));
	exe_path_len = GetModuleFileName(hInstance, exe_path, EXE_PATH_LEN);
	if (exe_path_len == 0 || exe_path_len >= EXE_PATH_LEN)
		FAIL_MESSAGE(_T("Failed to get the EXE path."));

	// Find the last backslash.
	last_backslash = _tcsrchr(exe_path, L'\\');
	if (last_backslash) {
		// NULL out everything after the backslash.
		last_backslash[1] = 0;
		exe_path_len = (DWORD)(last_backslash - exe_path + 1);
	} else {
		// Invalid path...
		// FIXME: Handle this.
		FAIL_MESSAGE(_T("EXE path is invalid."));
	}

	// Initialize dll_filename with exe_path.
	dll_filename = malloc(DLL_FILENAME_LEN*sizeof(TCHAR));
	if (!dll_filename)
		FAIL_MESSAGE(_T("Failed to allocate memory for the DLL filename."));
	memcpy(dll_filename, exe_path, exe_path_len*sizeof(TCHAR));

	// First, check for rom-properties.dll in rp-config.exe's directory.
	_tcscpy(&dll_filename[exe_path_len], _T("rom-properties.dll"));
	TRY_LOAD_DLL(dll_filename);

	// Check the architecture-specific subdirectory.
	_tcscpy(&dll_filename[exe_path_len], rp_subdir);
	// NOTE: -1 because _countof() includes the NULL terminator.
	_tcscpy(&dll_filename[exe_path_len + _countof(rp_subdir) - 1], _T("rom-properties.dll"));
	TRY_LOAD_DLL(dll_filename);

	// Check the CLSIDs.
	lResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_ENUMERATE_SUB_KEYS, &hkeyCLSID);
	if (lResult != ERROR_SUCCESS)
		FAIL_MESSAGE(_T("Failed to open HKEY_CLASSES_ROOT\\CLSID."));

	// Need to open "HKCR\\CLSID\\{CLSID}\\InprocServer32".
	for (i = 0; i < _countof(CLSIDs); i++) {
		HKEY hkeyClass, hkeyInprocServer32;
		DWORD cbData, dwType;

		lResult = RegOpenKeyEx(hkeyCLSID, CLSIDs[i], 0, KEY_ENUMERATE_SUB_KEYS, &hkeyClass);
		if (lResult != ERROR_SUCCESS)
			continue;

		lResult = RegOpenKeyEx(hkeyClass, _T("InprocServer32"), 0, KEY_READ, &hkeyInprocServer32);
		if (lResult != ERROR_SUCCESS) {
			RegCloseKey(hkeyClass);
			continue;
		}

		// Read the default value to get the DLL filename.
		cbData = DLL_FILENAME_LEN*sizeof(TCHAR);
		lResult = RegQueryValueEx(
			hkeyInprocServer32,	// hKey
			NULL,			// lpValueName
			NULL,			// lpReserved
			&dwType,		// lpType
			(LPBYTE)dll_filename,	// lpData
			&cbData);		// lpcbData
		RegCloseKey(hkeyInprocServer32);
		RegCloseKey(hkeyClass);

		if (lResult != ERROR_SUCCESS || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
			continue;

		// Verify the NULL terminator.
		if ((cbData % sizeof(TCHAR) != 0) || dll_filename[(cbData/sizeof(TCHAR))-1] != 0) {
			// Either this isn't a multiple of 2 bytes,
			// or there's no NULL terminator.
			continue;
		}

		if (dll_filename[0] != 0 && dwType == REG_EXPAND_SZ) {
			// Expand the string.
			// cchExpand includes the NULL terminator.
			TCHAR *wbuf;
			DWORD cchExpand = ExpandEnvironmentStrings(dll_filename, nullptr, 0);
			if (cchExpand == 0) {
				// Error expanding the string.
				continue;
			}
			wbuf = malloc(cchExpand*sizeof(TCHAR));
			cchExpand = ExpandEnvironmentStrings(dll_filename, wbuf, cchExpand);
			if (cchExpand == 0) {
				// Error expanding the string.
				free(wbuf);
			} else {
				// String has been expanded.
				free(dll_filename);
				dll_filename = wbuf;
			}
		}

		// Attempt to load this DLL.
		TRY_LOAD_DLL(dll_filename);
	}

	// All options have failed...
	MessageBox(NULL, _T("Could not find rom-properties.dll.\n\n")
		_T("Please ensure the DLL is present in the same\ndirectory as rp-config.exe."),
		prg_title, MB_ICONWARNING);

fail:
	free(exe_path);
	free(dll_filename);
	if (hkeyCLSID) {
		RegCloseKey(hkeyCLSID);
	}
	return EXIT_FAILURE;
}