kamagra how much to take

PDF IRM Protector For SharePoint – 2007 / 2010

Just want the code? : http://pdfirmprotector.codeplex.com

**Tested In SharePoint 2007 & SharePoint 2010**

Creating custom rights-management protectors for converting custom file types to arbitrary rights-management format(s) targeting a particular business need can be a necessary requirement depending on the company and industry. As part of this it might be necessary to break open a freshy VC++ project and start doing some code outside of the more commonly accepted business software development languages.

While I was researching this, these are…and this is literally based strictly on my experience and there might be other material freely available, is the following articles that are distributed ala MSDN:

http://msdn.microsoft.com/en-us/library/ms439253.aspx

http://msdn.microsoft.com/en-us/library/ms436515.aspx

http://msdn.microsoft.com/en-us/library/bb802693.aspx

(there are others directly on the left-hand navigation tree)

that *are* helpful as a brief introduction to the holistic architecture, and the project would be a month long deal if the VC++ reference project wasn’t available out of the ECM kit from the SDK. The header files available in the sample are literally invaluable; however the project in itself is incomplete.The aforementioned articles provide enough information that it really isn’t relevant to repeat it since it will add very little to no value for this article. Personally, it’s a little easier to start cooking up code, and when it is relevant make the appropriate back references. As an example, since it is probably the most demanded IRM protector on the market, I am going to target PDF file types.

Because of my choice of file type, things are going to get slightly complicated since Adobe made doing a client manipulation of Reader very, very difficult. IMHO, it’s hard to justify the time investment unless you are developing a COTS product, which I am not. Maybe sometime in the future, but now ain’t the time. That being said, a more practical approach since Reader has comparable control mechanisms to those that are toggled with IRM is to implement some sort of intermediate, linear transformation. In other words, based on certain IRM actions, execute certain structural, content-preserving transformations. By controlling the transformation of the PDF stream data, the amount of behavior that can be implemented is very, very robust. So, we simply introduce a tertiary step between initial content processing and the final, prepared document. Due to these requirements, I am going to use my favorite library, QPDF since it has native VC++ form and an abundance of other wrappers. Not saying it’s the be all for this requirement, but it is the only one that I have ever used.

I will post the important parts, but the code for the project is available here on CodePlex (it’s in VS2005 format [which I know is strange…it was on my 2007 VM since I usually run one version down from my version of SharePoint] but should port fine assuming the linking is taken care of if you want to use other project types).

For those folks who CodePlex’s code browser (and apparent lack of availability) does not blow their hair back, here is a brief summary of the project structure:

Since a bunch of this code is borrowed from the ECM kit, I am not going to discuss that end since it’s already canned (more commenting would of been a little kinder on the MSFT end, but it’s enough to guess at local variable intention), the more interesting stuff for this particular project  is in the PdfProtector header, the PdfIrmProtector and PdfProtector source files, and PdfIrmProtector MDIL file.

Firstly, the PdfProtector header file:

  1. #pragma once
  2. #include "PdfIrmProtector.h"
  3. #include "resource.h"      
  4. #include <comsvcs.h>
  5. #include "Globals.h"
  6. #include "strsafe.h"
  7.  
  8. class ATL_NO_VTABLE CPdfProtector :public I_IrmProtector,
  9.     public CComObjectRootEx<CComSingleThreadModel>,
  10.     public CComCoClass<CPdfProtector, &CLSID_PdfProtector>
  11.    
  12. {
  13. public:
  14.     CPdfProtector();
  15.  
  16.     DECLARE_PROTECT_FINAL_CONSTRUCT()
  17.  
  18.     HRESULT FinalConstruct()
  19.     {
  20.         return S_OK;
  21.     }
  22.  
  23.     void FinalRelease()
  24.     {
  25.     }
  26.  
  27. DECLARE_REGISTRY_RESOURCEID(IDR_PDFPROTECTOR)
  28.  
  29. DECLARE_NOT_AGGREGATABLE(CPdfProtector)
  30.  
  31. BEGIN_COM_MAP(CPdfProtector)
  32.     COM_INTERFACE_ENTRY(I_IrmProtector)
  33.  
  34. END_COM_MAP()
  35.  
  36. public:    
  37.     ~CPdfProtector();
  38.  
  39. public:
  40.     __override STDMETHOD(HrInit)           (BSTR *pbstrProduct, DWORD *pdwVersion, BSTR *pbstrExtensions, BOOL *pfUseRMS);
  41.     __override STDMETHOD(HrIsProtected)    (ILockBytes *pilbInput, DWORD *pdwResult);
  42.     __override STDMETHOD(HrSetLangId)      (LANGID langid);
  43.     __override STDMETHOD(HrProtectRMS)     (ILockBytes *pilbInput, ILockBytes *pilbOutput, I_IrmPolicyInfoRMS *piid, DWORD *pdwStatus);
  44.     __override STDMETHOD(HrUnprotectRMS)   (ILockBytes *pilbInput, ILockBytes *pilbOutput, I_IrmPolicyInfoRMS *piid, DWORD *pdwStatus);
  45.     __override STDMETHOD(HrProtect)        (ILockBytes *pilbInput, ILockBytes *pilbOutput, I_IrmPolicyInfo *piid, DWORD *pdwStatus);
  46.     __override STDMETHOD(HrUnprotect)      (ILockBytes *pilbInput, ILockBytes *pilbOutput, I_IrmPolicyInfo *piid, DWORD *pdwStatus);
  47.  
  48. protected:
  49.     __override WCHAR *WzRegKey();
  50.  
  51. protected:
  52.     unsigned int m_uRefCount;
  53.  
  54.     LANGID       m_langid;
  55. };
  56.  
  57. OBJECT_ENTRY_AUTO(__uuidof(PdfProtector), CPdfProtector)

