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.

249 lines
7.2 KiB

  1. //=======================================================================
  2. //
  3. // Copyright (c) 1998-1999 Microsoft Corporation. All Rights Reserved.
  4. //
  5. // File: bucket.cpp
  6. //
  7. // Owner: YanL
  8. //
  9. // Description:
  10. //
  11. // CDM bucket related functions
  12. //
  13. //=======================================================================
  14. #include <windows.h>
  15. #include <ole2.h>
  16. #include <setupapi.h>
  17. #include <tchar.h>
  18. #include <atlconv.h>
  19. #include <wustl.h>
  20. #include <wuv3cdm.h>
  21. #include <bucket.h>
  22. #include <findoem.h>
  23. #include <DrvInfo.h>
  24. #define LOGGING_LEVEL 1
  25. #include <log.h>
  26. #include "cdmlibp.h"
  27. PUID CDM_FindUpdateInBucket(
  28. IN LPCTSTR szHardwareIdFromDevice, IN FILETIME* pftInstalled,
  29. IN LPBYTE pBucket, IN int cbBucket, IN LPBYTE pBitmask,
  30. OUT PDRIVER_MATCH_INFO pDriverMatchInfo
  31. ) {
  32. LOG_block("CDM_FindUpdateInBucket");
  33. LOG_out("szHardwareIdFromDevice = %s", szHardwareIdFromDevice);
  34. USES_CONVERSION;
  35. // Driver for update
  36. PUID puid = 0;
  37. FILETIME ftLatest;
  38. for(
  39. LPBYTE pEnd = pBucket + cbBucket;
  40. pBucket < pEnd;
  41. pBucket += ((PCDM_RECORD_HEADER)pBucket)->cnRecordLength
  42. ) {
  43. PCDM_RECORD_HEADER pRecord = (PCDM_RECORD_HEADER)pBucket;
  44. // Should not be masked
  45. if (!GETBIT(pBitmask, pRecord->nBitmaskIdx))
  46. {
  47. LOG_out("puid %d Masked out", pRecord->puid);
  48. continue;
  49. }
  50. // Hadware ID has to match
  51. LPCSTR szHardwareId = (LPCSTR)pBucket + sizeof(CDM_RECORD_HEADER);
  52. if (0 != lstrcmpi(szHardwareIdFromDevice, A2T(const_cast<char*>(szHardwareId))))
  53. {
  54. LOG_out("puid %d HardwareID %s doesn't match device", pRecord->puid, A2T(const_cast<char*>(szHardwareId)));
  55. continue;
  56. }
  57. // Skip all this - we don't need it now
  58. LPCSTR szDescription = szHardwareId + strlen(szHardwareId) + 1;
  59. LPCSTR szMfg = szDescription + strlen(szDescription) + 1;
  60. LPCSTR szProvider = szMfg + strlen(szMfg) + 1;
  61. LPCSTR szDriverVer = szProvider + strlen(szProvider) + 1;
  62. LPCSTR szCabFileTitle = szDriverVer + strlen(szDriverVer) + 1;
  63. FILETIME ftDriver = {0,1};
  64. DriverVer2FILETIME(A2T(const_cast<char*>(szDriverVer)), ftDriver); // don't check driver ver
  65. // Check if this one is the latest on the site
  66. if (0 != puid && CompareFileTime(&ftDriver, &ftLatest) <= 0)
  67. {
  68. // #ifdef _WUV3TEST
  69. SYSTEMTIME stDriver;
  70. FileTimeToSystemTime(&ftDriver, &stDriver);
  71. SYSTEMTIME stLatest;
  72. FileTimeToSystemTime(&ftLatest, &stLatest);
  73. LOG_out("puid %d (DriverVer=%2d/%02d/%4d) is not the latest (DriverVer=%2d/%02d/%4d)",
  74. pRecord->puid, (int)stDriver.wMonth, (int)stDriver.wDay, (int)stDriver.wYear,
  75. (int)stLatest.wMonth, (int)stLatest.wDay, (int)stLatest.wYear
  76. );
  77. // #endif
  78. continue;
  79. }
  80. // Check if it's later then installed
  81. if (pftInstalled && CompareFileTime(&ftDriver, pftInstalled) <= 0)
  82. {
  83. // #ifdef _WUV3TEST
  84. SYSTEMTIME stDriver;
  85. FileTimeToSystemTime(&ftDriver, &stDriver);
  86. SYSTEMTIME stDriverInstalled;
  87. FileTimeToSystemTime(pftInstalled, &stDriverInstalled);
  88. LOG_out("puid %d (DriverVer=%2d/%02d/%4d) isn't later then installed (DriverVer=%2d/%02d/%4d)",
  89. pRecord->puid, (int)stDriver.wMonth, (int)stDriver.wDay, (int)stDriver.wYear,
  90. (int)stDriverInstalled.wMonth, (int)stDriverInstalled.wDay, (int)stDriverInstalled.wYear
  91. );
  92. // #endif
  93. continue;
  94. }
  95. // got a match
  96. puid = pRecord->puid;
  97. pDriverMatchInfo->pszHardwareID = szHardwareId;
  98. pDriverMatchInfo->pszDescription = szDescription;
  99. pDriverMatchInfo->pszMfgName = szMfg;
  100. pDriverMatchInfo->pszProviderName = szProvider;
  101. pDriverMatchInfo->pszDriverVer = szDriverVer;
  102. pDriverMatchInfo->pszCabFileTitle = szCabFileTitle;
  103. ftLatest = ftDriver;
  104. // #ifdef _WUV3TEST
  105. SYSTEMTIME stDriver;
  106. FileTimeToSystemTime(&ftDriver, &stDriver);
  107. LOG_out("puid %d (DriverVer=%2d/%02d/%4d) is the latest",
  108. pRecord->puid, (int)stDriver.wMonth, (int)stDriver.wDay, (int)stDriver.wYear
  109. );
  110. // #endif
  111. }
  112. if (puid)
  113. LOG_out("UPDATE FOUND puid %d for %s", puid, szHardwareIdFromDevice);
  114. return puid;
  115. }
  116. PUID CDM_FindInstalledInBucket(
  117. IN IDrvInfo* pDrvInfo, IN LPCTSTR szHardwareIdInstalled,
  118. IN LPBYTE pBucket, IN int cbBucket, IN LPBYTE pBitmask,
  119. OUT PDRIVER_MATCH_INFO pDriverMatchInfo
  120. ) {
  121. LOG_block("CDM_FindInstalledInBucket");
  122. LOG_out("szHardwareIdInstalled = %s", szHardwareIdInstalled);
  123. USES_CONVERSION;
  124. FILETIME ftDriverInstalled = {0,0};
  125. if (!pDrvInfo->GetDriverDate(ftDriverInstalled))
  126. {
  127. LOG_error("!pDrvInfo->GetDriverDate(ftDriverInstalled)");
  128. return NULL;
  129. }
  130. for(
  131. LPBYTE pEnd = pBucket + cbBucket;
  132. pBucket < pEnd;
  133. pBucket += ((PCDM_RECORD_HEADER)pBucket)->cnRecordLength
  134. ) {
  135. PCDM_RECORD_HEADER pRecord = (PCDM_RECORD_HEADER)pBucket;
  136. // Should not be masked
  137. if (!GETBIT(pBitmask, pRecord->nBitmaskIdx))
  138. {
  139. LOG_out("puid %d masked out", pRecord->puid);
  140. continue;
  141. }
  142. // Hadware ID has to match
  143. LPCSTR szHardwareId = (LPCSTR)pBucket + sizeof(CDM_RECORD_HEADER);
  144. if (0 != lstrcmpi(szHardwareIdInstalled, A2T(const_cast<char*>(szHardwareId))))
  145. {
  146. LOG_out("puid %d HardwareID %s doesn't match installed", pRecord->puid, A2T(const_cast<char*>(szHardwareId)));
  147. continue;
  148. }
  149. LPCSTR szDescription = szHardwareId + strlen(szHardwareId) + 1;
  150. LPCSTR szMfg = szDescription + strlen(szDescription) + 1;
  151. LPCSTR szProvider = szMfg + strlen(szMfg) + 1;
  152. LPCSTR szDriverVer = szProvider + strlen(szProvider) + 1;
  153. FILETIME ftDriver = {0,1};
  154. DriverVer2FILETIME(A2T(const_cast<char*>(szDriverVer)), ftDriver);
  155. LPCSTR szCabFileTitle = szDriverVer + strlen(szDriverVer) + 1;
  156. // Check if it's later then installed
  157. if (0 != CompareFileTime(&ftDriver, &ftDriverInstalled))
  158. {
  159. // #ifdef _WUV3TEST
  160. SYSTEMTIME stDriver;
  161. FileTimeToSystemTime(&ftDriver, &stDriver);
  162. SYSTEMTIME stDriverInstalled;
  163. FileTimeToSystemTime(&ftDriverInstalled, &stDriverInstalled);
  164. LOG_out("puid %d (DriverVer=%2d/%02d/%4d) isn't the same as installed (DriverVer=%2d/%02d/%4d)",
  165. pRecord->puid, (int)stDriver.wMonth, (int)stDriver.wDay, (int)stDriver.wYear,
  166. (int)stDriverInstalled.wMonth, (int)stDriverInstalled.wDay, (int)stDriverInstalled.wYear
  167. );
  168. // #endif
  169. continue;
  170. }
  171. // got a match
  172. pDriverMatchInfo->pszHardwareID = szHardwareId;
  173. pDriverMatchInfo->pszDescription = szDescription;
  174. pDriverMatchInfo->pszMfgName = szMfg;
  175. pDriverMatchInfo->pszProviderName = szProvider;
  176. pDriverMatchInfo->pszDriverVer = szDriverVer;
  177. pDriverMatchInfo->pszCabFileTitle = szCabFileTitle;
  178. LOG_out("INSTALLED FOUND puid %d for %s", pRecord->puid, szHardwareIdInstalled);
  179. return pRecord->puid;
  180. }
  181. return 0;
  182. }
  183. //These functions form a hash lookup for hwIDs.
  184. static ULONG HashFunction(
  185. IN ULONG seed //Seed value to use for hashing hwid.
  186. ) {
  187. ULONG q;
  188. ULONG r;
  189. ULONG a;
  190. ULONG m;
  191. ULONG val;
  192. q = 127773L;
  193. r = 2836L;
  194. a = 16807L;
  195. m = 2147483647;
  196. val = ((seed % q) * a) - (seed / q) * r;
  197. if(((long)val) <= 0)
  198. val = val + m;
  199. return val;
  200. }
  201. //These functions form a hash lookup for hwIDs.
  202. ULONG CDM_HwID2Hash(
  203. IN LPCTSTR szHwID, //Hardware id being hashed.
  204. IN ULONG iTableSize //Size of downloaded hash table.
  205. ) {
  206. if (0 == iTableSize)
  207. return 0; // error
  208. ULONG ulHashIndex = 1;
  209. while(*szHwID)
  210. {
  211. ulHashIndex = ulHashIndex + HashFunction(ulHashIndex + (ULONG)(INT_PTR)CharUpper((LPTSTR)*szHwID));
  212. szHwID++;
  213. }
  214. return (ulHashIndex % iTableSize);
  215. }