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.

167 lines
5.4 KiB

  1. // --------------------------------------------------------------------------------
  2. // u s e r a g n t . h
  3. //
  4. // author: Greg Friedman [gregfrie]
  5. //
  6. // converted to wab: Christopher Evans [cevans]
  7. //
  8. // history: 11-10-98 Created
  9. //
  10. // purpose: provide a common http user agent string for use by WAB
  11. // in all http queries.
  12. //
  13. // dependencies: depends on ObtainUserAgent function in urlmon.
  14. //
  15. // Copyright (c) 1998 Microsoft Corporation, All Rights Reserved
  16. // --------------------------------------------------------------------------------
  17. #include "_apipch.h"
  18. #include <iert.h>
  19. #include "useragnt.h"
  20. #include "demand.h"
  21. #include <string.h>
  22. static LPSTR g_pszWABUserAgent = NULL;
  23. CRITICAL_SECTION g_csWABUserAgent = {0};
  24. LPSTR c_szCompatible = "compatible";
  25. LPSTR c_szEndUATokens = ")";
  26. LPSTR c_szWABUserAgent = "Windows-Address-Book/6.0";
  27. LPSTR c_szBeginUATokens = " (";
  28. LPSTR c_szSemiColonSpace = "; ";
  29. // --------------------------------------------------------------------------------
  30. // PszSkipWhiteA
  31. // --------------------------------------------------------------------------
  32. static LPSTR PszSkipWhiteA(LPSTR psz)
  33. {
  34. while(*psz && (*psz == ' ' || *psz == '\t'))
  35. psz++;
  36. return psz;
  37. }
  38. static LPSTR _StrChrA(LPCSTR lpStart, WORD wMatch)
  39. {
  40. for ( ; *lpStart; lpStart++)
  41. {
  42. if ((BYTE)*lpStart == LOBYTE(wMatch)) {
  43. return((LPSTR)lpStart);
  44. }
  45. }
  46. return (NULL);
  47. }
  48. //----------------------------------------------------------------------
  49. // InitWABUserAgent
  50. //
  51. // Initialize or tear down WAB's user agent support.
  52. //----------------------------------------------------------------------
  53. void InitWABUserAgent(BOOL fInit)
  54. {
  55. if (fInit)
  56. InitializeCriticalSection(&g_csWABUserAgent);
  57. else
  58. {
  59. if (g_pszWABUserAgent)
  60. {
  61. LocalFree(g_pszWABUserAgent);
  62. g_pszWABUserAgent = NULL;
  63. }
  64. DeleteCriticalSection(&g_csWABUserAgent);
  65. }
  66. }
  67. //----------------------------------------------------------------------
  68. // GetWABUserAgentString
  69. //
  70. // Returns the Outlook Express user agent string. The caller MUST
  71. // delete the string that is returned.
  72. //----------------------------------------------------------------------
  73. LPSTR GetWABUserAgentString(void)
  74. {
  75. LPSTR pszReturn = NULL;
  76. // thread safety
  77. EnterCriticalSection(&g_csWABUserAgent);
  78. if (NULL == g_pszWABUserAgent)
  79. {
  80. CHAR szUrlMonUA[4048];
  81. DWORD cbSize = ARRAYSIZE(szUrlMonUA) - 1;
  82. CHAR szResult[4096];
  83. CHAR *pch, *pchBeginTok;
  84. BOOL fTokens = FALSE;
  85. HRESULT hr = S_OK;
  86. DWORD cchSize;
  87. szResult[0] = TEXT('\0');
  88. StrCpyNA(szResult, c_szWABUserAgent, ARRAYSIZE(szResult));
  89. // allow urlmon to generate our base user agent
  90. if (SUCCEEDED(ObtainUserAgentString(0, szUrlMonUA, &cbSize)))
  91. {
  92. // make sure the string we obtained is null terminated
  93. szUrlMonUA[cbSize] = '\0';
  94. // find the open beginning of the token list
  95. pch = _StrChrA(szUrlMonUA, '(');
  96. if ((NULL != pch) && pch[0])
  97. {
  98. pch++;
  99. pchBeginTok = pch;
  100. while (pch)
  101. {
  102. // find the next token
  103. pch = StrTokEx(&pchBeginTok, "(;)");
  104. if (pch)
  105. {
  106. // skip past white space
  107. pch = PszSkipWhiteA(pch);
  108. // omit the "compatible" token...it doesn't apply to WAB
  109. if (0 != lstrcmpiA(pch, c_szCompatible))
  110. {
  111. if ((lstrlenA(szResult) + lstrlenA(pch) + 5) > ARRAYSIZE(szResult))
  112. break;
  113. // begin the token list with an open paren, or insert a delimeter
  114. if (!fTokens)
  115. {
  116. StrCatBuffA(szResult, c_szBeginUATokens, ARRAYSIZE(szResult));
  117. fTokens = TRUE;
  118. }
  119. else
  120. StrCatBuffA(szResult, c_szSemiColonSpace, ARRAYSIZE(szResult));
  121. // write the token
  122. StrCatBuffA(szResult, pch, ARRAYSIZE(szResult));
  123. }
  124. }
  125. }
  126. // if one or more tokens were added, close the parens
  127. if (fTokens)
  128. StrCatBuffA(szResult, c_szEndUATokens, ARRAYSIZE(szResult));
  129. }
  130. }
  131. cchSize = (lstrlenA(szResult) + 1);
  132. g_pszWABUserAgent = LocalAlloc(LMEM_FIXED, sizeof(g_pszWABUserAgent[0]) * cchSize);
  133. if (g_pszWABUserAgent)
  134. StrCpyNA(g_pszWABUserAgent, szResult, cchSize);
  135. }
  136. // duplicate the user agent
  137. if (g_pszWABUserAgent)
  138. {
  139. DWORD cchSize2 = (lstrlenA(g_pszWABUserAgent) + 1);
  140. pszReturn = LocalAlloc(LMEM_FIXED, cchSize2 * sizeof(pszReturn[0]));
  141. if (pszReturn)
  142. StrCpyNA(pszReturn, g_pszWABUserAgent, cchSize2);
  143. }
  144. // thread safety
  145. LeaveCriticalSection(&g_csWABUserAgent);
  146. return pszReturn;
  147. }