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.

301 lines
7.4 KiB

  1. // KeyocxCtrl.cpp : Implementation of CKeyocxCtrl
  2. #include "stdafx.h"
  3. #include "keyocx.h"
  4. #include "KeyocxCtrl.h"
  5. /////////////////////////////////////////////////////////////////////////////
  6. // CKeyocxCtrl
  7. HRESULT CKeyocxCtrl::OnDraw(ATL_DRAWINFO& di)
  8. {
  9. RECT& rc = *(RECT*)di.prcBounds;
  10. Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);
  11. DrawText(di.hdcDraw, _T("ATL 2.0"), -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  12. return S_OK;
  13. }
  14. BOOL ChrCmpA_inline(WORD w1, WORD wMatch)
  15. {
  16. /* Most of the time this won't match, so test it first for speed.
  17. */
  18. if (LOBYTE(w1) == LOBYTE(wMatch))
  19. {
  20. if (IsDBCSLeadByte(LOBYTE(w1)))
  21. {
  22. return(w1 != wMatch);
  23. }
  24. return FALSE;
  25. }
  26. return TRUE;
  27. }
  28. LPSTR FAR ANSIStrChr(LPCSTR lpStart, WORD wMatch)
  29. {
  30. for ( ; *lpStart; lpStart = CharNext(lpStart))
  31. {
  32. // (ChrCmp returns FALSE when characters match)
  33. if (!ChrCmpA_inline(*(UNALIGNED WORD FAR *)lpStart, wMatch))
  34. return((LPSTR)lpStart);
  35. }
  36. return (NULL);
  37. }
  38. LPSTR FAR ANSIStrRChr(LPCSTR lpStart, WORD wMatch)
  39. {
  40. LPCSTR lpFound = NULL;
  41. for ( ; *lpStart; lpStart = CharNext(lpStart))
  42. {
  43. // (ChrCmp returns FALSE when characters match)
  44. if (!ChrCmpA_inline(*(UNALIGNED WORD FAR *)lpStart, wMatch))
  45. lpFound = lpStart;
  46. }
  47. return ((LPSTR)lpFound);
  48. }
  49. PathRemoveFileSpec(
  50. LPSTR pFile)
  51. {
  52. LPSTR pT;
  53. LPSTR pT2 = pFile;
  54. for (pT = pT2; *pT2; pT2 = CharNext(pT2)) {
  55. if (*pT2 == '\\')
  56. pT = pT2; // last "\" found, (we will strip here)
  57. else if (*pT2 == ':') { // skip ":\" so we don't
  58. if (pT2[1] =='\\') // strip the "\" from "C:\"
  59. pT2++;
  60. pT = pT2 + 1;
  61. }
  62. }
  63. if (*pT == 0)
  64. return FALSE; // didn't strip anything
  65. //
  66. // handle the \foo case
  67. //
  68. else if ((pT == pFile) && (*pT == '\\')) {
  69. // Is it just a '\'?
  70. if (*(pT+1) != '\0') {
  71. // Nope.
  72. *(pT+1) = '\0';
  73. return TRUE; // stripped something
  74. }
  75. else {
  76. // Yep.
  77. return FALSE;
  78. }
  79. }
  80. else {
  81. *pT = 0;
  82. return TRUE; // stripped something
  83. }
  84. }
  85. void Strip(LPSTR pszUrl)
  86. {
  87. char szTemp[MAX_PATH] ;
  88. int tempPtr=0, pathPtr=0 ;
  89. while (pszUrl[pathPtr])
  90. {
  91. if (pszUrl[pathPtr] == '%')
  92. {
  93. int value = 0 ;
  94. pathPtr++ ;
  95. while (pszUrl[pathPtr] && ((pszUrl[pathPtr] >= '0') && (pszUrl[pathPtr] <= '9')))
  96. {
  97. value = (value * 0x10) + (pszUrl[pathPtr] - '0') ;
  98. pathPtr++ ;
  99. }
  100. szTemp[tempPtr++] = (char)value;
  101. }
  102. else
  103. {
  104. szTemp[tempPtr++] = pszUrl[pathPtr++] ;
  105. }
  106. }
  107. szTemp[tempPtr] = pszUrl[pathPtr] ;
  108. lstrcpy(pszUrl, szTemp) ;
  109. }
  110. BOOL CompareDirs(LPCSTR pcszDir1, LPCSTR pcszDir2)
  111. {
  112. char szDir1[MAX_PATH];
  113. char szDir2[MAX_PATH];
  114. if (GetShortPathName(pcszDir1, szDir1, sizeof(szDir1)) && GetShortPathName(pcszDir2, szDir2, sizeof(szDir2))
  115. && (lstrcmpi(szDir1, szDir2) == 0))
  116. return TRUE;
  117. return FALSE;
  118. }
  119. BOOL CheckSignupDir(LPCSTR pcszFile)
  120. {
  121. char szIEPath[MAX_PATH];
  122. char szFilePath[MAX_PATH];
  123. DWORD dwSize;
  124. HKEY hkAppPaths;
  125. dwSize = sizeof(szIEPath);
  126. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\iexplore.exe",
  127. 0, KEY_READ, &hkAppPaths) != ERROR_SUCCESS)
  128. return FALSE;
  129. if (RegQueryValueEx(hkAppPaths, "Path", 0, NULL, (LPBYTE)&szIEPath, &dwSize) != ERROR_SUCCESS)
  130. {
  131. RegCloseKey(hkAppPaths);
  132. return FALSE;
  133. }
  134. RegCloseKey(hkAppPaths);
  135. if (szIEPath[lstrlen(szIEPath)-1] == ';')
  136. szIEPath[lstrlen(szIEPath)-1] = '\0';
  137. if (szIEPath[lstrlen(szIEPath)-1] == '\\')
  138. szIEPath[lstrlen(szIEPath)-1] = '\0';
  139. lstrcat(szIEPath, "\\signup");
  140. lstrcpy(szFilePath, pcszFile);
  141. PathRemoveFileSpec(szFilePath);
  142. // check that we are writing to a file in the signup dir
  143. if (!CompareDirs(szIEPath, szFilePath))
  144. return FALSE;
  145. return TRUE;
  146. }
  147. STDMETHODIMP CKeyocxCtrl::SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
  148. {
  149. CComBSTR strURL;
  150. char szURL[INTERNET_MAX_URL_LENGTH];
  151. char cBack;
  152. LPSTR pPtr, pSlash;
  153. ATLTRACE(_T("IObjectSafetyImpl::SetInterfaceSafetyOptions\n"));
  154. USES_CONVERSION;
  155. // check to make sure it's a file://<drive letter> URL that we're being hosted on
  156. CComPtr<IOleContainer> spContainer;
  157. m_spClientSite->GetContainer(&spContainer);
  158. CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2> spDoc(spContainer);
  159. if (spDoc)
  160. spDoc->get_URL(&strURL);
  161. else
  162. return E_NOINTERFACE;
  163. lstrcpy(szURL, OLE2A(strURL));
  164. Strip(szURL);
  165. cBack = szURL[7];
  166. szURL[7] = '\0';
  167. if (lstrcmpi(szURL, "file://") != 0)
  168. return E_NOINTERFACE;
  169. szURL[7] = cBack;
  170. pPtr = &szURL[7];
  171. while (*pPtr == '/')
  172. pPtr++;
  173. pSlash = pPtr;
  174. while (pSlash = ANSIStrChr(pSlash, '/'))
  175. *pSlash = '\\';
  176. if (!CheckSignupDir(pPtr))
  177. return E_FAIL;
  178. // If we're being asked to set our safe for scripting option then oblige
  179. if (riid == IID_IDispatch )
  180. {
  181. // Store our current safety level to return in GetInterfaceSafetyOptions
  182. m_dwSafety = dwEnabledOptions & dwOptionSetMask;
  183. return S_OK;
  184. }
  185. return E_NOINTERFACE;
  186. }
  187. void MakeKey(LPSTR pszSeed, BOOL fCorp)
  188. {
  189. int i;
  190. DWORD dwKey;
  191. CHAR szKey[5];
  192. i = lstrlen(pszSeed);
  193. if (i < 6)
  194. {
  195. // extend the input seed to 6 characters
  196. for (; i < 6; i++)
  197. pszSeed[i] = (char)('0' + i);
  198. }
  199. // let's calculate the DWORD key used for the last 4 chars of keycode
  200. // multiply by my first name
  201. dwKey = pszSeed[0] * 'O' + pszSeed[1] * 'L' + pszSeed[2] * 'I' +
  202. pszSeed[3] * 'V' + pszSeed[4] * 'E' + pszSeed[5] * 'R';
  203. // multiply the result by JONCE
  204. dwKey *= ('J' + 'O' + 'N' + 'C' + 'E');
  205. dwKey %= 10000;
  206. if (fCorp)
  207. {
  208. // give a separate keycode based on corp flag or not
  209. // 9 is chosen because is is a multiplier such that for any x,
  210. // (x+214) * 9 != x + 10000y
  211. // we have 8x = 10000y - 1926 which when y=1 gives us 8x = 8074
  212. // since 8074 is not divisible by 8 where guaranteed to be OK since
  213. // the number on the right can only increase by 10000 increments which
  214. // are always divisible by 8
  215. dwKey += ('L' + 'E' + 'E');
  216. dwKey *= 9;
  217. dwKey %= 10000;
  218. }
  219. wsprintf(szKey, TEXT("%04lu"), dwKey);
  220. lstrcpy(&pszSeed[6], szKey);
  221. }
  222. STDMETHODIMP CKeyocxCtrl::CorpKeycode(BSTR bstrBaseKey, BSTR *bstrKeycode)
  223. {
  224. CHAR szKey[32];
  225. USES_CONVERSION;
  226. lstrcpy(szKey, OLE2A(bstrBaseKey));
  227. CharUpper(szKey);
  228. MakeKey(szKey, TRUE);
  229. *bstrKeycode = A2BSTR(szKey);
  230. return S_OK;
  231. }
  232. STDMETHODIMP CKeyocxCtrl::ISPKeycode(BSTR bstrBaseKey, BSTR *bstrKeycode)
  233. {
  234. CHAR szKey[32];
  235. USES_CONVERSION;
  236. lstrcpy(szKey, OLE2A(bstrBaseKey));
  237. CharUpper(szKey);
  238. MakeKey(szKey, FALSE);
  239. *bstrKeycode = A2BSTR(szKey);
  240. return S_OK;
  241. }