Secondly, the PdfIrmProtector file:

  1. #include "stdafx.h"
  2. #include "resource.h"
  3. #include "PdfIrmProtector.h"
  4.  
  5.  
  6. class CPdfIrmProtectorModule : public CAtlDllModuleT< CPdfIrmProtectorModule >
  7. {
  8. public :
  9.   DECLARE_LIBID(LIBID_PdfProtectorLib)
  10.   DECLARE_REGISTRY_APPID_RESOURCEID(IDR_PDFIRMPROTECTOR, "{2C16543F-AF1B-4247-B55E-C59F3F4B79D0}")
  11. };
  12.  
  13. CPdfIrmProtectorModule _AtlModule;
  14.  
  15.  
  16. #ifdef _MANAGED
  17. #pragma managed(push, off)
  18. #endif
  19.  
  20. // DLL Entry Point
  21. extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  22. {
  23.   hInstance;
  24.   return _AtlModule.DllMain(dwReason, lpReserved);
  25. }
  26.  
  27. #ifdef _MANAGED
  28. #pragma managed(pop)
  29. #endif
  30.  
  31. // Used to determine whether the DLL can be unloaded by OLE
  32. STDAPI DllCanUnloadNow(void)
  33. {
  34.   return _AtlModule.DllCanUnloadNow();
  35. }
  36.  
  37.  
  38. // Returns a class factory to create an object of the requested type
  39. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  40. {
  41.   return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
  42. }
  43.  
  44.  
  45. // DllRegisterServer - Adds entries to the system registry
  46. STDAPI DllRegisterServer(void)
  47. {
  48.   // registers object, typelib and all interfaces in typelib
  49.   HRESULT hr = _AtlModule.DllRegisterServer();
  50.   return hr;
  51. }
  52.  
  53.  
  54. // DllUnregisterServer - Removes entries from the system registry
  55. STDAPI DllUnregisterServer(void)
  56. {
  57.   HRESULT hr = _AtlModule.DllUnregisterServer();
  58.   return hr;
  59. }

