This is a mirror of official site: http://jasper-net.blogspot.com/

Supporting 32-Bit I/O in Your 64-Bit Driver

| Thursday, February 23, 2012
Windows on Windows (WOW64) enables Microsoft Win32 user-mode applications to run on 64-bit Windows. It does this by intercepting Win32 function calls and converting parameters from pointer-precision types to fixed-precision types as appropriate before making the transition to the 64-bit kernel. This conversion, which is called thunking, is done automatically for all Win32 functions, with one important exception: the data buffers passed to DeviceIoControl. The contents of these buffers, which are pointed to by the InputBuffer and OutputBuffer parameters, are not thunked, because their structure is driver-specific.

Note   Although the buffer contents are not thunked, the buffer pointers are converted into 64-bit pointers.

User-mode applications call DeviceIoControl to send an I/O request directly to a specified kernel-mode driver. This request contains an I/O control code (IOCTL) or file system control code (FSCTL) and pointers to input and output data buffers. The format of these data buffers is specific to the IOCTL or FSCTL, which in turn is defined by the kernel-mode driver. Because the buffer format is arbitrary, and because it is known to the driver and not WOW64, the task of thunking the data is left to the driver.

Your 64-bit driver must support 32-bit I/O if all of the following are true:

    The driver exposes an IOCTL (or FSCTL) to user-mode applications.

    At least one of the I/O buffers used by the IOCTL contains pointer-precision data types.

    Your IOCTL code cannot easily be rewritten to eliminate the use of pointer-precision buffer data types.


Read more: MSDN
QR: Inline image 1

Posted via email from Jasper-net

Не стоит паниковать по поводу слабых RSA ключей — просто заботьтесь о своих P и Q

|
Вы возможно уже видели препринт опубликованный сегодня Ленстрой и др (обсуждение на хабре) о проблемах с энтропией в криптографических системах с открытыми ключами. Закир Дурумерик, Ерик Вустров, Алекс Халдерман, и Я (Надя Хенингер) ждали, чтобы раскрыть похожие результаты. Мы опубликуем полную статью после того, как все задействованные производители будут оповещены. А между тем мы хотим предоставить более полное объяснение того, что же реально происходит.

Мы смогли удалено скомпрометировать около 0.4 % от всех открытых ключей, используемых веб сайтами для SSL. Все скомпрометированные ключи были неправильно сгенерированы, с использованием предсказуемых «рандомных» чисел, которые к тому же ещё и иногда повторялись. Всего мы можем выделить два типа проблем: ключи, сгенерированные с предсказуемой рандомностью, и подмножество этих ключей, для которых нехватка рандомности позволяет атакующему быстро факторизовать открытый ключ и получить секретный ключ. Имея секретный ключ, атакующий сможет выдать себя за вебсайт и возможно сможет расшифровывать зашифрованный трафик направленый на этот сайт. Мы разработали программу которая за пару часов может факторизовать открытые ключи и выдавать секретные ключи для всех хостов уязвимых к этой атаке.

Тем не менее, не стоит паниковать, так как в основном проблема влияет на встраиваемые системы, такие как маршрутизаторы и VPN, и не касается полномасштабных серверов. (Во всяком случае это точно не причина терять доверенность к электронной коммерции, как это предполагает New York Times). К сожалению, мы нашли устройства с этой проблемой практически у каждого производителя и мы подозреваем, что около 200.000 устройств, представляющих 4.1% от всех ключей в наших данных, использовали плохую энтропию для генерации ключей. Любой найденный слабый ключ сгенерированный устройством предполагает, что весь класс этих устройств уязвим для атаки при должном анализе.

Мы не будем предоставлять полный список уязвимых устройств до того как мы свяжемся со всеми производителями, но используя уже опубликованные материалы можно довольно легко воспроизвести атаку. Поэтому мы сейчас работаем над веб сайтом, который позволит определить уязвимо ли ваше устройство.

Не волнуйтесь, ключ вашего банка скорее всего в безопасности.

SSL используется каждым большим сайтом в Интернете, но как показывает наш анализ, эти ключи не подвержены проблемам описанным в этом посте.

Read more: Habrahabr.ru
QR: Inline image 1

Posted via email from Jasper-net

Execute GIMP filters in C#

