Tag Archives: Visual Studio

Building OpenSSL with Visual Studio 2010 for x64 / Win64 causes error

visual-studio-2010-x64-cross-tools-command-prompt

Today I was trying to build the latest OpenSSL 1.0.1c with Visual Studio 2010. Following instructions form the INSTALL.W32, I was able to successfully build the 32-bit version. Trying the same with 64-bit (x64) version, again following the official instructions from INSTALL.W64.
To build for Win64/x64:
> perl Configure VC-WIN64A
> ms\do_win64a
> nmake -f ms\ntdll.mak
> cd out32dll
> ..\ms\test

The first line ‘perl Configure VC-WIN64A’ went without any errors:
Configuring for VC-WIN64A
no-ec_nistp_64_gcc_128 [default] OPENSSL_NO_EC_NISTP_64_GCC_128 (skip dir)
no-gmp [default] OPENSSL_NO_GMP (skip dir)
no-jpake [experimental] OPENSSL_NO_JPAKE (skip dir)
no-krb5 [krb5-flavor not specified] OPENSSL_NO_KRB5
no-md2 [default] OPENSSL_NO_MD2 (skip dir)
no-rc5 [default] OPENSSL_NO_RC5 (skip dir)
no-rfc3779 [default] OPENSSL_NO_RFC3779 (skip dir)
no-sctp [default] OPENSSL_NO_SCTP (skip dir)
no-shared [default]
no-store [experimental] OPENSSL_NO_STORE (skip dir)
no-zlib [default]
no-zlib-dynamic [default]
...
...
...
SIXTY_FOUR_BIT mode
DES_INT used
RC4_CHUNK is unsigned long long
Configured for VC-WIN64A.

The second line ‘ms\do_win64a’ always returned errors:
ml64 -c -Foms\uptable.obj ms\uptable.asm
Microsoft (R) Macro Assembler (x64) Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.


Assembling: ms\uptable.asm
ms\uptable.asm(356) : error A2088:END directive required at end of file
ms\uptable.asm(356) : fatal error A1010:unmatched block nesting : _lazy18

Luckily I found solution in cyber-lynx.livejournal.com
Translation from Russian:
To prevent this, need to change file ms\do_win64a.bat like this: instead of

perl ms\uplink-x86_64.pl masm > ms\uptable.asm
ml64 -c -Foms\uptable.obj ms\uptable.asm

write

perl ms\uplink-x86_64.pl masm > ms\uptable.asm
ping 127.0.0.1
ml64 -c -Foms\uptable.obj ms\uptable.asm

It seems like race condition to me. Command ‘ping 127.0.0.1′ just adds a pause between two commands.

Thanks to Белая рысь (cyber_lynx)! Source: http://cyber-lynx.livejournal.com/40001.html

Static code analysis for C++ for free and for Pro

Up and until Visual Studio 2010 Microsoft decided that Code Analysis tool was available only for Visual Studio Premium and Ultimate editions. I have Visual Studio 2010 Pro w/MSDN subscriptions (actually 2 of them), but can not use Code Analysis tool.

VS Pro w/o code analysis tool

This however will change with upcoming Visual Studio 11. See the SDL blog: Code Analysis for All.

This is the first time that Code Analysis has been made available in an Express edition of Visual Studio…

CreateProcessAsUser fails on Windows XP with System error 233

Today I fixed one bug that was very hard to reproduce. Many hours were spent to figure out what combination caused it:

  • It happens only on Windows XP (not on Vista, Server 2003, 2008, Win 7);
  • It does not happens on all Windows XP, because it is Race condition;
  • I was unable to reproduce it with physical glass/monitor attached to the computer; It only happened using Remote Desktop;
  • It does not happen when debugger is attached and breakpoint is being hit;

Latter I found people that have similar issue:

The code is the following:
WTSQueryUserToken(..., &hToken);
SetTokenInformation(hToken, ...);
SomeVistaAndWin7ElevatedTokenStuff(hToken);
CreateProcessAsUser(hToken, ...);

And CreateProcessAsUser fails with GetLastError() = 233. Looking in System Error Codes (0-499) – ERROR_PIPE_NOT_CONNECTED 233 (0xE9) – No process is on the other end of the pipe.

The confusing part is about Pipe, because you didn’t expect to get pipe error here – you have not created any pipe.

In the first post I have linked, Thomas Graefenhain writes:

I’ve debugged a little bit with the kernel debugger, and have found the
problem: CreateProcessAsUser uses internally, when creating a process in an
other session, the function CreateRemoteProcessW from ADVAPI32.DLL. This
function opens a pipe with the name
\\.\Pipe\TerminalServer\SystemExecSrvr\%d where %d is the SessionID and
sending the request over to csrss.exe. …

In another post someone mentioned that Sleep(2000) fixed the problem. This explains why under debugger everything works without an error.

The good news is that it happens only under Windows XP and under Remote Desktop, so small group of users are affected. The bad new is that there are no elegant workarounds. Windows XP is in the Extended Support Phase, so I am not counting on fix from Microsoft.

Currently I use the following workaround (simplified version, see below). If you have something better or more elegant, please let me know in the comments below.
{
     Sleep(100);
     CreateProcessAsUser(hToken, ...);
} while (wasError && GetLastError() == 233 && IsWindowsXP());