Leaked source code of windows server 2003
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.

225 lines
6.5 KiB

  1. //
  2. // tclnthlp.c
  3. //
  4. // There are some routines used within tclient2.c that were either
  5. // used multiple times or deserved its own function name. These
  6. // "Helper" functions are defined here.
  7. //
  8. // Copyright (C) 2001 Microsoft Corporation
  9. //
  10. // Author: a-devjen (Devin Jenson)
  11. //
  12. #include <stdlib.h>
  13. #include "tclnthlp.h"
  14. #include "tclient2.h"
  15. // T2SetBuildNumber
  16. //
  17. // Attempts to get the build number of a server we are
  18. // logging onto. We accomplish this by getting the TCLIENT.DLL
  19. // feedback buffer immediately, and enumerating all lines
  20. // for specific text along with the build number.
  21. //
  22. // Returns NULL on success, or a string explaining the error
  23. // on failure.
  24. LPCSTR T2SetBuildNumber(TSAPIHANDLE *T2Handle)
  25. {
  26. // Build the stack
  27. UINT BuildIndex = 0;
  28. WCHAR BuildNum[10] = { 0 };
  29. LPWSTR Buffers = NULL;
  30. LPWSTR BufPtr = NULL;
  31. LPWSTR TrigPtr = NULL;
  32. UINT TrigIndex = 0;
  33. UINT Index = 0;
  34. UINT Count = 0;
  35. UINT MaxStrLen = 0;
  36. LPCSTR Result = NULL;
  37. // This is the trigger list - it contains a list of strings
  38. // which exists on the same line as build numbers.
  39. WCHAR *Triggers[] = {
  40. L"Fortestingpurposesonly",
  41. L"Evaluationcopy",
  42. L""
  43. };
  44. // Get the feed back buffer so we can enumerate it
  45. Result = T2GetFeedback((HANDLE)T2Handle, &Buffers, &Count, &MaxStrLen);
  46. if (Result != NULL)
  47. return Result;
  48. // Loop through each string
  49. for (BufPtr = Buffers, Index = 0; Index < Count;
  50. BufPtr += MaxStrLen, ++Index) {
  51. // Loop through all the trigger substrings
  52. for (TrigIndex = 0; *(Triggers[TrigIndex]) != L'\0'; ++TrigIndex) {
  53. // Does this trigger exist in the current buffer string?
  54. TrigPtr = wcsstr(BufPtr, Triggers[TrigIndex]);
  55. if (TrigPtr != NULL) {
  56. // Find the first number after the trigger
  57. while (*TrigPtr != L'\0' && iswdigit(*TrigPtr) == FALSE)
  58. ++TrigPtr;
  59. // Make sure we found a digit
  60. if (*TrigPtr != L'\0') {
  61. // Begin recording this string
  62. for (BuildIndex = 0; BuildIndex < SIZEOF_ARRAY(BuildNum) - 1;
  63. ++BuildIndex) {
  64. // Record numbers until... we reach a non-number!
  65. if (iswdigit(*TrigPtr) == FALSE)
  66. break;
  67. BuildNum[BuildIndex] = *TrigPtr++;
  68. }
  69. // Convert it to a number
  70. T2Handle->BuildNumber = wcstoul(BuildNum, NULL, 10);
  71. // Free the memory on TCLIENT and return success!
  72. SCFreeMem(Buffers);
  73. return NULL;
  74. }
  75. }
  76. }
  77. }
  78. // Could not find any build number
  79. SCFreeMem(Buffers);
  80. return "A build number is not stored on the current feedback buffer";
  81. }
  82. // T2CopyStringWithoutSpaces
  83. //
  84. // This is a wide-character version of strcpy.. but additionally,
  85. // this will NOT copy spaces from the source to the destination.
  86. // This makes it fit for comparing with clxtshar strings.
  87. //
  88. // Returns the number of characters copied to the destination
  89. // (including the null terminator).
  90. ULONG_PTR T2CopyStringWithoutSpaces(LPWSTR Dest, LPCWSTR Source)
  91. {
  92. // Create temporary pointers
  93. LPWSTR SourcePtr = (LPWSTR)Source;
  94. LPWSTR DestPtr = (LPWSTR)Dest;
  95. // Sanity check the strings
  96. if (Dest == NULL || Source == NULL)
  97. return 0;
  98. // Loop the string
  99. do {
  100. // If the character is not a space, copy it over to the new buffer
  101. if (*SourcePtr != L' ')
  102. *DestPtr++ = *SourcePtr;
  103. } while(*SourcePtr++ != L'\0');
  104. // Return the number of characters
  105. return DestPtr - Dest;
  106. }
  107. // T2AddTimeoutToString
  108. //
  109. // This is a very specific function - all it does is take the specified
  110. // timeout and copy it to the string buffer. However the number is prefixed
  111. // by CHAT_SEPARATOR, meaning this allows to easily append timeouts
  112. // to a string. For example:
  113. //
  114. // "This string times out in 1 second<->1000"
  115. //
  116. // The buffer in which you would pass in is a pointer directly after the
  117. // word second. Note: this function does write a null terminator.
  118. //
  119. // No return value.
  120. void T2AddTimeoutToString(LPWSTR Buffer, UINT Timeout)
  121. {
  122. // Simply copy the chat sperator
  123. wcscpy(Buffer, CHAT_SEPARATOR);
  124. // Increment our pointer
  125. Buffer += wcslen(Buffer);
  126. // And now copy our number to the buffer
  127. _itow((int)Timeout, Buffer, 10);
  128. }
  129. // T2MakeMultipleString
  130. //
  131. // This takes an array of pointers to a string and copies them over
  132. // to a buffer which is compatible with TCLIENT.DLL format strings.
  133. // To indicate the end of an array, the last pointer must be NULL or
  134. // point to an empty string. An array can look like this:
  135. //
  136. // WCHAR *StrArray = {
  137. // "Str1",
  138. // "Str2",
  139. // NULL
  140. // };
  141. //
  142. // The function will then write the following string to Buffer:
  143. //
  144. // "Str1|Str2"
  145. //
  146. // Note: you MUST be sure Buffer has enough space yourself!
  147. //
  148. // The function returns the number of characters written to Buffer,
  149. // including the NULL terminator.
  150. ULONG_PTR T2MakeMultipleString(LPWSTR Buffer, LPCWSTR *Strings)
  151. {
  152. LPWSTR BufferPtr = Buffer;
  153. UINT Index = 0;
  154. // Sanity check
  155. if (Buffer == NULL || Strings == NULL)
  156. return 0;
  157. // Loop through the Strings array until NULL is hit
  158. for (; Strings[Index] != NULL && Strings[Index][0] != L'\0'; ++Index) {
  159. // Only write the delimeter for strings after the first string
  160. if (BufferPtr > Buffer)
  161. // Write the TCLIENT delimeter
  162. *BufferPtr++ = WAIT_STR_DELIMITER;
  163. // Use our handy function to now copy the string without spaces
  164. // after the delimiter location.
  165. BufferPtr += T2CopyStringWithoutSpaces(BufferPtr, Strings[Index]);
  166. // We are decrementing here because T2CopyStringWithoutSpaces
  167. // returns the count including the null terminator and
  168. // we may write over the terminator.
  169. --BufferPtr;
  170. }
  171. // This check is to make sure any strings were copied at all
  172. if (Buffer == BufferPtr)
  173. return 0;
  174. // Ensure a null terminator is written
  175. *(++BufferPtr) = L'\0';
  176. // We are bit
  177. return BufferPtr - Buffer;
  178. }