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.

442 lines
12 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: PROPSTRM.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 10/7/1999
  12. *
  13. * DESCRIPTION: Property Stream Wrapper
  14. *
  15. *******************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #include "propstrm.h"
  19. #include "simreg.h"
  20. CPropertyStream::CPropertyStream(void)
  21. {
  22. WIA_PUSHFUNCTION(TEXT("CPropertyStream::CPropertyStream(void)"));
  23. }
  24. CPropertyStream::CPropertyStream( IStream *pIStream )
  25. {
  26. WIA_PUSHFUNCTION(TEXT("CPropertyStream::CPropertyStream( IStream *pIStream )"));
  27. CopyFromStream( pIStream );
  28. }
  29. CPropertyStream::CPropertyStream( IWiaItem *pIWiaItem )
  30. {
  31. WIA_PUSHFUNCTION(TEXT("CPropertyStream::CPropertyStream( IWiaItem *pIWiaItem )"));
  32. AssignFromWiaItem( pIWiaItem );
  33. }
  34. CPropertyStream::CPropertyStream( const CPropertyStream &other )
  35. {
  36. WIA_PUSHFUNCTION(TEXT("CPropertyStream::CPropertyStream( const CPropertyStream &other )"));
  37. CopyFromStream( other.Stream() );
  38. }
  39. CPropertyStream::~CPropertyStream()
  40. {
  41. WIA_PUSHFUNCTION(TEXT("CPropertyStream::~CPropertyStream"));
  42. Destroy();
  43. }
  44. CPropertyStream &CPropertyStream::operator=( const CPropertyStream &other )
  45. {
  46. WIA_PUSHFUNCTION(TEXT("CPropertyStream::operator="));
  47. if (this != &other)
  48. {
  49. CopyFromStream( other.Stream() );
  50. }
  51. return (*this);
  52. }
  53. bool CPropertyStream::IsValid(void) const
  54. {
  55. WIA_PUSHFUNCTION(TEXT("CPropertyStream::IsValid"));
  56. return (m_pIStreamPropertyStream.p != NULL);
  57. }
  58. void CPropertyStream::Destroy(void)
  59. {
  60. WIA_PUSHFUNCTION(TEXT("CPropertyStream::Destroy"));
  61. m_pIStreamPropertyStream = NULL;
  62. }
  63. HRESULT CPropertyStream::CopyFromMemoryBlock( PBYTE pbSource, UINT_PTR nSize )
  64. {
  65. WIA_PUSHFUNCTION(TEXT("CPropertyStream::CopyFromMemoryBlock"));
  66. Destroy();
  67. HRESULT hr = S_OK;
  68. if (pbSource)
  69. {
  70. if (nSize)
  71. {
  72. // Allocate memory to back the new stream.
  73. HGLOBAL hTarget = GlobalAlloc(GMEM_MOVEABLE, nSize);
  74. if (hTarget)
  75. {
  76. PBYTE pbTarget = (PBYTE)GlobalLock(hTarget);
  77. if (pbTarget)
  78. {
  79. CopyMemory( pbTarget, pbSource, nSize );
  80. GlobalUnlock( hTarget );
  81. hr = CreateStreamOnHGlobal(hTarget, TRUE, &m_pIStreamPropertyStream );
  82. }
  83. else
  84. {
  85. WIA_ERROR(("CPropertyStream::CopyFromMemoryBlock, GlobalLock failed"));
  86. hr = HRESULT_FROM_WIN32(GetLastError());
  87. }
  88. }
  89. else
  90. {
  91. WIA_ERROR(("CPropertyStream::CopyFromMemoryBlock, GlobalAlloc failed, size: %d", nSize));
  92. hr = HRESULT_FROM_WIN32(GetLastError());
  93. }
  94. }
  95. else
  96. {
  97. WIA_ERROR(("CPropertyStream::CopyFromMemoryBlock, nSize == 0"));
  98. hr = E_INVALIDARG;
  99. }
  100. }
  101. else
  102. {
  103. WIA_ERROR(("CPropertyStream::CopyFromMemoryBlock, Invalid source buffer"));
  104. hr = E_INVALIDARG;
  105. }
  106. return(hr);
  107. }
  108. HRESULT CPropertyStream::CopyFromStream( IStream *pIStream )
  109. {
  110. WIA_PUSHFUNCTION(TEXT("CPropertyStream::CopyFromStream"));
  111. Destroy();
  112. HRESULT hr = S_OK;
  113. if (pIStream)
  114. {
  115. HGLOBAL hSource;
  116. hr = GetHGlobalFromStream(pIStream, &hSource);
  117. if (SUCCEEDED(hr))
  118. {
  119. // Get the size of the stream.
  120. UINT_PTR nSize = GlobalSize(hSource);
  121. if (nSize)
  122. {
  123. PBYTE pbSource = (PBYTE)GlobalLock(hSource);
  124. if (pbSource)
  125. {
  126. hr = CopyFromMemoryBlock( pbSource, nSize );
  127. GlobalUnlock(hSource);
  128. }
  129. else
  130. {
  131. WIA_ERROR(("CPropertyStream::CopyFromStream, GlobalLock failed"));
  132. hr = HRESULT_FROM_WIN32(GetLastError());
  133. }
  134. }
  135. else
  136. {
  137. WIA_ERROR(("CPropertyStream::CopyFromStream, GlobalSize failed"));
  138. hr = HRESULT_FROM_WIN32(GetLastError());
  139. }
  140. }
  141. else
  142. {
  143. WIA_ERROR(("CPropertyStream::CopyFromStream, GetHGlobalFromStream failed"));
  144. }
  145. }
  146. else
  147. {
  148. WIA_ERROR(("CPropertyStream::CopyFromStream, Invalid source stream"));
  149. hr = E_INVALIDARG;
  150. }
  151. if (FAILED(hr))
  152. {
  153. WIA_PRINTHRESULT((hr,TEXT("CPropertyStream::CopyFromStream failed")));
  154. }
  155. return(hr);
  156. }
  157. HRESULT CPropertyStream::AssignFromWiaItem( IWiaItem *pIWiaItem )
  158. {
  159. WIA_PUSHFUNCTION(TEXT("CPropertyStream::AssignFromWiaItem"));
  160. Destroy();
  161. HRESULT hr;
  162. if (pIWiaItem)
  163. {
  164. IWiaPropertyStorage *pIWiaPropertyStorage;
  165. hr = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage, (void**) &pIWiaPropertyStorage);
  166. if (SUCCEEDED(hr))
  167. {
  168. GUID guidCompatibilityId;
  169. hr = pIWiaPropertyStorage->GetPropertyStream(&guidCompatibilityId, &m_pIStreamPropertyStream);
  170. if (FAILED(hr))
  171. {
  172. WIA_PRINTHRESULT((hr,TEXT("CPropertyStream::AssignFromWiaItem, GetPropertyStream failed")));
  173. }
  174. pIWiaPropertyStorage->Release();
  175. }
  176. else
  177. {
  178. WIA_PRINTHRESULT((hr,TEXT("CPropertyStream::AssignFromWiaItem, QI of IID_IWiaPropertyStorage failed")));
  179. }
  180. }
  181. else
  182. {
  183. hr = E_INVALIDARG;
  184. WIA_ERROR(("CPropertyStream::AssignFromWiaItem, Invalid IWiaItem *"));
  185. }
  186. if (!SUCCEEDED(hr))
  187. {
  188. WIA_PRINTHRESULT((hr,"CPropertyStream::AssignFromWiaItem failed"));
  189. }
  190. return(hr);
  191. }
  192. HRESULT CPropertyStream::ApplyToWiaItem( IWiaItem *pIWiaItem )
  193. {
  194. WIA_PUSHFUNCTION(TEXT("CPropertyStream::ApplyToWiaItem"));
  195. HRESULT hr;
  196. if (pIWiaItem && m_pIStreamPropertyStream)
  197. {
  198. IWiaPropertyStorage *pIWiaPropertyStorage;
  199. hr = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage, (void**) &pIWiaPropertyStorage);
  200. if (SUCCEEDED(hr))
  201. {
  202. hr = pIWiaPropertyStorage->SetPropertyStream((GUID*) &GUID_NULL, m_pIStreamPropertyStream);
  203. if (FAILED(hr))
  204. {
  205. WIA_PRINTHRESULT((hr,TEXT("CPropertyStream::ApplyToWiaItem, SetPropertyStream failed")));
  206. }
  207. pIWiaPropertyStorage->Release();
  208. }
  209. else
  210. {
  211. WIA_PRINTHRESULT((hr,TEXT("CPropertyStream::ApplyToWiaItem, QI of IID_IWiaPropertyStorage failed")));
  212. }
  213. }
  214. else
  215. {
  216. hr = E_INVALIDARG;
  217. WIA_ERROR(("CPropertyStream::ApplyToWiaItem, Invalid IWiaItem *"));
  218. }
  219. if (!SUCCEEDED(hr))
  220. {
  221. WIA_PRINTHRESULT((hr,"CPropertyStream::ApplyToWiaItem failed"));
  222. }
  223. return(hr);
  224. }
  225. IStream *CPropertyStream::Stream(void)
  226. {
  227. WIA_PUSHFUNCTION(TEXT("*CPropertyStream::Stream(void)"));
  228. return(m_pIStreamPropertyStream);
  229. }
  230. IStream *CPropertyStream::Stream(void) const
  231. {
  232. WIA_PUSHFUNCTION(TEXT("*CPropertyStream::Stream(void) const"));
  233. return(m_pIStreamPropertyStream);
  234. }
  235. UINT_PTR CPropertyStream::Size(void) const
  236. {
  237. WIA_PUSHFUNCTION(TEXT("CPropertyStream::Size"));
  238. UINT_PTR nSize = 0;
  239. if (m_pIStreamPropertyStream)
  240. {
  241. STATSTG StatStg;
  242. if (SUCCEEDED(m_pIStreamPropertyStream->Stat(&StatStg,STATFLAG_NONAME)))
  243. nSize = StatStg.cbSize.LowPart;
  244. }
  245. return(nSize);
  246. }
  247. PBYTE CPropertyStream::Lock(void)
  248. {
  249. WIA_PUSHFUNCTION(TEXT("CPropertyStream::Lock"));
  250. PBYTE pBytes = NULL;
  251. if (m_pIStreamPropertyStream)
  252. {
  253. HGLOBAL hSource;
  254. HRESULT hr = GetHGlobalFromStream(m_pIStreamPropertyStream, &hSource);
  255. if (SUCCEEDED(hr))
  256. {
  257. pBytes = reinterpret_cast<PBYTE>(GlobalLock( hSource ));
  258. }
  259. }
  260. return(pBytes);
  261. }
  262. void CPropertyStream::Unlock(void)
  263. {
  264. WIA_PUSHFUNCTION(TEXT("CPropertyStream::Unlock"));
  265. PBYTE pBytes = NULL;
  266. if (m_pIStreamPropertyStream)
  267. {
  268. HGLOBAL hSource;
  269. HRESULT hr = GetHGlobalFromStream(m_pIStreamPropertyStream, &hSource);
  270. if (SUCCEEDED(hr))
  271. {
  272. GlobalUnlock( hSource );
  273. }
  274. }
  275. }
  276. bool ConstructRegistryPath( IWiaItem *pWiaItem, LPCTSTR pszSubKey, CSimpleString &strKeyName )
  277. {
  278. if (pWiaItem)
  279. {
  280. strKeyName = pszSubKey;
  281. if (strKeyName.Length())
  282. {
  283. // Append a backslash
  284. if (strKeyName[(int)(strKeyName.Length())] != TEXT('\\'))
  285. strKeyName += TEXT("\\");
  286. CSimpleStringWide strwItemName;
  287. if (PropStorageHelpers::GetProperty( pWiaItem, WIA_IPA_FULL_ITEM_NAME, strwItemName ))
  288. {
  289. strKeyName += CSimpleStringConvert::NaturalString( strwItemName );
  290. return true;
  291. }
  292. }
  293. }
  294. return false;
  295. }
  296. bool CPropertyStream::GetBytes( PBYTE &pByte, UINT_PTR &nSize )
  297. {
  298. bool bSuccess = false;
  299. if (m_pIStreamPropertyStream)
  300. {
  301. nSize = Size();
  302. if (nSize)
  303. {
  304. pByte = new BYTE[nSize];
  305. if (pByte)
  306. {
  307. LARGE_INTEGER li = {0,0};
  308. if (SUCCEEDED(m_pIStreamPropertyStream->Seek(li,STREAM_SEEK_SET,NULL)))
  309. {
  310. DWORD dwBytesRead = 0;
  311. if (SUCCEEDED(m_pIStreamPropertyStream->Read( pByte, static_cast<DWORD>(nSize), &dwBytesRead )))
  312. {
  313. if (static_cast<DWORD>(dwBytesRead) == nSize)
  314. {
  315. bSuccess = true;
  316. }
  317. }
  318. }
  319. if (!bSuccess)
  320. {
  321. delete[] pByte;
  322. pByte = NULL;
  323. nSize = 0;
  324. }
  325. }
  326. }
  327. }
  328. return bSuccess;
  329. }
  330. bool CPropertyStream::WriteToRegistry( IWiaItem *pWiaItem, HKEY hKeyRoot, LPCTSTR pszSubKey, LPCTSTR pszValueName )
  331. {
  332. bool bResult = false;
  333. CSimpleString strKeyName;
  334. if (ConstructRegistryPath( pWiaItem, pszSubKey, strKeyName ))
  335. {
  336. CSimpleReg reg( hKeyRoot, strKeyName, true, KEY_WRITE );
  337. if (reg.OK())
  338. {
  339. UINT_PTR nSize = 0;
  340. PBYTE pData = NULL;
  341. if (GetBytes(pData,nSize) && nSize && pData)
  342. {
  343. bResult = reg.SetBin( pszValueName, pData, static_cast<DWORD>(nSize), REG_BINARY );
  344. delete[] pData;
  345. }
  346. else
  347. {
  348. reg.Delete( pszValueName );
  349. }
  350. }
  351. }
  352. return bResult;
  353. }
  354. bool CPropertyStream::ReadFromRegistry( IWiaItem *pWiaItem, HKEY hKeyRoot, LPCTSTR pszSubKey, LPCTSTR pszValueName )
  355. {
  356. bool bResult = false;
  357. Destroy();
  358. CSimpleString strKeyName;
  359. if (ConstructRegistryPath( pWiaItem, pszSubKey, strKeyName ))
  360. {
  361. CSimpleReg reg( hKeyRoot, strKeyName, false, KEY_READ );
  362. if (reg.OK())
  363. {
  364. UINT_PTR nStreamSize = reg.Size(pszValueName);
  365. if (nStreamSize)
  366. {
  367. BYTE *pData = new BYTE[nStreamSize];
  368. if (pData)
  369. {
  370. if (reg.QueryBin( pszValueName, pData, static_cast<DWORD>(nStreamSize) ))
  371. {
  372. if (SUCCEEDED(CopyFromMemoryBlock( pData, nStreamSize )))
  373. {
  374. bResult = true;
  375. }
  376. }
  377. delete[] pData;
  378. }
  379. }
  380. }
  381. }
  382. return bResult;
  383. }
  384. CAutoRestorePropertyStream::CAutoRestorePropertyStream( IWiaItem *pItem )
  385. {
  386. m_hr = m_PropertyStream.AssignFromWiaItem(pItem);
  387. m_pWiaItem = pItem;
  388. }
  389. CAutoRestorePropertyStream::~CAutoRestorePropertyStream()
  390. {
  391. if (SUCCEEDED(m_hr))
  392. {
  393. m_PropertyStream.ApplyToWiaItem(m_pWiaItem);
  394. }
  395. }