Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
4.6 KiB

  1. #define UNICODE 1
  2. #include <windows.h>
  3. #include <lm.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #define BUILD_NUMBER_KEY L"SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
  7. #define BUILD_NUMBER_BUFFER_LENGTH 80
  8. #define BUILD_LAB_BUFFER_LENGTH 80
  9. DWORD GetBuildNumber(LPWSTR Server, LPWSTR BuildNumber, LPWSTR BuildLab);
  10. int __cdecl
  11. main(
  12. int argc,
  13. char ** argv
  14. )
  15. {
  16. DWORD error;
  17. DWORD cb;
  18. WCHAR server[MAX_COMPUTERNAME_LENGTH + 3];
  19. WCHAR buildNumber[BUILD_NUMBER_BUFFER_LENGTH];
  20. WCHAR buildLab[BUILD_LAB_BUFFER_LENGTH];
  21. BOOLEAN bBrief = FALSE;
  22. //
  23. // All server names start with \\.
  24. //
  25. server[0] = L'\\';
  26. server[1] = L'\\';
  27. //
  28. // Get the build number for each server requested.
  29. //
  30. argc--;
  31. argv++;
  32. if (argc > 0) {
  33. if ( (*argv[0]=='-' || *argv[0]=='/') && (argv[0][1]=='b' || argv[0][1]=='B') ) {
  34. bBrief=TRUE;
  35. argc--;
  36. argv++;
  37. }
  38. }
  39. //
  40. // Get the build number of the local machine
  41. //
  42. if (argc == 0 ) {
  43. cb = MAX_COMPUTERNAME_LENGTH + 1;
  44. if ( !GetComputerName( &server[2], &cb ) ) {
  45. wcscpy( &server[2], L"Local Machine" );
  46. }
  47. error = GetBuildNumber( NULL, buildNumber, buildLab );
  48. if ( error != ERROR_SUCCESS ) {
  49. printf( "Error %d querying build number for %ws\n", error, server);
  50. } else if (bBrief) {
  51. printf( "%ws", buildNumber );
  52. } else {
  53. if (buildLab[0])
  54. printf( "%ws is running build %ws (%ws)\n", server, buildNumber, buildLab );
  55. else
  56. printf( "%ws is running build %ws\n", server, buildNumber );
  57. }
  58. } else {
  59. while ( argc ) {
  60. CHAR *p = *argv;
  61. if ( !_stricmp( p, "/?" ) || !_stricmp( p, "-?" ) ) {
  62. puts( "Usage: BUILDNUM [-b] [ServerName [servername]...]\n"
  63. " If no servername, then local machine is assumed.\n"
  64. " -b prints only the build number digits (must be 1st arg if used).\n" );
  65. return 0;
  66. }
  67. if ( !strncmp( "\\\\", p, 2 ) ) {
  68. p += 2;
  69. }
  70. if ( strlen( p ) > MAX_COMPUTERNAME_LENGTH ) {
  71. printf( "Computer name \\\\%s is too long\n", *argv );
  72. } else {
  73. WCHAR *q = &server[2];
  74. while ( *p ) {
  75. *q++ = *p++;
  76. }
  77. *q = 0;
  78. error = GetBuildNumber( server, buildNumber, buildLab );
  79. if ( error != ERROR_SUCCESS ) {
  80. printf( "Error %d querying build number for %ws\n", error, server );
  81. } else if (bBrief) {
  82. printf( "%ws", buildNumber );
  83. } else {
  84. if (buildLab[0])
  85. printf( "%ws is running build %ws (%ws)\n", server, buildNumber, buildLab );
  86. else
  87. printf( "%ws is running build %ws\n", server, buildNumber );
  88. }
  89. }
  90. argc--;
  91. argv++;
  92. }
  93. }
  94. return 0;
  95. } // main
  96. DWORD
  97. GetBuildNumber(
  98. LPWSTR Server,
  99. LPWSTR BuildNumber,
  100. LPWSTR BuildLab
  101. )
  102. {
  103. DWORD error;
  104. HKEY key;
  105. HKEY keyBuildNumber;
  106. DWORD buildNumberLength;
  107. DWORD keyType;
  108. if ( Server == NULL ) {
  109. key = HKEY_LOCAL_MACHINE;
  110. }
  111. error = RegConnectRegistry( Server, HKEY_LOCAL_MACHINE, &key );
  112. if ( error != ERROR_SUCCESS ) {
  113. return error;
  114. }
  115. error = RegOpenKeyEx( key, BUILD_NUMBER_KEY, 0, KEY_READ, &keyBuildNumber );
  116. if ( error != ERROR_SUCCESS) {
  117. return error;
  118. }
  119. buildNumberLength = BUILD_NUMBER_BUFFER_LENGTH * sizeof(WCHAR);
  120. error = RegQueryValueEx(
  121. keyBuildNumber,
  122. L"CurrentBuildNumber",
  123. NULL,
  124. &keyType,
  125. (LPBYTE)BuildNumber,
  126. &buildNumberLength
  127. );
  128. if ( error != ERROR_SUCCESS ) {
  129. error = RegQueryValueEx(
  130. keyBuildNumber,
  131. L"CurrentBuild",
  132. NULL,
  133. &keyType,
  134. (LPBYTE)BuildNumber,
  135. &buildNumberLength
  136. );
  137. }
  138. buildNumberLength = BUILD_LAB_BUFFER_LENGTH * sizeof(WCHAR);
  139. if (RegQueryValueEx(
  140. keyBuildNumber,
  141. L"BuildLab",
  142. NULL,
  143. &keyType,
  144. (LPBYTE)BuildLab,
  145. &buildNumberLength
  146. ) != ERROR_SUCCESS )
  147. {
  148. *BuildLab = 0;
  149. }
  150. RegCloseKey( keyBuildNumber );
  151. RegCloseKey( key );
  152. return error;
  153. } // GetBuildNumber