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.

580 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. DWORD dwLen = lstrlen (pszSchema) + 1;
  101. m_pSchema = new WCHAR [dwLen];
  102. if (m_pSchema) {
  103. hr = StringCchCopy (m_pSchema, dwLen, pszSchema);
  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. DWORD dwLen = ( 1 + lstrlen (pszRespSchema)) * sizeof (TCHAR);
  237. pszSchema = (LPWSTR) CoTaskMemAlloc (dwLen);
  238. if (pszSchema) {
  239. StringCbCopy (pszSchema, dwLen, pszRespSchema);
  240. }
  241. else
  242. goto Cleanup;
  243. }
  244. else
  245. pszSchema = NULL;
  246. dwType = pRespData->GetType ();
  247. dwSize = pRespData->GetSize ();
  248. if (dwSize == 0) {
  249. hr = S_OK;
  250. }
  251. else {
  252. pData = (PBYTE) CoTaskMemAlloc (dwSize);
  253. if (pData) {
  254. CopyMemory (pData, pRespData->GetData (), dwSize);
  255. hr = S_OK;
  256. }
  257. }
  258. }
  259. else {
  260. SetLastError (ERROR_INVALID_DATA);
  261. }
  262. }
  263. Cleanup:
  264. if (FAILED (hr)) {
  265. hr = LastError2HRESULT ();
  266. if (pszSchema) {
  267. CoTaskMemFree (pszSchema);
  268. pszSchema = NULL;
  269. }
  270. if (pData) {
  271. CoTaskMemFree (pData);
  272. pData = NULL;
  273. }
  274. }
  275. else {
  276. *ppszSchema = pszSchema;
  277. *ppData = pData;
  278. *pdwType = dwType;
  279. *puSize = dwSize;
  280. }
  281. }
  282. else
  283. hr = E_POINTER;
  284. }
  285. else
  286. hr = E_HANDLE;
  287. return hr;
  288. }
  289. STDMETHODIMP
  290. TBidiRequest::GetEnumCount(
  291. OUT PDWORD pdwTotal)
  292. {
  293. HRESULT hr;
  294. DBGMSG(DBG_TRACE,("Enter GetOutputData\n"));
  295. if (m_bValid) {
  296. if (pdwTotal) {
  297. TAutoCriticalSection CritSec (m_CritSec);
  298. if (CritSec.bValid ()) {
  299. BOOL bRet;
  300. bRet = m_ResponseDataList.GetTotalNode (pdwTotal);
  301. if (bRet) {
  302. hr = S_OK;
  303. }
  304. else
  305. hr = LastError2HRESULT();
  306. }
  307. else
  308. hr = LastError2HRESULT();
  309. }
  310. else {
  311. hr = E_POINTER;
  312. }
  313. }
  314. else
  315. hr = E_HANDLE;
  316. return hr;
  317. }
  318. STDMETHODIMP
  319. TBidiRequest::GetSchema (
  320. OUT LPWSTR *ppszSchema)
  321. {
  322. HRESULT hr;
  323. LPWSTR pStr;
  324. DBGMSG(DBG_TRACE,("Enter GetSchema\n"));
  325. if (m_bValid) {
  326. if (ppszSchema) {
  327. TAutoCriticalSection CritSec (m_CritSec);
  328. if (CritSec.bValid ()) {
  329. if (m_pSchema) {
  330. DWORD dwLen = ( 1 + lstrlen (m_pSchema)) * sizeof (WCHAR);
  331. pStr = (LPWSTR) CoTaskMemAlloc (dwLen);
  332. if (pStr) {
  333. hr = StringCbCopy (pStr, dwLen, m_pSchema);
  334. if (SUCCEEDED(hr))
  335. *ppszSchema = pStr;
  336. else
  337. {
  338. *ppszSchema = NULL;
  339. CoTaskMemFree (pStr);
  340. }
  341. }
  342. else
  343. hr = E_OUTOFMEMORY;
  344. }
  345. else {
  346. *ppszSchema = NULL;
  347. hr = S_OK;
  348. }
  349. }
  350. else
  351. hr = LastError2HRESULT();
  352. }
  353. else {
  354. hr = E_POINTER;
  355. }
  356. }
  357. else
  358. hr = E_HANDLE;
  359. return hr;
  360. }
  361. STDMETHODIMP
  362. TBidiRequest::GetInputData (
  363. OUT PDWORD pdwType,
  364. OUT PBYTE *ppData,
  365. OUT PULONG puSize)
  366. {
  367. HRESULT hr;
  368. DBGMSG(DBG_TRACE,("Enter GetInputData\n"));
  369. if (m_bValid) {
  370. if (pdwType && ppData && puSize) {
  371. TAutoCriticalSection CritSec (m_CritSec);
  372. if (CritSec.bValid ()) {
  373. *pdwType = m_kDataType;
  374. if (m_pbData) {
  375. *ppData = (PBYTE) CoTaskMemAlloc (m_dwDataSize);
  376. if (*ppData) {
  377. CopyMemory (*ppData, m_pbData, m_dwDataSize);
  378. *puSize = m_dwDataSize;
  379. hr = S_OK;
  380. }
  381. else
  382. hr = E_OUTOFMEMORY;
  383. }
  384. else {
  385. *ppData = NULL;
  386. *puSize = 0;
  387. hr = S_OK;
  388. }
  389. }
  390. else
  391. hr = LastError2HRESULT();
  392. }
  393. else
  394. hr = E_POINTER;
  395. }
  396. else
  397. hr = E_HANDLE;
  398. return hr;
  399. }
  400. STDMETHODIMP
  401. TBidiRequest::SetResult (
  402. IN CONST HRESULT hrReq)
  403. {
  404. HRESULT hr;
  405. DBGMSG(DBG_TRACE,("Enter SetResult\n"));
  406. if (m_bValid) {
  407. TAutoCriticalSection CritSec (m_CritSec);
  408. if (CritSec.bValid ()) {
  409. m_hr = hrReq;
  410. hr = S_OK;
  411. }
  412. else
  413. hr = LastError2HRESULT();
  414. }
  415. else
  416. hr = E_HANDLE;
  417. return hr;
  418. }
  419. STDMETHODIMP
  420. TBidiRequest::AppendOutputData (
  421. IN CONST LPCWSTR pszSchema,
  422. IN CONST DWORD dwType,
  423. IN CONST BYTE *pData,
  424. IN CONST ULONG uSize)
  425. {
  426. HRESULT hr (E_FAIL);
  427. BOOL bRet;
  428. DBGMSG(DBG_TRACE,("Enter AppendOutputData\n"));
  429. if (m_bValid) {
  430. TResponseData *pRespData = NULL;
  431. pRespData = new TResponseData (pszSchema, dwType, pData, uSize);
  432. bRet = pRespData && pRespData->bValid ();
  433. if (bRet) {
  434. TAutoCriticalSection CritSec (m_CritSec);
  435. if (CritSec.bValid ()) {
  436. bRet = m_ResponseDataList.AppendItem (pRespData);
  437. if (bRet) {
  438. hr = S_OK;
  439. }
  440. }
  441. }
  442. if (FAILED (hr)) {
  443. hr = LastError2HRESULT();
  444. if (pRespData) {
  445. delete (pRespData);
  446. }
  447. }
  448. }
  449. else
  450. hr = E_HANDLE;
  451. return hr;
  452. }