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.

351 lines
10 KiB

  1. #include "precomp.h"
  2. static int checkVerHelper(LPCTSTR pcszPrevVer, LPCTSTR pcszNewVer);
  3. static void generateNewVersionStrHelper(LPCTSTR pcszInsFile, LPTSTR pszNewVersionStr);
  4. static void setOrClearVersionInfoHelper(LPCTSTR pcszInsFile, DWORD dwCabType, LPCTSTR pcszCabName,
  5. LPCTSTR pcszCabsURLPath, LPTSTR pszNewVersionStr, BOOL fSet);
  6. static void getBaseFileNameHelper(LPCTSTR pcszFile, LPTSTR pszBaseFileName, INT cchSize);
  7. // iRet > 0 ==> PrevVer is higher than NewVersion
  8. // iRet == 0 ==> PrevVer is the same as NewVersion
  9. // iRet < 0 ==> PrevVer is lower than NewVersion
  10. int WINAPI CheckVerA(LPCSTR pcszPrevVer, LPCSTR pcszNewVer)
  11. {
  12. USES_CONVERSION;
  13. return checkVerHelper(A2CT(pcszPrevVer), A2CT(pcszNewVer));
  14. }
  15. int WINAPI CheckVerW(LPCWSTR pcwszPrevVer, LPCWSTR pcwszNewVer)
  16. {
  17. USES_CONVERSION;
  18. return checkVerHelper(W2CT(pcwszPrevVer), W2CT(pcwszNewVer));
  19. }
  20. void WINAPI GenerateNewVersionStrA(LPCSTR pcszInsFile, LPSTR pszNewVersionStr)
  21. {
  22. TCHAR szNewVerStr[32];
  23. USES_CONVERSION;
  24. generateNewVersionStrHelper(A2CT(pcszInsFile), szNewVerStr);
  25. T2Abux(szNewVerStr, pszNewVersionStr);
  26. }
  27. void WINAPI GenerateNewVersionStrW(LPCWSTR pcwszInsFile, LPWSTR pwszNewVersionStr)
  28. {
  29. TCHAR szNewVerStr[32];
  30. USES_CONVERSION;
  31. generateNewVersionStrHelper(W2CT(pcwszInsFile), szNewVerStr);
  32. T2Wbux(szNewVerStr, pwszNewVersionStr);
  33. }
  34. void WINAPI SetOrClearVersionInfoA(LPCSTR pcszInsFile, DWORD dwCabType, LPCSTR pcszCabName,
  35. LPCSTR pcszCabsURLPath, LPSTR pszNewVersionStr, BOOL fSet)
  36. {
  37. TCHAR szNewVerStr[32];
  38. USES_CONVERSION;
  39. A2Tbux(pszNewVersionStr, szNewVerStr);
  40. setOrClearVersionInfoHelper(A2CT(pcszInsFile), dwCabType, A2CT(pcszCabName),
  41. A2CT(pcszCabsURLPath), szNewVerStr, fSet);
  42. T2Abux(szNewVerStr, pszNewVersionStr);
  43. }
  44. void WINAPI SetOrClearVersionInfoW(LPCWSTR pcwszInsFile, DWORD dwCabType, LPCWSTR pcwszCabName,
  45. LPCWSTR pcwszCabsURLPath, LPWSTR pwszNewVersionStr, BOOL fSet)
  46. {
  47. TCHAR szNewVerStr[32];
  48. USES_CONVERSION;
  49. W2Tbux(pwszNewVersionStr, szNewVerStr);
  50. setOrClearVersionInfoHelper(W2CT(pcwszInsFile), dwCabType, W2CT(pcwszCabName),
  51. W2CT(pcwszCabsURLPath), szNewVerStr, fSet);
  52. T2Wbux(szNewVerStr, pwszNewVersionStr);
  53. }
  54. void WINAPI GetBaseFileNameA(LPCSTR pcszFile, LPSTR pszBaseFileName, INT cchSize)
  55. {
  56. LPTSTR pszBuf = (LPTSTR)CoTaskMemAlloc(StrCbFromCch(cchSize));
  57. USES_CONVERSION;
  58. if (pszBuf != NULL)
  59. {
  60. getBaseFileNameHelper(A2CT(pcszFile), pszBuf, cchSize);
  61. T2Abux(pszBuf, pszBaseFileName);
  62. CoTaskMemFree(pszBuf);
  63. }
  64. }
  65. void WINAPI GetBaseFileNameW(LPCWSTR pcwszFile, LPWSTR pwszBaseFileName, INT cchSize)
  66. {
  67. LPTSTR pszBuf = (LPTSTR)CoTaskMemAlloc(StrCbFromCch(cchSize));
  68. USES_CONVERSION;
  69. if (pszBuf != NULL)
  70. {
  71. getBaseFileNameHelper(W2CT(pcwszFile), pszBuf, cchSize);
  72. T2Wbux(pszBuf, pwszBaseFileName);
  73. CoTaskMemFree(pszBuf);
  74. }
  75. }
  76. /* stolen from webcheck
  77. // PRIVATE VERSION HANDLING CODE - REVIEW THIS CODE SHOULD HAVE BEEN STOLEN
  78. // FROM SETUP
  79. */
  80. typedef struct _MYVERSION
  81. {
  82. DWORD dw1; /* most sig version number */
  83. DWORD dw2;
  84. DWORD dw3;
  85. DWORD dw4; /* least sig version number */
  86. } MYVERSION;
  87. static int compareDW(DWORD dw1, DWORD dw2)
  88. {
  89. if (dw1 > dw2)
  90. return 1;
  91. if (dw1 < dw2)
  92. return -1;
  93. return 0;
  94. }
  95. static int compareVersion(MYVERSION * pv1, MYVERSION * pv2)
  96. {
  97. int rv;
  98. rv = compareDW(pv1->dw1, pv2->dw1);
  99. if (rv == 0)
  100. {
  101. rv = compareDW(pv1->dw2, pv2->dw2);
  102. if (rv == 0)
  103. {
  104. rv = compareDW(pv1->dw3, pv2->dw3);
  105. if (rv == 0)
  106. {
  107. rv = compareDW(pv1->dw4, pv2->dw4);
  108. }
  109. }
  110. }
  111. return rv;
  112. }
  113. static void getDWORDFromStringAndAdvancePtr(DWORD *pdw, LPTSTR *psz)
  114. {
  115. LPTSTR pszTemp;
  116. if ((!(*psz)) || (!StrToIntEx(*psz, 0, (int *)pdw)))
  117. {
  118. *pdw = TEXT('\0');
  119. return;
  120. }
  121. // look for period separator first, then comma
  122. pszTemp = StrChr(*psz, TEXT('.'));
  123. if (pszTemp != NULL)
  124. *psz = pszTemp;
  125. else
  126. *psz = StrChr(*psz, TEXT(','));
  127. if (*psz)
  128. (*psz)++;
  129. return;
  130. }
  131. static void getVersionFromString(MYVERSION *pver, LPTSTR psz)
  132. {
  133. getDWORDFromStringAndAdvancePtr(&pver->dw1, &psz);
  134. getDWORDFromStringAndAdvancePtr(&pver->dw2, &psz);
  135. getDWORDFromStringAndAdvancePtr(&pver->dw3, &psz);
  136. getDWORDFromStringAndAdvancePtr(&pver->dw4, &psz);
  137. }
  138. // end of stolen code
  139. static int checkVerHelper(LPCTSTR pcszPrevVer, LPCTSTR pcszNewVer)
  140. {
  141. MYVERSION verOldVer, verNewVer;
  142. getVersionFromString(&verOldVer, (LPTSTR)pcszPrevVer);
  143. getVersionFromString(&verNewVer, (LPTSTR)pcszNewVer);
  144. return compareVersion(&verOldVer, &verNewVer);
  145. }
  146. static void incrementDotVer(LPTSTR pszVerStr)
  147. {
  148. LPTSTR pszT = pszVerStr;
  149. DWORD dwYear, dwMonth, dwDay, dwDotVer;
  150. getDWORDFromStringAndAdvancePtr(&dwYear, &pszT);
  151. getDWORDFromStringAndAdvancePtr(&dwMonth, &pszT);
  152. getDWORDFromStringAndAdvancePtr(&dwDay, &pszT);
  153. getDWORDFromStringAndAdvancePtr(&dwDotVer, &pszT);
  154. if (++dwDotVer > 99)
  155. {
  156. // this case should never arise
  157. }
  158. wnsprintf(pszVerStr, 32, TEXT("%04d.%02d.%02d.%02d"), dwYear, dwMonth, dwDay, dwDotVer);
  159. }
  160. static void generateNewVersionStrHelper(LPCTSTR pcszInsFile, LPTSTR pszNewVersionStr)
  161. {
  162. TCHAR szPrevVerStr[32];
  163. SYSTEMTIME st;
  164. GetPrivateProfileString(BRANDING, INSVERKEY, TEXT(""), szPrevVerStr, ARRAYSIZE(szPrevVerStr), pcszInsFile);
  165. GetLocalTime(&st);
  166. wnsprintf(pszNewVersionStr, 32, TEXT("%04d.%02d.%02d.%02d"), st.wYear, st.wMonth, st.wDay, 0);
  167. if (ISNONNULL(szPrevVerStr))
  168. {
  169. int iRet = CheckVer(szPrevVerStr, pszNewVersionStr);
  170. // iRet > 0 ==> PrevVer is higher than NewVersion
  171. // iRet == 0 ==> PrevVer is the same as NewVersion
  172. // iRet < 0 ==> PrevVer is lower than NewVersion
  173. if (iRet >= 0)
  174. {
  175. if (iRet > 0)
  176. StrCpy(pszNewVersionStr, szPrevVerStr);
  177. incrementDotVer(pszNewVersionStr);
  178. }
  179. }
  180. }
  181. static void setOrClearVersionInfoHelper(LPCTSTR pcszInsFile, DWORD dwCabType, LPCTSTR pcszCabName,
  182. LPCTSTR pcszCabsURLPath, LPTSTR pszNewVersionStr, BOOL fSet)
  183. {
  184. LPCTSTR pcszSection = NULL, pcszKey = NULL;
  185. TCHAR szCabInfoLine[INTERNET_MAX_URL_LENGTH + 128];
  186. LPTSTR pszCurField, pszNextField;
  187. TCHAR szCabURL[INTERNET_MAX_URL_LENGTH];
  188. TCHAR szExpiration[16];
  189. TCHAR szFlags[16];
  190. switch (dwCabType)
  191. {
  192. case CAB_TYPE_CONFIG:
  193. pcszSection = CUSTBRNDSECT;
  194. pcszKey = CUSTBRNDNAME;
  195. break;
  196. case CAB_TYPE_DESKTOP:
  197. pcszSection = CUSTDESKSECT;
  198. pcszKey = CUSTDESKNAME;
  199. break;
  200. case CAB_TYPE_CHANNELS:
  201. pcszSection = CUSTCHANSECT;
  202. pcszKey = CUSTCHANNAME;
  203. break;
  204. }
  205. if (pcszSection == NULL || pcszKey == NULL)
  206. return;
  207. if (fSet)
  208. {
  209. // save the info before deleting it
  210. if (GetPrivateProfileString(pcszSection, pcszKey, TEXT(""), szCabInfoLine, ARRAYSIZE(szCabInfoLine), pcszInsFile) == 0)
  211. GetPrivateProfileString(CUSTOMVERSECT, pcszKey, TEXT(""), szCabInfoLine, ARRAYSIZE(szCabInfoLine), pcszInsFile);
  212. }
  213. // clear out the version information in the INS file
  214. WritePrivateProfileString(pcszSection, NULL, NULL, pcszInsFile);
  215. WritePrivateProfileString(CUSTOMVERSECT, pcszKey, NULL, pcszInsFile);
  216. if (!fSet)
  217. return;
  218. *szCabURL = *szExpiration = *szFlags = TEXT('\0');
  219. if (ISNONNULL(szCabInfoLine))
  220. {
  221. // parse the szCabInfoLine
  222. pszCurField = szCabInfoLine;
  223. if ((pszNextField = StrChr(pszCurField, TEXT(','))) != NULL)
  224. {
  225. *pszNextField++ = TEXT('\0');
  226. StrCpy(szCabURL, pszCurField);
  227. pszCurField = pszNextField;
  228. if ((pszNextField = StrChr(pszCurField, TEXT(','))) != NULL)
  229. {
  230. *pszNextField++ = TEXT('\0');
  231. pszCurField = pszNextField;
  232. if ((pszNextField = StrChr(pszCurField, TEXT(','))) != NULL)
  233. {
  234. *pszNextField++ = TEXT('\0');
  235. StrCpy(szExpiration, pszCurField);
  236. pszCurField = pszNextField;
  237. if ((pszNextField = StrChr(pszCurField, TEXT(','))) != NULL)
  238. {
  239. *pszNextField++ = TEXT('\0');
  240. StrCpy(szFlags, pszCurField);
  241. }
  242. else
  243. StrCpy(szFlags, pszCurField);
  244. }
  245. else
  246. StrCpy(szExpiration, pszCurField);
  247. }
  248. }
  249. else
  250. StrCpy(szCabURL, pszCurField);
  251. }
  252. // initialize autoconfig URL
  253. StrCpy(szCabURL, pcszCabsURLPath);
  254. PathRemoveBackslash(szCabURL);
  255. if (ISNONNULL(szCabURL) && szCabURL[StrLen(szCabURL) - 1] != TEXT('/'))
  256. StrCat(szCabURL, TEXT("/"));
  257. StrCat(szCabURL, pcszCabName);
  258. generateNewVersionStrHelper(pcszInsFile, pszNewVersionStr);
  259. if (ISNULL(szExpiration))
  260. StrCpy(szExpiration, TEXT("-1")); // never expires
  261. // write the new version info line
  262. wnsprintf(szCabInfoLine, ARRAYSIZE(szCabInfoLine), TEXT("%s,%s,%s,%s"), szCabURL, pszNewVersionStr, szExpiration, szFlags);
  263. WritePrivateProfileString(pcszSection, pcszKey, szCabInfoLine, pcszInsFile);
  264. }
  265. static void getBaseFileNameHelper(LPCTSTR pcszFile, LPTSTR pszBaseFileName, INT cchSize)
  266. {
  267. TCHAR szFile[MAX_PATH];
  268. LPTSTR lpszFileName = NULL;
  269. if (pcszFile == NULL || ISNULL(pcszFile))
  270. return;
  271. StrCpy(szFile, pcszFile);
  272. lpszFileName = PathFindFileName(szFile);
  273. PathRemoveExtension(lpszFileName);
  274. StrCpyN(pszBaseFileName, lpszFileName, cchSize);
  275. }