home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / winnt / compact / support.c < prev    next >
C/C++ Source or Header  |  1997-06-17  |  8KB  |  377 lines

  1. /*++
  2.  
  3. Copyright (c) 1994-1995  Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     Support.c
  8.  
  9. Abstract:
  10.  
  11.     Support routines for compact utility
  12.  
  13. Author:
  14.  
  15.     Matthew Bradburn    [mattbr]        05-Oct-1994
  16.  
  17. Revision History:
  18.  
  19.  
  20. --*/
  21.  
  22. #define UNICODE
  23. #define _UNICODE
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <io.h>
  28. #include <windows.h>
  29. #include "support.h"
  30. #include "msg.h"
  31.  
  32.  
  33.  
  34. //
  35. //  Declare routines to put out internationalized messages
  36. //
  37.  
  38. typedef enum {
  39.     READ_ACCESS,
  40.     WRITE_ACCESS
  41. } STREAMACCESS;
  42.  
  43. HANDLE
  44. GetStandardStream(
  45.     IN HANDLE   Handle,
  46.     IN STREAMACCESS Access
  47.     );
  48.  
  49. HANDLE hInput;
  50. HANDLE hOutput;
  51. HANDLE hError;
  52.  
  53. #define STDIN   0
  54. #define STDOUT  1
  55. #define STDERR  2
  56.  
  57. BOOL ConsoleInput;
  58. BOOL ConsoleOutput;
  59. BOOL ConsoleError;
  60.  
  61. int
  62. FileIsConsole(int fh)
  63. {
  64.     unsigned htype;
  65.     DWORD dwMode;
  66.     HANDLE hFile;
  67.  
  68.     hFile = (HANDLE)_get_osfhandle(fh);
  69.     htype = GetFileType(hFile);
  70.     htype &= ~FILE_TYPE_REMOTE;
  71.  
  72.     if (FILE_TYPE_CHAR == htype) {
  73.  
  74.         switch (fh) {
  75.         case STDIN:
  76.             hFile = GetStdHandle(STD_INPUT_HANDLE);
  77.             break;
  78.         case STDOUT:
  79.             hFile = GetStdHandle(STD_OUTPUT_HANDLE);
  80.             break;
  81.         case STDERR:
  82.             hFile = GetStdHandle(STD_ERROR_HANDLE);
  83.             break;
  84.         }
  85.  
  86.         if (GetConsoleMode(hFile, &dwMode)) {
  87.             return TRUE;
  88.         }
  89.     }
  90.  
  91.     return FALSE;
  92.  
  93. }
  94.  
  95.  
  96. VOID
  97. InitializeIoStreams()
  98. {
  99. #ifdef FE_SB
  100.     LANGID LangId;
  101.  
  102.     switch (GetConsoleOutputCP()) {
  103.         case 932:
  104.             LangId = MAKELANGID( LANG_JAPANESE, SUBLANG_DEFAULT );
  105.             break;
  106.         case 949:
  107.             LangId = MAKELANGID( LANG_KOREAN, SUBLANG_KOREAN );
  108.             break;
  109.         case 936:
  110.             LangId = MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED );
  111.             break;
  112.         case 950:
  113.             LangId = MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL );
  114.             break;
  115.         default:
  116.             LangId = MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT );
  117.             break;
  118.     }
  119.  
  120.     SetThreadLocale( MAKELCID(LangId, SORT_DEFAULT) );
  121. #endif
  122.  
  123.     hInput = GetStdHandle(STD_INPUT_HANDLE);
  124.     ConsoleInput = FileIsConsole(STDIN);
  125.  
  126.     hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  127.     ConsoleOutput = FileIsConsole(STDOUT);
  128.  
  129.     hError = GetStdHandle(STD_ERROR_HANDLE);
  130.     ConsoleError = FileIsConsole(STDERR);
  131. }
  132.  
  133. TCHAR DisplayBuffer[4096];
  134. CHAR DisplayBuffer2[4096];
  135.  
  136. VOID
  137. DisplayMsg(DWORD MsgNum, ... )
  138. {
  139.     DWORD len, bytes_written;
  140.     BOOL success;
  141.     DWORD status;
  142.     va_list ap;
  143.  
  144.     va_start(ap, MsgNum);
  145.  
  146.     len = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, NULL, MsgNum, 0,
  147.         DisplayBuffer, 4096, &ap);
  148.        
  149.     if (ConsoleOutput) {
  150.         success = WriteConsole(hOutput, (LPVOID)DisplayBuffer, len,
  151.                  &bytes_written, NULL);
  152.  
  153.     } else {
  154.         CharToOem(DisplayBuffer, DisplayBuffer2);
  155.         success = WriteFile(hOutput, (LPVOID)DisplayBuffer2, len,
  156.                  &bytes_written, NULL);
  157.     }
  158.  
  159.     if (!success || bytes_written != len) {
  160.         status = GetLastError();
  161.     }
  162.  
  163.     va_end(ap);
  164. }
  165.  
  166. VOID
  167. DisplayErr(
  168.     PTCHAR Prefix,
  169.     DWORD MsgNum,
  170.     ...
  171.     )
  172. {
  173.     DWORD len, bytes_written;
  174.     BOOL success;
  175.     DWORD status;
  176.     va_list ap;
  177.     ULONG i;
  178.  
  179.     va_start(ap, MsgNum);
  180.  
  181.     if (NULL != Prefix) {
  182.         lstrcpy(DisplayBuffer, Prefix);
  183.         lstrcat(DisplayBuffer, TEXT(": "));
  184.     } else {
  185.         DisplayBuffer[0] = UNICODE_NULL;
  186.     }
  187.  
  188.     i = lstrlen(DisplayBuffer);
  189.  
  190.     len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, MsgNum, 0,
  191.         DisplayBuffer + i, 4096 - i, &ap);
  192.  
  193.     if (ConsoleError) {
  194.         success = WriteConsole(hError, (LPVOID)DisplayBuffer, len + i,
  195.                  &bytes_written, NULL);
  196.  
  197.     } else {
  198.         CharToOem(DisplayBuffer, DisplayBuffer2);
  199.         success = WriteFile(hError, (LPVOID)DisplayBuffer2, len + i,
  200.                  &bytes_written, NULL);
  201.     }
  202.  
  203.     if (!success) {
  204.         status = GetLastError();
  205.     }    
  206.     va_end(ap);
  207. }
  208.  
  209. BOOLEAN
  210. IsNtldr(
  211.     PTCHAR Path
  212.     )
  213. /*++
  214.  
  215. Routine Description:
  216.  
  217.     Used to keep the user from compressing \NTLDR (which would prevent
  218.     the machine from booting).
  219.     
  220. Arguments:
  221.  
  222.     Path - the path to examine.
  223.  
  224. Return Value:
  225.  
  226.     TRUE - the path looks like \ntldr.
  227.     FALSE - the path does not look like \ntldr.
  228.     
  229. --*/
  230. {
  231.     PTCHAR pch;
  232.  
  233.     // try "X:\ntldr"
  234.  
  235.     if (0 == lstricmp(Path + 2, TEXT("\\ntldr"))) {
  236.         return TRUE;
  237.     }
  238.  
  239.     // try "\\machine\share\ntldr"
  240.  
  241.     if ('\\' == Path[0] && '\\' != Path[1]) {
  242.         pch = lstrchr(Path + 2, '\\');
  243.         if (NULL == pch) {
  244.             return FALSE;
  245.         }
  246.         pch = lstrchr(pch + 1, '\\');
  247.         if (NULL == pch) {
  248.             return FALSE;
  249.         }
  250.         if (0 == lstricmp(pch, TEXT("\\ntldr"))) {
  251.             return TRUE;
  252.         }
  253.     }
  254.  
  255.     return FALSE;
  256. }
  257.  
  258. BOOLEAN
  259. IsUncRoot(
  260.     PTCHAR Path
  261.     )
  262. /*++
  263.  
  264. Routine Description:
  265.  
  266.     Determine whether the given path is of the form \\server\share.
  267.     
  268. Arguments:
  269.  
  270.     Path - the path to examine.
  271.  
  272. Return Value:
  273.  
  274.     TRUE - the path looks like a unc share name.
  275.     FALSE - the path does not look like that.
  276.     
  277. --*/
  278. {
  279.     PTCHAR pch;
  280.  
  281.     if ('\\' != *Path || '\\' != *(Path + 1)) {
  282.         return FALSE;
  283.     }
  284.  
  285.     pch = lstrchr(Path + 2, '\\');
  286.     if (NULL == pch) {
  287.         //
  288.         // There is no slash to seperate server and share.
  289.         //
  290.  
  291.         return FALSE;
  292.     }
  293.  
  294.     pch = lstrchr(pch + 1, '\\');
  295.     if (NULL != pch) {
  296.         //
  297.         // There are additional component -- no match.
  298.         //
  299.  
  300.         return FALSE;
  301.     }
  302.  
  303.     if ('\\' == *(Path + lstrlen(Path))) {
  304.     
  305.         //
  306.         // The string ends in slash -- it doesn't match.
  307.         //
  308.  
  309.         return FALSE;
  310.     }
  311.     
  312.     return TRUE;
  313. }
  314.  
  315. ULONG
  316. FormatFileSize(
  317.     IN PLARGE_INTEGER FileSize,
  318.     IN DWORD Width,
  319.     OUT PTCHAR FormattedSize,
  320.     IN BOOLEAN Commas
  321.     )
  322. {
  323.     TCHAR Buffer[100];
  324.     PTCHAR s, s1;
  325.     ULONG DigitIndex, Digit;
  326.     ULONG Size;
  327.     LARGE_INTEGER TempSize;
  328.  
  329.     s = &Buffer[ 99 ];
  330.     *s = TEXT('\0');
  331.     DigitIndex = 0;
  332.     TempSize = *FileSize;
  333.     while (TempSize.HighPart != 0) {
  334.         if (TempSize.HighPart != 0) {
  335.             Digit = (ULONG)(TempSize.QuadPart % 10);
  336.             TempSize.QuadPart = TempSize.QuadPart / 10;
  337.         } else {
  338.             Digit = TempSize.LowPart % 10;
  339.             TempSize.LowPart = TempSize.LowPart / 10;
  340.         }
  341.         *--s = (TCHAR)(TEXT('0') + Digit);
  342.  
  343.         if ((++DigitIndex % 3) == 0 && Commas) {
  344.             *--s = TEXT(',');
  345.         }
  346.     }
  347.     Size = TempSize.LowPart;
  348.     while (Size != 0) {
  349.         *--s = (TCHAR)(TEXT('0') + (Size % 10));
  350.         Size = Size / 10;
  351.  
  352.         if ((++DigitIndex % 3) == 0 && Commas) {
  353.             *--s = TEXT(',');
  354.         }
  355.     }
  356.  
  357.     if (DigitIndex == 0) {
  358.         *--s = TEXT('0');
  359.     } else if (Commas && *s == TEXT(',')) {
  360.         s += 1;
  361.     }
  362.  
  363.     Size = lstrlen( s );
  364.     if (Width != 0 && Size < Width) {
  365.         s1 = FormattedSize;
  366.         while (Width > Size) {
  367.             Width -= 1;
  368.             *s1++ = TEXT(' ');
  369.         }
  370.         lstrcpy( s1, s );
  371.     } else {
  372.         lstrcpy( FormattedSize, s );
  373.     }
  374.  
  375.     return lstrlen( FormattedSize );
  376. }
  377.