Source code of Windows XP (NT5)
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.

311 lines
12 KiB

  1. #include "windowsx.h"
  2. #include "ispdata.h"
  3. #include "validate.h"
  4. #include "tchar.h"
  5. #include "util.h"
  6. #include "resource.h"
  7. // NOTE: This order of this table is dependant on the order ot the ENUM in WEBVIEW.H for ISPDATA element.
  8. // DO NOT CHANGE 1 without CHANGING the other!!!!!
  9. ISPDATAELEMENT aryISPDataElements[] =
  10. {
  11. { csz_USER_FIRSTNAME, NULL, 0, IDS_USERINFO_FIRSTNAME, REQUIRE_FIRSTNAME },
  12. { csz_USER_LASTNAME, NULL, 0, IDS_USERINFO_LASTNAME, REQUIRE_LASTNAME },
  13. { csz_USER_ADDRESS, NULL, 0, IDS_USERINFO_ADDRESS1, REQUIRE_ADDRESS },
  14. { csz_USER_MOREADDRESS, NULL, 0, IDS_USERINFO_ADDRESS2, REQUIRE_MOREADDRESS },
  15. { csz_USER_CITY, NULL, 0, IDS_USERINFO_CITY, REQUIRE_CITY },
  16. { csz_USER_STATE, NULL, 0, IDS_USERINFO_STATE, REQUIRE_STATE },
  17. { csz_USER_ZIP, NULL, 0, IDS_USERINFO_ZIP, REQUIRE_ZIP },
  18. { csz_USER_PHONE, NULL, 0, IDS_USERINFO_PHONE, REQUIRE_PHONE },
  19. { csz_AREACODE, NULL, 0, 0, 0 },
  20. { csz_COUNTRYCODE, NULL, 0, 0, 0 },
  21. { csz_USER_FE_NAME, NULL, 0, IDS_USERINFO_FE_NAME, REQUIRE_FE_NAME },
  22. { csz_PAYMENT_TYPE, NULL, 0, 0, 0 },
  23. { csz_PAYMENT_BILLNAME, NULL, 0, IDS_PAYMENT_PBNAME, REQUIRE_PHONEIV_BILLNAME },
  24. { csz_PAYMENT_BILLADDRESS, NULL, 0, IDS_PAYMENT_CCADDRESS, REQUIRE_CCADDRESS },
  25. { csz_PAYMENT_BILLEXADDRESS, NULL, 0, IDS_USERINFO_ADDRESS2, REQUIRE_IVADDRESS2 },
  26. { csz_PAYMENT_BILLCITY, NULL, 0, IDS_USERINFO_CITY, REQUIRE_IVCITY },
  27. { csz_PAYMENT_BILLSTATE, NULL, 0, IDS_USERINFO_STATE, REQUIRE_IVSTATE },
  28. { csz_PAYMENT_BILLZIP, NULL, 0, IDS_USERINFO_ZIP, REQUIRE_IVZIP },
  29. { csz_PAYMENT_BILLPHONE, NULL, 0, IDS_PAYMENT_PBNUMBER, REQUIRE_PHONEIV_ACCNUM },
  30. { csz_PAYMENT_DISPLAYNAME, NULL, 0, 0, 0 },
  31. { csz_PAYMENT_CARDNUMBER, NULL, ValidateCCNumber, IDS_PAYMENT_CCNUMBER, REQUIRE_CCNUMBER },
  32. { csz_PAYMENT_EXMONTH, NULL, 0, 0, 0 },
  33. { csz_PAYMENT_EXYEAR, NULL, ValidateCCExpire, 0, 0 },
  34. { csz_PAYMENT_CARDHOLDER, NULL, 0, IDS_PAYMENT_CCNAME, REQUIRE_CCNAME },
  35. { csz_SIGNED_PID, NULL, 0, 0, 0 },
  36. { csz_GUID, NULL, 0, 0, 0 },
  37. { csz_OFFERID, NULL, 0, 0, 0 },
  38. { NULL, NULL, 0, 0, 0 },
  39. { NULL, NULL, 0, 0, 0 },
  40. { csz_USER_COMPANYNAME, NULL, 0, IDS_USERINFO_COMPANYNAME, REQUIRE_COMPANYNAME },
  41. { csz_ICW_VERSION, NULL, 0, 0, 0 }
  42. };
  43. #define ISPDATAELEMENTS_LEN sizeof(aryISPDataElements) / sizeof(ISPDATAELEMENT)
  44. extern const WCHAR cszEquals[];
  45. extern const WCHAR cszAmpersand[];
  46. extern const WCHAR cszPlus[];
  47. extern const WCHAR cszQuestion[];
  48. //+----------------------------------------------------------------------------
  49. //
  50. // Function CICWISPData:CICWISPData
  51. //
  52. // Synopsis This is the constructor, nothing fancy
  53. //
  54. //-----------------------------------------------------------------------------
  55. CICWISPData::CICWISPData()
  56. {
  57. m_lRefCount = 0;
  58. // Initialize the data elements array
  59. m_ISPDataElements = aryISPDataElements;
  60. }
  61. CICWISPData::~CICWISPData()
  62. {
  63. // Walk through and free any allocated values in m_ISPDataElements
  64. for (int i = 0; i < ISPDATAELEMENTS_LEN; i ++)
  65. {
  66. if (m_ISPDataElements[i].lpQueryElementValue)
  67. {
  68. free(m_ISPDataElements[i].lpQueryElementValue);
  69. m_ISPDataElements[i].lpQueryElementValue = NULL;
  70. }
  71. }
  72. }
  73. // BUGBUG need a destructor to walk the array and free the lpQueryElementValue members
  74. //+----------------------------------------------------------------------------
  75. //
  76. // Function CICWISPData::QueryInterface
  77. //
  78. // Synopsis This is the standard QI, with support for
  79. // IID_Unknown, IICW_Extension and IID_ICWApprentice
  80. // (stolen from Inside COM, chapter 7)
  81. //
  82. //
  83. //-----------------------------------------------------------------------------
  84. HRESULT CICWISPData::QueryInterface( REFIID riid, void** ppv )
  85. {
  86. return(S_OK);
  87. }
  88. //+----------------------------------------------------------------------------
  89. //
  90. // Function CICWISPData::AddRef
  91. //
  92. // Synopsis This is the standard AddRef
  93. //
  94. //
  95. //-----------------------------------------------------------------------------
  96. ULONG CICWISPData::AddRef( void )
  97. {
  98. return 1 ;
  99. }
  100. //+----------------------------------------------------------------------------
  101. //
  102. // Function CICWISPData::Release
  103. //
  104. // Synopsis This is the standard Release
  105. //
  106. //
  107. //-----------------------------------------------------------------------------
  108. ULONG CICWISPData::Release( void )
  109. {
  110. return( m_lRefCount );
  111. }
  112. BOOL CICWISPData::PutDataElement
  113. (
  114. WORD wElement,
  115. LPCWSTR lpValue,
  116. WORD wValidateLevel
  117. )
  118. {
  119. //ASSERT(wElement < ISPDATAELEMENTS_LEN);
  120. BOOL bValid = TRUE;
  121. LPISPDATAELEMENT lpElement = &m_ISPDataElements[wElement];
  122. //ASSERT(lpElement);
  123. if (wValidateLevel > ISPDATA_Validate_None)
  124. {
  125. // See if we even need to validate. A validateflag of 0 means we always validate
  126. if ((0 == lpElement->dwValidateFlag) || m_dwValidationFlags & lpElement->dwValidateFlag)
  127. {
  128. // process based on validation level
  129. switch (wValidateLevel)
  130. {
  131. case ISPDATA_Validate_DataPresent:
  132. {
  133. bValid = IsValid(lpValue, m_hWndParent, lpElement->wValidateNameID);
  134. break;
  135. }
  136. case ISPDATA_Validate_Content:
  137. {
  138. bValid = bValidateContent(lpElement->idContentValidator, lpValue);
  139. break;
  140. }
  141. }
  142. }
  143. }
  144. // If the element is valid, then store it.
  145. if (bValid)
  146. {
  147. // If this elemement has been previously set the free it
  148. if (lpElement->lpQueryElementValue)
  149. {
  150. free(lpElement->lpQueryElementValue);
  151. lpElement->lpQueryElementValue = NULL;
  152. }
  153. // lpValue can be NULL
  154. if (lpValue)
  155. lpElement->lpQueryElementValue = _wcsdup(lpValue);
  156. else
  157. lpElement->lpQueryElementValue = NULL;
  158. }
  159. return (bValid);
  160. }
  161. // This funtion will form the query string to be sent to the ISP signup server
  162. //
  163. HRESULT CICWISPData::GetQueryString
  164. (
  165. BSTR bstrBaseURL,
  166. BSTR *lpReturnURL
  167. )
  168. {
  169. LPWSTR lpWorkingURL;
  170. WORD cchBuffer = 0;
  171. LPISPDATAELEMENT lpElement;
  172. LPWSTR lpszBaseURL = bstrBaseURL;
  173. int i;
  174. //ASSERT(lpReturnURL);
  175. if (!lpReturnURL)
  176. return E_FAIL;
  177. // Calculate how big of a buffer we will need
  178. cchBuffer += (WORD)lstrlen(lpszBaseURL);
  179. cchBuffer += 1; // For the & or the ?
  180. for (i = 0; i < ISPDATAELEMENTS_LEN; i ++)
  181. {
  182. lpElement = &m_ISPDataElements[i];
  183. //ASSERT(lpElement);
  184. if (lpElement->lpQueryElementName)
  185. {
  186. cchBuffer += (WORD)lstrlen(lpElement->lpQueryElementName);
  187. cchBuffer += (WORD)lstrlen(lpElement->lpQueryElementValue) * 3; // *3 for encoding
  188. cchBuffer += 3; // For the = and & and the terminator (because we copy
  189. // lpQueryElementValue into a new buffer for encoding
  190. }
  191. else
  192. {
  193. cchBuffer += (WORD)lstrlen(lpElement->lpQueryElementValue);
  194. cchBuffer += 1; // for the trailing &
  195. }
  196. }
  197. cchBuffer += 1; // Terminator
  198. // Allocate a buffer large enough
  199. if (NULL == (lpWorkingURL = (LPWSTR)GlobalAllocPtr(GPTR, BYTES_REQUIRED_BY_CCH(cchBuffer))))
  200. return E_FAIL;
  201. lstrcpy(lpWorkingURL, lpszBaseURL);
  202. // See if this ISP provided URL is already a Query String.
  203. if (NULL != wcschr(lpWorkingURL, L'?'))
  204. lstrcat(lpWorkingURL, cszAmpersand); // Append our params
  205. else
  206. lstrcat(lpWorkingURL, cszQuestion); // Start with our params
  207. for (i = 0; i < ISPDATAELEMENTS_LEN; i ++)
  208. {
  209. lpElement = &m_ISPDataElements[i];
  210. //ASSERT(lpElement);
  211. if (lpElement->lpQueryElementName)
  212. {
  213. // If there is a query value, then encode it
  214. if (lpElement->lpQueryElementValue)
  215. {
  216. // Allocate a buffer to encode into
  217. size_t size = 3 * BYTES_REQUIRED_BY_SZ(lpElement->lpQueryElementValue);
  218. LPWSTR lpszVal = (LPWSTR) malloc(size+BYTES_REQUIRED_BY_CCH(1));
  219. lstrcpy(lpszVal, lpElement->lpQueryElementValue);
  220. URLEncode(lpszVal, size);
  221. URLAppendQueryPair(lpWorkingURL,
  222. (LPWSTR)lpElement->lpQueryElementName,
  223. lpszVal);
  224. free(lpszVal);
  225. }
  226. else
  227. {
  228. URLAppendQueryPair(lpWorkingURL,
  229. (LPWSTR)lpElement->lpQueryElementName,
  230. NULL);
  231. }
  232. }
  233. else
  234. {
  235. if (lpElement->lpQueryElementValue)
  236. {
  237. lstrcat(lpWorkingURL, lpElement->lpQueryElementValue);
  238. lstrcat(lpWorkingURL, cszAmpersand);
  239. }
  240. }
  241. }
  242. // Terminate the working URL properly, by removing the trailing ampersand
  243. lpWorkingURL[lstrlen(lpWorkingURL)-1] = L'\0';
  244. // Set the return VALUE. We must allocate here, since the caller will free
  245. // this returned string, and A2W only puts the string in the stack
  246. *lpReturnURL = SysAllocString(lpWorkingURL);
  247. // Free the buffer
  248. GlobalFreePtr(lpWorkingURL);
  249. return (S_OK);
  250. }
  251. // Dispatch functioin to handle content specific validation
  252. BOOL CICWISPData::bValidateContent
  253. (
  254. WORD wFunctionID,
  255. LPCWSTR lpData
  256. )
  257. {
  258. BOOL bValid = TRUE;
  259. switch (wFunctionID)
  260. {
  261. case ValidateCCNumber:
  262. break;
  263. case ValidateCCExpire:
  264. break;
  265. }
  266. return bValid;
  267. }