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.

197 lines
4.7 KiB

  1. #include <stdio.h>
  2. #include <atlbase.h>
  3. #include <msxml2.h>
  4. template <class Base>
  5. class __declspec(novtable) StackUnknown : public Base
  6. {
  7. public:
  8. virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppv);
  9. virtual ULONG STDMETHODCALLTYPE AddRef() {return 1;}
  10. virtual ULONG STDMETHODCALLTYPE Release() {return 1;}
  11. };
  12. template <class Base>
  13. HRESULT STDMETHODCALLTYPE
  14. StackUnknown<Base>::QueryInterface(REFIID riid, void ** ppv)
  15. {
  16. if (riid == __uuidof(Base) || riid == __uuidof(IUnknown))
  17. {
  18. //
  19. // No need to AddRef since this class
  20. // will only be created on the stack
  21. //
  22. *ppv = this;
  23. return S_OK;
  24. }
  25. *ppv = NULL;
  26. return E_NOINTERFACE;
  27. }
  28. class FileOutputStream : public StackUnknown<ISequentialStream>
  29. {
  30. public:
  31. FileOutputStream() {_fClose = false;}
  32. ~FileOutputStream() {Close();}
  33. HRESULT Init(HANDLE h) { _h = h; _fClose = false; return S_OK;}
  34. HRESULT Init(const WCHAR * pwszFileName);
  35. void Close() {if (_fClose) {::CloseHandle(_h); _fClose = false;} }
  36. virtual HRESULT STDMETHODCALLTYPE
  37. Read(void * pv, ULONG cb, ULONG * pcbRead) {return E_NOTIMPL;}
  38. virtual HRESULT STDMETHODCALLTYPE
  39. Write(void const * pv, ULONG cb, ULONG * pcbWritten);
  40. private:
  41. HANDLE _h;
  42. bool _fClose;
  43. };
  44. HRESULT
  45. FileOutputStream::Init(const WCHAR * pwszFileName)
  46. {
  47. HRESULT hr = S_OK;
  48. _h =::CreateFileW(
  49. pwszFileName,
  50. GENERIC_WRITE,
  51. 0,
  52. NULL,
  53. CREATE_ALWAYS,
  54. FILE_ATTRIBUTE_NORMAL,
  55. NULL);
  56. if( INVALID_HANDLE_VALUE != _h ){
  57. hr = HRESULT_FROM_WIN32( GetLastError() );
  58. }
  59. _fClose = true;
  60. return hr;
  61. }
  62. HRESULT STDMETHODCALLTYPE
  63. FileOutputStream::Write(void const * pv, ULONG cb, ULONG * pcbWritten)
  64. {
  65. HRESULT hr = S_OK;
  66. BOOL bResult;
  67. bResult = ::WriteFile(
  68. _h,
  69. pv,
  70. cb,
  71. pcbWritten,
  72. NULL);
  73. if( !bResult ){
  74. hr = HRESULT_FROM_WIN32( GetLastError() );
  75. }
  76. return hr;
  77. }
  78. extern "C" {
  79. HRESULT TransformXML( LPWSTR szXML, LPWSTR szXSL, LPWSTR szResult )
  80. {
  81. HRESULT hr;
  82. IXMLDOMDocument* pXMLDoc = NULL;
  83. IXMLDOMDocument* pXSLDoc = NULL;
  84. IXSLTemplate* pTemplate = NULL;
  85. IXSLProcessor * pProcessor = NULL;
  86. FileOutputStream OutputStream;
  87. BSTR bszResult = NULL;
  88. VARIANT_BOOL vStatus;
  89. VARIANT vXML;
  90. VARIANT vXSL;
  91. VARIANT vDoc;
  92. VariantInit( &vXML );
  93. VariantInit( &vXSL );
  94. hr = OutputStream.Init(szResult);
  95. if(FAILED(hr)){ goto cleanup; }
  96. vXML.vt = VT_BSTR;
  97. vXML.bstrVal = SysAllocString( szXML );
  98. vXSL.vt = VT_BSTR;
  99. vXSL.bstrVal = SysAllocString( szXSL );
  100. hr = CoInitialize(0);
  101. hr = CoCreateInstance(
  102. CLSID_FreeThreadedDOMDocument,
  103. NULL,
  104. CLSCTX_SERVER,
  105. IID_IXMLDOMDocument,
  106. (void**)&pXMLDoc );
  107. if(FAILED(hr)){ goto cleanup; }
  108. hr = CoCreateInstance(
  109. CLSID_FreeThreadedDOMDocument,
  110. NULL,
  111. CLSCTX_SERVER,
  112. IID_IXMLDOMDocument,
  113. (void**)&pXSLDoc );
  114. if(FAILED(hr)){ goto cleanup; }
  115. hr = CoCreateInstance(
  116. CLSID_XSLTemplate,
  117. NULL,
  118. CLSCTX_SERVER,
  119. IID_IXSLTemplate,
  120. (void**)&pTemplate );
  121. if(FAILED(hr)){ goto cleanup; }
  122. hr = pXMLDoc->put_preserveWhiteSpace(VARIANT_TRUE);
  123. hr = pXMLDoc->put_async(VARIANT_FALSE);
  124. hr = pXMLDoc->load( vXML, &vStatus );
  125. if(FAILED(hr) || vStatus == false ){ goto cleanup; }
  126. hr = pXSLDoc->put_preserveWhiteSpace(VARIANT_TRUE);
  127. hr = pXSLDoc->put_async(VARIANT_FALSE);
  128. hr = pXSLDoc->load( vXSL, &vStatus );
  129. if(FAILED(hr) || vStatus == false ){ goto cleanup; }
  130. hr = pTemplate->putref_stylesheet(pXSLDoc);
  131. vDoc.vt = VT_UNKNOWN;
  132. vDoc.punkVal = (IUnknown*)pXMLDoc;
  133. pTemplate->createProcessor(&pProcessor);
  134. hr = pProcessor->put_input( vDoc );
  135. vDoc.punkVal = &OutputStream;
  136. hr = pProcessor->put_output( vDoc );
  137. hr = pProcessor->transform( &vStatus );
  138. cleanup:
  139. if( NULL != pTemplate ){
  140. pTemplate->Release();
  141. }
  142. if( NULL != pProcessor ){
  143. pProcessor->Release();
  144. }
  145. if( NULL != pXMLDoc ){
  146. pXMLDoc->Release();
  147. }
  148. if( NULL != pXSLDoc ){
  149. pXSLDoc->Release();
  150. }
  151. VariantClear( &vXML );
  152. VariantClear( &vXSL );
  153. return hr;
  154. }
  155. } //extern C