Mercurial > hg > xemacs-beta
comparison src/ntproc.c @ 408:501cfd01ee6d r21-2-34
Import from CVS: tag r21-2-34
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:18:11 +0200 |
parents | b8cc9ab3f761 |
children | de805c49cfc1 |
comparison
equal
deleted
inserted
replaced
407:ed6218a7d4d3 | 408:501cfd01ee6d |
---|---|
456 EH_Fail: | 456 EH_Fail: |
457 DebPrint (("create_child.CreateProcess failed: %ld\n", GetLastError());); | 457 DebPrint (("create_child.CreateProcess failed: %ld\n", GetLastError());); |
458 return FALSE; | 458 return FALSE; |
459 } | 459 } |
460 | 460 |
461 #ifndef __MINGW32__ | |
462 /* Return pointer to section header for section containing the given | |
463 relative virtual address. */ | |
464 static IMAGE_SECTION_HEADER * | |
465 rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header) | |
466 { | |
467 PIMAGE_SECTION_HEADER section; | |
468 int i; | |
469 | |
470 section = IMAGE_FIRST_SECTION (nt_header); | |
471 | |
472 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++) | |
473 { | |
474 if (rva >= section->VirtualAddress | |
475 && rva < section->VirtualAddress + section->SizeOfRawData) | |
476 return section; | |
477 section++; | |
478 } | |
479 return NULL; | |
480 } | |
481 #endif | |
482 | |
483 void | |
484 win32_executable_type (const char * filename, int * is_dos_app, int * is_cygnus_app) | |
485 { | |
486 file_data executable; | |
487 char * p; | |
488 | |
489 /* Default values in case we can't tell for sure. */ | |
490 *is_dos_app = FALSE; | |
491 *is_cygnus_app = FALSE; | |
492 | |
493 if (!open_input_file (&executable, filename)) | |
494 return; | |
495 | |
496 p = strrchr (filename, '.'); | |
497 | |
498 /* We can only identify DOS .com programs from the extension. */ | |
499 if (p && stricmp (p, ".com") == 0) | |
500 *is_dos_app = TRUE; | |
501 else if (p && (stricmp (p, ".bat") == 0 || | |
502 stricmp (p, ".cmd") == 0)) | |
503 { | |
504 /* A DOS shell script - it appears that CreateProcess is happy to | |
505 accept this (somewhat surprisingly); presumably it looks at | |
506 COMSPEC to determine what executable to actually invoke. | |
507 Therefore, we have to do the same here as well. */ | |
508 /* Actually, I think it uses the program association for that | |
509 extension, which is defined in the registry. */ | |
510 p = egetenv ("COMSPEC"); | |
511 if (p) | |
512 win32_executable_type (p, is_dos_app, is_cygnus_app); | |
513 } | |
514 else | |
515 { | |
516 /* Look for DOS .exe signature - if found, we must also check that | |
517 it isn't really a 16- or 32-bit Windows exe, since both formats | |
518 start with a DOS program stub. Note that 16-bit Windows | |
519 executables use the OS/2 1.x format. */ | |
520 | |
521 #ifdef __MINGW32__ | |
522 /* mingw32 doesn't have enough headers to detect cygwin | |
523 apps, just do what we can. */ | |
524 FILHDR * exe_header; | |
525 | |
526 exe_header = (FILHDR*) executable.file_base; | |
527 if (exe_header->e_magic != DOSMAGIC) | |
528 goto unwind; | |
529 | |
530 if ((char*) exe_header->e_lfanew > (char*) executable.size) | |
531 { | |
532 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */ | |
533 *is_dos_app = TRUE; | |
534 } | |
535 else if (exe_header->nt_signature != NT_SIGNATURE) | |
536 { | |
537 *is_dos_app = TRUE; | |
538 } | |
539 #else | |
540 IMAGE_DOS_HEADER * dos_header; | |
541 IMAGE_NT_HEADERS * nt_header; | |
542 | |
543 dos_header = (PIMAGE_DOS_HEADER) executable.file_base; | |
544 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) | |
545 goto unwind; | |
546 | |
547 nt_header = (PIMAGE_NT_HEADERS) ((char*) dos_header + dos_header->e_lfanew); | |
548 | |
549 if ((char*) nt_header > (char*) dos_header + executable.size) | |
550 { | |
551 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */ | |
552 *is_dos_app = TRUE; | |
553 } | |
554 else if (nt_header->Signature != IMAGE_NT_SIGNATURE && | |
555 LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE) | |
556 { | |
557 *is_dos_app = TRUE; | |
558 } | |
559 else if (nt_header->Signature == IMAGE_NT_SIGNATURE) | |
560 { | |
561 /* Look for cygwin.dll in DLL import list. */ | |
562 IMAGE_DATA_DIRECTORY import_dir = | |
563 nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; | |
564 IMAGE_IMPORT_DESCRIPTOR * imports; | |
565 IMAGE_SECTION_HEADER * section; | |
566 | |
567 section = rva_to_section (import_dir.VirtualAddress, nt_header); | |
568 imports = (IMAGE_IMPORT_DESCRIPTOR *) RVA_TO_PTR (import_dir.VirtualAddress, | |
569 section, executable); | |
570 | |
571 for ( ; imports->Name; imports++) | |
572 { | |
573 char *dllname = (char*) RVA_TO_PTR (imports->Name, section, executable); | |
574 | |
575 if (strcmp (dllname, "cygwin.dll") == 0) | |
576 { | |
577 *is_cygnus_app = TRUE; | |
578 break; | |
579 } | |
580 } | |
581 } | |
582 #endif | |
583 } | |
584 | |
585 unwind: | |
586 close_file_data (&executable); | |
587 } | |
588 | |
589 int | |
590 compare_env (const void *strp1, const void *strp2) | |
591 { | |
592 const char *str1 = *(const char**)strp1, *str2 = *(const char**)strp2; | |
593 | |
594 while (*str1 && *str2 && *str1 != '=' && *str2 != '=') | |
595 { | |
596 if ((*str1) > (*str2)) | |
597 return 1; | |
598 else if ((*str1) < (*str2)) | |
599 return -1; | |
600 str1++, str2++; | |
601 } | |
602 | |
603 if (*str1 == '=' && *str2 == '=') | |
604 return 0; | |
605 else if (*str1 == '=') | |
606 return -1; | |
607 else | |
608 return 1; | |
609 } | |
610 | |
611 void | 461 void |
612 merge_and_sort_env (char **envp1, char **envp2, char **new_envp) | 462 merge_and_sort_env (char **envp1, char **envp2, char **new_envp) |
613 { | 463 { |
614 char **optr, **nptr; | 464 char **optr, **nptr; |
615 int num; | 465 int num; |
689 /* Determine whether program is a 16-bit DOS executable, or a Win32 | 539 /* Determine whether program is a 16-bit DOS executable, or a Win32 |
690 executable that is implicitly linked to the Cygnus dll (implying it | 540 executable that is implicitly linked to the Cygnus dll (implying it |
691 was compiled with the Cygnus GNU toolchain and hence relies on | 541 was compiled with the Cygnus GNU toolchain and hence relies on |
692 cygwin.dll to parse the command line - we use this to decide how to | 542 cygwin.dll to parse the command line - we use this to decide how to |
693 escape quote chars in command line args that must be quoted). */ | 543 escape quote chars in command line args that must be quoted). */ |
694 win32_executable_type (cmdname, &is_dos_app, &is_cygnus_app); | 544 mswindows_executable_type (cmdname, &is_dos_app, &is_cygnus_app); |
695 | 545 |
696 /* On Windows 95, if cmdname is a DOS app, we invoke a helper | 546 /* On Windows 95, if cmdname is a DOS app, we invoke a helper |
697 application to start it by specifying the helper app as cmdname, | 547 application to start it by specifying the helper app as cmdname, |
698 while leaving the real app name as argv[0]. */ | 548 while leaving the real app name as argv[0]. */ |
699 if (is_dos_app) | 549 if (is_dos_app) |