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.

432 lines
11 KiB

  1. #include "enum.h"
  2. BOOL GetVersion(LPCONTROLPIDL pcpidl, LPTSTR lpszBuf);
  3. BOOL GetTimeInfo(
  4. BOOL bCreation, LPCONTROLPIDL pcpidl,
  5. FILETIME* lpTime, LPTSTR lpszBuf, BOOL bShowTime);
  6. // Also defined in nt\private\inet\urlmon\isctrl.cxx
  7. const TCHAR *g_pszLastCheckDateKey = "LastCheckDate";
  8. const TCHAR *g_pszUpdateInfo = "UpdateInfo";
  9. #if defined(ALIGNMENT_MACHINE)
  10. BOOL
  11. __inline
  12. static
  13. uaGetControlInfo(
  14. IN HANDLE hControlHandle,
  15. IN UINT nFlag,
  16. IN OUT DWORD UNALIGNED *lpdwuData,
  17. IN OUT LPTSTR lpszBuf,
  18. IN int nBufLen
  19. )
  20. {
  21. DWORD dwData;
  22. LPDWORD lpdwData;
  23. BOOL result;
  24. if (lpdwuData != NULL) {
  25. dwData = *lpdwuData;
  26. lpdwData = &dwData;
  27. } else {
  28. lpdwData = NULL;
  29. }
  30. result = GetControlInfo( hControlHandle,
  31. nFlag,
  32. lpdwData,
  33. lpszBuf,
  34. nBufLen );
  35. if (lpdwuData != NULL) {
  36. *lpdwuData = dwData;
  37. }
  38. return result;
  39. }
  40. BOOL
  41. __inline
  42. static
  43. uaGetTimeInfo(
  44. IN BOOL bCreation,
  45. IN OUT LPCONTROLPIDL pcpidl,
  46. IN OUT FILETIME UNALIGNED *lpuTime,
  47. IN OUT LPTSTR lpszBuf,
  48. IN BOOL bShowTime
  49. )
  50. {
  51. FILETIME time;
  52. LPFILETIME lpTime;
  53. BOOL result;
  54. if (lpuTime != NULL) {
  55. time = *lpuTime;
  56. lpTime = &time;
  57. } else {
  58. lpTime = NULL;
  59. }
  60. result = GetTimeInfo( bCreation,
  61. pcpidl,
  62. lpTime,
  63. lpszBuf,
  64. bShowTime );
  65. if (lpuTime != NULL) {
  66. *lpuTime = time;
  67. }
  68. return result;
  69. }
  70. #else
  71. #define uaGetControlInfo GetControlInfo
  72. #define uaGetTimeInfo GetTimeInfo
  73. #endif
  74. ///////////////////////////////////////////////////////////////////////////////
  75. // IEnumIDList methods
  76. CControlFolderEnum::CControlFolderEnum(STRRET &str, LPCITEMIDLIST pidl, UINT shcontf) :
  77. m_shcontf(shcontf)
  78. {
  79. DebugMsg(DM_TRACE, TEXT("cfe - CControlFolderEnum() called"));
  80. m_cRef = 1;
  81. DllAddRef();
  82. m_bEnumStarted = FALSE;
  83. m_hEnumControl = NULL;
  84. StrRetToBuf(&str, pidl, m_szCachePath, MAX_PATH);
  85. SHGetMalloc(&m_pMalloc); // won't fail
  86. }
  87. CControlFolderEnum::~CControlFolderEnum()
  88. {
  89. Assert(m_cRef == 0); // we should always have a zero ref count here
  90. DebugMsg(DM_TRACE, TEXT("cfe - ~CControlFolderEnum() called."));
  91. DllRelease();
  92. }
  93. HRESULT CControlFolderEnum_CreateInstance(
  94. LPITEMIDLIST pidl,
  95. UINT shcontf,
  96. LPENUMIDLIST *ppeidl)
  97. {
  98. DebugMsg(DM_TRACE,("cfe - CreateInstance() called."));
  99. if (pidl == NULL)
  100. return HRESULT_FROM_WIN32(ERROR_BAD_ARGUMENTS);
  101. HRESULT hr;
  102. LPSHELLFOLDER pshf = NULL;
  103. if (FAILED(hr = SHGetDesktopFolder(&pshf)))
  104. return hr;
  105. STRRET name;
  106. hr = pshf->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &name);
  107. if (FAILED(hr))
  108. return hr;
  109. *ppeidl = NULL; // null the out param
  110. CControlFolderEnum *pCFE = new CControlFolderEnum(name, pidl, shcontf);
  111. if (!pCFE)
  112. return E_OUTOFMEMORY;
  113. *ppeidl = pCFE;
  114. return S_OK;
  115. }
  116. BOOL GetVersion(LPCONTROLPIDL pcpidl, LPTSTR lpszBuf)
  117. {
  118. Assert(pcpidl != NULL);
  119. LPCTSTR pszLocation = GetStringInfo(pcpidl, SI_LOCATION);
  120. DWORD dwBufLen;
  121. DWORD dwHandle;
  122. BOOL fResult = FALSE;
  123. UINT uLen;
  124. VS_FIXEDFILEINFO *pVersionInfo = NULL;
  125. // Quick copy to handle failure cases
  126. lstrcpy(lpszBuf, g_szUnknownData);
  127. if ((dwBufLen = ::GetFileVersionInfoSize(
  128. (LPTSTR)pszLocation,
  129. &dwHandle)) == 0)
  130. return FALSE;
  131. BYTE *pbData = new BYTE[dwBufLen];
  132. if (pbData == NULL)
  133. return FALSE;
  134. if (GetFileVersionInfo((LPTSTR)pszLocation, dwHandle, dwBufLen, pbData))
  135. {
  136. fResult = VerQueryValue(pbData, "\\", (LPVOID*)&pVersionInfo, &uLen);
  137. if (fResult)
  138. {
  139. wsprintf(lpszBuf, "%d,%d,%d,%d",
  140. (pVersionInfo->dwFileVersionMS & 0xffff0000)>>16,
  141. (pVersionInfo->dwFileVersionMS & 0xffff),
  142. (pVersionInfo->dwFileVersionLS & 0xffff0000)>>16,
  143. (pVersionInfo->dwFileVersionLS & 0xffff));
  144. }
  145. }
  146. delete [] pbData;
  147. return fResult;
  148. }
  149. BOOL GetTimeInfo(
  150. BOOL bCreation,
  151. LPCONTROLPIDL pcpidl,
  152. FILETIME* lpTime,
  153. LPTSTR lpszBuf,
  154. BOOL bShowTime)
  155. {
  156. Assert(pcpidl != NULL);
  157. Assert (lpszBuf != NULL);
  158. if (pcpidl == NULL || lpszBuf == NULL)
  159. return FALSE;
  160. LPCTSTR pszLocation = GetStringInfo(pcpidl, SI_LOCATION);
  161. BOOL fResult = TRUE;
  162. HANDLE hFile = NULL;
  163. WIN32_FIND_DATA findFileData;
  164. TCHAR szTime[TIMESTAMP_MAXSIZE];
  165. TCHAR szDate[TIMESTAMP_MAXSIZE];
  166. SYSTEMTIME sysTime;
  167. FILETIME localTime;
  168. hFile = FindFirstFile(pszLocation, &findFileData);
  169. if (hFile != INVALID_HANDLE_VALUE)
  170. {
  171. // Get the creation time and date information.
  172. if (bCreation)
  173. {
  174. *lpTime = findFileData.ftCreationTime;
  175. FileTimeToLocalFileTime(&findFileData.ftCreationTime, &localTime);
  176. }
  177. else
  178. {
  179. *lpTime = findFileData.ftLastAccessTime;
  180. FileTimeToLocalFileTime(&findFileData.ftLastAccessTime, &localTime);
  181. }
  182. FileTimeToSystemTime(&localTime, &sysTime);
  183. GetDateFormat(
  184. LOCALE_SYSTEM_DEFAULT,
  185. DATE_SHORTDATE,
  186. &sysTime,
  187. NULL,
  188. szDate,
  189. TIMESTAMP_MAXSIZE);
  190. lstrcpy(lpszBuf, szDate);
  191. if (bShowTime)
  192. {
  193. GetTimeFormat(
  194. LOCALE_SYSTEM_DEFAULT,
  195. TIME_NOSECONDS,
  196. &sysTime,
  197. NULL,
  198. szTime,
  199. TIMESTAMP_MAXSIZE
  200. );
  201. lstrcat(lpszBuf, TEXT(" "));
  202. lstrcat(lpszBuf, szTime);
  203. }
  204. FindClose(hFile);
  205. }
  206. else
  207. {
  208. fResult = FALSE;
  209. lstrcpy(lpszBuf, g_szUnknownData);
  210. lpTime->dwLowDateTime = lpTime->dwHighDateTime = 0;
  211. }
  212. return fResult;
  213. }
  214. LPCONTROLPIDL CreateControlPidl(IMalloc *pmalloc, HANDLE hControl)
  215. {
  216. Assert(pmalloc != NULL);
  217. DWORD dw;
  218. GetControlInfo(hControl, GCI_TOTALFILES, &dw, NULL, 0);
  219. ULONG ulSize = sizeof(CONTROLPIDL) + sizeof(USHORT);
  220. ulSize += (dw - 1) * sizeof(DEPENDENTFILEINFO);
  221. LPCONTROLPIDL pcpidl = (LPCONTROLPIDL)pmalloc->Alloc(ulSize);
  222. if (pcpidl)
  223. {
  224. memset(pcpidl, 0, ulSize);
  225. pcpidl->cb = (USHORT)(ulSize - sizeof(USHORT));
  226. pcpidl->ci.cTotalFiles = (UINT)dw;
  227. uaGetControlInfo(hControl, GCI_TOTALSIZE, &(pcpidl->ci.dwTotalFileSize), NULL, 0);
  228. uaGetControlInfo(hControl, GCI_SIZESAVED, &(pcpidl->ci.dwTotalSizeSaved), NULL, 0);
  229. GetControlInfo(hControl, GCI_NAME, NULL, pcpidl->ci.szName, CONTROLNAME_MAXSIZE);
  230. GetControlInfo(hControl, GCI_FILE, NULL, pcpidl->ci.szFile, MAX_PATH);
  231. GetControlInfo(hControl, GCI_CLSID, NULL, pcpidl->ci.szCLSID, MAX_CLSID_LEN);
  232. GetControlInfo(hControl, GCI_TYPELIBID, NULL, pcpidl->ci.szTypeLibID, MAX_CLSID_LEN);
  233. uaGetTimeInfo(TRUE, pcpidl, &(pcpidl->ci.timeCreation), pcpidl->ci.szCreation, TRUE);
  234. uaGetTimeInfo(FALSE, pcpidl, &(pcpidl->ci.timeLastAccessed), pcpidl->ci.szLastAccess, FALSE);
  235. GetControlInfo(hControl, GCI_CODEBASE, NULL, pcpidl->ci.szCodeBase, INTERNET_MAX_URL_LENGTH);
  236. uaGetControlInfo(hControl, GCI_ISDISTUNIT, &(pcpidl->ci.dwIsDistUnit), NULL, 0);
  237. uaGetControlInfo(hControl, GCI_STATUS, &(pcpidl->ci.dwStatus), NULL, 0);
  238. uaGetControlInfo(hControl, GCI_HAS_ACTIVEX, &(pcpidl->ci.dwHasActiveX), NULL, 0);
  239. uaGetControlInfo(hControl, GCI_HAS_JAVA, &(pcpidl->ci.dwHasJava), NULL, 0);
  240. if (pcpidl->ci.dwIsDistUnit)
  241. {
  242. GetControlInfo(hControl, GCI_DIST_UNIT_VERSION, NULL, pcpidl->ci.szVersion, VERSION_MAXSIZE);
  243. }
  244. else
  245. {
  246. GetVersion(pcpidl, pcpidl->ci.szVersion);
  247. }
  248. LONG lResult = ERROR_SUCCESS;
  249. DEPENDENTFILEINFO UNALIGNED *pInfo = &(pcpidl->ci.dependentFile);
  250. dw = GetTotalNumOfFiles(pcpidl);
  251. for (UINT iFile = 0; iFile < (UINT)dw; iFile++)
  252. {
  253. DWORD alignedSize = pInfo->dwSize;
  254. lResult = GetControlDependentFile(
  255. iFile,
  256. hControl,
  257. pInfo->szFile,
  258. &alignedSize,
  259. TRUE);
  260. pInfo->dwSize = alignedSize;
  261. if (lResult != ERROR_SUCCESS)
  262. break;
  263. pInfo = (LPDEPENDENTFILEINFO)(pInfo + 1);
  264. }
  265. }
  266. return pcpidl;
  267. }
  268. //////////////////////////////////
  269. //
  270. // IUnknown Methods...
  271. //
  272. HRESULT CControlFolderEnum::QueryInterface(REFIID iid,void **ppv)
  273. {
  274. DebugMsg(DM_TRACE, TEXT("cfe - QueryInterface called."));
  275. if ((iid == IID_IEnumIDList) || (iid == IID_IUnknown))
  276. {
  277. *ppv = (void *)this;
  278. AddRef();
  279. return S_OK;
  280. }
  281. *ppv = NULL;
  282. return E_NOINTERFACE;
  283. }
  284. ULONG CControlFolderEnum::AddRef(void)
  285. {
  286. return ++m_cRef;
  287. }
  288. ULONG CControlFolderEnum::Release(void)
  289. {
  290. if (--m_cRef)
  291. return m_cRef;
  292. delete this;
  293. return 0;
  294. }
  295. HRESULT CControlFolderEnum::Next(
  296. ULONG celt,
  297. LPITEMIDLIST *rgelt,
  298. ULONG *pceltFetched)
  299. {
  300. DebugMsg(DM_TRACE, TEXT("cfe - Next() called."));
  301. // If asking for stuff we don't have, say we don't have any
  302. if (!(m_shcontf & SHCONTF_NONFOLDERS))
  303. return S_FALSE;
  304. LONG lres = ERROR_SUCCESS;
  305. HANDLE hControl = NULL;
  306. LPCONTROLPIDL pcpidl = NULL;
  307. lres = (!m_bEnumStarted ?
  308. FindFirstControl(m_hEnumControl, hControl, m_szCachePath) :
  309. FindNextControl(m_hEnumControl, hControl));
  310. if (pceltFetched)
  311. *pceltFetched = (lres == ERROR_SUCCESS ? 1 : 0);
  312. if (lres != ERROR_SUCCESS)
  313. goto EXIT_NEXT;
  314. pcpidl = CreateControlPidl(m_pMalloc, hControl);
  315. if (pcpidl == NULL)
  316. {
  317. lres = ERROR_NOT_ENOUGH_MEMORY;
  318. goto EXIT_NEXT;
  319. }
  320. m_bEnumStarted = TRUE;
  321. rgelt[0] = (LPITEMIDLIST)pcpidl;
  322. EXIT_NEXT:
  323. ReleaseControlHandle(hControl);
  324. if (lres != ERROR_SUCCESS)
  325. {
  326. if (pcpidl != NULL)
  327. {
  328. m_pMalloc->Free(pcpidl);
  329. pcpidl = NULL;
  330. }
  331. FindControlClose(m_hEnumControl);
  332. m_bEnumStarted = FALSE;
  333. rgelt[0] = NULL;
  334. }
  335. return HRESULT_FROM_WIN32(lres);
  336. }
  337. HRESULT CControlFolderEnum::Skip(ULONG celt)
  338. {
  339. DebugMsg(DM_TRACE, TEXT("cfe - Skip() called."));
  340. return E_NOTIMPL;
  341. }
  342. HRESULT CControlFolderEnum::Reset()
  343. {
  344. DebugMsg(DM_TRACE, TEXT("cfe - Reset() called."));
  345. return E_NOTIMPL;
  346. }
  347. HRESULT CControlFolderEnum::Clone(IEnumIDList **ppenum)
  348. {
  349. DebugMsg(DM_TRACE, TEXT("cfe - Clone() called."));
  350. return E_NOTIMPL;
  351. }