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.

325 lines
14 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #include <simstr.h>
  4. #include <wiadebug.h>
  5. #include "wiadefui.h"
  6. #include "uicommon.h"
  7. #include "wiauiext.h"
  8. #include "resource.h"
  9. extern HINSTANCE g_hInstance;
  10. STDMETHODIMP CWiaDefaultUI::BandedDataCallback(
  11. LONG lReason,
  12. LONG lStatus,
  13. LONG lPercentComplete,
  14. LONG lOffset,
  15. LONG lLength,
  16. LONG lReserved,
  17. LONG lResLength,
  18. PBYTE pbBuffer)
  19. {
  20. WIA_PUSH_FUNCTION((TEXT("CWiaDefaultUI::BandedDataCallback(%08X,%08X,%08X,%08X,%08X,%08X,%08X,%08X)"),lReason,lStatus,lPercentComplete,lOffset,lLength,lReserved,lResLength,pbBuffer));
  21. HRESULT hr = S_OK;
  22. if (m_pSecondaryCallback)
  23. hr = m_pSecondaryCallback->BandedDataCallback(lReason,lStatus,lPercentComplete,lOffset,lLength,lReserved,lResLength,pbBuffer);
  24. WIA_PRINTHRESULT((hr,TEXT("m_pSecondaryCallback->BandedDataCallback returned")));
  25. if (SUCCEEDED(hr) && hr != S_FALSE && lReason == IT_MSG_STATUS)
  26. {
  27. if (m_pWiaProgressDialog)
  28. {
  29. m_pWiaProgressDialog->SetPercentComplete(lPercentComplete);
  30. BOOL bCancelled = FALSE;
  31. if (SUCCEEDED(m_pWiaProgressDialog->Cancelled(&bCancelled)) && bCancelled)
  32. {
  33. hr = S_FALSE;
  34. }
  35. }
  36. }
  37. else if (SUCCEEDED(hr) && hr != S_FALSE && lReason == IT_MSG_DATA)
  38. {
  39. if (m_pWiaProgressDialog)
  40. {
  41. m_pWiaProgressDialog->SetPercentComplete(lPercentComplete);
  42. BOOL bCancelled = FALSE;
  43. if (SUCCEEDED(m_pWiaProgressDialog->Cancelled(&bCancelled)) && bCancelled)
  44. {
  45. hr = S_FALSE;
  46. }
  47. }
  48. }
  49. WIA_PRINTHRESULT((hr,TEXT("CWiaDefaultUI::BandedDataCallback is returning")));
  50. return(hr);
  51. }
  52. STDMETHODIMP CWiaDefaultUI::TransferItemBanded( IWiaItem *pWiaItem, HWND hwndParent, DWORD dwFlags, GUID guidFormat, ULONG ulBufferSize, IWiaDataCallback *pSecondaryCallback )
  53. {
  54. if (!pWiaItem)
  55. {
  56. return E_INVALIDARG;
  57. }
  58. // Create status window, if requested
  59. m_pSecondaryCallback = pSecondaryCallback;
  60. HRESULT hr;
  61. if (0 == (dwFlags&WIA_TRANSFERHELPER_NOPROGRESS))
  62. {
  63. hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaProgressDialog, (void**)&m_pWiaProgressDialog );
  64. if (SUCCEEDED(hr))
  65. {
  66. m_pWiaProgressDialog->Create( hwndParent, WIA_PROGRESSDLG_NO_ANIM );
  67. m_pWiaProgressDialog->SetTitle(CSimpleStringConvert::WideString(CSimpleString(IDS_TRANSFER_IMAGE_ACQUIRING,g_hInstance)));
  68. m_pWiaProgressDialog->SetMessage(CSimpleStringConvert::WideString(CSimpleString(IDS_TRANSFER_IMAGE_PERCENT,g_hInstance)));
  69. m_pWiaProgressDialog->Show();
  70. }
  71. }
  72. if (m_pWiaProgressDialog || (dwFlags&WIA_TRANSFERHELPER_NOPROGRESS))
  73. {
  74. CComPtr<IWiaDataCallback> pWiaDataCallback;
  75. hr = this->QueryInterface(IID_IWiaDataCallback, (void **)&pWiaDataCallback);
  76. if (SUCCEEDED(hr))
  77. {
  78. CComPtr<IWiaPropertyStorage> pWiaPropertyStorage;
  79. hr = pWiaItem->QueryInterface(IID_IWiaPropertyStorage, (void **)&pWiaPropertyStorage);
  80. if (SUCCEEDED(hr))
  81. {
  82. if (guidFormat == GUID_NULL)
  83. {
  84. CComPtr<IWiaSupportedFormats> pWiaSupportedFormats;
  85. hr = this->QueryInterface(IID_IWiaSupportedFormats, (void **)&pWiaSupportedFormats);
  86. if (SUCCEEDED(hr))
  87. {
  88. hr = pWiaSupportedFormats->Initialize( pWiaItem, TYMED_CALLBACK );
  89. if (SUCCEEDED(hr))
  90. {
  91. hr = GetDefaultClipboardFileFormat( &guidFormat );
  92. }
  93. }
  94. }
  95. if (guidFormat == GUID_NULL)
  96. guidFormat = WiaImgFmt_MEMORYBMP;
  97. PROPSPEC PropSpec[2] = {0};
  98. PROPVARIANT PropVariant[2] = {0};
  99. PropSpec[0].ulKind = PRSPEC_PROPID;
  100. PropSpec[0].propid = WIA_IPA_FORMAT;
  101. PropSpec[1].ulKind = PRSPEC_PROPID;
  102. PropSpec[1].propid = WIA_IPA_TYMED;
  103. PropVariant[0].vt = VT_CLSID;
  104. PropVariant[0].puuid = &guidFormat;
  105. PropVariant[1].vt = VT_I4;
  106. PropVariant[1].lVal = TYMED_CALLBACK;
  107. hr = pWiaPropertyStorage->WriteMultiple( ARRAYSIZE(PropVariant), PropSpec, PropVariant, WIA_IPA_FIRST );
  108. if (SUCCEEDED(hr))
  109. {
  110. CComPtr<IWiaDataTransfer> pIWiaDataTransfer;
  111. hr = pWiaItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIWiaDataTransfer);
  112. if (SUCCEEDED(hr))
  113. {
  114. if (!ulBufferSize)
  115. {
  116. LONG lMinimumBufferSize;
  117. if (!PropStorageHelpers::GetProperty( pWiaItem, WIA_IPA_MIN_BUFFER_SIZE, lMinimumBufferSize ))
  118. {
  119. lMinimumBufferSize = 0x0000FFFF; // 64K
  120. }
  121. ulBufferSize = static_cast<ULONG>(lMinimumBufferSize);
  122. }
  123. WIA_DATA_TRANSFER_INFO WiaDataTransferInfo = {0};
  124. WiaDataTransferInfo.ulSize = sizeof(WIA_DATA_TRANSFER_INFO);
  125. WiaDataTransferInfo.ulBufferSize = ulBufferSize;
  126. hr = pIWiaDataTransfer->idtGetBandedData(&WiaDataTransferInfo, pWiaDataCallback);
  127. WIA_PRINTHRESULT((hr,TEXT("pIWiaDataTransfer->idtGetBandedData returned")));
  128. }
  129. else
  130. {
  131. WIA_PRINTHRESULT((hr,TEXT("TransferItemBanded, QI on IID_IWiaDataTransfer")));
  132. }
  133. }
  134. else
  135. {
  136. WIA_PRINTHRESULT((hr,TEXT("TransferItemBanded, pIWiaPropertyStorage->WriteMultiple failed")));
  137. }
  138. }
  139. else
  140. {
  141. WIA_PRINTHRESULT((hr,TEXT("TransferItemBanded, QI of IID_IWiaPropertyStorage failed.")));
  142. }
  143. }
  144. if (m_pWiaProgressDialog)
  145. {
  146. m_pWiaProgressDialog->Destroy();
  147. m_pWiaProgressDialog = NULL;
  148. }
  149. }
  150. else
  151. {
  152. WIA_ERROR((TEXT("TransferItemBanded, unable to create status window")));
  153. hr = HRESULT_FROM_WIN32(GetLastError());
  154. }
  155. return hr;
  156. }
  157. STDMETHODIMP CWiaDefaultUI::TransferItemFile( IWiaItem *pWiaItem, HWND hwndParent, DWORD dwFlags, GUID guidFormat, LPCWSTR pszFilename, IWiaDataCallback *pSecondaryCallback, LONG nMediaType )
  158. {
  159. WIA_PUSH_FUNCTION((TEXT("CWiaDefaultUI::TransferItemFile( %08X )"), pWiaItem ));
  160. if (!pszFilename || !lstrlenW(pszFilename) || !pWiaItem)
  161. {
  162. return E_INVALIDARG;
  163. }
  164. //
  165. // Create status window, if requested
  166. //
  167. m_pSecondaryCallback = pSecondaryCallback;
  168. HRESULT hr;
  169. if (0 == (dwFlags&WIA_TRANSFERHELPER_NOPROGRESS))
  170. {
  171. hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaProgressDialog, (void**)&m_pWiaProgressDialog );
  172. if (SUCCEEDED(hr))
  173. {
  174. m_pWiaProgressDialog->Create( hwndParent, WIA_PROGRESSDLG_NO_ANIM );
  175. m_pWiaProgressDialog->SetTitle(CSimpleStringConvert::WideString(CSimpleString(IDS_TRANSFER_IMAGE_ACQUIRING,g_hInstance)));
  176. m_pWiaProgressDialog->SetMessage(CSimpleStringConvert::WideString(CSimpleString(IDS_TRANSFER_IMAGE_PERCENT,g_hInstance)));
  177. m_pWiaProgressDialog->Show();
  178. }
  179. }
  180. if (m_pWiaProgressDialog || (dwFlags&WIA_TRANSFERHELPER_NOPROGRESS))
  181. {
  182. CComPtr<IWiaDataCallback> pWiaDataCallback;
  183. hr = this->QueryInterface(IID_IWiaDataCallback, (void **)&pWiaDataCallback);
  184. if (SUCCEEDED(hr))
  185. {
  186. CComPtr<IWiaPropertyStorage> pWiaPropertyStorage;
  187. hr = pWiaItem->QueryInterface(IID_IWiaPropertyStorage, (void **)&pWiaPropertyStorage);
  188. if (SUCCEEDED(hr))
  189. {
  190. if (guidFormat == GUID_NULL)
  191. {
  192. CComPtr<IWiaSupportedFormats> pWiaSupportedFormats;
  193. hr = this->QueryInterface(IID_IWiaSupportedFormats, (void **)&pWiaSupportedFormats);
  194. if (SUCCEEDED(hr))
  195. {
  196. hr = pWiaSupportedFormats->Initialize( pWiaItem, nMediaType );
  197. if (SUCCEEDED(hr))
  198. {
  199. hr = GetDefaultClipboardFileFormat( &guidFormat );
  200. }
  201. }
  202. }
  203. if (guidFormat == GUID_NULL)
  204. guidFormat = WiaImgFmt_BMP;
  205. PROPSPEC PropSpec[2] = {0};
  206. PROPVARIANT PropVariant[2] = {0};
  207. PropSpec[0].ulKind = PRSPEC_PROPID;
  208. PropSpec[0].propid = WIA_IPA_FORMAT;
  209. PropSpec[1].ulKind = PRSPEC_PROPID;
  210. PropSpec[1].propid = WIA_IPA_TYMED;
  211. PropVariant[0].vt = VT_CLSID;
  212. PropVariant[0].puuid = &guidFormat;
  213. PropVariant[1].vt = VT_I4;
  214. PropVariant[1].lVal = nMediaType;
  215. WIA_PRINTGUID((guidFormat,TEXT("TYMED: %d, guidFormat"), nMediaType ));
  216. hr = pWiaPropertyStorage->WriteMultiple( ARRAYSIZE(PropVariant), PropSpec, PropVariant, WIA_IPA_FIRST );
  217. if (SUCCEEDED(hr))
  218. {
  219. CComPtr<IWiaDataTransfer> pIWiaDataTransfer;
  220. hr = pWiaItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIWiaDataTransfer);
  221. if (SUCCEEDED(hr))
  222. {
  223. STGMEDIUM stgMedium = {0};
  224. hr = pIWiaDataTransfer->idtGetData(&stgMedium, pWiaDataCallback);
  225. WIA_PRINTHRESULT((hr,TEXT("pIWiaDataTransfer->idtGetData returned")));
  226. //
  227. // If the transfer succeeded, or it failed with the possibility of having a file
  228. // left over AND we want to preserve any leftover file.
  229. //
  230. if (SUCCEEDED(hr))
  231. {
  232. //
  233. // Make sure we didn't cancel.
  234. //
  235. if (hr != S_FALSE)
  236. {
  237. //
  238. // Get the file names
  239. //
  240. CSimpleString strName = CSimpleStringConvert::NaturalString(CSimpleStringWide(stgMedium.lpszFileName));
  241. CSimpleString strTarget = CSimpleStringConvert::NaturalString(CSimpleStringWide(pszFilename));
  242. if (strName.Length() && strTarget.Length())
  243. {
  244. //
  245. // This function will first try to move, then copy+erase the src file to the tgt file
  246. //
  247. hr = WiaUiUtil::MoveOrCopyFile( strName.String(), strTarget.String() );
  248. }
  249. else
  250. {
  251. hr = E_OUTOFMEMORY;
  252. WIA_ERROR((TEXT("TransferItemFile, unable to create source filename")));
  253. }
  254. }
  255. else
  256. {
  257. WIA_ERROR((TEXT("TransferItemFile, user cancelled")));
  258. }
  259. }
  260. else if ((WIA_ERROR_PAPER_JAM == hr || WIA_ERROR_PAPER_EMPTY == hr || WIA_ERROR_PAPER_PROBLEM == hr) && (dwFlags & WIA_TRANSFERHELPER_PRESERVEFAILEDFILE))
  261. {
  262. //
  263. // Get the file names
  264. //
  265. CSimpleString strName = CSimpleStringConvert::NaturalString(CSimpleStringWide(stgMedium.lpszFileName));
  266. CSimpleString strTarget = CSimpleStringConvert::NaturalString(CSimpleStringWide(pszFilename));
  267. if (strName.Length() && strTarget.Length())
  268. {
  269. //
  270. // Don't preserve any errors we encounter here.
  271. //
  272. WiaUiUtil::MoveOrCopyFile( strName.String(), strTarget.String() );
  273. }
  274. }
  275. else
  276. {
  277. WIA_PRINTHRESULT((hr,TEXT("TransferItemFile, idtGetData failed")));
  278. }
  279. //
  280. // Call this even in the error case, in case the driver/service left a file laying around.
  281. //
  282. ReleaseStgMedium(&stgMedium);
  283. }
  284. }
  285. else
  286. {
  287. WIA_PRINTHRESULT((hr,TEXT("TransferItemFile, pIWiaPropertyStorage->WriteMultiple failed")));
  288. }
  289. }
  290. else
  291. {
  292. WIA_PRINTHRESULT((hr,TEXT("TransferItemFile, QI of IWiaPropertyStorage failed.")));
  293. }
  294. }
  295. if (m_pWiaProgressDialog)
  296. {
  297. m_pWiaProgressDialog->Destroy();
  298. m_pWiaProgressDialog = NULL;
  299. }
  300. }
  301. else
  302. {
  303. WIA_ERROR((TEXT("TransferItemFile, unable to create status window")));
  304. hr = HRESULT_FROM_WIN32(GetLastError());
  305. }
  306. return hr;
  307. }