3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 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
20 #include "cygwin/include/sys/cygwin.h"
21 #include "cygwin/include/mntent.h"
23 #define alloca __builtin_alloca
36 typedef long long longlong
;
38 typedef __int64 longlong
;
41 void dump_setup (int, char **, bool);
42 void package_find (int, char **);
43 void package_list (int, char **);
45 static const char version
[] = "$Revision$";
47 static const char *known_env_vars
[] = {
55 "gcc_default_options",
77 static common_apps
[] = {
98 static int num_paths
= 0, max_paths
= 0;
99 static char **paths
= 0;
102 * keyeprint() is used to report failure modes
105 keyeprint (const char *name
)
107 fprintf (stderr
, "cygcheck: %s failed: %lu\n", name
, GetLastError ());
112 add_path (char *s
, int maxlen
)
114 if (num_paths
>= max_paths
)
118 paths
= (char **) realloc (paths
, max_paths
* sizeof (char *));
120 paths
= (char **) malloc (max_paths
* sizeof (char *));
122 paths
[num_paths
] = (char *) malloc (maxlen
+ 1);
123 if (paths
[num_paths
] == NULL
)
125 keyeprint ("add_path: malloc()");
128 memcpy (paths
[num_paths
], s
, maxlen
);
129 paths
[num_paths
][maxlen
] = 0;
130 char *e
= paths
[num_paths
] + strlen (paths
[num_paths
]);
131 if (e
[-1] == '\\' && e
[-2] != ':')
133 for (int i
= 1; i
< num_paths
; i
++)
134 if (strcasecmp (paths
[num_paths
], paths
[i
]) == 0)
136 free (paths
[num_paths
]);
146 add_path ((char *) ".", 1); /* to be replaced later */
147 add_path ((char *) ".", 1); /* the current directory */
148 if (GetSystemDirectory (tmp
, 4000))
149 add_path (tmp
, strlen (tmp
));
151 keyeprint ("init_paths: GetSystemDirectory()");
152 sl
= strrchr (tmp
, '\\');
155 strcpy (sl
, "\\SYSTEM");
156 add_path (tmp
, strlen (tmp
));
158 GetWindowsDirectory (tmp
, 4000);
159 add_path (tmp
, strlen (tmp
));
161 char *wpath
= getenv ("PATH");
168 for (e
= b
; *e
&& *e
!= ';'; e
++);
176 printf ("WARNING: PATH is not set at all!\n");
180 find_on_path (char *file
, char *default_extension
,
181 int showall
= 0, int search_sysdirs
= 0)
183 static char rv
[4000];
184 char tmp
[4000], *ptr
= rv
;
188 keyeprint ("find_on_path: NULL pointer for file");
192 if (default_extension
== NULL
)
194 keyeprint ("find_on_path: NULL pointer for default_extension");
198 if (strchr (file
, ':') || strchr (file
, '\\') || strchr (file
, '/'))
199 return cygpath (file
, NULL
);
201 if (strchr (file
, '.'))
202 default_extension
= (char *) "";
204 for (int i
= 0; i
< num_paths
; i
++)
206 if (!search_sysdirs
&& (i
== 0 || i
== 2 || i
== 3))
208 if (i
== 0 || !search_sysdirs
|| strcasecmp (paths
[i
], paths
[0]))
210 sprintf (ptr
, "%s\\%s%s", paths
[i
], file
, default_extension
);
211 if (GetFileAttributes (ptr
) != (DWORD
) - 1)
214 printf ("Found: %s\n", ptr
);
215 if (ptr
== tmp
&& verbose
)
216 printf ("Warning: %s hides %s\n", rv
, ptr
);
230 #define DID_INACTIVE 3
241 already_did (char *file
)
244 for (d
= did
; d
; d
= d
->next
)
245 if (strcasecmp (d
->file
, file
) == 0)
247 d
= (Did
*) malloc (sizeof (Did
));
248 d
->file
= strdup (file
);
256 get_word (HANDLE fh
, int offset
)
261 if (SetFilePointer (fh
, offset
, 0, FILE_BEGIN
) == INVALID_SET_FILE_POINTER
262 && GetLastError () != NO_ERROR
)
263 keyeprint ("get_word: SetFilePointer()");
265 if (!ReadFile (fh
, &rv
, 2, (DWORD
*) &r
, 0))
266 keyeprint ("get_word: Readfile()");
272 get_dword (HANDLE fh
, int offset
)
277 if (SetFilePointer (fh
, offset
, 0, FILE_BEGIN
) == INVALID_SET_FILE_POINTER
278 && GetLastError () != NO_ERROR
)
279 keyeprint ("get_word: SetFilePointer()");
281 if (!ReadFile (fh
, &rv
, 4, (DWORD
*) &r
, 0))
282 keyeprint ("get_dword: Readfile()");
292 int size_of_raw_data
;
293 int pointer_to_raw_data
;
297 rva_to_offset (int rva
, char *sections
, int nsections
, int *sz
)
301 if (sections
== NULL
)
303 keyeprint ("rva_to_offset: NULL passed for sections");
307 for (i
= 0; i
< nsections
; i
++)
309 Section
*s
= (Section
*) (sections
+ i
* 40);
311 printf ("%08x < %08x < %08x ? %08x\n",
312 s
->virtual_address
, rva
,
313 s
->virtual_address
+ s
->virtual_size
, s
->pointer_to_raw_data
);
315 if (rva
>= s
->virtual_address
316 && rva
< s
->virtual_address
+ s
->virtual_size
)
319 *sz
= s
->virtual_address
+ s
->virtual_size
- rva
;
320 return rva
- s
->virtual_address
+ s
->pointer_to_raw_data
;
337 unsigned characteristics
;
339 unsigned forwarder_chain
;
345 static void track_down (char *file
, char *suffix
, int lvl
);
347 #define CYGPREFIX (sizeof ("%%% Cygwin ") - 1)
349 cygwin_info (HANDLE h
)
351 char *buf
, *bufend
, *buf_start
= NULL
;
352 const char *hello
= " Cygwin DLL version info:\n";
353 DWORD size
= GetFileSize (h
, NULL
);
356 if (size
== 0xffffffff)
359 buf_start
= buf
= (char *) calloc (1, size
+ 1);
362 keyeprint ("cygwin_info: malloc()");
366 (void) SetFilePointer (h
, 0, NULL
, FILE_BEGIN
);
367 if (!ReadFile (h
, buf
, size
, &n
, NULL
))
373 static char dummy
[] = "\0\0\0\0\0\0\0";
374 char *dll_major
= dummy
;
377 if ((buf
= (char *) memchr (buf
, '%', bufend
- buf
)) == NULL
)
379 else if (strncmp ("%%% Cygwin ", buf
, CYGPREFIX
) != 0)
383 char *p
= strchr (buf
+= CYGPREFIX
, '\n');
386 if (strncasecmp (buf
, "dll major:", 10) == 0)
388 dll_major
= buf
+ 11;
394 if (strncasecmp (buf
, "dll minor:", 10) != 0)
398 char c
= dll_major
[1];
400 int maj
= atoi (dll_major
);
402 int min
= atoi (dll_major
+ 1);
403 sprintf (pbuf
, "DLL version: %d.%d.%.*s", maj
, min
, len
- 11,
405 len
= strlen (s
= pbuf
);
407 if (strncmp (s
, "dll", 3) == 0)
408 memcpy (s
, "DLL", 3);
409 else if (strncmp (s
, "api", 3) == 0)
410 memcpy (s
, "API", 3);
411 else if (islower (*s
))
413 fprintf (stdout
, "%s %.*s", hello
, len
, s
);
425 dll_info (const char *path
, HANDLE fh
, int lvl
, int recurse
)
429 int pe_header_offset
= get_dword (fh
, 0x3c);
430 int opthdr_ofs
= pe_header_offset
+ 4 + 20;
435 keyeprint ("dll_info: NULL passed for path");
439 if (SetFilePointer (fh
, opthdr_ofs
+ 40, 0, FILE_BEGIN
) ==
440 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
441 keyeprint ("dll_info: SetFilePointer()");
443 if (!ReadFile (fh
, &v
, sizeof (v
), &junk
, 0))
444 keyeprint ("dll_info: Readfile()");
447 printf (" - os=%d.%d img=%d.%d sys=%d.%d\n",
448 v
[0], v
[1], v
[2], v
[3], v
[4], v
[5]);
452 int num_entries
= get_dword (fh
, opthdr_ofs
+ 92);
453 int export_rva
= get_dword (fh
, opthdr_ofs
+ 96);
454 int export_size
= get_dword (fh
, opthdr_ofs
+ 100);
455 int import_rva
= get_dword (fh
, opthdr_ofs
+ 104);
456 int import_size
= get_dword (fh
, opthdr_ofs
+ 108);
458 int nsections
= get_word (fh
, pe_header_offset
+ 4 + 2);
459 char *sections
= (char *) malloc (nsections
* 40);
461 if (SetFilePointer (fh
, pe_header_offset
+ 4 + 20 +
462 get_word (fh
, pe_header_offset
+ 4 + 16), 0,
463 FILE_BEGIN
) == INVALID_SET_FILE_POINTER
464 && GetLastError () != NO_ERROR
)
465 keyeprint ("dll_info: SetFilePointer()");
467 if (!ReadFile (fh
, sections
, nsections
* 40, &junk
, 0))
468 keyeprint ("dll_info: Readfile()");
470 if (verbose
&& num_entries
>= 1 && export_size
> 0)
473 int expbase
= rva_to_offset (export_rva
, sections
, nsections
, &expsz
);
477 if (SetFilePointer (fh
, expbase
, 0, FILE_BEGIN
) ==
478 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
479 keyeprint ("dll_info: SetFilePointer()");
481 unsigned char *exp
= (unsigned char *) malloc (expsz
);
483 if (!ReadFile (fh
, exp
, expsz
, &junk
, 0))
484 keyeprint ("dll_info: Readfile()");
486 ExpDirectory
*ed
= (ExpDirectory
*) exp
;
487 int ofs
= ed
->name_rva
- export_rva
;
488 struct tm
*tm
= localtime ((const time_t *) &(ed
->timestamp
));
489 if (tm
->tm_year
< 60)
491 if (tm
->tm_year
< 200)
493 printf ("%*c", lvl
+ 2, ' ');
494 printf ("\"%s\" v%d.%d ts=", exp
+ ofs
,
495 ed
->major_ver
, ed
->minor_ver
);
496 printf ("%d/%d/%d %d:%02d\n",
497 tm
->tm_year
, tm
->tm_mon
+ 1, tm
->tm_mday
,
498 tm
->tm_hour
, tm
->tm_min
);
502 if (num_entries
>= 2 && import_size
> 0 && recurse
)
505 int impbase
= rva_to_offset (import_rva
, sections
, nsections
, &impsz
);
508 if (SetFilePointer (fh
, impbase
, 0, FILE_BEGIN
) ==
509 INVALID_SET_FILE_POINTER
&& GetLastError () != NO_ERROR
)
510 keyeprint ("dll_info: SetFilePointer()");
512 unsigned char *imp
= (unsigned char *) malloc (impsz
);
515 keyeprint ("dll_info: malloc()");
519 if (!ReadFile (fh
, imp
, impsz
, &junk
, 0))
520 keyeprint ("dll_info: Readfile()");
522 ImpDirectory
*id
= (ImpDirectory
*) imp
;
523 for (i
= 0; id
[i
].name_rva
; i
++)
525 /* int ofs = id[i].name_rva - import_rva; */
526 track_down ((char *) imp
+ id
[i
].name_rva
- import_rva
,
527 (char *) ".dll", lvl
+ 2);
531 if (strstr (path
, "\\cygwin1.dll"))
536 track_down (char *file
, char *suffix
, int lvl
)
540 keyeprint ("track_down: malloc()");
546 keyeprint ("track_down: malloc()");
550 char *path
= find_on_path (file
, suffix
, 0, 1);
553 printf ("Error: could not find %s\n", file
);
557 Did
*d
= already_did (file
);
566 printf ("%*c", lvl
, ' ');
568 printf (" (recursive)\n");
575 printf ("%*c", lvl
, ' ');
577 printf (" (already done)\n");
585 printf ("%*c", lvl
, ' ');
589 printf ("%s not found\n", file
);
596 CreateFile (path
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
597 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
598 if (fh
== INVALID_HANDLE_VALUE
)
600 printf (" - Cannot open\n");
604 d
->state
= DID_ACTIVE
;
606 dll_info (path
, fh
, lvl
, 1);
607 d
->state
= DID_INACTIVE
;
608 if (!CloseHandle (fh
))
609 keyeprint ("track_down: CloseHandle()");
615 HANDLE h
= CreateFile (f
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
616 0, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, 0);
617 BY_HANDLE_FILE_INFORMATION info
;
619 if (!GetFileInformationByHandle (h
, &info
))
620 keyeprint ("ls: GetFileInformationByHandle()");
624 if (!FileTimeToSystemTime (&info
.ftLastWriteTime
, &systime
))
625 keyeprint ("ls: FileTimeToSystemTime()");
626 printf ("%5dk %04d/%02d/%02d %s",
627 (((int) info
.nFileSizeLow
) + 512) / 1024,
628 systime
.wYear
, systime
.wMonth
, systime
.wDay
, f
);
629 dll_info (f
, h
, 16, 0);
630 if (!CloseHandle (h
))
631 keyeprint ("ls: CloseHandle()");
637 char *papp
= find_on_path (app
, (char *) ".exe", 1, 0);
640 printf ("Error: could not find %s\n", app
);
643 char *s
= strdup (papp
);
646 if (*t
== '/' || *t
== '\\' || *t
== ':')
649 paths
[0] = (char *) ".";
656 track_down (papp
, (char *) ".exe", 0);
660 extern char **environ
;
670 show_reg (RegInfo
* ri
, int nest
)
674 show_reg (ri
->prev
, 1);
676 printf ("%s\\", ri
->name
);
678 printf ("%s\n", ri
->name
);
682 scan_registry (RegInfo
* prev
, HKEY hKey
, char *name
, int cygnus
)
690 for (cp
= name
; *cp
; cp
++)
691 if (strncasecmp (cp
, "cygnus", 6) == 0)
694 DWORD num_subkeys
, max_subkey_len
, num_values
;
695 DWORD max_value_len
, max_valdata_len
, i
;
696 if (RegQueryInfoKey (hKey
, 0, 0, 0, &num_subkeys
, &max_subkey_len
, 0,
697 &num_values
, &max_value_len
, &max_valdata_len
, 0, 0)
702 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
, 0, GetLastError (),
703 MAKELANGID (LANG_NEUTRAL
, SUBLANG_DEFAULT
), tmp
, 400, 0);
704 printf ("RegQueryInfoKey: %s\n", tmp
);
713 char *value_name
= (char *) malloc (max_value_len
+ 1);
714 if (value_name
== NULL
)
716 keyeprint ("scan_registry: malloc()");
720 char *value_data
= (char *) malloc (max_valdata_len
+ 1);
721 if (value_data
== NULL
)
723 keyeprint ("scan_registry: malloc()");
727 for (i
= 0; i
< num_values
; i
++)
729 DWORD dlen
= max_valdata_len
+ 1;
730 DWORD nlen
= max_value_len
+ 1;
732 RegEnumValue (hKey
, i
, value_name
, &nlen
, 0,
733 &type
, (BYTE
*) value_data
, &dlen
);
735 printf (" %s = ", i
? value_name
: "(default)");
739 printf ("0x%08x\n", *(unsigned *) value_data
);
743 printf ("`%s'\n", value_data
);
746 printf ("(unsupported type)\n");
755 char *subkey_name
= (char *) malloc (max_subkey_len
+ 1);
756 for (i
= 0; i
< num_subkeys
; i
++)
758 if (RegEnumKey (hKey
, i
, subkey_name
, max_subkey_len
+ 1) ==
762 if (RegOpenKeyEx (hKey
, subkey_name
, 0, KEY_READ
, &sKey
)
765 scan_registry (&ri
, sKey
, subkey_name
, cygnus
);
766 if (RegCloseKey (sKey
) != ERROR_SUCCESS
)
767 keyeprint ("scan_registry: RegCloseKey()");
775 pretty_id (const char *s
, char *cygwin
, size_t cyglen
)
779 strcpy (cygwin
+ cyglen
++, " ");
780 strcpy (cygwin
+ cyglen
, s
);
783 char *id
= cygpath ("/bin/id.exe", NULL
);
784 for (char *p
= id
; (p
= strchr (p
, '/')); p
++)
787 if (access (id
, X_OK
))
789 fprintf (stderr
, "`id' program not found\n");
793 FILE *f
= popen (id
, "rt");
797 fgets (buf
, sizeof (buf
), f
);
799 char *uid
= strtok (buf
, ")");
801 uid
+= strlen ("uid=");
804 fprintf (stderr
, "garbled output from `id' command - no uid= found\n");
807 char *gid
= strtok (NULL
, ")");
809 gid
+= strlen ("gid=") + 1;
812 fprintf (stderr
, "garbled output from `id' command - no gid= found\n");
816 char **ng
= groups
- 1;
817 size_t len_uid
= strlen ("UID: )") + strlen (uid
);
818 size_t len_gid
= strlen ("GID: )") + strlen (gid
);
819 *++ng
= groups
[0] = (char *) alloca (len_uid
+ 1);
820 *++ng
= groups
[1] = (char *) alloca (len_gid
+ 1);
821 sprintf (groups
[0], "UID: %s)", uid
);
822 sprintf (groups
[1], "GID: %s)", gid
);
823 size_t sz
= max (len_uid
, len_gid
);
824 while ((*++ng
= strtok (NULL
, ",")))
826 char *p
= strchr (*ng
, '\n');
829 if (ng
== groups
+ 2)
830 *ng
+= strlen (" groups=");
831 size_t len
= strlen (*ng
);
837 printf ("\nOutput from %s (%s)\n", id
, s
);
838 int n
= 80 / (int) ++sz
;
839 int i
= n
> 2 ? n
- 2 : 0;
841 for (char **g
= groups
; g
<= ng
; g
++)
842 if ((g
!= ng
) && (++i
< n
))
843 printf ("%*s", sz
, *g
);
857 char *found_cygwin_dll
;
859 printf ("\nCygwin Configuration Diagnostics\n");
861 printf ("Current System Time: %s\n", ctime (&now
));
863 OSVERSIONINFO osversion
;
864 osversion
.dwOSVersionInfoSize
= sizeof (osversion
);
865 if (!GetVersionEx (&osversion
))
866 keyeprint ("dump_sysinfo: GetVersionEx()");
867 char *osname
= (char *) "unknown OS";
868 switch (osversion
.dwPlatformId
)
870 case VER_PLATFORM_WIN32s
:
871 osname
= (char *) "32s";
873 case VER_PLATFORM_WIN32_WINDOWS
:
874 switch (osversion
.dwMinorVersion
)
877 if (strchr (osversion
.szCSDVersion
, 'C'))
878 osname
= (char *) "95 OSR2";
880 osname
= (char *) "95";
883 if (strchr (osversion
.szCSDVersion
, 'A'))
884 osname
= (char *) "98 SE";
886 osname
= (char *) "98";
889 osname
= (char *) "ME";
892 osname
= (char *) "9X";
896 case VER_PLATFORM_WIN32_NT
:
897 if (osversion
.dwMajorVersion
== 5)
899 BOOL more_info
= FALSE
;
900 OSVERSIONINFOEX osversionex
;
901 osversionex
.dwOSVersionInfoSize
= sizeof (osversionex
);
902 if (GetVersionEx ((OSVERSIONINFO
*) &osversionex
))
904 if (osversion
.dwMinorVersion
== 0)
907 osname
= (char *) "2000";
908 else if (osversionex
.wProductType
== VER_NT_SERVER
909 || osversionex
.wProductType
==
910 VER_NT_DOMAIN_CONTROLLER
)
912 if (osversionex
.wSuiteMask
&VER_SUITE_DATACENTER
)
913 osname
= (char *) "2000 Datacenter Server";
914 else if (osversionex
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
915 osname
= (char *) "2000 Advanced Server";
917 osname
= (char *) "2000 Server";
920 osname
= (char *) "2000 Professional";
925 osname
= (char *) "XP";
926 else if (osversionex
.wProductType
== VER_NT_SERVER
927 || osversionex
.wProductType
==
928 VER_NT_DOMAIN_CONTROLLER
)
930 if (osversionex
.wSuiteMask
& VER_SUITE_ENTERPRISE
)
931 osname
= (char *) ".NET Enterprise Server";
933 osname
= (char *) ".NET Server";
935 else if (osversionex
.wSuiteMask
& VER_SUITE_PERSONAL
)
936 osname
= (char *) "XP Home Edition";
938 osname
= (char *) "XP Professional";
943 osname
= (char *) "NT";
946 osname
= (char *) "??";
949 printf ("Windows %s Ver %lu.%lu Build %lu %s\n\n", osname
,
950 osversion
.dwMajorVersion
, osversion
.dwMinorVersion
,
951 osversion
.dwPlatformId
== VER_PLATFORM_WIN32_NT
?
952 osversion
.dwBuildNumber
: (osversion
.dwBuildNumber
& 0xffff),
953 osversion
.dwPlatformId
== VER_PLATFORM_WIN32_NT
?
954 osversion
.szCSDVersion
: "");
957 char *s
= getenv ("PATH"), *e
;
958 char sep
= strchr (s
, ';') ? ';' : ':';
959 int count_path_items
= 0;
962 for (e
= s
; *e
&& *e
!= sep
; e
++);
964 printf ("\t%.*s\n", e
- s
, s
);
975 char *cygwin
= getenv ("CYGWIN");
977 cygwin
-= strlen ("CYGWIN=");
979 cygwin
= const_cast <char *> ("CYGWIN=");
980 size_t cyglen
= strlen (cygwin
);
981 cygwin
= strcpy ((char *) malloc (cyglen
+ sizeof (" nontsec")), cygwin
);
982 pretty_id ("nontsec", cygwin
, cyglen
);
983 pretty_id ("ntsec", cygwin
, cyglen
);
987 if (!GetSystemDirectory (tmp
, 4000))
988 keyeprint ("dump_sysinfo: GetSystemDirectory()");
989 printf ("\nSysDir: %s\n", tmp
);
991 GetWindowsDirectory (tmp
, 4000);
992 printf ("WinDir: %s\n\n", tmp
);
996 printf ("Here's some environment variables that may affect cygwin:\n");
997 for (i
= 0; environ
[i
]; i
++)
999 char *eq
= strchr (environ
[i
], '=');
1002 /* int len = eq - environ[i]; */
1003 for (j
= 0; known_env_vars
[j
]; j
++)
1006 if (strcmp (environ
[i
], "PATH") == 0)
1007 continue; /* we handle this one specially */
1008 if (strcasecmp (environ
[i
], known_env_vars
[j
]) == 0)
1009 printf ("%s = `%s'\n", environ
[i
], eq
+ 1);
1018 printf ("Here's the rest of your environment variables:\n");
1019 for (i
= 0; environ
[i
]; i
++)
1022 char *eq
= strchr (environ
[i
], '=');
1025 /* int len = eq - environ[i]; */
1026 for (j
= 0; known_env_vars
[j
]; j
++)
1029 if (strcasecmp (environ
[i
], known_env_vars
[j
]) == 0)
1036 printf ("%s = `%s'\n", environ
[i
], eq
+ 1);
1046 printf ("Scanning registry for keys with `Cygnus' in them...\n");
1048 /* big and not generally useful */
1049 scan_registry (0, HKEY_CLASSES_ROOT
, (char *) "HKEY_CLASSES_ROOT", 0);
1051 scan_registry (0, HKEY_CURRENT_CONFIG
,
1052 (char *) "HKEY_CURRENT_CONFIG", 0);
1053 scan_registry (0, HKEY_CURRENT_USER
, (char *) "HKEY_CURRENT_USER", 0);
1054 scan_registry (0, HKEY_LOCAL_MACHINE
, (char *) "HKEY_LOCAL_MACHINE", 0);
1056 /* the parts we need are duplicated in HKEY_CURRENT_USER anyway */
1057 scan_registry (0, HKEY_USERS
, (char *) "HKEY_USERS", 0);
1062 printf ("Use `-r' to scan registry\n\n");
1066 printf ("Listing available drives...\n");
1067 printf ("Drv Type Size Free Flags Name\n");
1070 SetErrorMode (SEM_FAILCRITICALERRORS
| SEM_NOOPENFILEERRORBOX
);
1071 int drivemask
= GetLogicalDrives ();
1073 HINSTANCE k32
= LoadLibrary ("kernel32.dll");
1074 BOOL (WINAPI
* gdfse
) (LPCSTR
, long long *, long long *, long long *) =
1075 (BOOL (WINAPI
*) (LPCSTR
, long long *, long long *, long long *))
1076 GetProcAddress (k32
, "GetDiskFreeSpaceExA");
1078 for (i
= 0; i
< 26; i
++)
1080 if (!(drivemask
& (1 << i
)))
1082 char drive
[4], name
[200], fsname
[200];
1083 DWORD serno
= 0, maxnamelen
= 0, flags
= 0;
1084 name
[0] = name
[0] = fsname
[0] = 0;
1085 sprintf (drive
, "%c:\\", i
+ 'a');
1086 /* Report all errors, except if the Volume is ERROR_NOT_READY.
1087 ERROR_NOT_READY is returned when removeable media drives are empty
1088 (CD, floppy, etc.) */
1089 if (!GetVolumeInformation
1090 (drive
, name
, sizeof (name
), &serno
, &maxnamelen
, &flags
, fsname
,
1091 sizeof (fsname
)) && GetLastError () != ERROR_NOT_READY
)
1092 keyeprint ("dump_sysinfo: GetVolumeInformation()");
1094 int dtype
= GetDriveType (drive
);
1095 char drive_type
[4] = "unk";
1098 case DRIVE_REMOVABLE
:
1099 strcpy (drive_type
, "fd ");
1102 strcpy (drive_type
, "hd ");
1105 strcpy (drive_type
, "net");
1108 strcpy (drive_type
, "cd ");
1111 strcpy (drive_type
, "ram");
1114 strcpy (drive_type
, "unk");
1117 long capacity_mb
= -1;
1118 int percent_full
= -1;
1120 long long free_me
= 0ULL, free_bytes
= 0ULL, total_bytes
= 1ULL;
1121 if (gdfse
!= NULL
&& gdfse (drive
, &free_me
, &total_bytes
, &free_bytes
))
1123 capacity_mb
= total_bytes
/ (1024L * 1024L);
1124 percent_full
= 100 - (int) ((100.0 * free_me
) / total_bytes
);
1128 DWORD spc
= 0, bps
= 0, fc
= 0, tc
= 1;
1129 if (GetDiskFreeSpace (drive
, &spc
, &bps
, &fc
, &tc
))
1131 capacity_mb
= (spc
* bps
* tc
) / (1024 * 1024);
1132 percent_full
= 100 - (int) ((100.0 * fc
) / tc
);
1136 printf ("%.2s %s %-6s ", drive
, drive_type
, fsname
);
1137 if (capacity_mb
>= 0)
1138 printf ("%5dMb %3d%% ", (int) capacity_mb
, (int) percent_full
);
1140 printf (" N/A N/A ");
1141 printf ("%s %s %s %s %s %s %s\n",
1142 flags
& FS_CASE_IS_PRESERVED
? "CP" : " ",
1143 flags
& FS_CASE_SENSITIVE
? "CS" : " ",
1144 flags
& FS_UNICODE_STORED_ON_DISK
? "UN" : " ",
1145 flags
& FS_PERSISTENT_ACLS
? "PA" : " ",
1146 flags
& FS_FILE_COMPRESSION
? "FC" : " ",
1147 flags
& FS_VOL_IS_COMPRESSED
? "VC" : " ",
1149 flags
& FILE_SUPPORTS_ENCRYPTION
? "EN" : " ",
1150 flags
& FILE_SUPPORTS_OBJECT_IDS
? "OI" : " ",
1151 flags
& FILE_SUPPORTS_REPARSE_POINTS
? "RP" : " ",
1152 flags
& FILE_SUPPORTS_SPARSE_FILES
? "SP" : " ",
1153 flags
& FILE_VOLUME_QUOTAS
? "QU" : " ",
1158 if (!FreeLibrary (k32
))
1159 keyeprint ("dump_sysinfo: FreeLibrary()");
1160 SetErrorMode (prev_mode
);
1163 printf ("fd=floppy, hd=hard drive, cd=CD-ROM, net=Network Share\n");
1164 printf ("CP=Case Preserving, CS=Case Sensitive, UN=Unicode\n");
1166 ("PA=Persistent ACLS, FC=File Compression, VC=Volume Compression\n");
1170 unsigned ml_fsname
= 4, ml_dir
= 7, ml_type
= 6;
1171 bool ml_trailing
= false;
1175 while ((mnt
= getmntent (0)))
1177 unsigned n
= (int) strlen (mnt
->mnt_fsname
);
1178 ml_trailing
|= (n
> 1 && strchr ("\\/", mnt
->mnt_fsname
[n
- 1]));
1181 n
= (int) strlen (mnt
->mnt_dir
);
1182 ml_trailing
|= (n
> 1 && strchr ("\\/", mnt
->mnt_dir
[n
- 1]));
1188 puts ("Warning: Mount entries should not have a trailing (back)slash\n");
1193 ("Mount entries: these map POSIX directories to your NT drives.\n");
1194 printf ("%-*s %-*s %-*s %s\n", ml_fsname
, "-NT-", ml_dir
, "-POSIX-",
1195 ml_type
, "-Type-", "-Flags-");
1199 while ((mnt
= getmntent (0)))
1201 printf ("%-*s %-*s %-*s %s\n",
1202 ml_fsname
, mnt
->mnt_fsname
,
1203 ml_dir
, mnt
->mnt_dir
, ml_type
, mnt
->mnt_type
, mnt
->mnt_opts
);
1207 add_path ((char *) "\\bin", 4); /* just in case */
1211 ("Looking to see where common programs can be found, if at all...\n");
1212 for (i
= 0; common_apps
[i
].name
; i
++)
1213 if (!find_on_path ((char *) common_apps
[i
].name
, (char *) ".exe", 1, 0))
1215 if (common_apps
[i
].missing_is_good
)
1216 printf ("Not Found: %s (good!)\n", common_apps
[i
].name
);
1218 printf ("Not Found: %s\n", common_apps
[i
].name
);
1223 printf ("Looking for various Cygnus DLLs... (-v gives version info)\n");
1224 for (i
= 0; i
< num_paths
; i
++)
1226 WIN32_FIND_DATA ffinfo
;
1227 sprintf (tmp
, "%s/*.*", paths
[i
]);
1228 HANDLE ff
= FindFirstFile (tmp
, &ffinfo
);
1229 int found
= (ff
!= INVALID_HANDLE_VALUE
);
1230 found_cygwin_dll
= NULL
;
1233 char *f
= ffinfo
.cFileName
;
1234 if (strcasecmp (f
+ strlen (f
) - 4, ".dll") == 0)
1236 if (strncasecmp (f
, "cyg", 3) == 0)
1238 sprintf (tmp
, "%s\\%s", paths
[i
], f
);
1239 if (strcasecmp (f
, "cygwin1.dll") == 0)
1240 found_cygwin_dll
= strdup (tmp
);
1245 found
= FindNextFile (ff
, &ffinfo
);
1247 if (found_cygwin_dll
)
1249 ls (found_cygwin_dll
);
1250 free (found_cygwin_dll
);
1260 HANDLE h
= CreateFileA ("CONIN$", GENERIC_READ
| GENERIC_WRITE
,
1261 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
1262 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1264 if (h
== INVALID_HANDLE_VALUE
|| h
== NULL
)
1265 return (keyeprint ("check_key: Opening CONIN$"));
1269 if (!GetConsoleMode (h
, &mode
))
1270 keyeprint ("check_keys: GetConsoleMode()");
1273 mode
&= ~ENABLE_PROCESSED_INPUT
;
1274 if (!SetConsoleMode (h
, mode
))
1275 keyeprint ("check_keys: GetConsoleMode()");
1278 fputs ("\nThis key check works only in a console window,", stderr
);
1279 fputs (" _NOT_ in a terminal session!\n", stderr
);
1280 fputs ("Abort with Ctrl+C if in a terminal session.\n\n", stderr
);
1281 fputs ("Press `q' to exit.\n", stderr
);
1283 INPUT_RECORD in
, prev_in
;
1285 // Drop first <RETURN> key
1286 ReadConsoleInput (h
, &in
, 1, &mode
);
1288 memset (&in
, 0, sizeof in
);
1293 if (!ReadConsoleInput (h
, &in
, 1, &mode
))
1294 keyeprint ("ReadConsoleInput");
1296 if (!memcmp (&in
, &prev_in
, sizeof in
))
1299 switch (in
.EventType
)
1302 printf ("%s %ux VK: 0x%02x VS: 0x%02x A: 0x%02x CTRL: ",
1303 in
.Event
.KeyEvent
.bKeyDown
? "Pressed " : "Released",
1304 in
.Event
.KeyEvent
.wRepeatCount
,
1305 in
.Event
.KeyEvent
.wVirtualKeyCode
,
1306 in
.Event
.KeyEvent
.wVirtualScanCode
,
1307 (unsigned char) in
.Event
.KeyEvent
.uChar
.AsciiChar
);
1308 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& CAPSLOCK_ON
?
1309 "CL " : "-- ", stdout
);
1310 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& ENHANCED_KEY
?
1311 "EK " : "-- ", stdout
);
1312 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& LEFT_ALT_PRESSED
?
1313 "LA " : "-- ", stdout
);
1314 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& LEFT_CTRL_PRESSED
?
1315 "LC " : "-- ", stdout
);
1316 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& NUMLOCK_ON
?
1317 "NL " : "-- ", stdout
);
1318 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& RIGHT_ALT_PRESSED
?
1319 "RA " : "-- ", stdout
);
1320 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& RIGHT_CTRL_PRESSED
?
1321 "RC " : "-- ", stdout
);
1322 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& SCROLLLOCK_ON
?
1323 "SL " : "-- ", stdout
);
1324 fputs (in
.Event
.KeyEvent
.dwControlKeyState
& SHIFT_PRESSED
?
1325 "SH " : "-- ", stdout
);
1326 fputc ('\n', stdout
);
1333 while (in
.EventType
!= KEY_EVENT
||
1334 in
.Event
.KeyEvent
.bKeyDown
!= FALSE
||
1335 in
.Event
.KeyEvent
.uChar
.AsciiChar
!= 'q');
1342 usage (FILE * stream
, int status
)
1345 Usage: cygcheck [OPTIONS] [PROGRAM...]\n\
1346 Check system information or PROGRAM library dependencies\n\
1348 -c, --check-setup check packages installed via setup.exe\n\
1349 -d, --dump-only no integrity checking of package contents (requires -c)\n\
1350 -s, --sysinfo system information (not with -k)\n\
1351 -v, --verbose verbose output (indented) (for -[cfls] or programs)\n\
1352 -r, --registry registry search (requires -s)\n\
1353 -k, --keycheck perform a keyboard check session (not with -[scfl])\n\
1354 -f, --find-package find installed packages containing files (not with -[cl])\n\
1355 -l, --list-package list the contents of installed packages (not with -[cf])\n\
1356 -h, --help give help about the info (not with -[cfl])\n\
1357 -V, --version output version information and exit\n\
1358 You must at least give either -s or -k or a program name\n");
1362 struct option longopts
[] = {
1363 {"check-setup", no_argument
, NULL
, 'c'},
1364 {"dump-only", no_argument
, NULL
, 'd'},
1365 {"sysinfo", no_argument
, NULL
, 's'},
1366 {"registry", no_argument
, NULL
, 'r'},
1367 {"verbose", no_argument
, NULL
, 'v'},
1368 {"keycheck", no_argument
, NULL
, 'k'},
1369 {"find-package", no_argument
, NULL
, 'f'},
1370 {"list-package", no_argument
, NULL
, 'l'},
1371 {"help", no_argument
, NULL
, 'h'},
1372 {"version", no_argument
, 0, 'V'},
1373 {0, no_argument
, NULL
, 0}
1376 static char opts
[] = "cdfhklrsvV";
1381 const char *v
= strchr (version
, ':');
1391 len
= strchr (v
, ' ') - v
;
1394 cygcheck version %.*s\n\
1395 System Checker for Cygwin\n\
1396 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.\n\
1398 ", len
, v
, __DATE__
);
1402 main (int argc
, char **argv
)
1406 (void) putenv("POSIXLY_CORRECT=1");
1407 while ((i
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) != EOF
)
1446 if (argc
== 0 && !sysinfo
&& !keycheck
&& !check_setup
)
1452 if ((check_setup
|| sysinfo
|| find_package
|| list_package
) && keycheck
)
1455 if ((find_package
|| list_package
) && check_setup
)
1458 if (dump_only
&& !check_setup
)
1461 if (find_package
&& list_package
)
1465 return check_keys ();
1469 /* FIXME: Add help for check_setup and {list,find}_package */
1470 if (argc
>= 1 && givehelp
&& !check_setup
&& !find_package
&& !list_package
)
1472 printf("Here is where the OS will find your program%s, and which dlls\n",
1473 argc
> 1 ? "s" : "");
1474 printf ("will be used for it. Use -v to see DLL version info\n");
1482 dump_setup (verbose
, argv
, !dump_only
);
1484 else if (find_package
)
1486 package_find (verbose
, argv
);
1488 else if (list_package
)
1490 package_list (verbose
, argv
);
1493 for (i
= 0; i
< argc
; i
++)
1506 dump_setup (verbose
, NULL
, false);
1510 puts ("Use -h to see help about each section");