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.

574 lines
13 KiB

  1. /*****************************************************************************\
  2. * MODULE: request.cpp
  3. *
  4. * PURPOSE: Implementation of COM interface for BidiSpooler
  5. *
  6. * Copyright (C) 2000 Microsoft Corporation
  7. *
  8. * History:
  9. *
  10. * 03/07/00 Weihai Chen (weihaic) Created
  11. *
  12. \*****************************************************************************/
  13. #include "precomp.h"
  14. #include "priv.h"
  15. //
  16. // Constructor
  17. //
  18. TBidiRequest::TBidiRequest() :
  19. m_cRef(1),
  20. m_kDataType (BIDI_NULL),
  21. m_dwDataSize (0),
  22. m_pbData (NULL),
  23. m_pSchema (NULL),
  24. m_bValid (FALSE)
  25. {
  26. InterlockedIncrement(&g_cComponents) ;
  27. m_bValid = m_CritSec.bValid () && m_ResponseDataList.bValid ();
  28. DBGMSG(DBG_TRACE,("TBidiRequest Created\n"));
  29. }
  30. //
  31. // Destructor
  32. //
  33. TBidiRequest::~TBidiRequest()
  34. {
  35. InterlockedDecrement(&g_cComponents) ;
  36. if (m_pSchema)
  37. delete [] m_pSchema;
  38. DBGMSG(DBG_TRACE,("TBidiRequest Dstroy self\n"));
  39. }
  40. //
  41. // IUnknown implementation
  42. //
  43. STDMETHODIMP
  44. TBidiRequest::QueryInterface(
  45. REFIID iid,
  46. PVOID* ppv)
  47. {
  48. HRESULT hr = S_OK;
  49. DBGMSG(DBG_TRACE,("Enter TBidiRequest QI\n"));
  50. if (iid == IID_IUnknown) {
  51. *ppv = static_cast<IBidiRequest*>(this) ;
  52. }
  53. else if (iid == IID_IBidiRequest) {
  54. *ppv = static_cast<IBidiRequest*>(this) ;
  55. }
  56. else if (iid == IID_IBidiRequestSpl) {
  57. *ppv = static_cast<IBidiRequestSpl*>(this) ;
  58. }
  59. else {
  60. *ppv = NULL ;
  61. hr = E_NOINTERFACE ;
  62. }
  63. if (*ppv) {
  64. reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  65. }
  66. DBGMSG(DBG_TRACE,("Leave TBidiRequest QI hr=%x\n", hr));
  67. return hr ;
  68. }
  69. STDMETHODIMP_ (ULONG)
  70. TBidiRequest::AddRef()
  71. {
  72. DBGMSG(DBG_TRACE,("Enter TBidiRequest::AddRef ref= %d\n", m_cRef));
  73. return InterlockedIncrement(&m_cRef) ;
  74. }
  75. STDMETHODIMP_ (ULONG)
  76. TBidiRequest::Release()
  77. {
  78. DBGMSG(DBG_TRACE,("Enter TBidiRequest::Release ref= %d\n", m_cRef));
  79. if (InterlockedDecrement(&m_cRef) == 0)
  80. {
  81. delete this ;
  82. return 0 ;
  83. }
  84. return m_cRef ;
  85. }
  86. STDMETHODIMP
  87. TBidiRequest::SetSchema(
  88. LPCWSTR pszSchema)
  89. {
  90. HRESULT hr (E_FAIL);
  91. DBGMSG(DBG_TRACE,("Enter SetSchema %ws\n", pszSchema));
  92. if (m_bValid) {
  93. TAutoCriticalSection CritSec (m_CritSec);
  94. if (CritSec.bValid ()) {
  95. if (m_pSchema) {
  96. delete[] m_pSchema;
  97. m_pSchema = NULL;
  98. }
  99. if (pszSchema) {
  100. m_pSchema = new WCHAR [lstrlen (pszSchema) + 1];
  101. if (m_pSchema) {
  102. lstrcpy (m_pSchema, pszSchema);
  103. hr = S_OK;
  104. }
  105. }
  106. else
  107. SetLastError (ERROR_INVALID_PARAMETER);
  108. }
  109. if (FAILED (hr)) {
  110. hr = LastError2HRESULT();
  111. }
  112. }
  113. else
  114. hr = E_HANDLE;
  115. return hr;
  116. }
  117. STDMETHODIMP
  118. TBidiRequest::SetInputData(
  119. IN CONST DWORD dwType,
  120. IN CONST BYTE *pData,
  121. IN CONST UINT uSize)
  122. {
  123. HRESULT hr (S_OK);
  124. DBGMSG(DBG_TRACE,("Enter SetInputData dwType=%d\n", dwType));
  125. if (m_bValid) {
  126. // Verify data type and its size
  127. switch (dwType) {
  128. case BIDI_NULL:
  129. if (uSize)
  130. hr = E_INVALIDARG;
  131. break;
  132. case BIDI_INT:
  133. if (uSize != sizeof (ULONG)) {
  134. hr = E_INVALIDARG;
  135. }
  136. break;
  137. case BIDI_FLOAT:
  138. if (uSize != sizeof (FLOAT)) {
  139. hr = E_INVALIDARG;
  140. }
  141. break;
  142. case BIDI_BOOL:
  143. if (uSize != sizeof (BOOL)) {
  144. hr = E_INVALIDARG;
  145. }
  146. break;
  147. case BIDI_ENUM:
  148. case BIDI_STRING:
  149. case BIDI_TEXT:
  150. if (uSize != sizeof (WCHAR) * (lstrlen (reinterpret_cast<LPCWSTR> (pData)) + 1)) {
  151. hr = E_INVALIDARG;
  152. }
  153. break;
  154. case BIDI_BLOB:
  155. hr = S_OK;
  156. break;
  157. default:
  158. hr = E_INVALIDARG;
  159. }
  160. if (hr == S_OK) {
  161. TAutoCriticalSection CritSec (m_CritSec);
  162. if (CritSec.bValid ()) {
  163. if (m_pbData) {
  164. delete [] m_pbData;
  165. m_pbData = NULL;
  166. }
  167. m_kDataType = (BIDI_TYPE) dwType;
  168. m_dwDataSize = uSize;
  169. if (uSize > 0) {
  170. m_pbData = new BYTE [uSize];
  171. if (m_pbData) {
  172. CopyMemory (m_pbData, pData, uSize);
  173. hr = S_OK;
  174. }
  175. else
  176. hr = E_OUTOFMEMORY;
  177. }
  178. else
  179. hr = S_OK;
  180. }
  181. else {
  182. hr = LastError2HRESULT();
  183. }
  184. }
  185. }
  186. else
  187. hr = E_HANDLE;
  188. return hr;
  189. }
  190. STDMETHODIMP
  191. TBidiRequest::GetResult(
  192. HRESULT *phr)
  193. {
  194. HRESULT hr;
  195. DBGMSG(DBG_TRACE,("Enter GetResult\n"));
  196. if (m_bValid) {
  197. if (phr) {
  198. TAutoCriticalSection CritSec (m_CritSec);
  199. if (CritSec.bValid ()) {
  200. *phr = m_hr;
  201. hr = S_OK;
  202. }
  203. else
  204. hr = LastError2HRESULT();
  205. }
  206. else {
  207. hr = E_POINTER;
  208. }
  209. }
  210. else
  211. hr = E_HANDLE;
  212. return hr;
  213. }
  214. STDMETHODIMP
  215. TBidiRequest::GetOutputData(
  216. DWORD dwIndex,
  217. LPWSTR *ppszSchema,
  218. PDWORD pdwType,
  219. PBYTE *ppData,
  220. PULONG puSize)
  221. {
  222. HRESULT hr (E_FAIL);
  223. DBGMSG(DBG_TRACE,("Enter GetOutputData\n"));
  224. if (m_bValid) {
  225. if (ppszSchema && ppData && pdwType && puSize) {
  226. TAutoCriticalSection CritSec (m_CritSec);
  227. PBYTE pData = NULL;
  228. LPWSTR pszSchema = NULL;
  229. DWORD dwType = 0;
  230. DWORD dwSize = 0;
  231. if (CritSec.bValid ()) {
  232. TResponseData * pRespData = m_ResponseDataList.GetItemFromIndex (dwIndex);
  233. if (pRespData) {
  234. LPCTSTR pszRespSchema = pRespData->GetSchema ();
  235. if (pszRespSchema) {
  236. pszSchema = (LPWSTR) CoTaskMemAlloc (( 1 + lstrlen (pszRespSchema)) * sizeof (TCHAR));
  237. if (pszSchema) {
  238. lstrcpy (pszSchema, pszRespSchema);
  239. }
  240. else
  241. goto Cleanup;
  242. }
  243. else
  244. pszSchema = NULL;
  245. dwType = pRespData->GetType ();
  246. dwSize = pRespData->GetSize ();
  247. if (dwSize == 0) {
  248. hr = S_OK;
  249. }
  250. else {
  251. pData = (PBYTE) CoTaskMemAlloc (dwSize);
  252. if (pData) {
  253. CopyMemory (pData, pRespData->GetData (), dwSize);
  254. hr = S_OK;
  255. }
  256. }
  257. }
  258. else {
  259. SetLastError (ERROR_INVALID_DATA);
  260. }
  261. }
  262. Cleanup:
  263. if (FAILED (hr)) {
  264. hr = LastError2HRESULT ();
  265. if (pszSchema) {
  266. CoTaskMemFree (pszSchema);
  267. pszSchema = NULL;
  268. }
  269. if (pData) {
  270. CoTaskMemFree (pData);
  271. pData = NULL;
  272. }
  273. }
  274. else {
  275. *ppszSchema = pszSchema;
  276. *ppData = pData;
  277. *pdwType = dwType;
  278. *puSize = dwSize;
  279. }
  280. }
  281. else
  282. hr = E_POINTER;
  283. }
  284. else
  285. hr = E_HANDLE;
  286. return hr;
  287. }
  288. STDMETHODIMP
  289. TBidiRequest::GetEnumCount(
  290. OUT PDWORD pdwTotal)
  291. {
  292. HRESULT hr;
  293. DBGMSG(DBG_TRACE,("Enter GetOutputData\n"));
  294. if (m_bValid) {
  295. if (pdwTotal) {
  296. TAutoCriticalSection CritSec (m_CritSec);
  297. if (CritSec.bValid ()) {
  298. BOOL bRet;
  299. bRet = m_ResponseDataList.GetTotalNode (pdwTotal);
  300. if (bRet) {
  301. hr = S_OK;
  302. }
  303. else
  304. hr = LastError2HRESULT();
  305. }
  306. else
  307. hr = LastError2HRESULT();
  308. }
  309. else {
  310. hr = E_POINTER;
  311. }
  312. }
  313. else
  314. hr = E_HANDLE;
  315. return hr;
  316. }
  317. STDMETHODIMP
  318. TBidiRequest::GetSchema (
  319. OUT LPWSTR *ppszSchema)
  320. {
  321. HRESULT hr;
  322. LPWSTR pStr;
  323. DBGMSG(DBG_TRACE,("Enter GetSchema\n"));
  324. if (m_bValid) {
  325. if (ppszSchema) {
  326. TAutoCriticalSection CritSec (m_CritSec);
  327. if (CritSec.bValid ()) {
  328. if (m_pSchema) {
  329. pStr = (LPWSTR) CoTaskMemAlloc (( 1 + lstrlen (m_pSchema)) * sizeof (WCHAR));
  330. if (pStr) {
  331. lstrcpy (pStr, m_pSchema);
  332. *ppszSchema = pStr;
  333. hr = S_OK;
  334. }
  335. else
  336. hr = E_OUTOFMEMORY;
  337. }
  338. else {
  339. *ppszSchema = NULL;
  340. hr = S_OK;
  341. }
  342. }
  343. else
  344. hr = LastError2HRESULT();
  345. }
  346. else {
  347. hr = E_POINTER;
  348. }
  349. }
  350. else
  351. hr = E_HANDLE;
  352. return hr;
  353. }
  354. STDMETHODIMP
  355. TBidiRequest::GetInputData (
  356. OUT PDWORD pdwType,
  357. OUT PBYTE *ppData,
  358. OUT PULONG puSize)
  359. {
  360. HRESULT hr;
  361. DBGMSG(DBG_TRACE,("Enter GetInputData\n"));
  362. if (m_bValid) {
  363. if (pdwType && ppData && puSize) {
  364. TAutoCriticalSection CritSec (m_CritSec);
  365. if (CritSec.bValid ()) {
  366. *pdwType = m_kDataType;
  367. if (m_pbData) {
  368. *ppData = (PBYTE) CoTaskMemAlloc (m_dwDataSize);
  369. if (*ppData) {
  370. CopyMemory (*ppData, m_pbData, m_dwDataSize);
  371. *puSize = m_dwDataSize;
  372. hr = S_OK;
  373. }
  374. else
  375. hr = E_OUTOFMEMORY;
  376. }
  377. else {
  378. *ppData = NULL;
  379. *puSize = 0;
  380. hr = S_OK;
  381. }
  382. }
  383. else
  384. hr = LastError2HRESULT();
  385. }
  386. else
  387. hr = E_POINTER;
  388. }
  389. else
  390. hr = E_HANDLE;
  391. return hr;
  392. }
  393. STDMETHODIMP
  394. TBidiRequest::SetResult (
  395. IN CONST HRESULT hrReq)
  396. {
  397. HRESULT hr;
  398. DBGMSG(DBG_TRACE,("Enter SetResult\n"));
  399. if (m_bValid) {
  400. TAutoCriticalSection CritSec (m_CritSec);
  401. if (CritSec.bValid ()) {
  402. m_hr = hrReq;
  403. hr = S_OK;
  404. }
  405. else
  406. hr = LastError2HRESULT();
  407. }
  408. else
  409. hr = E_HANDLE;
  410. return hr;
  411. }
  412. STDMETHODIMP
  413. TBidiRequest::AppendOutputData (
  414. IN CONST LPCWSTR pszSchema,
  415. IN CONST DWORD dwType,
  416. IN CONST BYTE *pData,
  417. IN CONST ULONG uSize)
  418. {
  419. HRESULT hr (E_FAIL);
  420. BOOL bRet;
  421. DBGMSG(DBG_TRACE,("Enter AppendOutputData\n"));
  422. if (m_bValid) {
  423. TResponseData *pRespData = NULL;
  424. pRespData = new TResponseData (pszSchema, dwType, pData, uSize);
  425. bRet = pRespData && pRespData->bValid ();
  426. if (bRet) {
  427. TAutoCriticalSection CritSec (m_CritSec);
  428. if (CritSec.bValid ()) {
  429. bRet = m_ResponseDataList.AppendItem (pRespData);
  430. if (bRet) {
  431. hr = S_OK;
  432. }
  433. }
  434. }
  435. if (FAILED (hr)) {
  436. hr = LastError2HRESULT();
  437. if (pRespData) {
  438. delete (pRespData);
  439. }
  440. }
  441. }
  442. else
  443. hr = E_HANDLE;
  444. return hr;
  445. }