Thirdly, the PdfProtector source:

  1. #include "stdafx.h"
  2.  
  3. #include <qpdf/QPDF.hh>
  4. #include <qpdf/QUtil.hh>
  5. #include <qpdf/QTC.hh>
  6. #include <qpdf/Pl_StdioFile.hh>
  7. #include <qpdf/QPDFExc.hh>
  8. #include <qpdf/QPDFWriter.hh>
  9.  
  10. #include "PdfProtector.h"
  11.  
  12. HINSTANCE g_hInstance = 0;
  13. long      g_cLocks    = 0;
  14. const WCHAR wzKey[] = L"I am protected";
  15. const WCHAR wzSignedIL[] = L"SignedIL";
  16. const WCHAR wzServerID[] = L"ServerID";
  17. const WCHAR wzLicenses[] = L"Licenses";
  18. const WCHAR wzRightsTemplate[] = L"RightsTemplate";
  19. const WCHAR wzListGuid[] = L"ListGuid";
  20. const WCHAR wzContent[] = L"Content";
  21. const WCHAR wzRightsMask[] = L"RightsMask";
  22. const WCHAR wzRequestingUser[] = L"RequestingUser";
  23. const WCHAR wzURL[] = L"URL";
  24. const WCHAR wzPolicyTitle[] = L"PolicyTitle";
  25. const WCHAR wzPolicyDescription[] = L"PolicyDescription";
  26. const WCHAR wzOfflineDays[] = L"OfflineDays";
  27. const int STREAM_MAX = 32;
  28. const WCHAR wzEULPrefix[] = L"EUL-";
  29. #define STACK_RW_BUF_SIZE (8192)
  30.  
  31. #ifndef Unreferenced
  32. #define Unreferenced(x)    ((void)x)
  33. #endif
  34.  
  35. #ifndef cElements
  36. #define cElements(ary) (sizeof(ary) / sizeof(ary[0]))
  37. #endif
  38.  
  39. #define GUIDLEN 38
  40.  
  41. HRESULT HrEnsureStg(IStorage *pistg, const WCHAR *wzStg, bool fReadWrite, IStorage **ppistg)
  42. {
  43.   HRESULT hr = S_OK;
  44.  
  45.   if (pistg == NULL || wzStg == NULL || ppistg == NULL)
  46.     return E_INVALIDARG;
  47.  
  48.   *ppistg = NULL;
  49.   hr = pistg->OpenStorage(wzStg, NULL, (fReadWrite ? STGM_READWRITE : 0) | STGM_SHARE_EXCLUSIVE, NULL, 0, ppistg);
  50.   if (hr == STG_E_FILENOTFOUND && fReadWrite)
  51.     hr = pistg->CreateStorage(wzStg, STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, 0, ppistg);
  52.  
  53.   if (FAILED(hr))
  54.   {
  55.     if (*ppistg != NULL)
  56.     {
  57.       (*ppistg)->Release();
  58.       *ppistg = NULL;
  59.     }
  60.   }
  61.   return hr;
  62. }
  63.  
  64. HRESULT HrEnsureStm(IStorage *pistg, const WCHAR *wzStm, bool fReadWrite, IStream **ppistm)
  65. {
  66.   HRESULT hr = S_OK;
  67.  
  68.   if (pistg == NULL || wzStm == NULL || ppistm == NULL)
  69.     return E_INVALIDARG;
  70.  
  71.   *ppistm = NULL;
  72.   hr = pistg->OpenStream(wzStm, NULL, (fReadWrite ? STGM_READWRITE : 0) | STGM_SHARE_EXCLUSIVE, 0, ppistm);
  73.   if (hr == STG_E_FILENOTFOUND && fReadWrite)
  74.     hr = pistg->CreateStream(wzStm, STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, 0, ppistm);
  75.  
  76.   if (FAILED(hr))
  77.   {
  78.     if (*ppistm != NULL)
  79.     {
  80.       (*ppistm)->Release();
  81.       *ppistm = NULL;
  82.     }
  83.   }
  84.   return hr;
  85. }
  86.  
  87. HRESULT HrWriteRaw(IStream *pistm, const WCHAR *wzData)
  88. {
  89.   HRESULT hr = S_OK;
  90.   DWORD cbSrc = 0;
  91.   DWORD cbWritten = 0;
  92.  
  93.   if (pistm == NULL || wzData == NULL)
  94.     return E_INVALIDARG;
  95.  
  96.   cbSrc = ((DWORD)wcslen(wzData) + 1) * sizeof(WCHAR);
  97.   hr = pistm->Write((void*)&cbSrc, sizeof(DWORD), &cbWritten);
  98.   if (SUCCEEDED(hr) && sizeof(DWORD) != cbWritten)
  99.     hr = STG_E_WRITEFAULT;
  100.   if (FAILED(hr))
  101.     goto LExit;
  102.   if (cbSrc > 0)
  103.   {
  104.     hr = pistm->Write((void*)wzData, cbSrc, &cbWritten);
  105.     if (SUCCEEDED(hr) && cbSrc != cbWritten)
  106.       hr = STG_E_WRITEFAULT;
  107.     if (FAILED(hr))
  108.       goto LExit;
  109.   }
  110.  
  111. LExit:
  112.   return hr;
  113. }
  114.  
  115. HRESULT HrWriteRaw(IStream *pistm, const DWORD dwData)
  116. {
  117.   HRESULT hr = S_OK;
  118.   DWORD cbSrc = 0;
  119.   DWORD cbWritten = 0;
  120.  
  121.   if (pistm == NULL || dwData == NULL)
  122.     return E_INVALIDARG;
  123.  
  124.   cbSrc = sizeof(DWORD);
  125.   hr = pistm->Write((void*)&cbSrc, sizeof(DWORD), &cbWritten);
  126.   if (SUCCEEDED(hr) && sizeof(DWORD) != cbWritten)
  127.     hr = STG_E_WRITEFAULT;
  128.   if (FAILED(hr))
  129.     goto LExit;
  130.   if (cbSrc > 0)
  131.   {
  132.     hr = pistm->Write((void*)&dwData, cbSrc, &cbWritten);
  133.     if (SUCCEEDED(hr) && cbSrc != cbWritten)
  134.       hr = STG_E_WRITEFAULT;
  135.     if (FAILED(hr))
  136.       goto LExit;
  137.   }
  138.  
  139. LExit:
  140.   return hr;
  141. }
  142.  
  143. HRESULT HrReadRaw(IStream *pistm, WCHAR **pwz)
  144. {
  145.   HRESULT hr = S_OK;
  146.   DWORD cbSrc = 0;
  147.   DWORD cbRead = 0;
  148.  
  149.   if (pistm == NULL || pwz == NULL)
  150.   {    
  151.     return E_INVALIDARG;
  152.   }
  153.  
  154.   *pwz = NULL;
  155.  
  156.   hr = pistm->Read((void*)&cbSrc, sizeof(DWORD), &cbRead);
  157.   if (SUCCEEDED(hr) && sizeof(DWORD) != cbRead)
  158.     hr = STG_E_READFAULT;
  159.   if (FAILED(hr))
  160.     goto LExit;
  161.  
  162.   *pwz = (WCHAR *)new BYTE [cbSrc];
  163.   if (*pwz == NULL)
  164.   {
  165.     hr = E_OUTOFMEMORY;
  166.     goto LExit;
  167.   }
  168.  
  169.   hr = pistm->Read(*pwz, cbSrc, NULL);
  170.   if (FAILED(hr))
  171.     goto LExit;
  172.  
  173. LExit:
  174.   if (FAILED(hr) && *pwz != NULL)
  175.   {
  176.     delete [] *pwz;
  177.     *pwz = NULL;
  178.   }
  179.   return hr;
  180. }
  181.  
  182. HRESULT HrReadRaw(IStream *pistm, DWORD *pdw)
  183. {
  184.   HRESULT hr = S_OK;
  185.   DWORD cbSrc = 0;
  186.   DWORD cbRead = 0;
  187.  
  188.   if (pistm == NULL || pdw == NULL)
  189.     return E_INVALIDARG;
  190.  
  191.   *pdw = 0;
  192.  
  193.   hr = pistm->Read((void*)&cbSrc, sizeof(DWORD), &cbRead);
  194.   if (SUCCEEDED(hr) && sizeof(DWORD) != cbRead)
  195.     hr = STG_E_READFAULT;
  196.   if (cbSrc != sizeof(DWORD))
  197.     hr = STG_E_READFAULT;
  198.   if (FAILED(hr))
  199.     goto LExit;
  200.  
  201.   hr = pistm->Read((void*)pdw, cbSrc, NULL);
  202.   if (FAILED(hr))
  203.     goto LExit;
  204.  
  205. LExit:
  206.   return hr;
  207. }
  208.  
  209. HRESULT HrWriteSubStream(IStorage *pistg, const WCHAR *wzStream, BSTR *pbstr)
  210. {
  211.   HRESULT hr = S_OK;
  212.   IStream *pistmT = NULL;
  213.  
  214.   if (pbstr == NULL)
  215.   {
  216.     hr = E_INVALIDARG;
  217.     goto LExit;
  218.   }
  219.  
  220.   hr = HrEnsureStm(pistg, wzStream, true, &pistmT);
  221.   if (FAILED(hr))
  222.     goto LExit;
  223.   if (*pbstr == NULL)
  224.     goto LExit;
  225.   hr = HrWriteRaw(pistmT, *pbstr);
  226.   if (FAILED(hr))
  227.     goto LExit;
  228.  
  229. LExit:
  230.   if (pistmT != NULL)
  231.     pistmT->Release();
  232.   if (*pbstr != NULL)
  233.   {
  234.     SysFreeString(*pbstr);
  235.     *pbstr = NULL;
  236.   }
  237.   return hr;
  238. }
  239.  
  240. HRESULT HrReadSubStream(IStorage *pistg, const WCHAR *wzStream, BSTR *pbstr)
  241. {
  242.   HRESULT hr = S_OK;
  243.   IStream *pistmT = NULL;
  244.   WCHAR *wzT = NULL;
  245.  
  246.   if (pbstr == NULL)
  247.   {
  248.     hr = E_INVALIDARG;
  249.     goto LExit;
  250.   }
  251.  
  252.   hr = HrEnsureStm(pistg, wzStream, false, &pistmT);
  253.  
  254.   if (FAILED(hr))
  255.     goto LExit;
  256.   hr = HrReadRaw(pistmT, &wzT);
  257.   if (FAILED(hr))
  258.     goto LExit;
  259.   *pbstr = SysAllocString(wzT);
  260.   if (*pbstr == NULL)
  261.   {
  262.     hr = E_OUTOFMEMORY;
  263.     goto LExit;
  264.   }
  265.  
  266. LExit:
  267.   if (wzT != NULL)
  268.     delete wzT;
  269.   if (pistmT != NULL)
  270.     pistmT->Release();
  271.   return hr;
  272. }
  273.  
  274. CPdfProtector::CPdfProtector()
  275. : m_uRefCount(1),
  276. m_langid(1033)
  277. {
  278.   ::InterlockedIncrement(&g_cLocks);
  279. }
  280.  
  281. CPdfProtector::~CPdfProtector()
  282. {
  283.   ::InterlockedDecrement(&g_cLocks);
  284. }
  285.  
  286. HRESULT CPdfProtector::QueryInterface(const IID& riid, void** ppvObj)
  287. {
  288.   if (riid == IID_IUnknown || riid == IID_I_IrmProtector)
  289.   {
  290.     *ppvObj = (I_IrmProtector*)this;
  291.     AddRef();
  292.     return S_OK;
  293.   }
  294.   *ppvObj = 0;
  295.   return E_NOINTERFACE;
  296. }
  297.  
  298. unsigned long CPdfProtector::AddRef()
  299. {
  300.   return ++m_uRefCount;
  301. }
  302.  
  303. unsigned long CPdfProtector::Release()
  304. {
  305.   if (--m_uRefCount != 0)
  306.     return m_uRefCount;
  307.   delete this;
  308.   return 0;
  309. }
  310.  
  311. STDMETHODIMP CPdfProtector::HrInit(BSTR *pbstrProduct, DWORD *pdwVersion, BSTR *pbstrExtensions, BOOL *pfUseRMS)
  312. {
  313.   if ( pbstrExtensions == NULL || pfUseRMS == NULL)
  314.     return E_INVALIDARG;
  315.  
  316.   *pfUseRMS        = true;
  317.   *pbstrProduct    = SysAllocString(L"PdfIrmProtector");
  318.   *pdwVersion      = 1;
  319.   *pbstrExtensions = SysAllocString(L"pdf");
  320.  
  321.   return S_OK;
  322. }
  323.  
  324. HRESULT CPdfProtector::HrIsProtected(ILockBytes *pilbInput, DWORD *pdwResult)
  325. {
  326.   HRESULT hr = S_OK;
  327.   IStorage *pistgInput = NULL;
  328.   IStream *pistmKey = NULL;
  329.   IStream  *pistmContent = NULL;
  330.  
  331.   if (pilbInput == NULL || pdwResult == NULL)
  332.   {
  333.     hr = E_INVALIDARG;
  334.     goto LExit;
  335.   }
  336.  
  337.   *pdwResult = MSOIPI_RESULT_UNKNOWN;
  338.   hr = StgIsStorageILockBytes(pilbInput);
  339.   if (FAILED(hr))
  340.     goto LExit;
  341.   if (hr == S_FALSE)
  342.   {    
  343.     *pdwResult = MSOIPI_RESULT_UNPROTECTED;
  344.     goto LExit;
  345.   }
  346.   hr = StgOpenStorageOnILockBytes(pilbInput, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, NULL, NULL, &pistgInput);
  347.   if (FAILED(hr))
  348.     goto LExit;
  349.   hr = HrEnsureStm(pistgInput, wzKey, FALSE, &pistmKey);
  350.   if (FAILED(hr))
  351.   {    
  352.     *pdwResult = MSOIPI_RESULT_UNPROTECTED;
  353.     goto LExit;
  354.   }
  355.   hr = HrEnsureStm(pistgInput, wzContent, FALSE, &pistmContent);
  356.   if (FAILED(hr))
  357.    
  358.     goto LExit;
  359.   *pdwResult = MSOIPI_RESULT_PROTECTED;
  360.  
  361. LExit:
  362.   if (pistmContent != NULL)
  363.     pistmContent->Release();
  364.   if (pistmKey != NULL)
  365.     pistmKey->Release();
  366.   if (pistgInput != NULL)
  367.     pistgInput->Release();
  368.   return S_OK;
  369. }
  370.  
  371. STDMETHODIMP CPdfProtector::HrSetLangId(LANGID langid)
  372. {
  373.   m_langid = langid;
  374.   return S_OK;
  375. }
  376.  
  377. HRESULT CPdfProtector::HrProtectRMS(ILockBytes *pilbInput, ILockBytes *pilbOutput, I_IrmPolicyInfoRMS *piid, DWORD *pdwStatus)
  378. {
  379.     return E_NOTIMPL;
  380. }
  381.  
  382. HRESULT CPdfProtector::HrUnprotectRMS(ILockBytes *pilbInput, ILockBytes *pilbOutput, I_IrmPolicyInfoRMS *piid, DWORD *pdwStatus)
  383. {
  384.     return E_NOTIMPL;
  385. }
  386.  
  387. HRESULT CPdfProtector::HrProtect(ILockBytes *pilbInput, ILockBytes *pilbOutput, I_IrmPolicyInfo *piid, DWORD *pdwStatus)
  388. {
  389.   HRESULT hr = S_OK;
  390.   IStorage *pistgOutput = NULL;
  391.   IStream *pistmT = NULL;
  392.   BSTR bstr = NULL;
  393.   DWORD dw = 0;
  394.   BOOL bRequestingUserIsSystem = false;
  395.   BYTE rgbBuffer[STACK_RW_BUF_SIZE];
  396.   ULARGE_INTEGER ulOffset = { 0 };
  397.  
  398.   if (pilbInput == NULL || pilbOutput == NULL || piid == NULL || pdwStatus == NULL)
  399.   {
  400.     hr = E_INVALIDARG;
  401.     goto LExit;
  402.   }
  403.  
  404.   *pdwStatus = MSOIPI_STATUS_UNKNOWN;
  405.  
  406.   hr = StgIsStorageILockBytes(pilbOutput);
  407.   if (FAILED(hr))
  408.     goto LExit;
  409.   if (hr != S_FALSE)
  410.   {
  411.     hr = StgOpenStorageOnILockBytes(pilbOutput, NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, NULL, &pistgOutput);
  412.     if (hr == STG_E_FILEALREADYEXISTS)
  413.       goto LCreateStorage;
  414.   }
  415.   else
  416.   {
  417. LCreateStorage:
  418.     hr = StgCreateDocfileOnILockBytes(pilbOutput, STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, &pistgOutput);
  419.   }
  420.   if (FAILED(hr))
  421.     goto LExit;
  422.   BSTR key = SysAllocString(wzKey);
  423.   hr = HrWriteSubStream(pistgOutput, wzKey, &key);
  424.   hr = piid->HrGetListGuid(&bstr);
  425.   if (FAILED(hr) || bstr == NULL)
  426.     goto LExit;
  427.   hr = HrWriteSubStream(pistgOutput, wzListGuid, &bstr);
  428.   if (FAILED(hr))
  429.     goto LExit;
  430.   hr = piid->HrGetRightsMask(&dw);
  431.   if (FAILED(hr))
  432.     goto LExit;
  433.   hr = HrWriteSubStream(pistgOutput, wzRightsMask, &bstr);
  434.   if (FAILED(hr))
  435.     goto LExit;
  436.  
  437.   hr = piid->HrGetRequestingUser(&bstr, &bRequestingUserIsSystem);
  438.   if (FAILED(hr) || bstr == NULL)
  439.     goto LExit;
  440.   hr = HrWriteSubStream(pistgOutput, wzRequestingUser, &bstr);
  441.   if (FAILED(hr))
  442.     goto LExit;
  443.  
  444.   hr = piid->HrGetURL(&bstr);
  445.   if (FAILED(hr) || bstr == NULL)
  446.     goto LExit;
  447.   hr = HrWriteSubStream(pistgOutput, wzURL, &bstr);
  448.   if (FAILED(hr))
  449.     goto LExit;
  450.  
  451.   hr = piid->HrGetPolicyTitle(&bstr);
  452.   if (FAILED(hr) || bstr == NULL)
  453.     goto LExit;
  454.   hr = HrWriteSubStream(pistgOutput, wzPolicyTitle, &bstr);
  455.   if (FAILED(hr))
  456.     goto LExit;
  457.  
  458.   hr = piid->HrGetPolicyTitle(&bstr);
  459.   if (FAILED(hr) || bstr == NULL)
  460.     goto LExit;
  461.   hr = HrWriteSubStream(pistgOutput, wzPolicyDescription, &bstr);
  462.   if (FAILED(hr))
  463.     goto LExit;
  464.  
  465.   hr = piid->HrGetOfflineDays(&dw);
  466.   if (FAILED(hr))
  467.     goto LExit;
  468.   hr = HrWriteSubStream(pistgOutput, wzOfflineDays, &bstr);
  469.   if (FAILED(hr))
  470.     goto LExit;
  471.  
  472.   hr = HrEnsureStm(pistgOutput, wzContent, true, &pistmT);
  473.   if (FAILED(hr))
  474.     goto LExit;
  475.   ulOffset.QuadPart = 0;
  476.  
  477.   TCHAR temp_path[ MAX_PATH ];
  478.   const DWORD temp_path_len = GetTempPath( MAX_PATH, temp_path );
  479.   if (!temp_path_len)
  480.       goto LExit;
  481.   GetTempFileName( temp_path, _T("irm"), FALSE, temp_path );
  482.  
  483.   HANDLE hTempFile = CreateFile( temp_path,  
  484.     GENERIC_WRITE,  
  485.     0,              
  486.     NULL,          
  487.     CREATE_ALWAYS,  
  488.     FILE_ATTRIBUTE_NORMAL,
  489.     NULL );
  490.   if ( hTempFile == INVALID_HANDLE_VALUE )
  491.     goto LExit;
  492.  
  493.   while (true)
  494.   {
  495.     ULONG cbRead = cElements(rgbBuffer);
  496.     ULONG cbWritten = 0;
  497.     hr = pilbInput->ReadAt(ulOffset, rgbBuffer, cbRead, &cbRead);
  498.     if (FAILED(hr))
  499.       goto LExit;
  500.     if (cbRead == 0)
  501.       goto LFinished;
  502.  
  503.     WriteFile( hTempFile, rgbBuffer, cbRead, &cbWritten, NULL );
  504.  
  505.     if (cbRead != cbWritten)
  506.     {
  507.       hr = STG_E_CANTSAVE;
  508.       goto LExit;
  509.     }
  510.     ulOffset.QuadPart += cbRead;
  511.   }
  512.  
  513. LFinished:
  514.   TCHAR temp_path2[ MAX_PATH ];
  515.   const DWORD temp_path2_len = GetTempPath( MAX_PATH, temp_path2 );
  516.   if (!temp_path2_len)
  517.       goto LExit;
  518.   GetTempFileName( temp_path2, _T("irm"), FALSE, temp_path2 );
  519.  
  520.   CloseHandle( hTempFile );
  521.   {
  522.     const char* password = NULL;
  523.     const char* user_password = NULL;
  524.     const bool decrypt = false;
  525.     const bool encrypt = true;
  526.  
  527.     USES_CONVERSION;
  528.     QPDF pdf;
  529.     pdf.processFile(T2A(temp_path), password);
  530.       QPDFWriter w(pdf, T2A(temp_path2));
  531.     if (decrypt)
  532.       {
  533.           w.setPreserveEncryption(false);
  534.       }
  535.     if (encrypt)
  536.     {
  537.       w.setR3EncryptionParameters(
  538.         user_password, W2A(wzKey),
  539.         false,
  540.         false,  
  541.         qpdf_r3p_none,  
  542.         qpdf_r3m_none  
  543.         );
  544.     }
  545.     w.write();
  546.  
  547.     HANDLE hOutFile = CreateFile( temp_path2, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
  548.     if ( hOutFile == INVALID_HANDLE_VALUE )
  549.     {
  550.       goto LExit;
  551.     }
  552.  
  553.     DWORD cbReaded = 0, cbWritten;
  554.     while ( ReadFile( hOutFile, rgbBuffer, sizeof( rgbBuffer ), &cbReaded, NULL ) || cbReaded )
  555.     {
  556.       hr = pistmT->Write(rgbBuffer, cbReaded, &cbWritten);
  557.       if (FAILED(hr))
  558.         goto LExit;
  559.       if ( cbReaded != cbWritten )
  560.       {
  561.         hr = STG_E_CANTSAVE;
  562.         goto LExit;
  563.       }
  564.     }
  565.   }
  566.  
  567.   hr = pistmT->Commit(STGC_DEFAULT);
  568.  
  569. LExit:
  570.   DeleteFile( temp_path );
  571.   DeleteFile( temp_path2 );
  572.  
  573.   *pdwStatus = SUCCEEDED(hr) ? MSOIPI_STATUS_PROTECT_SUCCESS : MSOIPI_STATUS_CANT_PROTECT;
  574.   if (bstr != NULL)
  575.     SysFreeString(bstr);
  576.   if (pistmT != NULL)
  577.     pistmT->Release();
  578.   if (pistgOutput != NULL)
  579.     pistgOutput->Release();
  580.  
  581.   return hr;
  582. }
  583.  
  584. HRESULT CPdfProtector::HrUnprotect(ILockBytes *pilbInput, ILockBytes *pilbOutput, I_IrmPolicyInfo *piid, DWORD *pdwStatus)
  585. {
  586.   HRESULT hr = S_OK;
  587.   IStorage *pistgInput = NULL;
  588.   IStream *pistmT = NULL;
  589.   BYTE rgbBuffer[STACK_RW_BUF_SIZE];
  590.   ULARGE_INTEGER ulOffset = { 0 };
  591.  
  592.   if (pilbInput == NULL || pilbOutput == NULL || piid == NULL || pdwStatus == NULL)
  593.   {
  594.     return E_INVALIDARG;
  595.   }
  596.  
  597.   *pdwStatus = MSOIPI_STATUS_UNKNOWN;
  598.  
  599.   hr = StgIsStorageILockBytes(pilbInput);
  600.   if (FAILED(hr) || hr == S_FALSE)
  601.   {
  602.     *pdwStatus = MSOIPI_STATUS_ALREADY_UNPROTECTED;
  603.     goto LExit;
  604.   }
  605.  
  606.   hr = StgOpenStorageOnILockBytes(pilbInput, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, NULL, NULL, &pistgInput);
  607.   if (FAILED(hr))
  608.     goto LExit;
  609.  
  610.   hr = HrEnsureStm(pistgInput, wzContent, false, &pistmT);
  611.   if (FAILED(hr))
  612.     goto LExit;
  613.   ulOffset.QuadPart = 0;
  614.  
  615.   while (true)
  616.   {
  617.     ULONG cbRead = cElements(rgbBuffer);
  618.     ULONG cbWritten = 0;
  619.     hr = pistmT->Read(rgbBuffer, cbRead, &cbRead);
  620.     if (FAILED(hr))
  621.       goto LExit;
  622.     if (cbRead == 0)
  623.       goto LFinished;
  624.     for (ULONG i = 0; i < cbRead; i++)
  625.       rgbBuffer&#91;i&#93; ^= 1;
  626.     hr = pilbOutput->WriteAt(ulOffset, rgbBuffer, cbRead, &cbWritten);
  627.     if (FAILED(hr))
  628.       goto LExit;
  629.     if (cbRead != cbWritten)
  630.     {
  631.       hr = STG_E_CANTSAVE;
  632.       goto LExit;
  633.     }
  634.     ulOffset.QuadPart += cbRead;
  635.   }
  636. LFinished:
  637.   pistmT->Release();
  638.   pistmT = NULL;
  639.  
  640. LExit:
  641.   if (pistmT != NULL)
  642.     pistmT->Release();
  643.   if (pistgInput != NULL)
  644.     pistgInput->Release();
  645.   return hr;
  646. }

and lastly, the PdfIrmProtector.idl file:

  1. // PdfIrmProtector.idl : IDL source for PdfIrmProtector
  2. //
  3.  
  4. // This file will be processed by the MIDL tool to
  5. // produce the type library (PdfIrmProtector.tlb) and marshalling code.
  6.  
  7. import "oaidl.idl";
  8. import "ocidl.idl";
  9.  
  10. [
  11. uuid(598F03E8-948A-425e-B7B2-2D613CEDFFEF)
  12. ]
  13. interface I_IrmCrypt: IUnknown
  14. {
  15.     HRESULT HrGetBlockSize(
  16.         /*[OUT]*/ DWORD *pdwBlockSize) ;
  17.  
  18.     HRESULT HrEncrypt(
  19.         /*[IN]*/     ULONG  ulOffset,
  20.         /*[IN/OUT]*/ BYTE  *pbData,
  21.         /*[IN]*/     DWORD  cbData,
  22.         /*[OUT]*/    DWORD *pcbData) ;
  23.  
  24.     HRESULT HrDecrypt(
  25.         /*[IN]*/     ULONG  ulOffset,
  26.         /*[IN/OUT]*/ BYTE  *pbData,
  27.         /*[IN]*/     DWORD  cbData,
  28.         /*[OUT]*/    DWORD *pcbData) ;
  29.  
  30.     HRESULT HrEncode(
  31.         /*[IN]*/     WCHAR *wszAlgID,
  32.         /*[IN]*/     UINT   uDataLen,
  33.         /*[IN]*/     BYTE  *pbDecodedData,
  34.         /*[IN/OUT]*/ UINT  *puEncodedStringLen,
  35.         /*[OUT]*/    WCHAR *wszEncodedString) ;
  36.  
  37.     HRESULT HrDecode(
  38.         /*[IN]*/     WCHAR *wszAlgID,
  39.         /*[IN]*/     WCHAR *wszEncodedString,
  40.         /*[IN/OUT]*/ UINT  *puDecodedDataLen,
  41.         /*[OUT]*/    BYTE  *pbDecodedData) ;
  42. };
  43.  
  44. [
  45. uuid(175EF0A4-8EB8-49ac-9049-F40EC69EC0A7)
  46. ]
  47. interface I_IrmPolicyInfoRMS: IUnknown
  48. {
  49.     HRESULT HrGetICrypt(
  50.         /*[OUT]*/ I_IrmCrypt **piic) ;
  51.  
  52.     HRESULT HrGetSignedIL(
  53.         /*[OUT]*/ BSTR *pbstrIL) ;
  54.     HRESULT HrGetServerId(
  55.         /*[OUT]*/ BSTR *pbstrServerId) ;
  56.     HRESULT HrGetEULs(
  57.         /*[OUT]*/ BSTR *rgbstrEUL,
  58.         /*[OUT]*/ BSTR *rgbstrId,
  59.         /*[OUT]*/ UINT *pcbEULs) ;
  60.  
  61.     HRESULT HrSetSignedIL(
  62.         /*[IN]*/  BSTR bstrIL) ;
  63.     HRESULT HrSetServerEUL(
  64.         /*[IN]*/  BSTR bstrEUL) ;
  65.  
  66.     HRESULT HrGetRightsTemplate(
  67.         /*[OUT]*/ BSTR* pbstrRightsTemplate) ;
  68.  
  69.     HRESULT HrGetListGuid(
  70.         /*[OUT]*/ BSTR* pbstrListGuid) ;
  71. };
  72.  
  73. [
  74. uuid(2CDC48E9-DB49-47E6-8487-A2EA1FCE292F)
  75. ]
  76. interface I_IrmPolicyInfo:  IUnknown
  77. {
  78.     HRESULT HrGetListGuid(
  79.         /*[OUT]*/  BSTR* pbstrListGuid) ;
  80.  
  81.     HRESULT HrSetListGuid(
  82.         /*[IN]*/   BSTR bstrListGuid) ;
  83.    
  84.     HRESULT HrGetRightsMask(
  85.         /*[OUT]*/  DWORD* pdwRightsMask) ;
  86.  
  87.     HRESULT HrGetRequestingUser(
  88.         /*[OUT]*/  BSTR* pbstrRequestingUser,
  89.         /*[OUT]*/  BOOL* pfRequestingUserIsSystem) ;
  90.  
  91.     HRESULT HrGetURL(
  92.         /*[OUT]*/  BSTR* pbstrURL) ;
  93.  
  94.     HRESULT HrGetPolicyTitle(
  95.         /*[OUT]*/  BSTR* pbstrPolicyTitle) ;
  96.    
  97.     HRESULT HrGetPolicyDescription(
  98.         /*[OUT]*/  BSTR* pbstrPolicyDescription) ;
  99.    
  100.     HRESULT HrGetOfflineDays(
  101.         /*[OUT]*/  DWORD* pdwOfflineDays) ;
  102. };
  103.  
  104. [
  105.     uuid(fcfbc0ac-672b-452d-80e5-40652503d96e)
  106. ]
  107. interface I_IrmProtector: IUnknown
  108. {
  109.     HRESULT HrInit(
  110.         /*[OUT]*/ BSTR  *pbstrProduct,
  111.         /*[OUT]*/ DWORD *pdwVersion,
  112.         /*[OUT]*/ BSTR  *pbstrExtentions,
  113.         /*[OUT]*/ BOOL  *pfUseRMS) ;
  114.  
  115.     HRESULT HrIsProtected(
  116.         /*[IN]*/  ILockBytes *pilbInput,
  117.         /*[OUT]*/ DWORD *pdwResult) ;
  118.  
  119.     HRESULT HrSetLangId(
  120.         /*[IN]*/  LANGID langid) ;
  121.  
  122.     HRESULT HrProtectRMS(
  123.         /*[IN]*/  ILockBytes         *pilbInput,
  124.         /*[IN]*/  ILockBytes         *pilbOutput,
  125.         /*[IN]*/  I_IrmPolicyInfoRMS *piid,
  126.         /*[OUT]*/ DWORD              *pdwStatus) ;
  127.  
  128.     HRESULT HrUnprotectRMS(
  129.         /*[IN]*/  ILockBytes         *pilbInput,
  130.         /*[IN]*/  ILockBytes         *pilbOutput,
  131.         /*[IN]*/  I_IrmPolicyInfoRMS *piid,
  132.         /*[OUT]*/ DWORD              *pdwStatus) ;
  133.  
  134.     HRESULT HrProtect(
  135.         /*[IN]*/  ILockBytes      *pilbInput,
  136.         /*[IN]*/  ILockBytes      *pilbOutput,
  137.         /*[IN]*/  I_IrmPolicyInfo *piid,
  138.         /*[OUT]*/ DWORD           *pdwStatus) ;
  139.  
  140.     HRESULT HrUnprotect (/*[IN]*/  ILockBytes      *pilbInput,
  141.         /*[IN]*/  ILockBytes      *pilbOutput,
  142.         /*[IN]*/  I_IrmPolicyInfo *piid,
  143.         /*[OUT]*/ DWORD           *pdwStatus) ;
  144. };
  145. [
  146.     object,
  147.     uuid(9F6F6D2C-434C-49D1-ACD5-C8B1C70A38DD),
  148.     dual,
  149.     nonextensible,
  150.     helpstring("IPdfProtector Interface"),
  151.     pointer_default(unique)
  152. ]
  153. interface IPdfProtector : IDispatch{
  154. };
  155. [
  156.     uuid(50FB39F2-4C18-460a-9A45-FD79980DFD8D),
  157.     version(1.0),
  158.     helpstring("PdfIrmProtector 1.0 Type Library")
  159. ]
  160. library PdfProtectorLib
  161. {
  162.     importlib("stdole2.tlb");
  163.     [
  164.         uuid(D2CE39CC-DF1D-48f2-86CC-7640B307E868),
  165.         helpstring("PdfProtector Class")
  166.     ]
  167.     coclass PdfProtector
  168.     {
  169.         [default] interface I_IrmProtector;
  170.     };
  171. };
Share

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>