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.

139 lines
4.6 KiB

  1. // --------------------------------------------------------------------------------
  2. // u s e r a g n t . h
  3. //
  4. // author: Greg Friedman [gregfrie]
  5. //
  6. // history: 11-10-98 Created
  7. //
  8. // purpose: provide a common http user agent string for use by Outlook Express
  9. // in all http queries.
  10. //
  11. // dependencies: depends on ObtainUserAgent function in urlmon.
  12. //
  13. // Copyright (c) 1998 Microsoft Corporation, All Rights Reserved
  14. // --------------------------------------------------------------------------------
  15. #include "pch.hxx"
  16. #include <iert.h>
  17. #include "useragnt.h"
  18. #include "demand.h"
  19. static LPSTR g_pszOEUserAgent = NULL;
  20. CRITICAL_SECTION g_csOEUserAgent = {0};
  21. BOOL g_fUserAgentInit = FALSE;
  22. //----------------------------------------------------------------------
  23. // InitOEUserAgent
  24. //
  25. // Initialize or tear down OE's user agent support.
  26. //----------------------------------------------------------------------
  27. void InitOEUserAgent(BOOL fInit)
  28. {
  29. if (fInit && !g_fUserAgentInit)
  30. {
  31. InitializeCriticalSection(&g_csOEUserAgent);
  32. g_fUserAgentInit = TRUE;
  33. }
  34. else if (g_fUserAgentInit)
  35. {
  36. SafeMemFree(g_pszOEUserAgent);
  37. DeleteCriticalSection(&g_csOEUserAgent);
  38. g_fUserAgentInit = FALSE;
  39. }
  40. }
  41. //----------------------------------------------------------------------
  42. // GetOEUserAgentString
  43. //
  44. // Returns the Outlook Express user agent string. The caller MUST
  45. // delete the string that is returned.
  46. //----------------------------------------------------------------------
  47. LPSTR GetOEUserAgentString(void)
  48. {
  49. LPSTR pszReturn = NULL;
  50. Assert(g_fUserAgentInit);
  51. // thread safety
  52. EnterCriticalSection(&g_csOEUserAgent);
  53. if (NULL == g_pszOEUserAgent)
  54. {
  55. TCHAR szUrlMonUA[4048];
  56. DWORD cbSize = ARRAYSIZE(szUrlMonUA) - 1;
  57. CByteStream bs;
  58. TCHAR *pch, *pchBeginTok;
  59. BOOL fTokens = FALSE;
  60. HRESULT hr = S_OK;
  61. TCHAR szUserAgent[MAX_PATH];
  62. ULONG cchMax = MAX_PATH;
  63. DWORD type;
  64. if (ERROR_SUCCESS != SHGetValue(HKEY_LOCAL_MACHINE, c_szRegFlat,
  65. c_szAgent,
  66. &type, (LPBYTE)szUserAgent, &cchMax) || cchMax == 0)
  67. StrCpyN(szUserAgent, c_szOEUserAgent, ARRAYSIZE(szUserAgent));
  68. IF_FAILEXIT(hr = bs.Write(szUserAgent, lstrlen(szUserAgent), NULL));
  69. // allow urlmon to generate our base user agent
  70. if (SUCCEEDED(ObtainUserAgentString(0, szUrlMonUA, &cbSize)))
  71. {
  72. // make sure the string we obtained is null terminated
  73. szUrlMonUA[cbSize] = '\0';
  74. // find the open beginning of the token list
  75. pch = StrChr(szUrlMonUA, '(');
  76. if (NULL != pch)
  77. {
  78. pch++;
  79. pchBeginTok = pch;
  80. while (pch)
  81. {
  82. // find the next token
  83. pch = StrTokEx(&pchBeginTok, "(;)");
  84. if (pch)
  85. {
  86. // skip past white space
  87. pch = PszSkipWhiteA(pch);
  88. // omit the "compatible" token...it doesn't apply to oe
  89. if (0 != lstrcmpi(pch, c_szCompatible))
  90. {
  91. // begin the token list with an open paren, or insert a delimeter
  92. if (!fTokens)
  93. {
  94. fTokens = TRUE;
  95. }
  96. else
  97. IF_FAILEXIT(hr = bs.Write(c_szSemiColonSpace, lstrlen(c_szSemiColonSpace), NULL));
  98. // write the token
  99. IF_FAILEXIT(hr = bs.Write(pch, lstrlen(pch), NULL));
  100. }
  101. }
  102. }
  103. }
  104. }
  105. // if one or more tokens were added, add a semicolon before adding the end tokens
  106. if (fTokens)
  107. IF_FAILEXIT(hr = bs.Write(c_szSemiColonSpace, lstrlen(c_szSemiColonSpace), NULL));
  108. IF_FAILEXIT(hr = bs.Write(c_szEndUATokens, lstrlen(c_szEndUATokens), NULL));
  109. // adopt the string from the stream
  110. IF_FAILEXIT(hr = bs.HrAcquireStringA(NULL, &g_pszOEUserAgent, ACQ_DISPLACE));
  111. }
  112. // duplicate the user agent
  113. pszReturn = PszDupA(g_pszOEUserAgent);
  114. exit:
  115. // thread safety
  116. LeaveCriticalSection(&g_csOEUserAgent);
  117. return pszReturn;
  118. }