Thursday, February 27, 2014

About Msi Installer impersonate problem.

About Msi Installer impersonate problem.
I using vs2010 create installer project to update GPO, the problem is even I run as administrator, there still have permission issue.
The script no problem, when I just run script, it worked fine. but the custom action
when I run the import the GPO backup,
return "Name translation: Could not find the name or insufficient right to see name. "
So I think it is the Installer impersonate problem ,It not run as Administrator or not get full permission.
I search online , find a helpful script, update custom action NoImpersonate, but it run under SYSTEM, it not my need.
Custom Action In-Script Execution Options
http://msdn.microsoft.com/en-us/library/aa368069(v=vs.85).aspx
Mailbag: How to set the NoImpersonate flag for a custom action in Visual Studio 2005
http://blogs.msdn.com/b/astebner/archive/2006/10/23/mailbag-how-to-set-the-noimpersonate-flag-for-a-custom-action-in-visual-studio-2005.aspx

just change a little bit, it worked find.
if with NoImpersonate :
// NoImpersonate.js <msi-file>
// Performs a post-build fixup of an msi to change all deferred custom actions to NoImpersonate
// Constant values from Windows Installer
var msiOpenDatabaseModeTransact = 1;
var msiViewModifyInsert         = 1
var msiViewModifyUpdate         = 2
var msiViewModifyAssign         = 3
var msiViewModifyReplace        = 4
var msiViewModifyDelete         = 6
var msidbCustomActionTypeInScript       = 0x00000400;
var msidbCustomActionTypeNoImpersonate  = 0x00000800
var msidbCustomActionTypeTSAware  = 0x00004000
if (WScript.Arguments.Length != 1)
{
 WScript.StdErr.WriteLine(WScript.ScriptName + " file");
 WScript.Quit(1);
}
var filespec = WScript.Arguments(0);
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
var sql
var view
var record
try
{
 sql = "SELECT `Action`, `Type`, `Source`, `Target` FROM `CustomAction`";
 view = database.OpenView(sql);
 view.Execute();
 record = view.Fetch();
 while (record)
 {
     if (record.IntegerData(2) & msidbCustomActionTypeInScript)
     {
         record.IntegerData(2) = record.IntegerData(2) | msidbCustomActionTypeNoImpersonate;
   'change to
   record.IntegerData(2) = record.IntegerData(2) & ~msidbCustomActionTypeNoImpersonate;
         view.Modify(msiViewModifyReplace, record);
     }
        record = view.Fetch();
 }
 view.Close();
 database.Commit();
}
catch(e)
{
 WScript.StdErr.WriteLine(e);
 WScript.Quit(1);
}

Thursday, February 13, 2014

How to get procress image name

My  file operation monitor project need get name from process id, in case this process is create by other user, not in same session, generally , it is not, because my program run as service, it is run as local system.  get process name became an issue.

 it need AdjustTokenPrivileges  , I use SE_DEBUG_NAME the high privilege for get process name.

Sample code :


void EnableDebugPriv()
{
    HANDLE hToken;
    LUID luid;
    TOKEN_PRIVILEGES tkp;

    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

    if (!::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
    {
        wprintf(_T("ERROR %u\n"),GetLastError());
        CloseHandle(hToken);
        return;
    }

    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if (!::AdjustTokenPrivileges(hToken, false, &tkp, sizeof(tkp), NULL, NULL))
    {
        wprintf(_T("ERROR %u\n"),GetLastError());
        CloseHandle(hToken);
        return;
    }

    CloseHandle(hToken);
    wprintf(_T("Should have worked"));
}


ProcessInfoStruct pInfo ;
  DWORD err = ERROR_SUCCESS;
  HANDLE Handle;
  char buffer[MAX_PATH];
  DWORD i = MAX_PATH ;
  Handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processHandle);
  if (Handle != 0)
  {
    if (QueryFullProcessImageNameA(Handle, 0, buffer, &i) != 0)
    {
    pProcess->processHandle = processHandle;
    std::string pfullpath(buffer);
    Poco::Path pathname(pfullpath);
    pProcess->processName = pathname.getFileName();
    pProcess->processPath = pathname.parent().toString() ;
    pInfo.processHandle = processHandle ;
    pInfo.processName = pProcess->processName;
    pInfo.processPath = pProcess->processPath ;
    processCache.add(processHandle, pInfo);   
    }
    else
    {
 
      wprintf(_T("ERROR %u\n"),GetLastError());
   
   }
   CloseHandle(Handle);
  }
  else
  {
  
    wprintf(_T("ERROR %u\n"),GetLastError());
  
  
  }

Wednesday, February 5, 2014

MSMQ Transactional Message Processing using Multiple Receive Queues

copy from http://code-ronin.blogspot.ca/2008/09/msmq-transactional-message-processing.html

MSMQ Transactional Message Processing using Multiple Receive Queues
Here's the situation:
  1. You want to asynchronously process messages on a queue in a transactional manner, such that the message is only taken from the queue upon successfully processing it. This allows messages that failed to be properly processed to be processed again later with a chance at success.
  2. You want to have multiple workers processing these messages to improve efficiency and performance of long-running processing on large numbers of messages.
  3. When you shutdown, you want all the processing code to complete before allowing the process to exit.
