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.

258 lines
6.3 KiB

  1. #include <windows.h>
  2. #include <objbase.h>
  3. #include <stdio.h>
  4. #include <shlwapi.h>
  5. #include <autoupd.h>
  6. #include <malloc.h>
  7. #include <wustl.h>
  8. #include <download.h>
  9. #include <tchar.h>
  10. #include <comdef.h>
  11. // needed to resolve references to AtlA2WHelper() in cdmlib.lib
  12. #include <atlconv.h>
  13. #define _ASSERTE(expr) ((void)0)
  14. #include <atlconv.cpp>
  15. #define GETCATALOG_STATUS_EXCLUSIVE (long)0x00008000 //Catalog item is exclusive it cannot be selected with other components.
  16. #define CATLIST_AUTOUPDATE ((DWORD)0x04)
  17. const CLSID CLSID_CV3 = {0xCEBC955E,0x58AF,0x11D2,{0xA3,0x0A,0x00,0xA0,0xC9,0x03,0x49,0x2B}};
  18. bool g_fOnline = true;
  19. // delete the whole subtree starting from current directory
  20. void DeleteNode(LPTSTR szDir)
  21. {
  22. TCHAR szFilePath[MAX_PATH];
  23. lstrcpy(szFilePath, szDir);
  24. PathAppend(szFilePath, TEXT("*.*"));
  25. // Find the first file
  26. WIN32_FIND_DATA fd;
  27. auto_hfindfile hFindFile = FindFirstFile(szFilePath, &fd);
  28. if(!hFindFile.valid())
  29. return;
  30. do
  31. {
  32. if (
  33. !lstrcmpi(fd.cFileName, TEXT(".")) ||
  34. !lstrcmpi(fd.cFileName, TEXT(".."))
  35. ) continue;
  36. // Make our path
  37. lstrcpy(szFilePath, szDir);
  38. PathAppend(szFilePath, fd.cFileName);
  39. if ((fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ||
  40. (fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
  41. ) {
  42. SetFileAttributes(szFilePath, FILE_ATTRIBUTE_NORMAL);
  43. }
  44. if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  45. {
  46. DeleteNode(szFilePath);
  47. }
  48. else
  49. {
  50. DeleteFile(szFilePath);
  51. }
  52. }
  53. while (FindNextFile(hFindFile, &fd));// Find the next entry
  54. hFindFile.release();
  55. RemoveDirectory(szDir);
  56. }
  57. void RemoveWindowsUpdateDirectory()
  58. {
  59. TCHAR szWinUpDir[MAX_PATH] = {0};
  60. auto_hkey hkey;
  61. if (RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"), &hkey) == ERROR_SUCCESS)
  62. {
  63. DWORD cbPath = MAX_PATH;
  64. RegQueryValueEx(hkey, _T("ProgramFilesDir"), NULL, NULL, (LPBYTE)szWinUpDir, &cbPath);
  65. }
  66. if (szWinUpDir[0] == _T('\0'))
  67. {
  68. GetWindowsDirectory(szWinUpDir, sizeof(szWinUpDir));
  69. szWinUpDir[1] = _T('\0');
  70. _tcscat(szWinUpDir, _T(":\\Program Files"));
  71. }
  72. _tcscat(szWinUpDir, _T("\\WindowsUpdate"));
  73. DeleteNode(szWinUpDir);
  74. }
  75. void QueryDownloadFilesCallback( void* pCallbackParam, long puid, LPCTSTR pszURL, LPCTSTR pszLocalFile)
  76. {
  77. if (g_fOnline)
  78. {
  79. wprintf(_T(" %s - %s\n"), pszURL, pszLocalFile);
  80. // download file
  81. CDownload download;
  82. TCHAR szURL[INTERNET_MAX_PATH_LENGTH];
  83. _tcscpy(szURL, pszURL);
  84. TCHAR* pszServerFile = _tcsrchr(szURL, _T('/'));
  85. *pszServerFile = 0;
  86. pszServerFile ++;
  87. TCHAR szDir[MAX_PATH];
  88. _tcscpy(szDir, pszLocalFile);
  89. *_tcsrchr(szDir, _T('\\')) = 0;
  90. TCHAR szDirCabs[MAX_PATH];
  91. _tcscpy(szDirCabs, szDir);
  92. *_tcsrchr(szDirCabs, _T('\\')) = 0;
  93. CreateDirectory(szDirCabs, NULL);
  94. CreateDirectory(szDir, NULL);
  95. if(!download.Connect(szURL))
  96. {
  97. wprintf(_T(" ERROR - Connect(%s) fails\n"), szURL);
  98. return;
  99. }
  100. if(!download.Copy(pszServerFile, pszLocalFile))
  101. {
  102. wprintf(_T(" ERROR - Copy(%s, %s) fails\n"), pszServerFile, pszLocalFile);
  103. return;
  104. }
  105. }
  106. else
  107. {
  108. // verify file exists
  109. auto_hfile hFileOut = CreateFile(pszLocalFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  110. if (!hFileOut.valid())
  111. wprintf(_T(" ERROR - %s doesn't exist\n"), pszLocalFile);
  112. else
  113. wprintf(_T(" %s\n"), pszLocalFile);
  114. }
  115. }
  116. void InstallCallback(void* pCallbackParam, long puid, int iStatus, HRESULT hrError)
  117. {
  118. if (0 == iStatus)
  119. {
  120. wprintf(_T("puid %d installed OK \n"), puid);
  121. }
  122. else
  123. {
  124. wprintf(_T("ERROR - puid %d status %d, error %08X \n"), puid, iStatus, hrError);
  125. }
  126. }
  127. void DoIt(LPCTSTR pszContentServer)
  128. {
  129. IAutoUpdate* pAutoUpdate = NULL;
  130. try
  131. {
  132. if (FAILED(CoCreateInstance(CLSID_CV3, NULL, CLSCTX_ALL, __uuidof(IAutoUpdate), (void**)&pAutoUpdate)))
  133. {
  134. printf("ERROR - CoCreateInstance() failed.\n");
  135. throw 0;
  136. }
  137. if (FAILED(pAutoUpdate->BuildCatalog(g_fOnline, CATLIST_AUTOUPDATE, _bstr_t(pszContentServer))))
  138. {
  139. printf("ERROR - pAutoUpdate->BuildCatalog() failed.\n");
  140. throw 0;
  141. }
  142. VARIANT vCatalogArray;
  143. if (FAILED(pAutoUpdate->GetCatalogArray(&vCatalogArray)))
  144. {
  145. printf("ERROR - pAutoUpdate->GetCatalogArray() failed.\n");
  146. throw 0;
  147. }
  148. bool fHasExclusive = false;
  149. LPSAFEARRAY psaCatalogArray = V_ARRAY(&vCatalogArray);
  150. LONG lCatUBound;
  151. SafeArrayGetUBound(psaCatalogArray, 1, &lCatUBound);
  152. for(int i = 0; i <= lCatUBound; i++)
  153. {
  154. long rgIndices[] = { i, 3 };
  155. VARIANT var;
  156. //Get status
  157. VariantClear(&var);
  158. SafeArrayGetElement(psaCatalogArray, rgIndices, &var);
  159. if (GETCATALOG_STATUS_EXCLUSIVE & var.lVal)
  160. {
  161. fHasExclusive = true;
  162. // Get PUID
  163. rgIndices[1] = 0;
  164. VariantClear(&var);
  165. SafeArrayGetElement(psaCatalogArray, rgIndices, &var);
  166. if (FAILED(pAutoUpdate->SelectPuid(var.lVal)))
  167. {
  168. wprintf(_T("ERROR - pAutoUpdate->SelectPuid() failed.\n"));
  169. throw 0;
  170. }
  171. break;
  172. }
  173. }
  174. if (!fHasExclusive)
  175. {
  176. if (FAILED(pAutoUpdate->SelectAllPuids()))
  177. {
  178. printf("ERROR - pAutoUpdate->SelectAllPuids() failed.\n");
  179. throw 0;
  180. }
  181. }
  182. LONG cnPuids = 0;
  183. LONG* pPuids;
  184. if (FAILED(pAutoUpdate->GetPuidsList(&cnPuids, &pPuids)))
  185. {
  186. printf("ERROR - pAutoUpdate->GetPuidsList() failed.\n");
  187. throw 0;
  188. }
  189. for(LONG l = 0; l < cnPuids; l ++)
  190. {
  191. printf("puid %d\n", pPuids[l]);
  192. pAutoUpdate->QueryDownloadFiles(pPuids[l], 0, QueryDownloadFilesCallback);
  193. }
  194. if (!g_fOnline)
  195. {
  196. pAutoUpdate->InstallSelectedPuids(0, InstallCallback);
  197. pAutoUpdate->CleanupCabsAndReadThis();
  198. }
  199. }
  200. catch(...){}
  201. if(pAutoUpdate)
  202. pAutoUpdate->Release();
  203. }
  204. int _cdecl main(int argc, char** argv)
  205. {
  206. wprintf(_T("--------------- download -----------------------------------\n"));
  207. CoInitialize(NULL);
  208. TCHAR szContentServer[INTERNET_MAX_URL_LENGTH] = {0};
  209. {
  210. auto_hkey hkey;
  211. if (NO_ERROR == RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update"), 0, KEY_READ, &hkey))
  212. {
  213. DWORD dwSize = sizeof(szContentServer);
  214. RegQueryValueEx(hkey, _T("ContentServer"), 0, 0, (LPBYTE)&szContentServer, &dwSize);
  215. }
  216. }
  217. if (0 == lstrlen(szContentServer))
  218. {
  219. wprintf(_T("ERROR - content server is not set.\n"));
  220. return 0;
  221. }
  222. RemoveWindowsUpdateDirectory();
  223. DoIt(szContentServer);
  224. g_fOnline = false;
  225. printf("--------------- install offline ----------------------------\n");
  226. DoIt(szContentServer);
  227. CoUninitialize();
  228. return 0;
  229. }