3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
11 #define cygwin_internal cygwin_internal_dontuse
21 #include "cygwin/include/sys/cygwin.h"
22 #include "cygwin/include/mntent.h"
23 #undef cygwin_internal
25 #define alloca __builtin_alloca
38 typedef long long longlong
;
40 typedef __int64 longlong
;
43 void dump_setup (int, char **, bool);
44 void package_find (int, char **);
45 void package_list (int, char **);
47 static const char version
[] = "$Revision$";
49 static const char *known_env_vars
[] = {
57 "gcc_default_options",
79 static common_apps
[] = {
100 static int num_paths
= 0, max_paths
= 0;
101 static char **paths
= 0;
104 eprintf (const char *format
, ...)
107 va_start (ap
, format
);
108 vfprintf (stderr
, format
, ap
);
113 * display_error() is used to report failure modes
116 display_error (const char *name
, bool show_error
= true, bool print_failed
= true)
119 fprintf (stderr
, "cygcheck: %s%s: %lu\n", name
,
120 print_failed
? " failed" : "", GetLastError ());
122 fprintf (stderr
, "cygcheck: %s%s\n", name
,
123 print_failed
? " failed" : "");
128 add_path (char *s
, int maxlen
)
130 if (num_paths
>= max_paths
)
134 paths
= (char **) realloc (paths
, max_paths
* sizeof (char *));
136 paths
= (char **) malloc (max_paths
* sizeof (char *));
138 paths
[num_paths
] = (char *) malloc (maxlen
+ 1);
139 if (paths
[num_paths
] == NULL
)
141 display_error ("add_path: malloc()");
144 memcpy (paths
[num_paths
], s
, maxlen
);
145 paths
[num_paths
][maxlen
] = 0;
146 char *e
= paths
[num_paths
] + strlen (paths
[num_paths
]);
147 if (e
[-1] == '\\' && e
[-2] != ':')
149 for (int i
= 1; i
< num_paths
; i
++)
150 if (strcasecmp (paths
[num_paths
], paths
[i
]) == 0)
152 free (paths
[num_paths
]);
162 add_path ((char *) ".", 1); /* to be replaced later */
164 if (GetCurrentDirectory (4000, tmp
))
165 add_path (tmp
, strlen (tmp
));
167 display_error ("init_paths: GetCurrentDirectory()");
169 if (GetSystemDirectory (tmp
, 4000))
170 add_path (tmp
, strlen (tmp
));
172 display_error ("init_paths: GetSystemDirectory()");
173 sl
= strrchr (tmp
, '\\');
176 strcpy (sl
, "\\SYSTEM");
177 add_path (tmp
, strlen (tmp
));
179 GetWindowsDirectory (tmp
, 4000);
180 add_path (tmp
, strlen (tmp
));
182 char *wpath
= getenv ("PATH");
189 for (e
= b
; *e
&& *e
!= ';'; e
++);
190 if (strncmp(b
, ".", 1) && strncmp(b
, ".\\", 2))
198 printf ("WARNING: PATH is not set at all!\n");
202 find_on_path (char *file
, char *default_extension
,
203 int showall
= 0, int search_sysdirs
= 0)
205 static char rv
[4000];
206 char tmp
[4000], *ptr
= rv
;
210 display_error ("find_on_path: NULL pointer for file", false, false);
214 if (default_extension
== NULL
)
216 display_error ("find_on_path: NULL pointer for default_extension", false, false);
220 if (strchr (file
, ':') || strchr (file
, '\\') || strchr (file
, '/'))
221 return cygpath (file
, NULL
);
223 if (strchr (file
, '.'))
224 default_extension
= (char *) "";
226 for (int i
= 0; i
< num_paths
; i
++)
228 if (!search_sysdirs
&& (i
== 0 || i
== 2 || i
== 3))
230 if (i
== 0 || !search_sysdirs
|| strcasecmp (paths
[i
], paths
[0]))
232 sprintf (ptr
, "%s\\%s%s", paths
[i
], file
, default_extension
);
233 if (GetFileAttributes (ptr
) != (DWORD
) - 1)
236 printf ("Found: %s\n", ptr
);
237 if (ptr
== tmp
&& verbose
)
238 printf ("Warning: %s hides %s\n", rv
, ptr
);
252 #define DID_INACTIVE 3
263 already_did (char *file
)
266 for (d
= did
; d
; d
= d
->next
)
267 if (strcasecmp (d
->file
, file
) == 0)
269 d
= (Did
*) malloc (sizeof (Did
));
270 d
->file
= strdup (file
);
278 get_word (HANDLE fh
, int offset
)
283 if (SetFilePointer (fh
, offset
, 0, FILE_BEGIN
) == INVALID_SET_FILE_POINTER
284 && GetLastError () != NO_ERROR
)
285 display_error ("get_word: SetFilePointer()");
287 if (!ReadFile (fh
, &rv
, 2, (DWORD
*) &r
, 0))
288 display_error ("get_word: Readfile()");
294 get_dword (HANDLE fh
, int offset
)
299 if (SetFilePointer (fh
, offset
, 0, FILE_BEGIN
) == INVALID_SET_FILE_POINTER
300 && GetLastError () != NO_ERROR
)
301 display_error ("get_dword: SetFilePointer()");
303 if (!ReadFile (fh
, &rv
, 4, (DWORD
*) &r
, 0))
304 display_error ("get_dword: Readfile()");
314 int size_of_raw_data
;
315 int pointer_to_raw_data
;
319 rva_to_offset (int rva
, char *sections
, int nsections
, int *sz
)
323 if (sections
== NULL
)
325 display_error ("rva_to_offset: NULL passed for sections", true, false);
329 for (i
= 0; i
< nsections
; i
++)
331 Section
*s
= (Section
*) (sections
+ i
* 40);
333 printf ("%08x < %08x < %08x ? %08x\n",
334 s
->virtual_address
, rva
,
335 s
->virtual_address
+ s
->virtual_size
, s
->pointer_to_raw_data
);
337 if (rva
>= s
->virtual_address
338 && rva
< s
->virtual_address
+ s
->virtual_size
)
341 *sz
= s
->virtual_address
+ s
->virtual_size
- rva
;
342 return rva
- s
->virtual_address
+ s
->pointer_to_raw_data
;
359 unsigned characteristics
;
361 unsigned forwarder_chain
;
367 static void track_down (char *file
, char *suffix
, int lvl
);
369 #define CYGPREFIX (sizeof ("%%% Cygwin ") - 1)
371 cygwin_info (HANDLE h
)
373 char *buf
, *bufend
, *buf_start
= NULL
;
374 const char *hello
= " Cygwin DLL version info:\n";
375 DWORD size
= GetFileSize (h
, NULL
);
378 if (size
== 0xffffffff)
381 buf_start
= buf
= (char *) calloc (1, size
+ 1);
384 display_error ("cygwin_info: calloc()");
388 (void) SetFilePointer (h
, 0, NULL
, FILE_BEGIN
);
389 if (!ReadFile (h
, buf
, size
, &n
, NULL
))
395 static char dummy
[] = "\0\0\0\0\0\0\0";
396 char *dll_major
= dummy
;
399 if ((buf
= (char *) memchr (buf
, '%', bufend
- buf
)) == NULL
)
401 else if (strncmp ("%%% Cygwin ", buf
, CYGPREFIX
) != 0)
405 char *p
= strchr (buf
+= CYGPREFIX
, '\n');
408 if (strncasecmp (buf
, "dll major:", 10) == 0)
410 dll_major
= buf
+ 11;
416 if (strncasecmp (buf
, "dll minor:", 10) != 0)
420 char c
= dll_major
[1];
422 int maj
= atoi (dll_major
);
424 int min
= atoi (dll_major
+ 1);
425 sprintf (pbuf
, "DLL version: %d.%d.%.*s", maj
, min
, len
- 11,
427 len
= strlen (s
= pbuf
);
429 if (strncmp (s
, "dll", 3) == 0)
430 memcpy (s
, "DLL", 3);
431 else if (strncmp (s
, "api", 3) == 0)
432 memcpy (s
, "API", 3);
433 else if (islower (*s
))
435 fprintf (stdout
, "%s %.*s", hello
, len
, s
);
447 dll_info (const char *path
, HANDLE fh
, int lvl
, int recurse
)
451 int pe_header_offset
= get_dword (fh
, 0x3c);
452 int opthdr_ofs
= pe_header_offset
+ 4 + 20;
457 display_error ("dll_info: NULL passed for path", true, false);
461 if (SetFilePointer (fh
, opthdr_ofs
+ 40, 0, FILE_BEGIN
) ==
462 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
463 display_error ("dll_info: SetFilePointer()");
465 if (!ReadFile (fh
, &v
, sizeof (v
), &junk
, 0))
466 display_error ("dll_info: Readfile()");
469 printf (" - os=%d.%d img=%d.%d sys=%d.%d\n",
470 v
[0], v
[1], v
[2], v
[3], v
[4], v
[5]);
474 int num_entries
= get_dword (fh
, opthdr_ofs
+ 92);
475 int export_rva
= get_dword (fh
, opthdr_ofs
+ 96);
476 int export_size
= get_dword (fh
, opthdr_ofs
+ 100);
477 int import_rva
= get_dword (fh
, opthdr_ofs
+ 104);
478 int import_size
= get_dword (fh
, opthdr_ofs
+ 108);
480 int nsections
= get_word (fh
, pe_header_offset
+ 4 + 2);
481 char *sections
= (char *) malloc (nsections
* 40);
483 if (SetFilePointer (fh
, pe_header_offset
+ 4 + 20 +
484 get_word (fh
, pe_header_offset
+ 4 + 16), 0,
485 FILE_BEGIN
) == INVALID_SET_FILE_POINTER
486 && GetLastError () != NO_ERROR
)
487 display_error ("dll_info: SetFilePointer()");
489 if (!ReadFile (fh
, sections
, nsections
* 40, &junk
, 0))
490 display_error ("dll_info: Readfile()");
492 if (verbose
&& num_entries
>= 1 && export_size
> 0)
495 int expbase
= rva_to_offset (export_rva
, sections
, nsections
, &expsz
);
499 if (SetFilePointer (fh
, expbase
, 0, FILE_BEGIN
) ==
500 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
501 display_error ("dll_info: SetFilePointer()");
503 unsigned char *exp
= (unsigned char *) malloc (expsz
);
505 if (!ReadFile (fh
, exp
, expsz
, &junk
, 0))
506 display_error ("dll_info: Readfile()");
508 ExpDirectory
*ed
= (ExpDirectory
*) exp
;
509 int ofs
= ed
->name_rva
- export_rva
;
510 struct tm
*tm
= localtime ((const time_t *) &(ed
->timestamp
));
511 if (tm
->tm_year
< 60)
513 if (tm
->tm_year
< 200)
515 printf ("%*c", lvl
+ 2, ' ');
516 printf ("\"%s\" v%d.%d ts=", exp
+ ofs
,
517 ed
->major_ver
, ed
->minor_ver
);
518 printf ("%d/%d/%d %d:%02d\n",
519 tm
->tm_year
, tm
->tm_mon
+ 1, tm
->tm_mday
,
520 tm
->tm_hour
, tm
->tm_min
);
524 if (num_entries
>= 2 && import_size
> 0 && recurse
)
527 int impbase
= rva_to_offset (import_rva
, sections
, nsections
, &impsz
);
530 if (SetFilePointer (fh
, impbase
, 0, FILE_BEGIN
) ==
531 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
532 display_error ("dll_info: SetFilePointer()");
534 unsigned char *imp
= (unsigned char *) malloc (impsz
);
537 display_error ("dll_info: malloc()");
541 if (!ReadFile (fh
, imp
, impsz
, &junk
, 0))
542 display_error ("dll_info: Readfile()");
544 ImpDirectory
*id
= (ImpDirectory
*) imp
;
545 for (i
= 0; id
[i
].name_rva
; i
++)
547 /* int ofs = id[i].name_rva - import_rva; */
548 track_down ((char *) imp
+ id
[i
].name_rva
- import_rva
,
549 (char *) ".dll", lvl
+ 2);
553 if (strstr (path
, "\\cygwin1.dll"))
558 track_down (char *file
, char *suffix
, int lvl
)
562 display_error ("track_down: NULL passed for file", true, false);
568 display_error ("track_down: NULL passed for suffix", false, false);
572 char *path
= find_on_path (file
, suffix
, 0, 1);
575 printf ("Error: could not find %s\n", file
);
579 Did
*d
= already_did (file
);
588 printf ("%*c", lvl
, ' ');
590 printf (" (recursive)\n");
597 printf ("%*c", lvl
, ' ');
599 printf (" (already done)\n");
607 printf ("%*c", lvl
, ' ');
611 printf ("%s not found\n", file
);
618 CreateFile (path
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
619 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
620 if (fh
== INVALID_HANDLE_VALUE
)
622 printf (" - Cannot open\n");
626 d
->state
= DID_ACTIVE
;
628 dll_info (path
, fh
, lvl
, 1);
629 d
->state
= DID_INACTIVE
;
630 if (!CloseHandle (fh
))
631 display_error ("track_down: CloseHandle()");
637 HANDLE h
= CreateFile (f
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
638 0, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, 0);
639 BY_HANDLE_FILE_INFORMATION info
;
641 if (!GetFileInformationByHandle (h
, &info
))
642 display_error ("ls: GetFileInformationByHandle()");
646 if (!FileTimeToSystemTime (&info
.ftLastWriteTime
, &systime
))
647 display_error ("ls: FileTimeToSystemTime()");
648 printf ("%5dk %04d/%02d/%02d %s",
649 (((int) info
.nFileSizeLow
) + 512) / 1024,
650 systime
.wYear
, systime
.wMonth
, systime
.wDay
, f
);
651 dll_info (f
, h
, 16, 0);
652 if (!CloseHandle (h
))
653 display_error ("ls: CloseHandle()");
659 char *papp
= find_on_path (app
, (char *) ".exe", 1, 0);
662 printf ("Error: could not find %s\n", app
);
665 char *s
= strdup (papp
);
668 if (*t
== '/' || *t
== '\\' || *t
== ':')
671 paths
[0] = (char *) ".";
678 track_down (papp
, (char *) ".exe", 0);
682 extern char **environ
;
692 show_reg (RegInfo
* ri
, int nest
)
696 show_reg (ri
->prev
, 1);
698 printf ("%s\\", ri
->name
);
700 printf ("%s\n", ri
->name
);
704 scan_registry (RegInfo
* prev
, HKEY hKey
, char *name
, int cygnus
)
712 for (cp
= name
; *cp
; cp
++)
713 if (strncasecmp (cp
, "cygnus", 6) == 0)
716 DWORD num_subkeys
, max_subkey_len
, num_values
;
717 DWORD max_value_len
, max_valdata_len
, i
;
718 if (RegQueryInfoKey (hKey
, 0, 0, 0, &num_subkeys
, &max_subkey_len
, 0,
719 &num_values
, &max_value_len
, &max_valdata_len
, 0, 0)
724 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
, 0, GetLastError (),
725 MAKELANGID (LANG_NEUTRAL
, SUBLANG_DEFAULT
), tmp
, 400, 0);
726 printf ("RegQueryInfoKey: %s\n", tmp
);
735 char *value_name
= (char *) malloc (max_value_len
+ 1);
736 if (value_name
== NULL
)
738 display_error ("scan_registry: malloc()");
742 char *value_data
= (char *) malloc (max_valdata_len
+ 1);
743 if (value_data
== NULL
)
745 display_error ("scan_registry: malloc()");
749 for (i
= 0; i
< num_values
; i
++)
751 DWORD dlen
= max_valdata_len
+ 1;
752 DWORD nlen
= max_value_len
+ 1;
754 RegEnumValue (hKey
, i
, value_name
, &nlen
, 0,
755 &type
, (BYTE
*) value_data
, &dlen
);
757 printf (" %s = ", i
? value_name
: "(default)");
761 printf ("0x%08x\n", *(unsigned *) value_data
);
765 printf ("`%s'\n", value_data
);
768 printf ("(unsupported type)\n");
777 char *subkey_name
= (char *) malloc (max_subkey_len
+ 1);
778 for (i
= 0; i
< num_subkeys
; i
++)
780 if (RegEnumKey (hKey
, i
, subkey_name
, max_subkey_len
+ 1) ==
784 if (RegOpenKeyEx (hKey
, subkey_name
, 0, KEY_READ
, &sKey
)
787 scan_registry (&ri
, sKey
, subkey_name
, cygnus
);
788 if (RegCloseKey (sKey
) != ERROR_SUCCESS
)
789 display_error ("scan_registry: RegCloseKey()");
797 pretty_id (const char *s
, char *cygwin
, size_t cyglen
)
801 strcpy (cygwin
+ cyglen
++, " ");
802 strcpy (cygwin
+ cyglen
, s
);
805 char *id
= cygpath ("/bin/id.exe", NULL
);
806 for (char *p
= id
; (p
= strchr (p
, '/')); p
++)
809 if (access (id
, X_OK
))
811 fprintf (stderr
, "`id' program not found\n");
815 FILE *f
= popen (id
, "rt");
819 fgets (buf
, sizeof (buf
), f
);
821 char *uid
= strtok (buf
, ")");
823 uid
+= strlen ("uid=");
826 fprintf (stderr
, "garbled output from `id' command - no uid= found\n");
829 char *gid
= strtok (NULL
, ")");
831 gid
+= strlen ("gid=") + 1;
834 fprintf (stderr
, "garbled output from `id' command - no gid= found\n");
838 char **ng
= groups
- 1;
839 size_t len_uid
= strlen ("UID: )") + strlen (uid
);
840 size_t len_gid
= strlen ("GID: )") + strlen (gid
);
841 *++ng
= groups
[0] = (char *) alloca (len_uid
+ 1);
842 *++ng
= groups
[1] = (char *) alloca (len_gid
+ 1);
843 sprintf (groups
[0], "UID: %s)", uid
);
844 sprintf (groups
[1], "GID: %s)", gid
);
845 size_t sz
= max (len_uid
, len_gid
);
846 while ((*++ng
= strtok (NULL
, ",")))
848 char *p
= strchr (*ng
, '\n');
851 if (ng
== groups
+ 2)
852 *ng
+= strlen (" groups=");
853 size_t len
= strlen (*ng
);
859 printf ("\nOutput from %s (%s)\n", id
, s
);
860 int n
= 80 / (int) ++sz
;
861 int i
= n
> 2 ? n
- 2 : 0;
863 for (char **g
= groups
; g
<= ng
; g
++)
864 if ((g
!= ng
) && (++i
< n
))
865 printf ("%*s", sz
, *g
);
879 char *found_cygwin_dll
;
881 printf ("\nCygwin Configuration Diagnostics\n");
883 printf ("Current System Time: %s\n", ctime (&now
));
885 OSVERSIONINFO osversion
;
886 osversion
.dwOSVersionInfoSize
= sizeof (osversion
);
887 if (!GetVersionEx (&osversion
))
888 display_error ("dump_sysinfo: GetVersionEx()");
889 char *osname
= (char *) "unknown OS";
890 switch (osversion
.dwPlatformId
)
892 case VER_PLATFORM_WIN32s
:
893 osname
= (char *) "32s";
895 case VER_PLATFORM_WIN32_WINDOWS
:
896 switch (osversion
.dwMinorVersion
)
899 if (strchr (osversion
.szCSDVersion
, 'C'))
900 osname
= (char *) "95 OSR2";
902 osname
= (char *) "95";
905 if (strchr (osversion
.szCSDVersion
, 'A'))
906 osname
= (char *) "98 SE";
908 osname
= (char *) "98";
911 osname
= (char *) "ME";
914 osname
= (char *) "9X";
918 case VER_PLATFORM_WIN32_NT
:
919 if (osversion
.dwMajorVersion
== 5)
921 BOOL more_info
= FALSE
;
922 OSVERSIONINFOEX osversionex
;
923 osversionex
.dwOSVersionInfoSize
= sizeof (osversionex
);
924 if (GetVersionEx ((OSVERSIONINFO
*) &osversionex
))
926 if (osversion
.dwMinorVersion
== 0)
929 osname
= (char *) "2000";
930 else if (osversionex
.wProductType
== VER_NT_SERVER
931 || osversionex
.wProductType
==
932 VER_NT_DOMAIN_CONTROLLER
)
934 if (osversionex
.wSuiteMask
&VER_SUITE_DATACENTER
)
935 osname
= (char *) "2000 Datacenter Server";
936 else if (osversionex
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
937 osname
= (char *) "2000 Advanced Server";
939 osname
= (char *) "2000 Server";
942 osname
= (char *) "2000 Professional";
947 osname
= (char *) "XP";
948 else if (osversionex
.wProductType
== VER_NT_SERVER
949 || osversionex
.wProductType
==
950 VER_NT_DOMAIN_CONTROLLER
)
952 if (osversionex
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
953 osname
= (char *) ".NET Enterprise Server";
955 osname
= (char *) ".NET Server";
957 else if (osversionex
.wSuiteMask
& VER_SUITE_PERSONAL
)
958 osname
= (char *) "XP Home Edition";
960 osname
= (char *) "XP Professional";
965 osname
= (char *) "NT";
968 osname
= (char *) "??";
971 printf ("Windows %s Ver %lu.%lu Build %lu %s\n\n", osname
,
972 osversion
.dwMajorVersion
, osversion
.dwMinorVersion
,
973 osversion
.dwPlatformId
== VER_PLATFORM_WIN32_NT
?
974 osversion
.dwBuildNumber
: (osversion
.dwBuildNumber
& 0xffff),
975 osversion
.dwPlatformId
== VER_PLATFORM_WIN32_NT
?
976 osversion
.szCSDVersion
: "");
979 char *s
= getenv ("PATH"), *e
;
980 char sep
= strchr (s
, ';') ? ';' : ':';
981 int count_path_items
= 0;
984 for (e
= s
; *e
&& *e
!= sep
; e
++);
986 printf ("\t%.*s\n", e
- s
, s
);
997 char *cygwin
= getenv ("CYGWIN");
999 cygwin
-= strlen ("CYGWIN=");
1001 cygwin
= const_cast <char *> ("CYGWIN=");
1002 size_t cyglen
= strlen (cygwin
);
1003 cygwin
= strcpy ((char *) malloc (cyglen
+ sizeof (" nontsec")), cygwin
);
1004 pretty_id ("nontsec", cygwin
, cyglen
);
1005 pretty_id ("ntsec", cygwin
, cyglen
);
1009 if (!GetSystemDirectory (tmp
, 4000))
1010 display_error ("dump_sysinfo: GetSystemDirectory()");
1011 printf ("\nSysDir: %s\n", tmp
);
1013 GetWindowsDirectory (tmp
, 4000);
1014 printf ("WinDir: %s\n\n", tmp
);
1018 printf ("Here's some environment variables that may affect cygwin:\n");
1019 for (i
= 0; environ
[i
]; i
++)
1021 char *eq
= strchr (environ
[i
], '=');
1024 /* int len = eq - environ[i]; */
1025 for (j
= 0; known_env_vars
[j
]; j
++)
1028 if (strcmp (environ
[i
], "PATH") == 0)
1029 continue; /* we handle this one specially */
1030 if (strcasecmp (environ
[i
], known_env_vars
[j
]) == 0)
1031 printf ("%s = `%s'\n", environ
[i
], eq
+ 1);
1040 printf ("Here's the rest of your environment variables:\n");
1041 for (i
= 0; environ
[i
]; i
++)
1044 char *eq
= strchr (environ
[i
], '=');
1047 /* int len = eq - environ[i]; */
1048 for (j
= 0; known_env_vars
[j
]; j
++)
1051 if (strcasecmp (environ
[i
], known_env_vars
[j
]) == 0)
1058 printf ("%s = `%s'\n", environ
[i
], eq
+ 1);
1068 printf ("Scanning registry for keys with `Cygnus' in them...\n");
1070 /* big and not generally useful */
1071 scan_registry (0, HKEY_CLASSES_ROOT
, (char *) "HKEY_CLASSES_ROOT", 0);
1073 scan_registry (0, HKEY_CURRENT_CONFIG
,
1074 (char *) "HKEY_CURRENT_CONFIG", 0);
1075 scan_registry (0, HKEY_CURRENT_USER
, (char *) "HKEY_CURRENT_USER", 0);
1076 scan_registry (0, HKEY_LOCAL_MACHINE
, (char *) "HKEY_LOCAL_MACHINE", 0);
1078 /* the parts we need are duplicated in HKEY_CURRENT_USER anyway */
1079 scan_registry (0, HKEY_USERS
, (char *) "HKEY_USERS", 0);
1084 printf ("Use `-r' to scan registry\n\n");
1088 printf ("Listing available drives...\n");
1089 printf ("Drv Type Size Used Flags Name\n");
1092 SetErrorMode (SEM_FAILCRITICALERRORS
| SEM_NOOPENFILEERRORBOX
);
1093 int drivemask
= GetLogicalDrives ();
1095 HINSTANCE k32
= LoadLibrary ("kernel32.dll");
1096 BOOL (WINAPI
* gdfse
) (LPCSTR
, long long *, long long *, long long *) =
1097 (BOOL (WINAPI
*) (LPCSTR
, long long *, long long *, long long *))
1098 GetProcAddress (k32
, "GetDiskFreeSpaceExA");
1100 for (i
= 0; i
< 26; i
++)
1102 if (!(drivemask
& (1 << i
)))
1104 char drive
[4], name
[200], fsname
[200];
1105 DWORD serno
= 0, maxnamelen
= 0, flags
= 0;
1106 name
[0] = name
[0] = fsname
[0] = 0;
1107 sprintf (drive
, "%c:\\", i
+ 'a');
1108 /* Report all errors, except if the Volume is ERROR_NOT_READY.
1109 ERROR_NOT_READY is returned when removeable media drives are empty
1110 (CD, floppy, etc.) */
1111 if (!GetVolumeInformation
1112 (drive
, name
, sizeof (name
), &serno
, &maxnamelen
, &flags
, fsname
,
1113 sizeof (fsname
)) && GetLastError () != ERROR_NOT_READY
)
1114 display_error ("dump_sysinfo: GetVolumeInformation()");
1116 int dtype
= GetDriveType (drive
);
1117 char drive_type
[4] = "unk";
1120 case DRIVE_REMOVABLE
:
1121 strcpy (drive_type
, "fd ");
1124 strcpy (drive_type
, "hd ");
1127 strcpy (drive_type
, "net");
1130 strcpy (drive_type
, "cd ");
1133 strcpy (drive_type
, "ram");
1136 strcpy (drive_type
, "unk");
1139 long capacity_mb
= -1;
1140 int percent_full
= -1;
1142 long long free_me
= 0ULL, free_bytes
= 0ULL, total_bytes
= 1ULL;
1143 if (gdfse
!= NULL
&& gdfse (drive
, &free_me
, &total_bytes
, &free_bytes
))
1145 capacity_mb
= total_bytes
/ (1024L * 1024L);
1146 percent_full
= 100 - (int) ((100.0 * free_me
) / total_bytes
);
1150 DWORD spc
= 0, bps
= 0, fc
= 0, tc
= 1;
1151 if (GetDiskFreeSpace (drive
, &spc
, &bps
, &fc
, &tc
))
1153 capacity_mb
= (spc
* bps
* tc
) / (1024 * 1024);
1154 percent_full
= 100 - (int) ((100.0 * fc
) / tc
);
1158 printf ("%.2s %s %-6s ", drive
, drive_type
, fsname
);
1159 if (capacity_mb
>= 0)
1160 printf ("%7dMb %3d%% ", (int) capacity_mb
, (int) percent_full
);
1162 printf (" N/A N/A ");
1163 printf ("%s %s %s %s %s %s %s\n",
1164 flags
& FS_CASE_IS_PRESERVED
? "CP" : " ",
1165 flags
& FS_CASE_SENSITIVE
? "CS" : " ",
1166 flags
& FS_UNICODE_STORED_ON_DISK
? "UN" : " ",
1167 flags
& FS_PERSISTENT_ACLS
? "PA" : " ",
1168 flags
& FS_FILE_COMPRESSION
? "FC" : " ",
1169 flags
& FS_VOL_IS_COMPRESSED
? "VC" : " ",
1171 flags
& FILE_SUPPORTS_ENCRYPTION
? "EN" : " ",
1172 flags
& FILE_SUPPORTS_OBJECT_IDS
? "OI" : " ",
1173 flags
& FILE_SUPPORTS_REPARSE_POINTS
? "RP" : " ",
1174 flags
& FILE_SUPPORTS_SPARSE_FILES
? "SP" : " ",
1175 flags
& FILE_VOLUME_QUOTAS
? "QU" : " ",
1180 if (!FreeLibrary (k32
))
1181 display_error ("dump_sysinfo: FreeLibrary()");
1182 SetErrorMode (prev_mode
);
1186 "fd = floppy, hd = hard drive, cd = CD-ROM\n"
1187 "net= Network Share, ram= RAM drive, unk= Unknown\n"
1188 "CP = Case Preserving, CS = Case Sensitive, UN = Unicode\n"
1189 "PA = Persistent ACLS, FC = File Compression, VC = Volume Compression");
1193 unsigned ml_fsname
= 4, ml_dir
= 7, ml_type
= 6;
1194 bool ml_trailing
= false;
1198 while ((mnt
= getmntent (0)))
1200 unsigned n
= (int) strlen (mnt
->mnt_fsname
);
1201 ml_trailing
|= (n
> 1 && strchr ("\\/", mnt
->mnt_fsname
[n
- 1]));
1204 n
= (int) strlen (mnt
->mnt_dir
);
1205 ml_trailing
|= (n
> 1 && strchr ("\\/", mnt
->mnt_dir
[n
- 1]));
1211 puts ("Warning: Mount entries should not have a trailing (back)slash\n");
1216 ("Mount entries: these map POSIX directories to your NT drives.\n");
1217 printf ("%-*s %-*s %-*s %s\n", ml_fsname
, "-NT-", ml_dir
, "-POSIX-",
1218 ml_type
, "-Type-", "-Flags-");
1222 while ((mnt
= getmntent (0)))
1224 printf ("%-*s %-*s %-*s %s\n",
1225 ml_fsname
, mnt
->mnt_fsname
,
1226 ml_dir
, mnt
->mnt_dir
, ml_type
, mnt
->mnt_type
, mnt
->mnt_opts
);
1230 add_path ((char *) "\\bin", 4); /* just in case */
1234 ("Looking to see where common programs can be found, if at all...\n");
1235 for (i
= 0; common_apps
[i
].name
; i
++)
1236 if (!find_on_path ((char *) common_apps
[i
].name
, (char *) ".exe", 1, 0))
1238 if (common_apps
[i
].missing_is_good
)
1239 printf ("Not Found: %s (good!)\n", common_apps
[i
].name
);
1241 printf ("Not Found: %s\n", common_apps
[i
].name
);
1246 printf ("Looking for various Cygnus DLLs... (-v gives version info)\n");
1247 int cygwin_dll_count
= 0;
1248 for (i
= 1; i
< num_paths
; i
++)
1250 WIN32_FIND_DATA ffinfo
;
1251 sprintf (tmp
, "%s/*.*", paths
[i
]);
1252 HANDLE ff
= FindFirstFile (tmp
, &ffinfo
);
1253 int found
= (ff
!= INVALID_HANDLE_VALUE
);
1254 found_cygwin_dll
= NULL
;
1257 char *f
= ffinfo
.cFileName
;
1258 if (strcasecmp (f
+ strlen (f
) - 4, ".dll") == 0)
1260 if (strncasecmp (f
, "cyg", 3) == 0)
1262 sprintf (tmp
, "%s\\%s", paths
[i
], f
);
1263 if (strcasecmp (f
, "cygwin1.dll") == 0)
1266 found_cygwin_dll
= strdup (tmp
);
1272 found
= FindNextFile (ff
, &ffinfo
);
1274 if (found_cygwin_dll
)
1276 ls (found_cygwin_dll
);
1277 free (found_cygwin_dll
);
1282 if (cygwin_dll_count
> 1)
1283 puts ("Warning: There are multiple cygwin1.dlls on your path");
1284 if (!cygwin_dll_count
)
1285 puts ("Warning: cygwin1.dll not found on your path");
1291 HANDLE h
= CreateFileA ("CONIN$", GENERIC_READ
| GENERIC_WRITE
,
1292 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
1293 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1295 if (h
== INVALID_HANDLE_VALUE
|| h
== NULL
)
1296 return (display_error ("check_keys: Opening CONIN$"));
1300 if (!GetConsoleMode (h
, &mode
))
1301 display_error ("check_keys: GetConsoleMode()");
1304 mode
&= ~ENABLE_PROCESSED_INPUT
;
1305 if (!SetConsoleMode (h
, mode
))
1306 display_error ("check_keys: SetConsoleMode()");
1309 fputs ("\nThis key check works only in a console window,", stderr
);
1310 fputs (" _NOT_ in a terminal session!\n", stderr
);
1311 fputs ("Abort with Ctrl+C if in a terminal session.\n\n", stderr
);
1312 fputs ("Press `q' to exit.\n", stderr
);
1314 INPUT_RECORD in
, prev_in
;
1316 // Drop first <RETURN> key
1317 ReadConsoleInput (h
, &in
, 1, &mode
);
1319 memset (&in
, 0, sizeof in
);
1324 if (!ReadConsoleInput (h
, &in
, 1, &mode
))
1325 display_error ("check_keys: ReadConsoleInput()");
1327 if (!memcmp (&in
, &prev_in
, sizeof in
))
1330 switch (in
.EventType
)
1333 printf ("%s %ux VK: 0x%02x VS: 0x%02x A: 0x%02x CTRL: ",
1334 in
.Event
.KeyEvent
.bKeyDown
? "Pressed " : "Released",
1335 in
.Event
.KeyEvent
.wRepeatCount
,
1336 in
.Event
.KeyEvent
.wVirtualKeyCode
,
1337 in
.Event
.KeyEvent
.wVirtualScanCode
,
1338 (unsigned char) in
.Event
.KeyEvent
.uChar
.AsciiChar
);
1339 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& CAPSLOCK_ON
?
1340 "CL " : "-- ", stdout
);
1341 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& ENHANCED_KEY
?
1342 "EK " : "-- ", stdout
);
1343 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& LEFT_ALT_PRESSED
?
1344 "LA " : "-- ", stdout
);
1345 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& LEFT_CTRL_PRESSED
?
1346 "LC " : "-- ", stdout
);
1347 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& NUMLOCK_ON
?
1348 "NL " : "-- ", stdout
);
1349 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& RIGHT_ALT_PRESSED
?
1350 "RA " : "-- ", stdout
);
1351 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& RIGHT_CTRL_PRESSED
?
1352 "RC " : "-- ", stdout
);
1353 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& SCROLLLOCK_ON
?
1354 "SL " : "-- ", stdout
);
1355 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& SHIFT_PRESSED
?
1356 "SH " : "-- ", stdout
);
1357 fputc ('\n', stdout
);
1364 while (in
.EventType
!= KEY_EVENT
||
1365 in
.Event
.KeyEvent
.bKeyDown
!= FALSE
||
1366 in
.Event
.KeyEvent
.uChar
.AsciiChar
!= 'q');
1373 usage (FILE * stream
, int status
)
1376 Usage: cygcheck [OPTIONS] [PROGRAM...]\n\
1377 Check system information or PROGRAM library dependencies\n\
1379 -c, --check-setup check packages installed via setup.exe\n\
1380 -d, --dump-only no integrity checking of package contents (requires -c)\n\
1381 -s, --sysinfo system information (not with -k)\n\
1382 -v, --verbose verbose output (indented) (for -[cfls] or programs)\n\
1383 -r, --registry registry search (requires -s)\n\
1384 -k, --keycheck perform a keyboard check session (not with -[scfl])\n\
1385 -f, --find-package find installed packages containing files (not with -[cl])\n\
1386 -l, --list-package list the contents of installed packages (not with -[cf])\n\
1387 -h, --help give help about the info (not with -[cfl])\n\
1388 -V, --version output version information and exit\n\
1389 You must at least give either -s or -k or a program name\n");
1393 struct option longopts
[] = {
1394 {"check-setup", no_argument
, NULL
, 'c'},
1395 {"dump-only", no_argument
, NULL
, 'd'},
1396 {"sysinfo", no_argument
, NULL
, 's'},
1397 {"registry", no_argument
, NULL
, 'r'},
1398 {"verbose", no_argument
, NULL
, 'v'},
1399 {"keycheck", no_argument
, NULL
, 'k'},
1400 {"find-package", no_argument
, NULL
, 'f'},
1401 {"list-package", no_argument
, NULL
, 'l'},
1402 {"help", no_argument
, NULL
, 'h'},
1403 {"version", no_argument
, 0, 'V'},
1404 {0, no_argument
, NULL
, 0}
1407 static char opts
[] = "cdfhklrsvV";
1412 const char *v
= strchr (version
, ':');
1422 len
= strchr (v
, ' ') - v
;
1425 cygcheck version %.*s\n\
1426 System Checker for Cygwin\n\
1427 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.\n\
1429 ", len
, v
, __DATE__
);
1435 int n
= 1 + strchr (*_environ
, '=') - ev
;
1436 char *s
= (char *) alloca (n
);
1442 DWORD (*cygwin_internal
) (int, ...);
1445 load_cygwin (int& argc
, char **&argv
)
1449 if (!(h
= LoadLibrary ("cygwin1.dll")))
1451 if (!(cygwin_internal
= (DWORD (*) (int, ...)) GetProcAddress (h
, "cygwin_internal")))
1454 char **av
= (char **) cygwin_internal (CW_ARGV
);
1456 for (argc
= 0, argv
= av
; *av
; av
++)
1459 char **envp
= (char **) cygwin_internal (CW_ENVP
);
1462 /* Store path and revert to this value, otherwise path gets overwritten
1463 by the POSIXy Cygwin variation, which breaks cygcheck.
1464 Another approach would be to use the Cygwin PATH and convert it to
1469 if (!strncmp (*_environ
, "PATH=", 5))
1470 path
= strdup (*_environ
);
1473 for (char **ev
= envp
; *ev
; ev
++)
1474 putenv (!strncmp (*ev
, "PATH=", 5) ? path
: *ev
);
1479 main (int argc
, char **argv
)
1482 load_cygwin (argc
, argv
);
1484 (void) putenv("POSIXLY_CORRECT=1");
1485 while ((i
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
1524 if (argc
== 0 && !sysinfo
&& !keycheck
&& !check_setup
&& !list_package
)
1530 if ((check_setup
|| sysinfo
|| find_package
|| list_package
) && keycheck
)
1533 if ((find_package
|| list_package
) && check_setup
)
1536 if (dump_only
&& !check_setup
)
1539 if (find_package
&& list_package
)
1543 return check_keys ();
1547 /* FIXME: Add help for check_setup and {list,find}_package */
1548 if (argc
>= 1 && givehelp
&& !check_setup
&& !find_package
&& !list_package
)
1550 printf("Here is where the OS will find your program%s, and which dlls\n",
1551 argc
> 1 ? "s" : "");
1552 printf ("will be used for it. Use -v to see DLL version info\n");
1559 dump_setup (verbose
, argv
, !dump_only
);
1560 else if (find_package
)
1561 package_find (verbose
, argv
);
1562 else if (list_package
)
1563 package_list (verbose
, argv
);
1565 for (i
= 0; i
< argc
; i
++)
1578 dump_setup (verbose
, NULL
, false);
1582 puts ("Use -h to see help about each section");