The first item can be accomplished with using MessageQueue's BeginPeek method and PeekCompleted event. This will allow you to peek at the queue and and begin a transaction before actually receiving the message. Beginning a transaction before receiving the message allows you to abort the transaction should an error occur during processing, leaving the message on the queue to be processed again later (hopefully with a higher chance of success). The following event handler shows the boilerplate code to accomplish this:
private void queue_PeekCompleted(object sender, PeekCompletedEventArgs e)
{
    var queue = (MessageQueue)sender;

    var transaction = new MessageQueueTransaction();
    transaction.Begin();
    try
    {
       var message = queue.Receive(transaction);
       // process the message here
       transaction.Commit();
    }
    catch (Exception ex)
    {
       // abort if processing fails
       transaction.Abort();
    }
    finally
    {
       // start watching for another message
       queue.BeginPeek();
    }
}

The second item can be accomplished by creating multiple receiving queues and telling them to start watching for incoming messages. The following snippets of code demonstrate how to accomplish this:
private readonly MessageQueue[] Receivers; // member
...
this.Receivers = Enumerable.Range(0, (count <= 0) ? 1 : count)
   .Select(i =>
   {
       var queue = new MessageQueue(path, QueueAccessMode.Receive)
       {
           Formatter = new BinaryMessageFormatter()
       };
       queue.MessageReadPropertyFilter.SetAll();
       return queue;
   })
   .ToArray();

// begin watching
foreach (var queue in this.Receivers)
{
   queue.PeekCompleted += queue_PeekCompleted;
   queue.BeginPeek();
}

...
// closing
foreach (var queue in this.Receivers)
{
   queue.PeekCompleted -= queue_PeekCompleted;
   queue.Close(); // stop peeking
}

The third item can be accomplished by simply incrementing and decrementing a counter when processing begins and ends respectively; then you simply block until that counter reaches zero. You'll want to place the decrement in a finally block to ensure that the counter is decremented even if processing throws an exception. Assuming you have a Counter class that implements thread safe increment and decrement operations (see bottom), you can create a member named "ProcessingCounter", and your PeekCompleted handler has the following line to do the processing,
this.Handle(queue.Receive(transaction));

your Handle method would look like this,
private void Handle(Message message)
{
   this.ProcessingCounter.Increment();
   try
   {
       // process message here;
   }
   finally
   {
       this.ProcessingCounter.Decrement();
   }
}

and you could block after your MessageQueue.Close() calls like this
while (this.ProcessingCounter.Value > 0)
    Thread.Sleep(100);

The following abstract class puts it all together. Simply implement the Process method and away you go!
public abstract class MessageProcessor<TMessage>
{
    private readonly MessageQueue[] Receivers;
    private readonly Counter ProcessingCounter = new Counter();
    private bool IsClosing;

    public MessageProcessor(string path)
        : this(path, 1) { }

    public MessageProcessor(string path, int count)
        : base()
    {
        if (string.IsNullOrEmpty(path))
            throw new ArgumentNullException("path");

        if (!MessageQueue.Exists(path))
            MessageQueue.Create(path, true);

        this.Receivers = Enumerable.Range(0, (count <= 0) ? 1 : count)
            .Select(i =>
            {
                var queue = new MessageQueue(path, QueueAccessMode.Receive)
                {
                    Formatter = new BinaryMessageFormatter()
                };
                queue.MessageReadPropertyFilter.SetAll();
                return queue;
            })
            .ToArray();
    }

    public void Close()
    {
        this.IsClosing = true;

        this.OnClosing();

        foreach (var queue in this.Receivers)
        {
            queue.PeekCompleted -= queue_PeekCompleted;
            queue.Close();
        }

        while (this.IsProcessing)
            Thread.Sleep(100);

        this.IsClosing = this.IsOpen = false;
        this.OnClosed();
    }

    public bool IsOpen { get; private set; }

    protected bool IsProcessing
    {
        get { return this.ProcessingCounter.Value > 0; }
    }

    protected virtual void OnClosing() { }
    protected virtual void OnClosed() { }
    protected virtual void OnOpening() { }
    protected virtual void OnOpened() { }

    public void Open()
    {
        if (this.IsOpen)
            throw new Exception("This processor is already open.");

        this.OnOpening();

        foreach (var queue in this.Receivers)
        {
            queue.PeekCompleted += queue_PeekCompleted;
            queue.BeginPeek();
        }

        this.IsOpen = true;
        this.OnOpened();
    }

    protected abstract void Process(TMessage @object);

    private void Handle(Message message)
    {
        Trace.Assert(null != message);

        this.ProcessingCounter.Increment();
        try
        {
            this.Process((TMessage)message.Body);
        }
        finally
        {
            this.ProcessingCounter.Decrement();
        }
    }

    private void queue_PeekCompleted(object sender, PeekCompletedEventArgs e)
    {
        var queue = (MessageQueue)sender;

        var transaction = new MessageQueueTransaction();
        transaction.Begin();
        try
        {
            // if the queue closes after the transaction begins,
            // but before the call to Receive, then an exception
            // will be thrown and the transaction will be aborted
            // leaving the message to be processed next time
            this.Handle(queue.Receive(transaction));
            transaction.Commit();
        }
        catch (Exception ex)
        {
            transaction.Abort();
            Trace.WriteLine(ex.Message);
        }
        finally
        {
            if (!this.IsClosing)
                queue.BeginPeek();
        }
    }
}

Incidentally, the following is my implementation of a thread-safe counter.
public class Counter
{
    private readonly object SyncRoot = new object();
    private int value;

    public int Value
    {
        get
        {
            lock (this.SyncRoot)
            {
                return value;
            }
        }
    }

    public int Decrement()
    {
        lock (this.SyncRoot)
        {
            return --value;
        }
    }

    public int Increment()
    {
        lock (this.SyncRoot)
        {
            return ++value;
        }
    }
}