Tuesday, April 28, 2009

Creating Win32 security descriptor with Delphi

Sometimes it is necessary to specify a non-default security options for a system object. In Windows API, this can be done specifying SecurityAttributes parameter in CreateFile, CreateSemaphore, CreateFileMapping etc. functions. However, filling the security attributes is not a very simple task, especially in Delphi. So I want to share my Delphi code that creates security attributes that allow full access for built-in Everyone account.

var
EveryoneSecurityDescriptor:TSecurityDescriptor;
pEveryoneACL:PACL;
EveryoneSID:PSID;
EveryoneSecurityAttributes:TSecurityAttributes;

procedure InitializeEveryoneSecurityDescriptor;
const
SECURITY_WORLD_SID_AUTHORITY : _SID_IDENTIFIER_AUTHORITY =
(Value : (0, 0, 0, 0, 0, 1));
SECURITY_WORLD_RID = $00000000;
ACL_REVISION = 2;
var cbAcl:Integer;
SIDAuthWorld:TSIDIdentifierAuthority;
begin
// create empty security descriptor
InitializeSecurityDescriptor(@EveryoneSecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);

// create SID for 'Everyone' account ('S-1-1-0')
SIDAuthWorld := SECURITY_WORLD_SID_AUTHORITY;
AllocateAndInitializeSID(SIDAuthWorld, 1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0, EveryoneSID);

// initialize ACL (Access Control List)
// size for an ACL with a single ACE
cbAcl := SizeOf(TACL) + 12 {SizeOf(ACCESS_ALLOWED_ACE)} +
GetLengthSid(EveryoneSID) - sizeof(DWORD);
GetMem(pEveryoneACL, cbAcl);
InitializeAcl(pEveryoneACL^, cbAcl, ACL_REVISION);

// add entry (ACE, Access Control Entry) for 'Everyone'
// to the ACL
AddAccessAllowedAce(pEveryoneACL^, ACL_REVISION,
GENERIC_ALL or GENERIC_READ or GENERIC_WRITE or
SPECIFIC_RIGHTS_ALL or STANDARD_RIGHTS_ALL,
EveryoneSID);

// set reference to the ACL for our security descriptor
SetSecurityDescriptorDacl(@EveryoneSecurityDescriptor,
True, pEveryoneACL, False);

// now fill in SECURITY_ATTRIBUTES structure. It can be
// passed to most WinAPI 'create' functions.
EveryoneSecurityAttributes.nLength:=
SizeOf(EveryoneSecurityAttributes);
EveryoneSecurityAttributes.lpSecurityDescriptor:=
@EveryoneSecurityDescriptor;
// change this if you need your handle to be inherited
EveryoneSecurityAttributes.bInheritHandle:=False;
end;

procedure FinalizeEveryoneSecurityDescriptor;
begin
if Assigned(EveryoneSID) then FreeSID(EveryoneSID);
if Assigned(pEveryoneACL) then FreeMem(pEveryoneACL);
end;

After calling InitializeEveryoneSecurityDescriptor, you can pass @EveryoneSecurityAttributes to any Create... function.

Sunday, April 19, 2009

Flash Player, Mozilla Firefox for Linux and cyrillic symbols

I use Kubuntu 8.04 Linux on my home box. And I have found that it is impossible to enter cyrillic text in Adobe Flash Player forms when using Firefox and Linux. When I type in Russian, it is a total mess. In Windows, everything is ok.

I have spent some time trying to solve the problem. I have installed different versions of FlashPlayer plugin, but none of them worked.
The problem is in Adobe software.
Some people advise to change Firefox's locale via LC_ALL=ru_RU.CP1251 firefox, but this doesn't work.
So don't waste your time.

The only solution I have found is to run Firefox for Windows under WINE. Also, you may type Russian text in any text editor and then copy-paste the text into flash -- that works.

Saturday, April 18, 2009

MPI, MS Windows and Cygwin

I have seen a lot of articles discussing which MPI implementation -- LAM, MPICH, or something else -- is better or worse. But none of them mentioned using MPI under Windows and Cygwin.

You may ask: why to use MPI under Cygwin? Well, it's difficult for me to imagine that MPI could be efficiently utilized under Windows at all. Most modern clusters do not use Windows -- they are built on Linux. Supercomputers also do not run Microsoft products.

And, of course, development of parallel program should be performed under Linux or some another UNIX-like system. But it is not always possible. For example, I can install Linux on my home computer (in fact, I have), but I am stuck to Windows in my office. Windows is not such bad, I have a lot of Windows projects. In fact, all of my projects except recent one are Windows-oriented, and I still make some changes there from time to time. So I cannot get rid of Windows, but I want to develop MPI application that will be run on a supercomputer.

There are at least two ways to have Windows as OS and to work in Linux-like environment: to use virtual machine or to install Cygwin. I have selected the second option (I don't feel myself comfortable when working with a virtual machine, it's still slow and... well, you may try). So I downloaded and installed cygwin with development tools (I needed gcc), I have installed Eclipse to use it as IDE, and then I have encountered a question: how will I debug MPI code? I needed MPI implementation that could run under Cygwin.

At that point I have read a number of articles and found that LAM is a bit faster than MPICH - in some cases. Well, operating speed was not important for debug purposes, but I nevertheless decided to try LAM.
There is no LAM binaries for a cygwin at LAM's website. But I am familiar quite well with './configure' and 'make', so I downloaded the source codes and started build. After a several hours (yes, cygwin + Windows configure and compile rather slowly) I have got an error -- something was wrong with include files. Searching the web gave me an answer: I had to disable ROMIO. Ok, I haven't planned to use it in any case, so I have run:

./configure --without-romio --prefix=/opt/lam
make
make install

And this time LAM was compiled all right (though it took many hours). At least I had been thinking so -- until I tried to build my MPI application with mpicxx. Then I have discovered that my installation didn't work. It encountered segmentation fault error every time I started its compiler wrappers. Also, mpirun didn't run the simplest programs too. Searching the web gave nothing this time, and I have removed LAM from my computer. LAM is a good product, but I think it's just incompatible with Cygwin.

Next, I have tried MPICH. And it just worked. Although I had to start mpd daemon and write single-line script so that 'make' could run mpicxx compiler.