|
First of all you need to install GIMP. After that, set the path variable (C:\Program Files\GIMP-2.0\bin). Now write a GIMP script and save it with the .scm extention in the C:\Users\[username]\.gimp-2.6\scripts folder. You can write various GIMP scripts. You get details about GIMP filters from the pluginrc file in your home floder(C:\Users\dhanu-sdu\.gimp-2.6).

GIMP script for Unsharpmask filter

(define (simple-unsharp-mask filename
                             radius
                             amount
                             threshold)
   (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
          (drawable (car (gimp-image-get-active-layer image))))
     (plug-in-unsharp-mask RUN-NONINTERACTIVE
                       image drawable radius amount threshold)
     (set! drawable (car (gimp-image-get-active-layer image)))
     (gimp-file-save RUN-NONINTERACTIVE image drawable filename filename)
     (gimp-image-delete image)))

Now in the C# application, construct the command and execute in the command line:

private void unsharpMaskButton_Click(object sender, EventArgs e)
{
    try
    {
        if (!string.IsNullOrEmpty(choosenFile))
        {
            int radius = radiusTrackBar.Value;
            int amount = amountTrackBar.Value;
            int threshold = ThresholdTrackBar.Value;
            string path = choosenFile.Replace(@"\", @"\\");
            //creating the command
            string a = @"gimp-2.6.exe -i -b ""(simple-unsharp-mask \""" +
                   path + @"\"" " + radius + " " + amount + " " + threshold +
                   @")"" -b ""(gimp-quit 0)""";
            //execute gimp filter in command line
            string result = ExecuteCommandSync(a);
            //sets the new image as the pictureBox image
            Bitmap newImage = (Bitmap)Image.FromFile(choosenFile);
            pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
            pictureBox1.Image = new Bitmap(newImage);
            newImage.Dispose();
            newImage = null;
        }
        else
        {
            MessageBox.Show("please select a image");
        }
    }
    catch (Exception a)
    {
        MessageBox.Show(a.ToString());
    }
}

Read more: Codeproject
QR: Inline image 1

Posted via email from Jasper-net

Практическое применение DNSSEC

|
В статье описываются недостатки существующей структуры DNS, полный процесс внедрения DNSSEC на примере доменов .com и .org, процедура создания валидного самоподписанного SSL-сертификата подписанного с помощью DNSSEC.

Чем плох DNS


Система DNS в нынешнем виде была разработана более 20 лет назад, когда о защите информации не особенно задумывались. Она имеет несколько фундаментальных уязвимостей.

Достоверность ответа DNS-сервера никак не проверяется. Это позволяет отправить пользователя, обратившегося к доменному имени, на произвольный IP-адрес, подменив ответ сервера. На практике подобная атака может выглядеть так.

Также уязвимы кеширующие DNS-серверы провайдеров, выступающие как резолверы для клиентов: Атака Каминского.

Сегодня существуют технологии, предусматривающие хранение открытых ключей в DNS-записях, например, DKIM-подписи в электронной почте, SSH-ключей в записях SSHFP и т.д. Все эти технологии требуют защиты от подделки DNS.

Теория DNSSEC


DNSSEC — технология, позволяющая однозначно удостовериться в подлинности DNS информации при помощи криптографической подписи.

Популярно о DNSSEC можно прочитать здесь: dxdt.ru/2009/03/04/2163/

Более подробно здесь: habrahabr.ru/blogs/sysadm/120620/

И на сайте Verisign.com

Перед продолжением настоятельно рекомендуется внимательно прочитать вышеприведенные ссылки, так как на первый взгляд процедура подписания зоны кажется довольно запутанной.


Максимально упрощенно это выглядит примерно так: есть корневая зона ".", которая содержит в себе информацию о всех доменах первого уровня. Условно говоря, это текстовый файл с некоторым множеством строк, который изменяется не очень часто. Создается пара открытый/закрытый ключ и каждая строка в этом файле подписывается (по типу «clear sign» в PGP/GPG, которая используется в электронной почте для открытого подписания текста и начинается с «BEGIN PGP SIGNATURE»).
Теперь, имея открытый ключ от этой пары, можно удостовериться в подлинности каждой записи в этом списке. Например, проверить, что за зону «ru.» действительно отвечают серверы ripn.net:

dig -t any +dnssec @k.root-servers.net ru.


Read more: Habrahabr.ru
QR: Inline image 1

Posted via email from Jasper-net

VisualDDK - develop/debug drivers directly from VS

| Tuesday, February 21, 2012
Inline image 2

Overview

Welcome to the VisualDDK homepage. This project brings the simplicity and convenience of Windows application development to the driver development world. No more manual creation of build scripts, copying of driver files, installing drivers from INFs, switching between WinDbg and the source editor or waiting for seconds after each step due to the extra-slow virtual COM port. Just create a driver project using a convenient Driver Wizard, select a virtual machine, and enjoy debugging your driver directly from Visual Studio. Want to test a change? Just normally press Shift-F5, modify your driver, rebuild it and launch again. VisualDDK will unload the old driver, install the new one and load it automatically and quickly. Bored with WinDbg loading symbol files for minutes and looking up symbols for seconds? Just let VisualDDK optimize this for you using its own DIA-based symbol engine. Using C++/STLPort in your drivers? VisualDDK will natively visualize all STL containers and strings, as good as Visual Studio does for user-mode applications.

Note that Visual Studio by default queries lots of values from debuggee after each break/step (such as Autos, all locals, call stack, etc.). If you are planning to use VisualDDK with VMWare or VirtualBox, use the VirtualKD project (installed with VisualDDK), that replaces Virtual COM Port for VMWare and VirtualBox machines by a native KD interface, speeding up debugging ~18x for VMWare and ~48x for VirtualBox. Nevertheless, see the debugging speedup guide for more details.

Read more: VisualDDK
QR: Inline image 1

Posted via email from Jasper-net

Skypekit.NET

| Monday, February 20, 2012
Introduction

Some developers today tend to use Skypekit in their applications to make it more interactive with the user. Skype API is very awesome indeed but the problem is it is only available in C++, Java and Python. I can't understand why Microsoft didn't develop API for .NET so we can develop it in C# or VB.NET.

I'm one of those, I needed to embed Skype into my graduation project and after I paid the 5$ fees and downloaded the SDK and Runtime I was surprised when I found that there is no support for the .NET languages.

So, the only way I found is to convert C++ methods into a COM component then I can call it in C# using DLLImport. And I spent weeks trying to do this solution but all in vain.

A punch of errors came to my face when I tried to create a new C++ project away from their pre-made tutorials. I was very sad with this result.

I tried to do it in Python but for some reason the socket couldn't make the connection to Skype.

Then I found the magic tool IKVM.


Background

IKVM is a tool that is used to convert Java Applications to .NET Executables (.exe) and Assemblies (.dll).

I used it to convert the Skype Class in their ready-made Java Classes into a .NET 'skypekit' class

Then I manually converted all the Java utilities Code to their corresponding C# code including:

    AppKeyPairMgr Class
    Listeners Class
    MySession Class
    ParseSkypeKitVersion Class
    PrintStream Class
    SignInMgr Class
    XmlStrMgr Class

Read more: Codeproject
QR: Inline image 1

Posted via email from Jasper-net

How to release an unmanaged library loaded into managed .NET code

|
Motivation

I had found this article on how to release a DLL library already loaded into a process using P-Invoke. It uses the LoadLibrary() and FreeLibrary() WinAPI calls to achieve this.

And what is wrong with it?

It forces to unload all instances of the DLL library currently loaded within the process. Which means, that in the case you have more than one instance of the class using these external functions, all these will stop working!

And that is not all - you cannot use this DLL in the same application domain again after unloading.


Solution

The solution is a pretty simple one, but I have to say that it wasn't very obvious to me at the beginning. You can use P-Invoke to import the following standard WinAPI functions for dynamical function loading:

    LoadLibrary()
    FreeLibrary()
    GetProcAddress()

We will use the following wrapping class:

internal static class UnsafeMethods
{
    [DllImport("kernel32.dll", SetLastError = true)]
    internal extern static IntPtr LoadLibrary(string libraryName);
    [DllImport("kernel32.dll", SetLastError = true)]
    internal extern static bool FreeLibrary(IntPtr hModule);
    [DllImport("kernel32.dll", SetLastError = true)]
    internal extern static IntPtr GetProcAddress(IntPtr hModule, string procName);
}

We also need signatures of the imported functions - we will convert them into delegates (the following ones come from the sample project):


// int multiply(int value1, int value2);
private delegate int MultiplyDelegate(int value1, int value2);
// int str2int(const char *input);
private delegate int Str2IntDelegate([MarshalAs(UnmanagedType.LPStr)]string source);


Read more: Codeproject
QR: Inline image 1

Posted via email from Jasper-net

Design pattern FAQ Part 1 (Training)

|

Design Pattern FAQ

What are design patterns?
Can you explain factory pattern?
Can you explain abstract factory pattern?
Can you explain builder pattern?
Can you explain prototype pattern?
Can you explain shallow copy and deep copy in prototype patterns?
Can you explain singleton pattern?
Can you explain command patterns?


Introduction

Here's a small quick FAQ on design patterns in Q and A format. In this section we will cover factory , abstract factory , builder , prototype , shallow and deep prototype , singleton and command patterns.

You can read my other design pattern FAQ sections of the same in the below links :-

Part 2 Design Pattern FAQ's -- Interpreter pattern, iterator pattern, mediator pattern, memento pattern and observer pattern

Part 3 Design Pattern FAQ's -- state pattern, strategy pattern, visitor pattern, adapter pattern and fly weight pattern

Part 4 Design Pattern FAQ's -- bridge pattern, composite pattern, decorator pattern, Façade pattern, chain of responsibility(COR), proxy pattern and template pattern
What are design patterns?

Design patterns are documented tried and tested solutions for recurring problems in a given context. So basically you have a problem context and the proposed solution for the same. Design patterns existed in some or other form right from the inception stage of software development. Let’s say if you want to implement a sorting algorithm the first thing comes to mind is bubble sort. So the problem is sorting and solution is bubble sort. Same holds true for design patterns.
Which are the three main categories of design patterns?

There are three basic classifications of patterns Creational, Structural, and Behavioral patterns.

Creational Patterns

• Abstract Factory:- Creates an instance of several families of classes
• Builder: - Separates object construction from its representation
• Factory Method:- Creates an instance of several derived classes
• Prototype:- A fully initialized instance to be copied or cloned
• Singleton:- A class in which only a single instance can exist

Note: - The best way to remember Creational pattern is by remembering ABFPS (Abraham Became First President of States).
Structural Patterns

• Adapter:-Match interfaces of different classes .
• Bridge:-Separates an object’s abstraction from its implementation.
• Composite:-A tree structure of simple and composite objects.
• Decorator:-Add responsibilities to objects dynamically.
• Façade:-A single class that represents an entire subsystem.
• Flyweight:-A fine-grained instance used for efficient sharing.
• Proxy:-An object representing another object.

• Mediator:-Defines simplified communication between classes.
• Memento:-Capture and restore an object's internal state.
• Interpreter:- A way to include language elements in a program.
• Iterator:-Sequentially access the elements of a collection.
• Chain of Resp: - A way of passing a request between a chain of objects.
• Command:-Encapsulate a command request as an object.
• State:-Alter an object's behavior when its state changes.
• Strategy:-Encapsulates an algorithm inside a class.
• Observer: - A way of notifying change to a number of classes.
• Template Method:-Defer the exact steps of an algorithm to a subclass.
• Visitor:-Defines a new operation to a class without change.

Read more: Codeproject
QR: Inline image 1

Posted via email from Jasper-net

NHibernate's mapping-by-code - the summary

|
   Six weeks ago, when I started my experiments with NHibernate's 3.2 new mapping feature - mapping-by-code, I was a loyal Fluent NHibernate user and a fan of method chains in APIs. My first impression about mapping-by-code was that it seems to be a good direction, but it's still immature and - what's important - not documented at all. I decided to have a deeper look and it turned into a tvelwe-part series exploring all the possible mappings - probably the only complete guide to mapping-by-code on the web so far. Time to sum the series up.

Let's start with what mapping-by-code is. It is an XML-less mapping solution being an integral part of NHibernate since 3.2, based on ConfORM library. Its API tries to conform to XML naming and structure. There's a strong convention in how the mapping methods are built. Its names are almost always equal to XML elements names. The first parameter points to the mapped property, second is for its options corresponding XML attributes (and XML <key> element, if applicable) and the rest of parameters, if any, corresponds to nested XML elements. It's very convenient for those familiar with XML schema or for documentation readers.

Read more: NOtherDev
QR: Inline image 1

Posted via email from Jasper-net

Carousel Effect in Silverlight

| Sunday, February 19, 2012
Inline image 3

Introduction

This article explains how to code the carousel animation effect in Silverlight. This animation has been the forte of tools like flash and dojo for a very long time, but with the entry of Microsoft Silverlight, it no longer remains a mystery. This article digs deep into the intricacies of the geometry involved in coding such a effect.

Background

The reader must be reasonably familiar with programming in Silverlight and basic 3-dimensinal geometry and a bit about Storyboards.


Using the Code

The application consists of a main page with a revolving carousel of thumbnails. When the user passes the mouse over any of the revolving thumbnails, the animation stops and sets the current thumb nail as the background of the application. There are sliders provided that can speed up or slow down the revolving of the thumb nails, change the axis of revolution and bring the revolving thumb nails closer or farther from the viewer. The right side of the application has one thumb nail that helps in understanding the effect in depth.

A Bit of 3 Dimensional Geometry

Inline image 2

Read more: Codeproject
QR: Inline image 1

Posted via email from Jasper-net

Prism 4.1 - February 2012

|
Prism provides guidance designed to help you more easily design and build rich, flexible, and easy to maintain Windows Presentation Foundation (WPF) desktop applications and Silverlight Rich Internet Applications (RIAs) and Windows Phone 7.1 ("Mango") applications.

Read more: MS Download
QR: Inline image 1

Posted via email from Jasper-net

How do I find out which process has a file open?

|
Classically, there was no way to find out which process has a file open. A file object has a reference count, and when the reference count drops to zero, the file is closed. But there's nobody keeping track of which processes own how many references. (And that's ignoring the case that the reference is not coming from a process in the first place; maybe it's coming from a kernel driver, or maybe it came from a process that no longer exists but whose reference is being kept alive by a kernel driver that captured the object reference.)

This falls into the category of not keeping track of information you don't need. The file system doesn't care who has the reference to the file object. Its job is to close the file when the last reference goes away.

You do the same thing with your COM object reference counts. All you care about is whether your reference count has reached zero (at which point it's time to destroy the object). If you later discover an object leak in your process, you don't have a magic query "Show me all the people who called AddRef on my object" because you never kept track of all the people who called AddRef on your object. Or even, "Here's an object I want to destroy. Show me all the people who called AddRef on it so I can destroy them and get them to call Release."

At least that was the story under the classical model.

Enter the Restart Manager.

The official goal of the Restart Manager is to help make it possible to shut down and restart applications which are using a file you want to update. In order to do that, it needs to keep track of which processes are holding references to which files. And it's that database that is of use here. (Why is the kernel keeping track of which processes have a file open? Because it's the converse of the principle of not keeping track of information you don't need: Now it needs the information!)

Here's a simple program which takes a file name on the command line and shows which processes have the file open.

#include <windows.h>
#include <RestartManager.h>
#include <stdio.h>

int __cdecl wmain(int argc, WCHAR **argv)
{
 DWORD dwSession;
 WCHAR szSessionKey[CCH_RM_SESSION_KEY+1] = { 0 };
 DWORD dwError = RmStartSession(&dwSession, 0, szSessionKey);
 wprintf(L"RmStartSession returned %d\n", dwError);
 if (dwError == ERROR_SUCCESS) {
   PCWSTR pszFile = argv[1];
   dwError = RmRegisterResources(dwSession, 1, &pszFile,
                                 0, NULL, 0, NULL);
   wprintf(L"RmRegisterResources(%ls) returned %d\n",
           pszFile, dwError);
  if (dwError == ERROR_SUCCESS) {
   DWORD dwReason;
   UINT i;
   UINT nProcInfoNeeded;
   UINT nProcInfo = 10;
   RM_PROCESS_INFO rgpi[10];
   dwError = RmGetList(dwSession, &nProcInfoNeeded,
                       &nProcInfo, rgpi, &dwReason);
   wprintf(L"RmGetList returned %d\n", dwError);
...
...

Read more: The old new thing
QR: Inline image 1

Posted via email from Jasper-net

11 Alternatives to Microsoft Sharepoint

|
I have just started to get my hands on a huge gigantic software (another one) from Microsoft called the Microsoft Sharepoint, and since I am more of a open-source kind of a guy I am not very comfortable with it for now… will be soon :) .
It’s a massive collaborative software package which is associated with content management and document management systems. But those are just a part of it , it’s actually a big collection of more capabilities and services like for web technologies, intranet portals, extranets, websites, document & file management, collaboration spaces, social tools, enterprise search, business intelligence, process integration, system integration, workflow automation and core infrastructure for third-party solutions.

So I just had a small idea for the fact that it also costs a lot and it takes a lot of time for a person like me to get used to a Microsoft product if he/she is not used to it … so I started to look for (just in case) other alternatives for Sharepoint which a smaller company may use or understand better. So I decided to make a list of it and post it in my blog :) so maybe it can help out a few other people like me

1. Alfresco
2. O3Spaces


Read more: Arunace
QR: Inline image 1

Posted via email from Jasper-net

Client Certificates V/s Server Certificates

|
Inline image 1

In the past I have blogged about various certificate file extensions along with their usage. Here is the link: http://blogs.msdn.com/b/kaushal/archive/2010/11/05/ssl-certificates.aspx

I use blogs as reference so that they can refer the content and I need not repeat the same thing every time. Saves time and helps others too.

This time I though of writing another blog explaining the difference between Client Certificates and Server Certificates. Something which is not clearly understood by everyone. I will be discussing this strictly in context of IIS only. (There are several types of certificates. you will come to know later Smile)

One of my colleagues, David Dietz has already published a KB article relating to this:

IIS and client certificates: http://support.microsoft.com/kb/907274

The above documentation is good enough to understand the difference between client and server certificates along with error messages associated with them.

Lets start off in an Layman’s language and then I’ll discuss it in complete depth.

    How are Client and Server Certificates different?

Server Certificates: Server Certificates are used to identify a server. Typically they are issued to hostnames, which could be a machine name (like “PIIS-SVR01”) or a host-header (like “www.Microsoft.com”). Both client and server certificates have the “Issued to” section. For a server certificate the “Issued to” section’s value would specify the hostname for which it has been issued.

Read more: Be Nimble, Be Quick and Blog
QR: Inline image 2

Posted via email from Jasper-net

Implementing Google Account Authentication in an ASP.NET application

|
Few years back I blogged about adding OpenID login support in ASP.NET application. This time I am blogging about adding Google login support in ASP.NET application. A friend of mine is trying to integrate multiple third party authentication support for one of the application he is developing for his client. He is using DotNetOpenAuth for Google authentication. the code I am using here is from my friend and I am sharing it with his explicit permission.

First, download the latest version of DotNetOpenAuth and add its reference in your web application and these two namespaces.

using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.RelyingParty;

After adding the reference, add a normal button with CommandArgument to point https://www.google.com/accounts/o8/id.

<asp:Button ID="btnGoogleLogin" runat="server" CommandArgument="https://www.google.com/accounts/o8/id"
        OnCommand="btnGoogleLogin_Click" Text="Sign In with Google" />

On the button click event on the server side:

protected void btnGoogleLogin_Click(object sender, CommandEventArgs e)
{
    string discoveryUri = e.CommandArgument.ToString();
    OpenIdRelyingParty openid = new OpenIdRelyingParty();
    var URIbuilder = new UriBuilder(Request.Url) { Query = "" };
    var req = openid.CreateRequest(discoveryUri, URIbuilder.Uri, URIbuilder.Uri);
    req.RedirectToProvider();
}

Read more: DZone
QR: Inline image 1

Posted via email from Jasper-net

Visual Studio 2010 SDK Samples - One 30MB download, 68 samples, tons of learning...

|
Visual Studio 2010 is an integrated development environment (IDE) that allows you to develop a wide variety of software applications quickly and easily. The Visual Studio SDK provides a framework that you can use to extend the functionality of Visual

...

Visual Studio 2010 is an integrated development environment (IDE) that allows you to develop a wide variety of software applications quickly and easily. The Visual Studio SDK provides a framework that you can use to extend the functionality of Visual Studio 2010.

Read more: Greg's Cool [Insert Clever Name] of the Day
Read more: Visual Studio 2010 SDK Samples
QR: Inline image 1

Posted via email from Jasper-net