Un peu de mon expérience dans le monde .NET
# Monday, August 27, 2007
Changer le WindowsIdentity en cours d’exécution (impersonalisation)…

 Par défaut, le WindowsIdentity (system.security.principal) est celui de l’utilisateur logué, et est récupérable en utilisant l’instruction suivante :

WindowsIdentity.GetCurrent()

 

Dans le cadre d’un projet, j’avais besoin que mon code s’execute temporairement sous une autre identité que celle de l’utilisateur executant l’application. Après quelques recherche, voici les trois étapes a effectuer :

 

1 - Se loguer avec le nouveau compte

 

Pour se faire, on va utiliser l’API advapi32, dont voici la signature :

[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool LogonUser(
    string lpszUsername,
    string lpszDomain,
    string lpszPassword,
    int dwLogonType,
    int dwLogonProvider,
    out IntPtr phToken
    );

 

Le code suivant retourne vrai si le login à réussi. Il retourne surtout le handler du token lié à ce login, que nous utiliserons plus tard.

LogonUser(

« nom d’utilisateur »,

« domaine »,

« mot de passe »,

2,

0,

ref TokenHandler)

 

2 – Dupliquer le token

 

A nouveau, il faut utiliser l’API advapi32 :

[DllImport("advapi32.dll", SetLastError=true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int
   SECURITY_IMPERSONATION_LEVEL, out IntPtr DuplicateTokenHandle);

 

Le code suivant retourne vrai si la duplication à réussie. Il retourne aussi le token utiliser plus tard afin de créer un nouveau WindowsIdentity.

DuplicateToken(

TokenHandler,

2,

ref pDuplicateTokenHandle);

 

 

3 – Créer un nouveau WindowsIdentity

 

Opération qui est un jeu d’enfant, via le code suitant :

 

WindowsIdentity newId = new WindowsIdentity(pDuplicateTokenHandle);

WindowsImpersonationContext impersonatedUser = newId.Impersonate();

 

 

Dorénavant, WindowsIdentity.GetCurrent() retoune le nouveau WindowsIdentity et le code s’execute avec les droits de celui-ci. Pour revenir à l’état avant impersonalisation, il suffit d’utiliser la méthode Undo de WindowsImpersonationContext


Monday, August 27, 2007 3:09:47 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  Securité

# Wednesday, August 15, 2007
SQL Tips

Comment reconstruire tous les indexes d'une base de données :
EXEC sp_MSforeachtable @command1="print '?' DBCC DBREINDEX ('?', ' ', 80)"


Wednesday, August 15, 2007 7:25:39 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  Main

# Friday, August 10, 2007
Windows Mobile en mode Kiosk

Voici l'article que j'ai publié sous www.codeproject.com, résultat de mon expérience suite au développement d'un POC ...

Introduction

Windows Mobile is a great production device. But by default, the device give access to all functionalities (e-mail, contacts ...) and in particular context, you will probably be interested to restrict end-user access to some of these functionalities.

You'll have two options:

  • Integrate in the standard Sheel
  • Customize the system in kiosk mode

    I'll focus on the second option. In order to set the system in kiosk mode, we'll have to:

  • Write an application with a screen which will work like the 'Today' screen
  • Control the hardware button to restrict access to Windows Mobile functionalities
  • Of course, have the application launch at startup
  • This is a non exhaustive list...

    Background

    I will not focus on Compact Framework development and OS low level library interaction. But keep in mind the .Net Compact Framework Artchitecture:

  • Framework
  • Common Language Runtime
  • Windows CE

    You will then understand why we reference microsoft.windowsce.forms for low level functionality

    I also use OpenNETCF www.openNETCF.com for reading/writing registry. Library is fully explained on their web-site.

    Using the code

    Our first task is to create a new Smart Device project from Visual Studio. As mentioned in the introduction, we'll set properties of the default Form Form1.cs in order to create a 'Today' like screen. You can do it using the properties windows or by code :

    public frmKiosk()
    {
        InitializeComponent();
    
        ControlBox = false;
        FormBorderStyle = FormBorderStyle.None;
        MaximizeBox = false;
        MinimizeBox = false;
        WindowState = FormWindowState.Maximized;
    }
    

    Now, we'll have to control hardware button. This is done using the Microsoft.WindowsCE.Form.MessageWindows. This class will allow us to intercept Windows Messages and decide how to handle them (internal routine, raising events to be handled by other class, or ... do nothing). This will allow us to intercept messages send by hardware button and simply decide to not react to them!

    The logic is quite simple:

  • Create a class which will inherit from MessageWindows. Override the WndProc method to catch windows message and implement our own business logic. We will intercept only HOTKEY message, but the same code could be use to handle all windows message type (full list here: http:\\www.pinvoke.net)
  • Unregister the hardware button : by default, message raised by hardware button are handled by the default process
  • Register the hardware button : message raised by hardware button will be handled by our custom MessageWindows

    The code of our custom MessageWindows will be like this:

    public class internalMessageWindow : MessageWindow
    {
            // Which message type ?
            public const int WM_HOTKEY = 0x0312;
    
            Form referedForm;
    
            public internalMessageWindow(Form referedForm)
            {
                this.referedForm = referedForm;
            }
    
            protected override void WndProc(ref Message msg)
            {
                switch (msg.Msg)
                {
                    case WM_HOTKEY:
                        // Do no reply to this key ...
                        return;
                }
                base.WndProc(ref msg);
            }
    }
    

    We have now to link our form with our custom WindowsMessage

    FormCode
    {    
        internalMessageWindow messageWindow;
        public Form Constructor()
        {
            this.messageWindow = new internalMessageWindow(this); 
        }        
    }
    

    And unregister/register hardware buttons using UnregisterFunc1 and RegisterRecordKey from coredll.dll (see http:\\www.pinvoke.net for signature detail

    FormCode
    {    
        public Form Constructor()
        {
            ...
            RegisterHKeys.RegisterRecordKey(this.messageWindow.Hwnd);
        }        
    }
    public class RegisterHKeys
        {
            [DllImport("coredll.dll", SetLastError = true)]
            public static extern bool RegisterHotKey
            ...
            and
            private static extern bool UnregisterFunc1
            ...
            
            public static void RegisterRecordKey(IntPtr hWnd)
            {
                UnregisterFunc1(KeyModifiers.Windows, (int)KeysHardware.Hardware1);
                RegisterHotKey(hWnd, (int)KeysHardware.Hardware1, KeyModifiers.Windows, (int)KeysHardware.Hardware1);
                
                // Repeat for every single hardware button you wan to handle
            }
        }
    

    Now, we need to force our application to start avery time the Windows Mobile is started. This could be done using the CeRunAppAtEvent function of the coredll.dll library. This function allows linking an application to a specific event of the device. In our context, we'll link our application to the Wakeup event. This mean that every time the device is started, the Wakeup event will be raised, an as we will like our application with this event, our application will be started.

    To link application to event, we'll use this code:

    Win32.CeRunAppAtEvent(_kioskName, NotificationEvent.Wakeup);
    

    And we'll use this code to 'unlink' application / event:

    Win32.CeRunAppAtEvent(_kioskName, NotificationEvent.Wakeup);
    

    So now, we have a start page, which appears every time the device is started. And we have also caught button events to disable hardware interaction. Final step is to allow end-user to launch specific application and wait that this application to be closed to return to our start page.

    This is a quite easy step, using ProcessStartInfo class. This will allows us to start an application in a new process and put our current application in a waiting state, waiting that a specific process exit.

    To start a new process, we'll use this code, which will return the process handler:

    private static Process LaunchApp(string filename)
    {
        ProcessStartInfo s = new ProcessStartInfo();
        s.FileName = filename;
        s.UseShellExecute = true;
        return Process.Start(s);
    }
    

    And we have just to add routine to start an application, waiting the process to exit, with this code:

    private void but_Click(object sender, EventArgs e)
    {
        this.Hide();
        Process ela = LaunchApp(application2);
        ela.WaitForExit();
        this.Show();
    }
    

    Things to be aware

  • Hard reset of the device is not handled. Doing an hard reset will unsubscribe the application from the Wakeup event.
  • This solution is not portable ! Form is designed for a specific resolution (240x320 in this sample) and device with the default four hardware buttons. Installing it a device with other specification will fail.

    How to

    Handling non standard hardware button
    The sample is based on default device, with four buttons. If your target device has more buttons, or that MessageWindow didn't catch button interaction, you'll have to validate your button code. Use Registry Editor (Remote Registry Editor) and go in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shell\Keys\. You will see multiple "Folders", corresponding to your hardware keys, like 40C1, 40C2, ... Convert the last two letters to Decimal and you will get your button key (C1=193,C2=194,...)

    Conclusion

    This sample is far from a production product, but show that handling specific device like PocketPC is quite easy. Interacting with such hardware need a little bit of pinvoke, as compact framework encapsulates some but not all functionalities. Any comments/proposition are welcomes

    Reference

  • MSDN : Get an Application to Automatically Start When a mobile Device Wakes Up?

    History

  • 08/10/2007: Posted to CodeProject

  • Friday, August 10, 2007 12:43:10 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  Windows Mobile

    # Wednesday, August 08, 2007
    Windows Mobile Registry editor

    Windows Mobile (US)

    Je travail actuellement sur un projet ayant comme cible des Windows Mobile 6.

    Mon premier soucis à été de trouver un moyen "simple" d'éditer la base de registre de ces machines.
    Mobile Registry Editor permet d'éditer comfortablement la base de registre du device connecté via ActiveSync.
    Remote Registry Editor et fournit avec le SDK, et fonctionne selon le même principe que le produit ci-dessus.
    Registry Editor for Windows CE est un logiciel trouvé sur www.CodeProject,com, qui s'installe sur le PocketPC et permet d'éditer directement se base de registre

    Pour explorer les fenêtres actives du PocketPC, le produti Windows CE Remote Spy est fournit avec le SDK.

    La suite demain.

    Stéphane


    Wednesday, August 08, 2007 2:52:14 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  Windows Mobile

    # Tuesday, August 07, 2007
    GhostDoc 2.1.1 pour vs2008 disponible ...

    What’s New in GhostDoc 2.1.1:

    • Added: A bit more detailed logging information at certain places. Please take a look at the topic “How to Enable Logging” in the help file for details.
    • Fixed: "Document this" not working on properties defined in interfaces.
    • Fixed: Readonly properties in interfaces not recognized properly in VB.Net.

    Tuesday, August 07, 2007 7:45:49 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  Main

    # Monday, August 06, 2007
    NUnitForms

    Je me suis penché sur la cas NunitForms, afin de créer une librairie permettant de valider la non-régression d’un projet en cours de développement.

     

    Cette extension de Nunit est très intéressant, malgré le fait que le projet ne soit plus très actif. Pour rappel, cette sur couche permet de tester l’interface utilisateur d’une application en simulant les interactions entre l’utilisateur final et l’application.

     

    Voici donc quelques idées en vrac :

     

    L’installation.

    NunitForms et aujourd’hui en décalage avec son projet source Nunit. L’assemblage nunit.framework référencé est la version 2.2.7.0, alors que la version actuelle de Nunit utilise la v. 2.4.1.0. Cela ne semble pas poser de problèmes, mais il faut référencer cette dernière dans la projet de test.

     

    Création des tests

    Je ne vais pas m’étendre sur la syntaxe, celle-ci étant quasiment identique à un projet Nunit normal ([TestFixture], [Test], …).

    1. La class de test doit hériter le la classe NunitFormTest.
    2. J’ai eu quelques problèmes avec les fenêtre ouvrant elle-même d’autre fenêtre de type modal. La documentation est pauvre, et fait souvent référence aux version précédents. Il faut utiliser la méthode ExpectModal en lui passant deux arguments : le type de l’objets modal, et la méthode délegate à utiliser. Ex :
      {
          ExpectModal("ObjectType", new ModalFormActivated(CloseForm
      ));
      }

      public void CloseForm
      ()
      {
          
      ButtonTester btnOk = new ButtonTester("bt_ok"
      );
         
      btnOk.Click
      ();
      }

    La suite au prochaine épisode.

     

    Stéphane



    Monday, August 06, 2007 4:16:56 PM (GMT Daylight Time, UTC+01:00)  #    Comments [1]  UnitTesting

    # Thursday, August 02, 2007
    VS2008 Beta 2

    Pour évacuer ma frustration ...

    Après avoir installé VS2008, j'ai décidé de me lancer dans un nouveau projet Web. Ni une, ni deux, je crée une Master Page (avec un contentplaceholder), puis une default page héritant de celle-ci (avec un content référent au place holder de la Master Page). Rien de plus basique.

    Et la commence ma frustration : En mode Split ou Design de ma page default.aspx, un message d'erreur m'invitant à corriger celle-ci en implémentant le contentplaceholder, gasp ! Encore plus bizzard, tout fonctione correctement à l'execution ?!?!

    Différentes recherches ne donnant rien, j'ai finallement tenté l'option repaire sur VS2008. 10 minutes plus tard, tout est rentré dans l'order et je peux jouer avec le master page imbriqués sans problèmes.

    Qui a dit que l'informatique était une science exacte ?

    Stéphane


    Thursday, August 02, 2007 12:52:42 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  VS2008

    Microsoft Office 2007 Add-in : Save as PDF

    Ce n'est pas une info très récente (11 août 2006), mais toujours utile ...

    Voici donc le lien pour installer le complèment permettant de sauvegarder presque tous les documents d'Office 2007 au format PDF. Permet d'éviter d'acheter un produit spécifique pour cette opération.

    Stéphane


    Thursday, August 02, 2007 8:52:03 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  add-in | office2007

    # Tuesday, June 26, 2007
    Regionate & Gohstdoc

    Voici deux utilitaires qui vous facilitent la vie ...

    Regionate permet de gérer facilement les balises #Region. Regarder la video sur leur site pour constater que cette add-in est puissant :
    http://www.rauchy.net/regionerate/

    Et la version 2.1.0 du celèbre Gostdoc, que je pense ne pas avoir a commenter
    http://weblogs.asp.net/rweigelt/archive/2007/06/24/2919273.aspx

     

    Stéphane


    Tuesday, June 26, 2007 12:07:43 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0]  Utilitaires | Windows