tag:blogger.com,1999:blog-18243303614760606512024-03-14T13:00:42.889+01:00My Tech Solutionskibitzerhttp://www.blogger.com/profile/09736938527680098828noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-1824330361476060651.post-86022507353125006142018-03-29T13:44:00.001+02:002018-03-29T13:45:28.789+02:00XPS driver certification for Windows 10 <div>
If you follow Microsoft's <a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/dashboard/attestation-signing-a-kernel-driver-for-public-release">Attestation signing a kernel driver for public release</a> guide and try to get your driver signed, you may encouter some troubles as I did. Unfortunately, MS guide does not cover all steps required (and possible errors), neither is there any other resource to read and follow, so I went the hard way through the darkness of the signing process alone and wrote down some notes, which I would like to share with you now.<br />
<br />
NOTE: If you have some knowledge of (or experience working with) INF installation files, you may find this article stupid or useless. I do not have any, so I was writing it from my point of view.<br />
<br />
After uploading your CAB file in the Dashboard's first step, you have to specify the W10 versions the driver has been tested on. You may be confused as I was when seeing RS2 and RS3 options for the first time:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4FkrMCw2ugNzAggxC_zKnUU4uR962szcIGiqCugow0btL48RzlSTRulwdX32Y72AXLTFtchy_COWEKBQ35w3LBnNJd870Z4IYlyolf_-oS8JeHdFiI3zKiTqXIYZ5QO0y9T5plLThKhEm/s1600/builds.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="168" data-original-width="931" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4FkrMCw2ugNzAggxC_zKnUU4uR962szcIGiqCugow0btL48RzlSTRulwdX32Y72AXLTFtchy_COWEKBQ35w3LBnNJd870Z4IYlyolf_-oS8JeHdFiI3zKiTqXIYZ5QO0y9T5plLThKhEm/s640/builds.PNG" width="640" /></a></div>
<br />
So here is a little light for this darkness:<br />
- <b>Windows 10 RS2</b> means Redstone 2 which is a codename for build 1703, known as <b>Creators Update</b></div>
<div>
- <b>RS3</b> = build 1709 - <b>Fall Creators Update</b></div>
<div>
<br /></div>
The <i>Preparing</i> stage starts and there is an error almost immediately: "<i>Could not load the Inf file install.inf due to Version section is missing from inf</i>"<br />
<blockquote class="tr_bq">
<b>First lesson learned:</b><i> Well, apparently the INF file that you use for CAB creation must have a Version section</i><br />
<i> </i>(<a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/install/inf-version-section">https://docs.microsoft.com/en-us/windows-hardware/drivers/install/inf-version-section</a>)<i>. </i><b>Where is this mentioned in your guide, Microsoft??!</b></blockquote>
<br />
Specifying just the two mandatory attributes <span style="font-family: "courier new" , "courier" , monospace;">Signature</span> and <span style="font-family: "courier new" , "courier" , monospace;">DriverVer</span> seems to be enough for now to eliminate this error:<br />
<br />
<div style="font-family: courier;">
<span style="background-color: #444444;">[Version]</span><br />
<span style="background-color: #444444;">Signature="$Windows NT$"</span><br />
<span style="background-color: #444444;">DriverVer=07/14/2017,2.0.153.0</span></div>
<br />
(But there is <b>a lot more</b> on this. See below.)<br />
<div>
<br /></div>
<div>
As you may have noticed, when the process fails dashboard allows you to download a file with an error message. Pity that sometimes that file is empty... <b>Thanks, Microsoft! REALLY HELPFUL!!!</b></div>
<blockquote class="tr_bq">
<b>Second lesson learned</b>: <i>Do not forget to specify the </i><span style="font-family: "courier new" , "courier" , monospace;">DestinationDir</span><i> attribute in your ddf script, otherwise the resulting CAB file will contain no folder and the driver files will be placed in the "root", which is a no-go. Cab file must contain a folder with the driver files.</i><br />
<span style="background-color: #444444; font-family: "courier new" , "courier" , monospace;">.Set DestinationDir=XPS</span></blockquote>
<br />
- If you are lucky enough and make it to the <i>Catalog creation</i> stage, it may fail saying<br />
<blockquote class="tr_bq">
<i>No installation INF found in the root path of the driver. For the driver to be digitally signed, and for it to install properly the installation inf must be in the root of each driver path you have provided. If you have separate folders with different driver packages for different languages, operating systems or device categories then specify each driver set as a separate driver. Each driver package must be selected separately and must contain an installation INF.</i></blockquote>
<div>
Oh, well. So my Inf is not an Inf or what? Should it be in CAB root or inside a folder? After a while spent with unsuccessful attempts, I decided to only work with just one platform (x86) at once - no mixed CAB.</div>
<br />
<i>Catalog creation</i> stage sometimes recommends using <i>Inf2Cat</i> utility to check your INF file used in created CAB. And it turns out, it is quite a good thing,<br />
(<a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/install/using-inf2cat-to-create-a-catalog-file">https://docs.microsoft.com/en-us/windows-hardware/drivers/install/using-inf2cat-to-create-a-catalog-file</a>). I did not manage to find its W10 version on my system, so I used W8.0 version - just to check what it does and what the result is (<span style="font-family: "courier new" , "courier" , monospace;">c:\Program Files (x86)\Windows Kits\8.0\bin\x86\</span>) - it works fine, just don't forget you need to set the OS parameter to Win8, not Win10.<br />
<br />
So I took the bunch of files I use for CAB creation (specified in ddf script file), put them in a folder and ran <i>inf2cat</i>:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">inf2cat /driver:c:\development\xpsdriver\files /os:8_X86</span><br />
<br />
...and it leads to the exact same error as in Dashboard's <i>Catalog creation</i> stage: <i>No installation INF found in the root path of the driver...</i><br />
Fine, I can now get the error prior to uploading, which saves some time, but hey, what now...?!<br />
<br />
Being more and more desperate I decided to run the <i>Inf2Cat</i> over a Microsoft <i>XPSDrvSample</i> from WDK directory (<span style="font-family: "courier new" , "courier" , monospace;">WinDDK\7600.16385.1\src\print\XPSDrvSmpl\install\</span>) - and wow, the error changes to just some file not found complaints! So now it can find the INF, apparently there must be something special I am missing!<br />
<br />
<b style="background-color: #444444;">ATTENTION: Here comes a few hours trial-error part where I just desperately tried some things without even knowing why and what it would result in (having no experience with or knowledge of INF). So I can say for sure that I will NOT be able to help you with your questions, should there be any.</b><br />
<span style="background-color: #444444;"><b><br /></b><b>NOTE: </b>I can do it this way because of the way I install my printer - I use c++ code to process driver files "manually" and call Windows API, so the INF file works rather as a list of needed files, than an installation script. The parts taken from sample INF file are just for making Inf2Cat (and the Dashboard) happy.</span><br />
<br />
Long story short - I was trying to use parts of <span style="font-family: "courier new" , "courier" , monospace;">xdsmpl.inf</span> file in my own INF file. Turned out that the "right" (read "working") parts are these:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">[Manufacturer]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">%Microsoft%=Microsoft,NTx86</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">[Microsoft.NTx86]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">"XPSDrv Sample Driver" = INSTALL_XDSMPL_FILTERS_VISTA</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">[INSTALL_XDSMPL_FILTERS_VISTA]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">DriverFile=mxdwdrv.dll</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">CoreDriverSections="{D20EA372-DD35-4950-9ED8-A6335AFE79F0},UNIDRV.OEM", "{D20EA372-DD35-4950-9ED8-A6335AFE79F5},XPSDRV.OEM,XPSGPD.OEM"</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">[Strings]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Microsoft="Microsoft"</span><br />
<div>
<br />
(the <span style="font-family: "courier new" , "courier" , monospace;">Strings</span> section is mostly placed at the end of the INF file, so don't forget it, otherwise the signing process will fail).<br />
<br /></div>
After I added this block to my INF file, <i>Inf2Cat</i> stopped complaining - just printed out some warning. This looked promising. So i uploaded yet another submission to the Dashboard, and after few minutes - Heureka! <b>All stages are green and my driver files are now finally signed by Microsoft!</b><br />
<br />
<br />
My resulting INF file follows (highlighted are parts that needed to be added - and Microsoft did not consider it important to tell us in the <a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/dashboard/attestation-signing-a-kernel-driver-for-public-release">guide</a>). Just please note company name has been changed to ACME.<br />
<br />
<span style="color: white; font-family: "courier new" , "courier" , monospace;"><cab_input_path>\files\acme_xps_install86.inf</span><br />
<br />
<span style="color: #e06666; font-family: "courier new" , "courier" , monospace;">[</span><span style="color: #e06666; font-family: "courier new" , "courier" , monospace;">Version]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #e06666;">Signature="$Windows NT$"</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #e06666;">DriverVer=mm/dd/yyyy,1.2.345.6</span><span style="color: #990000;"> </span><span style="color: #38761d;">;use your date and version number</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #e06666;">Provider="<your_company_name_here>"</span><span style="color: #990000;"> </span><span style="color: #38761d;">;not sure if it has to match your name in EV cert</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #e06666;">Class=Printer</span><span style="color: #990000;"> </span><span style="color: #38761d;">;oh yes, we are "installing" printer</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #e06666;">ClassGuid={4d36e979-e325-11ce-bfc1-08002be10318}</span><span style="color: #990000;"> </span><span style="color: #38761d;">;Windows defined guid for printers</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #e06666;">CatalogFile=xps.cat</span><span style="color: #990000;"> </span><span style="color: #38761d;">;this is IMPORTANT for INF2CAT - the named file gets created but is not necessary for your CAB; if you do not specify this, inf2cat will fail with "CatalogFile not specified in Version section" (or something like that)</span></span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<span style="color: #e06666; font-family: "courier new" , "courier" , monospace;">[Manufacturer]</span><br />
<span style="color: #e06666; font-family: "courier new" , "courier" , monospace;">%Microsoft%=Microsoft,NTx86</span><br />
<span style="color: #e06666;"><span style="color: #990000; font-family: "courier new" , "courier" , monospace;"><br /></span><span style="color: #990000; font-family: "courier new" , "courier" , monospace;">[Microsoft.NTx86]</span></span><br />
<span style="color: #e06666; font-family: "courier new" , "courier" , monospace;">"XPSDrv Sample Driver" = INSTALL_XDSMPL_FILTERS_VISTA</span><br />
<span style="color: #e06666;"><span style="color: #990000; font-family: "courier new" , "courier" , monospace;"><br /></span><span style="color: #990000; font-family: "courier new" , "courier" , monospace;">[INSTALL_XDSMPL_FILTERS_VISTA]</span></span><br />
<span style="color: #e06666; font-family: "courier new" , "courier" , monospace;">DriverFile=mxdwdrv.dll</span><br />
<span style="color: #e06666; font-family: "courier new" , "courier" , monospace;">CoreDriverSections="{D20EA372-DD35-4950-9ED8-A6335AFE79F0},UNIDRV.OEM", "{D20EA372-DD35-4950-9ED8-A6335AFE79F5},XPSDRV.OEM,XPSGPD.OEM"</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">[Monitor]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">MonitorName=ACME XPS port monitor</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">MonitorDll=acme_localmon.dll</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">MonitorUiDll=acme_localui.dll</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">MonitorEnv=Windows NT x86</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">[Driver]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">DriverName=ACME XPS printer driver</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">DriverEnv=Windows NT x86</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">DriverFile=mxdwdrv.dll</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">DataFile=acme_xps.gpd</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">ConfigFile=UniDrvUI.dll</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">HelpFile=UniDrv.HLP</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">XpsSvcFile=xpssvcs.dll</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">DependentFiles=acme_xps.gpd,acme_xpsnames.gpd,acme_xpspipeline.xml,acme_xps_install86.inf,acme_xps.ini,acme_xpsui.dll,xdCMYKPrinter.icc,xdwscRGB.icc,xpssvcs.dll,</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">DataType=RAW</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">[PrintProcessor]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">;WinPrint can be used on XP as well</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">PrintProcessorPreVista=WinPrint</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">PrintProcessor=WinPrint</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">[Printer]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">PrinterName=ACME XPS Printer</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">PrinterEnv=Windows x86</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="color: #e06666; font-family: "courier new" , "courier" , monospace;">[Strings]</span><br />
<span style="color: #e06666; font-family: "courier new" , "courier" , monospace;">Microsoft="Microsoft"</span><br />
<div>
<br /></div>
<b>DDF file for CAB creation:</b><br />
<span style="background-color: #3d85c6; color: white; font-family: "courier new" , "courier" , monospace;"><cab_input_path>\xps.ddf</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">.OPTION EXPLICIT ; Generate errors</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.Set CabinetFileCountThreshold=0</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.Set FolderFileCountThreshold=0</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.Set FolderSizeThreshold=0</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.Set MaxCabinetSize=0</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.Set MaxDiskFileCount=0</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.Set MaxDiskSize=0</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.Set CompressionType=MSZIP</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.Set Cabinet=on</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.Set Compress=on</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">;Specify file name for new cab file</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.Set CabinetNameTemplate=xps.cab</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">; Specify the subdirectory for the files.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">; Your cab file should not have files at the root level,</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">; and each driver package must be in a separate subfolder.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.Set DestinationDir=XPS</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">;Specify files to be included in cab file</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><cab_input_path>\files\acme_localmon.dll</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><cab_input_path>\files\acme_localmon.pdb</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><cab_input_path>\files\acme_localui.dll</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><cab_input_path>\files\acme_localui.pdb</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><cab_input_path>\files\acme_xpsui.dll</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><cab_input_path>\files\acme_xps_install86.inf</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: inherit;"><b>64bit driver </b></span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">For attestation signing of a 64bit driver use </span><span style="font-family: "courier new" , "courier" , monospace;">NTamd64</span><span style="font-family: inherit;"> decorated model section in your INF file (using NTia64 leads to an error "<i>Inf does not have NTAMD64 decorated model sections</i>" in Inf2Cat and Dashboards also fails):</span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">[Manufacturer]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">%Microsoft%=Microsoft,NTamd64</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">[Microsoft.NTamd64]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">"XPSDrv Sample Driver" = INSTALL_XDSMPL_FILTERS_VISTA</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">[INSTALL_XDSMPL_FILTERS_VISTA]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">DriverFile=mxdwdrv.dll</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">CoreDriverSections="{D20EA372-DD35-4950-9ED8-A6335AFE79F0},UNIDRV.OEM", "{D20EA372-DD35-4950-9ED8-A6335AFE79F5},XPSDRV.OEM,XPSGPD.OEM"</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></span><br />
<br />
<span style="font-family: inherit;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: inherit;"><b>Hope you will get the whole sh*t working too soon!</b></span>kibitzerhttp://www.blogger.com/profile/09736938527680098828noreply@blogger.com0tag:blogger.com,1999:blog-1824330361476060651.post-81530801359770958072014-05-05T16:21:00.000+02:002014-05-05T16:21:57.499+02:00Setting up WNS on Windows Phone 8.1 - Part 2Hi again everyone.<br />
<br />
Just wanted to let you know of another problem in setting up the Windows Notification Service (Push notifications) on Windows Phone 8.1.<br />
<br />
In my <a href="http://kibitzercz.blogspot.cz/2014/05/setting-up-wns-on-windows-phone-81.html" target="_blank">previous article</a> I was following up the <a href="http://msdn.microsoft.com/en-us/library/windows/apps/xaml/Hh868221%28v=win.10%29.aspx" target="_blank">WNS tutorial from Microsoft</a>, resolving an issue from step 2. As I supposed, this one is not the only one.<br />
<br />
In Step 3 "<em>Send the channel URI to your server</em>" a <span style="font-family: "Courier New", Courier, monospace;">System.NotSupportedException</span> occurs when you try to read the server response using <span style="font-family: "Courier New", Courier, monospace;">GetResponseAsync</span> function. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqQ_J6cLTr_sPjgPTs_9jjH4Ji6Q3yM1ajiXfnnUMUJlOpn8MJdpoblgmBQ4aC3jVIkHtpQ5T3oFt2Lkh0nXqxgSnJdssl0IuIp8RZLVbcTUDvZ0l2aTcZ2eQn7k5SsLxA3lnnvqV2oxA/s1600/notsupported.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqQ_J6cLTr_sPjgPTs_9jjH4Ji6Q3yM1ajiXfnnUMUJlOpn8MJdpoblgmBQ4aC3jVIkHtpQ5T3oFt2Lkh0nXqxgSnJdssl0IuIp8RZLVbcTUDvZ0l2aTcZ2eQn7k5SsLxA3lnnvqV2oxA/s1600/notsupported.png" height="320" width="400" /></a></div>
<br />
<br />
It is a shame that Microsoft's official tutorial is so buggy. As in my previous post, not a single mention about possible error is available. At first I though there is a problem with Internet connection on my emulator. However it turned out that the problem is somewhere else and this exception is thrown when <strong>the request stream has not been flushed and closed</strong> before trying to read the response from server.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuWs5sGvr79686qzVhs5OIhhGpLmdm78YBanmVmZsCirdrY6Je7siGvO0AzTuJzbddSvf5B_ZtE11j48cnm7ATi_UYLsL2C-tmZIdR5afp8bjn6K0QgcbacnwALcYTf7Bcz7f3JSRTkhU/s1600/notsupported2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuWs5sGvr79686qzVhs5OIhhGpLmdm78YBanmVmZsCirdrY6Je7siGvO0AzTuJzbddSvf5B_ZtE11j48cnm7ATi_UYLsL2C-tmZIdR5afp8bjn6K0QgcbacnwALcYTf7Bcz7f3JSRTkhU/s1600/notsupported2.png" height="320" width="400" /></a></div>
<br />
<br />
Many thanks to StackOverflow user Kristof Van De Voorde, who has proposed the <a href="http://stackoverflow.com/a/23303362/917764" target="_blank">solution</a> to this issue.<br />
<br />
Hope this will help someone.kibitzerhttp://www.blogger.com/profile/09736938527680098828noreply@blogger.com0tag:blogger.com,1999:blog-1824330361476060651.post-11949590306651126292014-05-05T13:08:00.000+02:002014-05-05T16:21:17.866+02:00Setting up WNS on Windows Phone 8.1 - Part 1If you try to add the WNS (<em>Windows Notification Service</em> - aka Push Notifications) to your Windows Phone 8.1 application, you may encouter the same problem as I did recently.<br />
<br />
Microsoft provides nice <a href="http://msdn.microsoft.com/en-us/library/windows/apps/xaml/Hh868221%28v=win.10%29.aspx" target="_blank">tutorial</a>, however they do not tell you everything. First pain comes in the block of code labeled Step 2. These two lines of code seem quite nice until you run the code. The call of <span style="font-family: "Courier New", Courier, monospace;">CreatePushNotificationChannelForApplicationAsync()</span> will probably result in "The application does not have the cloud notification capability." error <span style="font-family: "Courier New", Courier, monospace;">(HRESULT</span> value <span style="font-family: "Courier New", Courier, monospace;">0x803E0110</span>). Now this is where Microsoft's tutorial (as well as Google) leaves you with no help. Neither the <span style="font-family: "Courier New", Courier, monospace;">PushNotificationChannel</span> class nor <span style="font-family: "Courier New", Courier, monospace;">CreatePushNotificationChannelForApplicationAsync </span>function documentation mentions what to do.<br />
<br />
Perhaps the first thing that will come to your mind is setting this capability in the application manifest (WMAppManifest.xml). But whoops - there is no such capability listed! The only one close to this is <span style="font-family: "Courier New", Courier, monospace;">ID_CAP_PUSH_NOTIFICATION</span>. Yeah, but the scenario (and result) is exactly the same.<br />
So, after some time, being quite desperate I tried to search Google for the error code (<span style="font-family: "Courier New", Courier, monospace;">0x803E0110</span>). Bah, just 5 links - and all look similar, being just lists of error codes. I tried <a href="http://joshpoley.blogspot.cz/2011/09/hresults-facilitywpn.html" target="_blank">this one</a> which in fact turned to be a good one - it contains a list of HRESULTs with respective codes, messages and also defines. Here I learned that the one I am investigating is <span style="font-family: "Courier New", Courier, monospace;">WPN_E_CLOUD_INCAPABLE</span> - let's Google this. And voilá - second link lead me to <a href="http://207.46.99.208/pl-pl/library/windows/apps/dn457490" target="_blank">this page</a> (being a copy of MS documentation). Slightly below the half of that page called "<em>Troubleshooting tile, toast, and badge notifications</em>" there is a short paragraph titled "<em>Errors when attempting to create a push notification channel</em>", explaining three common errors that may occur:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEismH11i5sLhFk3rGXmnHWYdvUXuZXrJuB8-RoQ1cG_t9tqemkuLEIgRp1T2ueorrGztty5BjFolE8BkBkACjqgdQIe9GCfWDdSLTRwqdql_-kqjWnAr522hv3HISO15JyBF0PQuUmYRwY/s1600/incapable.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEismH11i5sLhFk3rGXmnHWYdvUXuZXrJuB8-RoQ1cG_t9tqemkuLEIgRp1T2ueorrGztty5BjFolE8BkBkACjqgdQIe9GCfWDdSLTRwqdql_-kqjWnAr522hv3HISO15JyBF0PQuUmYRwY/s1600/incapable.png" height="300" width="400" /></a></div>
<br />
The reason is <strong>missing Internet capability declaration</strong>! Quite different from the actual error message, isn't it? <br />
<br />
Okay, so enable it. But there is one more small thing - do not forget to <strong>rebuild</strong> and redeploy your application for the change to come into play.<br />
<br />
Happy coding!kibitzerhttp://www.blogger.com/profile/09736938527680098828noreply@blogger.com0tag:blogger.com,1999:blog-1824330361476060651.post-20883431067628275982012-01-26T14:06:00.001+01:002012-01-27T15:53:30.184+01:004. Propagating UI states to PrintTicketIn last article we learned how to design an user interface (UI) for our XPS filter - simple setting page with checkbox, that was <i>supposed</i> to control the Reverse filter usage. Today we look at how to ensure that the checkbox state will be propagated to the PrintTicket (an XML file carrying all the print settings).<br />
<br />
<i><b>This is going to be a little bit messy and demanding, so please work carefully, as even a tiny mistake can result in complete malfunction of the driver.</b></i><br />
<br />
Ready?<br />
<br />
<ol><li>Go to <span style="font-family: "Courier New",Courier,monospace;">[sample root]\src\ui</span> and open <b style="font-family: "Courier New",Courier,monospace;">xdsmpldlg.rc</b> for editing (I recommend you to open it in MS Visual Studio). Open its <span style="font-family: "Courier New",Courier,monospace;">String Table</span> and add following records to it. The IDs and string values are not so much important (they will probably be displayed in the list of printer capabilities), but be careful to ensure each record has its <b>unique numerical Value</b> to prevent conflicts, that can result in driver malfunction. The best practice is to use numbers a bit further behind the last one used. Here I started with value of 2200. <br />
<span style="font-family: "Courier New",Courier,monospace;"> IDS_GPD_REVERSETITLE 2200 "Revert page order"</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> IDS_GPD_NOREVERSAL 2201 "No reversal"<br />
IDS_GPD_REVERSAL 2202 "Reversal"</span><br />
</li>
<li>Now go to <span style="font-family: "Courier New",Courier,monospace;">[sample root]\install</span> and open <b><span style="font-family: "Courier New",Courier,monospace;">xdnames.gpd</span></b> for editing. Go to the end of file and add those new strings to the list of StdFeatureNames. You should have something like this:<br />
<span style="font-family: "Courier New",Courier,monospace;"> IDS_GPD_REVERSETITLE: RESDLL.xdsmplui.2200</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> IDS_GPD_NOREVERSAL: RESDLL.xdsmplui.2201</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> IDS_GPD_REVERSAL: RESDLL.xdsmplui.2202</span><br />
<span style="font-family: inherit;">(The <span style="font-family: "Courier New",Courier,monospace;">RESDLL</span> macro says the driver to look up the <span style="font-family: "Courier New",Courier,monospace;">xdsmplui.dll</span> for values of those strings</span>)<br />
</li>
<li>Create a <b>new file</b> in <span style="font-family: "Courier New",Courier,monospace;">[sample root]\install</span> and name it <b><span style="font-family: "Courier New",Courier,monospace;">xdreverse.gpd</span></b>. Copy and paste the following code in it. This is a so called "Generic Printer Description" script which defines one of printer's capabilities.<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">*% File Name:</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*%</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*% xdreverse.gpd</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*%</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*% Abstract:</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*%</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*% Reverse filter feature specific GPD settings.</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*%</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*%***********************************************************</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*% Reverse</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*%***********************************************************</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*% rcNameID feature name listed in </span><span style="font-family: "Courier New",Courier,monospace;">Printer Capabilities </span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*%***********************************************************</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">*Feature: PageReversal</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">{</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> *rcNameID: =IDS_GPD_REVERSETITLE</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> *DefaultOption: Reversal</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> *PrintSchemaKeywordMap: "PageReversal"</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> *Option: NoReversal</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> *rcNameID: =IDS_GPD_NOREVERSAL</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> *PrintSchemaKeywordMap: "NoReversal"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> }</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> *Option: Reversal</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> *rcNameID: =IDS_GPD_REVERSAL</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> *PrintSchemaKeywordMap: "Reversal"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> }</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">}</span><br style="font-family: "Courier New",Courier,monospace;" /><br />
It says that we define a new printer feature - <b><i>PageReversal</i></b> (<b>this name is <u>very important</u></b> as we will use it in source code), which has two options (we use checkbox, aren't we? So two options are pretty enough). The <i>Reversal</i> option is taken as default (that means our checkbox is checked by default and the Reverse filter is ON). Keep in mind that the feature (so as both options) needs to have a <b>unique keyword </b>provided in <span style="font-family: "Courier New",Courier,monospace;">PrintSchemaKeywordMap</span> identifier. This keyword will be used in PrintTicket.<br />
You can save and close this file now. Please make sure that the <i>PageReversal</i> name is used in <span style="font-family: "Courier New",Courier,monospace;">revctrls.cpp</span> file. <br />
</li>
<li>Open <b><span style="font-family: "Courier New",Courier,monospace;">[sample root]\install\xdsmpl.inf</span></b> for edit and perform following tasks:<ul><li>add <span style="font-family: "Courier New",Courier,monospace;">xdreverse.gpd</span> in <span style="font-family: "Courier New",Courier,monospace;">[XPSDrvSample]</span> section</li>
<li>add <span style="font-family: "Courier New",Courier,monospace;">xdreverse.gpd = 1</span> in <span style="font-family: "Courier New",Courier,monospace;">[SourceDisksFiles]</span> section<br />
</li>
</ul></li>
<li>Now open <span style="font-family: "Courier New",Courier,monospace;">[sample root]\src\ui\uiproperties.cpp</span> and add the following on line 198:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"> m_OptItemList.push_back("PageReversal");</span><br />
<br />
This will add our new feature to the driver's internal feature list, which ensures that our checkbox will get it's default value (defined in <span style="font-family: "Courier New",Courier,monospace;">xdreverse.gpd</span> file) when the user clicks on Reverse setting page in advanced print dialog and will also "communicate" with UniDrv to update PrintTicket when it's state changes.<br />
</li>
<li>Save all files and rebuild and reinstall the driver (as we have changed its sources). <br />
</li>
<li>Now when you open the print dialog, go to Advanced and open the <i>Reverse</i> page, you should see your checkbox checked (or unchecked in case you changed the default value in GPD file to <span style="font-family: "Courier New",Courier,monospace;">NoReversal</span>).<br />
</li>
<li>Try to print some document. When it's done, change the output xps file's extension to <span style="font-family: "Courier New",Courier,monospace;">zip</span> and go inside and lookup <span style="font-family: "Courier New",Courier,monospace;">\Metadata\Job_PT.xml</span> file. This is the <b>PrintTicket</b> associated to your printed document which controlled its printing. Open it for reading (in Notepad, for example). You should be able to find the following near the end of the file:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"> <psf:Feature name="psk:PageReversal"></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <psf:Option name="psk:NoReversal"/></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </psf:Feature></span><br />
<br />
</li>
<li>If so, congratulations! Your PrintTicket knows about your checkbox and its state now. But <b>one thing still remains</b> - we have to edit our Reverse filter sources for it to follow the PrintTicket settings and control its function. See you in next part of this tutorial, which is hopefully coming very soon :)</li>
</ol>Should you not find the piece of XML text listed in step 8, be sure to revise all the steps carefully with stress on <i>PageReversal</i> attribute as it is one of the main identifiers, which all the action is controlled by.<br />
<br />
<u>HINT:</u> If you would like to edit your GPD file after installation (e.g. to change your default option of <i>PageReversal</i> feature), you can do it without subsequent driver reinstallation. You just need to know where to find it - the <span style="font-family: "Courier New",Courier,monospace;">xdreverse.gpd</span> file (together with all the others) resides in <span style="font-family: "Courier New",Courier,monospace;">c:\windows\system32\spool\drivers\w32x86\3</span> (in case you use 64 bit Windows go to <span style="font-family: "Courier New",Courier,monospace;">...\drivers\x64\3</span> instead).kibitzerhttp://www.blogger.com/profile/09736938527680098828noreply@blogger.com1tag:blogger.com,1999:blog-1824330361476060651.post-63468811137518570432012-01-25T14:56:00.003+01:002012-01-26T14:06:53.298+01:003. Creating XPS filter settings pageWelcome.<br />
Today's tutorial will guide you through the process of creating filter settings page for the Reverse filter we created in <a href="http://kibitzercz.blogspot.com/2012/01/implementing-custom-simple-xps-filter.html" target="_blank">last article</a>. The page will be displayed as a part of the regular system dialog after clicking the "Advanced" button for our sample XPS driver and will be <u>very simple</u> as it will contain just one checkbox (for enabling/disabling the reverse function).<br />
<i>The settings, however, will have no effect yet - the filter will be always active. Connecting the settings to the filter will be discussed in some future article.</i><br />
<br />
Unlike the previous article, today's all work will be done only in <span style="font-family: "Courier New",Courier,monospace;">[sample root]\src\ui</span> directory.<br />
<br />
<ol><li>Open <span style="font-family: "Courier New",Courier,monospace;">[sample root]\src\ui\xdsmpldlg.rc</span> resource file for edit (in MSVC). </li>
<ol><li>Right-click the <i>Dialog</i> tree item, choose "Add resource..." and <b>create new dialog</b>. In Properties set this dialog's ID to <span style="font-family: "Courier New",Courier,monospace;">IDD_REVERSE</span>. Then also make following changes: </li>
<ul><li>set <i style="font-family: inherit;">3D look</i> to <b>true</b></li>
<li>set <i><span style="font-family: inherit;">Border</span></i> to <b>none</b> </li>
<li>set <i>Style</i> to <b>Child</b></li>
<li>set <i>System menu</i> to <b>false</b></li>
<li>set <i>Disabled</i> to <b>true</b></li>
</ul><li>Now add a <b>checkbox control</b> to the dialog. Call it <span style="font-family: "Courier New",Courier,monospace;">IDC_CHECK_REVERSE</span> and let its caption be "Revert page order". <span id="goog_605333224"></span><span id="goog_605333225"></span></li>
<li>Go back to resources tree and double click the <i>String table [English (U.S.)]</i> to open it. Choose "New string" on right click to <b>add new string</b> into table. Call it <span style="font-family: "Courier New",Courier,monospace;">IDS_REVERSE</span> and let its caption be "Reverse". This string will represent the title of our new settings page.</li>
</ol><li>That's all for visual design. Now let's move to the second part - coding. To follow the style of coding of the other filters, we now have to create 4 new files in current <span style="font-family: "Courier New",Courier,monospace;">ui</span> directory:<br />
<ul style="font-family: "Courier New",Courier,monospace;"><li>revctrls.h</li>
<li>revctrls.cpp</li>
<li>revppg.h</li>
<li>revppg.cpp</li>
</ul><b>Every settings page</b> <b>must</b> have its own class (inherited from <span style="font-family: "Courier New",Courier,monospace;">CDocPropPage</span>); what's more - even <b>each control</b> on the setting page <b>must</b> do so (and inherit from default control class (<span style="font-family: "Courier New",Courier,monospace;">CUICtrlDefaultCheck</span> in our case)). Thus, the first two files (their abbreviated names stand for ReverseControls) will contain the class declarations and definitions for every control used on our page (fortunately we have just one - checkbox), while the other two files (the name stands for ReversePropertyPage) will contain the declarations and definitions for the page class.<br />
<ul><li>Every <i>control class</i> must contain: constructor, virtual destructor, private static string. If the control need some initialisation (e.g. setting default value), the class must also contain an overriden <span style="font-family: "Courier New",Courier,monospace;">OnInit</span> method.</li>
<li>Every <i>page class</i> must contain constructor, virtual destructor and overriden method <span style="font-family: "Courier New",Courier,monospace;">InitDlgBox</span> (which will set the dialog UI template and title).</li>
</ul></li>
<li>Open <span style="font-family: "Courier New",Courier,monospace;">xdsmplui.cpp</span> for edit and add the <span style="font-family: "Courier New",Courier,monospace;">#include "revppg.h"</span> line to the beginning (right after the line 31 where the <span style="font-family: "Courier New",Courier,monospace;">ftrppg.h</span> file is included). Go to line 920 inside the <span style="font-family: "Courier New",Courier,monospace;">CreatePropertyPages</span> function and add the following <span style="font-family: "Courier New",Courier,monospace;">CReversePropPage</span> class instance creating:<br />
<span style="font-family: "Courier New",Courier,monospace;"><br />
if (SUCCEEDED(hr))</span><span style="font-family: "Courier New",Courier,monospace;"><br />
{</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> pPropPage = new CReversePropPage();</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> if (SUCCEEDED(hr = CHECK_POINTER(pPropPage, E_OUTOFMEMORY)))</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> m_vectPropPages.push_back(pPropPage);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> }</span><span style="font-family: "Courier New",Courier,monospace;"><br />
}</span><br />
<br />
This code snippet creates a new instance of our setting page and adds it in the pages vector if successful. When user opens the "Advanced" dialog of our XPS printer (in Windows Control Panel), the system calls <span style="font-family: "Courier New",Courier,monospace;">DocumentPropertySheets</span> function where the content of this vector is processed (<span style="font-family: "Courier New",Courier,monospace;">PropPageInit</span> function is then called on every page which invokes the provided <span style="font-family: "Courier New",Courier,monospace;">InitDlgBox</span> function of each page).</li>
<li>We are almost done here. Now open the <b><span style="font-family: "Courier New",Courier,monospace;">sources</span></b> file and add <span style="font-family: "Courier New",Courier,monospace;">revctrls.cpp</span> and <span style="font-family: "Courier New",Courier,monospace;">revppg.cpp</span> to <b><span style="font-family: "Courier New",Courier,monospace;">SOURCES</span></b> variable for these files to get compiled.</li>
<li>Run x86 build environment (for Vista or later), type <b style="font-family: "Courier New",Courier,monospace;">build -cZ</b>, hit enter.</li>
<li>Reinstall the driver of our XPS sample printer.</li>
<li>Open any document and call print dialog. After selecting our sample XPS printer, click "Advanced" button and see the new tab with your brand new settings page :)</li>
</ol><u style="background-color: #666666; color: white;"><b>Sources</b></u><span style="background-color: #666666; color: white;">: </span><a href="https://docs.google.com/open?id=0B1dPIO-HAP4dMjdiNjAzMGQtNzNiOS00MmVlLWI3OTAtYjkyYTRhMjU4MmUy" style="background-color: #666666; color: white;" target="_blank">revctrls.h</a><span style="background-color: #666666; color: white;">, </span><a href="https://docs.google.com/open?id=0B1dPIO-HAP4dMWQ1MmZhMDQtYmViZC00OTA2LWEwM2UtNmRmMDUxMzhhNjFh" style="background-color: #666666; color: white;" target="_blank">revctrls.cpp</a><span style="background-color: #666666; color: white;">, </span><a href="https://docs.google.com/open?id=0B1dPIO-HAP4dMjJhYWVkMmYtMzY5Zi00ODY2LTg2YzQtZWM1ODcyNzM3OWY2" style="background-color: #666666; color: white;" target="_blank">revppg.h</a><span style="background-color: #666666; color: white;">, </span><a href="https://docs.google.com/open?id=0B1dPIO-HAP4dZDFlMWY0NDgtOGRkMC00ODljLWJjZmUtZTIzZmJhOTQ3MzBi" style="background-color: #666666; color: white;" target="_blank">revppg.cpp</a>kibitzerhttp://www.blogger.com/profile/09736938527680098828noreply@blogger.com0tag:blogger.com,1999:blog-1824330361476060651.post-10004784088881055262012-01-24T17:09:00.004+01:002012-01-26T15:19:23.012+01:002. Implementing custom simple XPS filterHi,<br />
<br />
<br />
in this article I will show you what to do if you want to create your own XPS print filter and use it in the existing XPSDrvSmpl pipeline. Thanks to the modular structure of pipeline it's quite easy to do so :)<br />
<br />
<i><b><u>Prerequisities</u></b></i> <br />
<i>This article assumes that:</i><br />
<ul><li><b><i>you are at least a bit familiar with XPS, its pipeline and the code used in XPSDrvSmpl from WDK</i></b></li>
<li><b><i>you have WDK installed and XPSDrvSmpl built (see my previous post <a href="http://kibitzercz.blogspot.com/2012/01/building-and-using-xpsdrvsmpl-under.html" target="_blank">"Building and using XPSDrvSmpl Under Windows XP"</a>)</i></b>)</li>
<li><i><b>you have Windows SDK Tools installed (or at least have the GUID Generator utility)</b></i></li>
</ul><br />
So, we are going to create a quite simple filter - its only purpose will be <b>reverting the order of pages</b> in document being printed. That means if you print a document (for example from MS Word) with 10 pages, this filter will make the order of the pages go descending (from 10 to 1). It will be used always (during every printing) as we will not provide any setting possibilities yet.<br />
<br />
We will use this filter (let's call it <b>Reverse</b>) as the first one in the pipeline, before any other changes are made to the document.<br />
Here are all the steps we need to take before we proceed to coding (of course we can code the filter first and then take all the other steps, but I believe the order presented here will be better for the article structure ;) )<br />
<br />
(Note: <i>throughout the steps I often use the term "<b>sample root</b>" - it denotes the directory in which you have the XPSDrvSmpl sample copied, e.g.</i> <span style="font-family: "Courier New",Courier,monospace;">c:\projects\xpssample</span> <i>or its original location in WDK directory or whatever else it is<span style="font-family: "Courier New",Courier,monospace;"></span></i>)<br />
<ol><li>Ok, let's move on the first step. Go to <span style="font-family: "Courier New",Courier,monospace;">[sample root]\src\filters</span> and create a new subfolder here, called <b>reverse</b>.<br />
</li>
<li>Go to Start menu and choose Programs - Windows SDK Tools and run <b>GUID Generator</b> utility. Generate new unique ID (it should read <b>{</b>8<b>-</b>4<b>-</b>4<b>-</b>4<b>-</b>12 hex chars<b>}</b>, for example <span style="font-family: "Courier New",Courier,monospace;">{AA356934-2EC6-43af-BF20-05F05D2448D6}</span>), copy it to clipboard and keep somewhere for later use.<br />
</li>
<li>You need to edit the XPS print pipeline itself and add the new (yet to come) filter at the first position (to revert pages before any other action is performed). <br />
Open <span style="font-family: "Courier New",Courier,monospace;">[sample root]\install\xdsmpl-PipelineConfig.xml</span> for edit. Move behind the <b style="font-family: "Courier New",Courier,monospace;">Filters</b> opening tag and paste the following code (explanation below):<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><Filter dll = "XDReverse.dll"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> clsid = "<your generated GUID from step 2>"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> name = "Reverse Filter"></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <Input guid = "{b8cf8530-5562-47c4-ab67-b1f69ecf961e}" comment="IID_IXpsDocumentProvider"/></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <Output guid = "{4368d8a2-4181-4a9f-b295-3d9a38bb9ba0}" comment="IID_IXpsDocumentConsumer"/></span><span style="font-family: "Courier New",Courier,monospace;"></Filter></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </span><br />
The value of <i>dll</i> attribute denotes the name of our (yet to come) filter dynamic library. The <i>clsid</i> attribute should contain your generated GUID exactly in the form which it has in your clipboard. The <i>name</i> can be whatever you want, but should be related to the function of the filter. <b>Please note that there is a <u>closing bracket</u> after the name value</b>.<br />
Since our filter is of XPS type (not the Stream one), it uses already existing XPS input and output providers with given GUIDs. If you look at the other filters in the pipeline, almost all of them (except the Scale filter, which uses Stream) use XPS interface and thus have the same input and output interfaces. Just copy and paste this items and don't worry about it ;)<br />
</li>
<li>Go to <span style="font-family: "Courier New",Courier,monospace;">[sample root]\install\</span> and open <b style="font-family: "Courier New",Courier,monospace;">xdsmpl.inf</b> for edit. <br />
<ol><li>Find the <b style="font-family: "Courier New",Courier,monospace;">[XPSDrvSample]</b> section and add the <b style="font-family: "Courier New",Courier,monospace;">xdreverse.dll</b> line to it.</li>
<li>Find the <b style="font-family: "Courier New",Courier,monospace;">[SourceDisksFiles]</b> section and add the <b><span style="font-family: "Courier New",Courier,monospace;">xdreverse.dll = 2</span></b> line to it.</li>
</ol>The former line tells the install script that we want to include our dll in the installation. The latter says where the installator should look for it.<br />
</li>
<li>Add two new empty files to <span style="font-family: "Courier New",Courier,monospace;">[sample root]\src\filters\reverse </span>directory (we will fill them later):</li>
<ol><li style="font-family: "Courier New",Courier,monospace;">reverse.h</li>
<li style="font-family: "Courier New",Courier,monospace;">reverse.cpp<br />
</li>
</ol><li>You need to add the <span style="font-family: "Courier New",Courier,monospace;">dllentry.cpp</span> file. But it will be almost the same as in the other filters, so go to some other filter directory (e.g. booklet) and copy the <span style="font-family: "Courier New",Courier,monospace;">dllentry.cpp</span> file from here to the <span style="font-family: "Courier New",Courier,monospace;">reverse</span> directory. Open it and make following edits:<br />
<ol><li>on the line <b>28</b> replace the <b style="font-family: "Courier New",Courier,monospace;">bkflt.h</b> include with<span style="font-family: "Courier New",Courier,monospace;"> </span><b style="font-family: "Courier New",Courier,monospace;">reverse.h</b> (for the new dll to know about our filter class)<br />
<span style="font-family: "Courier New",Courier,monospace;">#include "bkflt.h" ==> #include "reverse.h"</span></li>
<li>Move down to the end of the file and look for <b style="font-family: "Courier New",Courier,monospace;">DllGetClasObject</b> function. At the top of the function there are commented lines with the GUID of the Booklet filter. I recommend you to replace this GUID with your own (generated in step 2) to easily make following changes.</li>
<li>Rename the <span style="font-family: "Courier New",Courier,monospace;">bookletCLSID</span> variable (e.g. to <span style="font-family: "Courier New",Courier,monospace;">reverseCLSID</span>).</li>
<li>Now follow the way of transforming the GUID in this variable <u>exactly</u> and replace the hexadecimal values with your own. Provided your generated GUID is <span style="font-family: "Courier New",Courier,monospace;">{AA356934-2EC6-43af-BF20-05F05D2448D6}</span>, you should get something like this:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">CLSID reverseCLSID = {0xAA356934, 0x2EC6, 0x43af, {0xBF, 0x20, 0x05, 0xF0, 0x5D, 0x24, 0x48, 0xD6}};<br />
</span></li>
<li>On the <span style="font-family: "Courier New",Courier,monospace;">return</span> line change the parameter of <span style="font-family: "Courier New",Courier,monospace;">GetFilterClassFactory</span> from <b><span style="font-family: "Courier New",Courier,monospace;">CBookletFilter</span></b> to <b style="font-family: "Courier New",Courier,monospace;">CReverseFilter</b>. Then change the third parameter from <b style="font-family: "Courier New",Courier,monospace;">bookletCLSID</b> to <b style="font-family: "Courier New",Courier,monospace;">reverseCLSID</b>. Save the file and close it. Now the dll interface knows (by the changed GUID) which filter to handle when it gets called.</li>
</ol><br />
</li>
<li>Add <b><span style="font-family: "Courier New",Courier,monospace;">sources</span></b> file (no extension). It is similar to the way of obtaining <span style="font-family: "Courier New",Courier,monospace;">dllentry.cpp</span> in previous step. Just copy it from some other filter. Then open it and:</li>
<ol><li> edit the <b><span style="font-family: "Courier New",Courier,monospace;">SOURCES</span></b> variable to have only two files: <span style="font-family: "Courier New",Courier,monospace;">reverse.cpp</span> and <span style="font-family: "Courier New",Courier,monospace;">dllentry.cpp</span> (these files will be compiled when build is run). So it should read<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">SOURCES=$(SOURCES) \</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> dllentry.cpp \</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> reverse.cpp \</span><br />
<br />
<b>Bear the backslashes in mind! Keep an empty line after <span style="font-family: "Courier New",Courier,monospace;">reverse.cpp</span>.<br />
</b></li>
<li>edit the <b><span style="font-family: "Courier New",Courier,monospace;">TARGETNAME</span></b> variable value to <span style="font-family: "Courier New",Courier,monospace;">xdreverse</span> (or whatever name you wish the created dll should have. But <b>keep in mind that the same name must be listed in the filter pipeline</b> file!). Save the file and close it.<br />
</li>
</ol><li>Copy the <b><span style="font-family: "Courier New",Courier,monospace;">makefile</span></b> and <b><span style="font-family: "Courier New",Courier,monospace;">makefile.inc</span></b> files from other filter without any other changes made.<br />
</li>
<li>Copy <span style="font-family: "Courier New",Courier,monospace;">xdbook.inc</span> from the <span style="font-family: "Courier New",Courier,monospace;">booklet</span> filter directory, rename it to <b style="font-family: "Courier New",Courier,monospace;">xdreverse.inc</b>, open it and change the value of <b><span style="font-family: "Courier New",Courier,monospace;">LIBRARY</span></b> parameter from <span style="font-family: "Courier New",Courier,monospace;">xdbook.inc</span> to <b style="font-family: "Courier New",Courier,monospace;">xdreverse.inc</b><br />
</li>
<li>You are now ready to write the reverse-filter source code and build the driver. The source code is available through my Google Documents storage. It is short and clear as it contains only the class definition and two overriden functions and will probably be discussed later in the future.<br />
<b style="background-color: #444444; color: white;">Source code:</b><span style="background-color: #444444; color: white;"> </span><a href="https://docs.google.com/open?id=0B1dPIO-HAP4dMTljYWRlNDItMDAzYS00MTU5LTg0OTUtMzUyOWQ5MTcxYzMy" style="background-color: #444444; color: white;" target="_blank">reverse.h</a><span style="background-color: #444444; color: white;">, </span><a href="https://docs.google.com/open?id=0B1dPIO-HAP4dZGI1YmE3M2EtNzI1Mi00ZTgyLWEyNmEtNzQ5ZTg0YmY4ZTRh" style="background-color: #444444; color: white;" target="_blank">reverse.cpp</a></li>
<li>Run <b>x86 checked build</b> utility from Start - Programs - Windows Driver Kits - WDK [version] - Windows Vista and Windows Server 2008 (or higher). After the console comes up, use <span style="font-family: "Courier New",Courier,monospace;">cd</span> command to move to your <span style="font-family: "Courier New",Courier,monospace;">[sample root]</span> directory, write <span style="font-family: "Courier New",Courier,monospace;">build -cZ</span> and hit Enter.<br />
</li>
<li>Hurray! Your driver is built and ready to use. Now install (or reinstall) the driver following the steps in Part 1 of this tutorial:)<br />
</li>
</ol>kibitzerhttp://www.blogger.com/profile/09736938527680098828noreply@blogger.com11tag:blogger.com,1999:blog-1824330361476060651.post-59825217710304890152012-01-24T14:49:00.002+01:002012-01-26T14:07:19.508+01:001. Building and using XPSDrvSmpl under Windows XPMicrosoft Windows Driver Developer Kit (DDK/WDK) comes with a sample of XPS print driver. This post will tell you what to do to build it and use it under WinXP.<br />
<br />
(<b><i>XPS print path isn't supported in standard Windows XP, you need to have either SP3 with .Net3.0, <a href="http://www.microsoft.com/download/en/details.aspx?id=11816" target="_blank">MS XPS Essentials Pack</a> or <a href="http://support.microsoft.com/kb/954550/en-us?fr=1" target="_blank">this MS hotfix</a></i></b> <b><i>installed in order to use it. We will assume that you have this done</i></b>)<br />
<br />
Having WDK <a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=11800" target="_blank">downloaded (for free)</a> and installed, you should find this sample at <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">[WDK root]\[WDK version]\src\print\XPSDrvSmpl</span></span> folder (e.g. <span style="font-family: "Courier New",Courier,monospace; font-size: small;">c:\WinDDK\7600.16385.1\src\print\XPSDrvSmpl</span>). Further you should see some records in your Start menu under <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">Programs/Windows Driver Kits</span></span>. This folder and its content is important, as it provides <b>building environments</b> for various MS operating systems (<b>XPSDrvSmpl must be built using at least Vista build environment</b>, as it is not supported in XP and trying to build the sample using XP build environment will result in lot of errors and no output libraries).<br />
<br />
<u>So let's start:</u><br />
<ol><li><u></u>Go to Start - Programs - Windows Driver Kits - WDK [version number] - Build environments and choose <b>Windows Vistaand Windows Server 2008 - x86 checked environment</b> (the checked environment should provide more information at output when errors occur; it's something like Debug/Release configuration in MSVC). A <b>console</b> should start.</li>
<li>If you have copied the XPS sample to a custom directory, use<span style="font-size: small;"><b> <span style="font-family: "Courier New",Courier,monospace;">cd</span></b></span> command to go there (e.g. <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">cd c:\projects\xpsdrvsmpl</span></span>). From now on I will call this directory a <i>sample root.</i></li>
<li>Type <span style="font-size: small;"><b><span style="font-family: "Courier New",Courier,monospace;">build -cZ</span></b></span> and hit Enter. After few moments the build should end successfully (without any error and warning) telling you the count of files compiled and libraries and executables built. Now your new <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">dll</span></span> output files are located in <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">[sample root]\</span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">install\</span><span style="font-family: "Courier New",Courier,monospace;">x86</span></span> directory.</li>
<li>We can now proceed to new XPS printer installation.<br />
Go to Start - Control Panel - Add new printer. Then choose Local printer and Create new port. Select Local Port in combo box. The dialog asking for a port name will appear. For our XPS driver to print to specified file without asking a user for a location, write in full path for this output file. This file need not to exist at the moment (something like <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">c:\mydriveroutput.xps</span></span> for example).</li>
<li>Now when you see the list of vendors and devices, click the "From disk" button. Then select <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">[sample root]\install\xdsmpl.inf</span> </span>and click Next. This will load the printer installing instructions. </li>
<li>As you go on, the wizard can ask you for some files it cannot find. But this should be no big trouble if you have SP3 or XPS Extension Pack installed. <br />
If the wizard asks you for <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">xdsmpl.gpd</span></span>, click Browse and find this file in <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">[sample root]\install\x86</span></span>.<br />
If it asks for <span style="font-family: "Courier New",Courier,monospace; font-size: small;">xdwmark.dll</span>, navigate to <span style="font-family: "Courier New",Courier,monospace; font-size: small;">[sample root]\install\x86</span> as well.<br />
For <span style="font-family: "Courier New",Courier,monospace; font-size: small;">msxpsinc.gpd</span> go to <span style="font-family: "Courier New",Courier,monospace; font-size: small;">c:\windows\Driver cache\i386</span>.<br />
The <span style="font-family: "Courier New",Courier,monospace; font-size: small;">xpssvcs.dll</span> file should be found in <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">c:\windows\system32</span></span>.</li>
<li>And that's it. The printer driver should now be installed and ready to use. Now go to any of your favourite application and under File - Print menu choose XPSDrv Sample Driver. The output XPS file is the one you provided aas the port name at the beginning of printer installation (e.g. <span style="font-family: "Courier New",Courier,monospace; font-size: small;">c:\mydriveroutput.xps</span>)</li>
</ol>kibitzerhttp://www.blogger.com/profile/09736938527680098828noreply@blogger.com6