Best windows questions in April 2011

Win32 - Backtrace from C code

15 votes

I'm currently looking for a way to get backtrace information under Windows, from C code (no C++).

I'm building a cross-platform C library, with reference-counting memory management. It also have an integrated memory debugger that provides informations about memory mistakes (XEOS C Foundation Library).

When a fault occurs, the debugger is launched, providing information about the fault, and the memory record involved.

enter image description here

On Linux or Mac OS X, I can look for execinfo.h in order to use the backtrace function, so I can display additional infos about the memory fault.

I'm looking for the same thing on Windows.

I've seen How can one grab a stack trace in C? on Stack Overflow. I don't want to use a third-party library, so the CaptureStackBackTrace or StackWalk functions looks good.

The only problem is that I just don't get how to use them, even with the Microsoft documentation.

I'm not used to Windows programming, as I usually work on POSIX compliant systems.

What are some explanations for those functions, and maybe some examples?

EDIT

I'm now considering using the CaptureStackBackTrace function from DbgHelp.lib, as is seems there's a little less overhead...

Here's what I've tried so far:

unsigned int   i;
void         * stack[ 100 ];
unsigned short frames;
SYMBOL_INFO    symbol;
HANDLE         process;

process = GetCurrentProcess();

SymInitialize( process, NULL, TRUE );

frames = CaptureStackBackTrace( 0, 100, stack, NULL );

for( i = 0; i < frames; i++ )
{
    SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, &symbol );

    printf( "%s\n", symbol.Name );
}

I'm just getting junk. I guess I should use something else than SymFromAddr.

Alright, now I got it. : )

The problem was in the SYMBOL_INFO structure. It needs to be allocated on the heap, reserving space for the symbol name, and initialized properly.

Here's the final code:

void printStack( void );
void printStack( void )
{
     unsigned int   i;
     void         * stack[ 100 ];
     unsigned short frames;
     SYMBOL_INFO  * symbol;
     HANDLE         process;

     process = GetCurrentProcess();

     SymInitialize( process, NULL, TRUE );

     frames               = CaptureStackBackTrace( 0, 100, stack, NULL );
     symbol               = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
     symbol->MaxNameLen   = 255;
     symbol->SizeOfStruct = sizeof( SYMBOL_INFO );

     for( i = 0; i < frames; i++ )
     {
         SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );

         printf( "%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address );
     }

     free( symbol );
}

Output is:

6: printStack - 0xD2430
5: wmain - 0xD28F0
4: __tmainCRTStartup - 0xE5010
3: wmainCRTStartup - 0xE4FF0
2: BaseThreadInitThunk - 0x75BE3665
1: RtlInitializeExceptionChain - 0x770F9D0F
0: RtlInitializeExceptionChain - 0x770F9D0F

Getting The Size of a C++ Function

12 votes

I was reading this question because I'm trying to find the size of a function in a C++ program, It is hinted at that there may be a way that is platform specific. My targeted platform is windows

The method I currently have in my head is the following:
1. Obtain a pointer to the function
2. Increment the Pointer (& counter) until I reach the machine code value for ret
3. The counter will be the size of the function?

Edit1: To clarify what I mean by 'size' I mean the number of bytes (machine code) that make up the function.
Edit2: There have been a few comments asking why or what do I plan to do with this. The honest answer is I have no intention, and I can't really see the benefits of knowing a functions length pre-compile time. (although I'm sure there are some)

This seems like a valid method to me, will this work?

No, this will not work:

  1. There is no guarantee that your function only contains a single ret instruction.
  2. Even if it only does contain a single ret, you can't just look at the individual bytes - because the corresponding value could appear as simply a value, rather than an instruction.

The first problem can possibly be worked around if you restrict your coding style to, say, only have a single point of return in your function, but the other basically requires a disassembler so you can tell the individual instructions apart.

Performance problem with Euler problem and recursion on Int64 types

11 votes

I'm currently learning Haskell using the project Euler problems as my playground. I was astound by how slow my Haskell programs turned out to be compared to similar programs written in other languages. I'm wondering if I've forseen something, or if this is the kind of performance penalties one has to expect when using Haskell.

The following program in inspired by Problem 331, but I've changed it before posting so I don't spoil anything for other people. It computes the arc length of a discrete circle drawn on a 2^30 x 2^30 grid. It is a simple tail recursive implementation and I make sure that the updates of the accumulation variable keeping track of the arc length is strict. Yet it takes almost one and a half minute to complete (compiled with the -O flag with ghc).

import Data.Int

arcLength :: Int64->Int64
arcLength n = arcLength' 0 (n-1) 0 0 where
    arcLength' x y norm2 acc
        | x > y = acc
        | norm2 < 0 = arcLength' (x + 1) y (norm2 + 2*x +1) acc
        | norm2 > 2*(n-1) = arcLength' (x - 1) (y-1) (norm2 - 2*(x + y) + 2) acc
        | otherwise = arcLength' (x + 1) y (norm2 + 2*x + 1) $! (acc + 1)

main = print $ arcLength (2^30)

Here is a corresponding implementation in Java. It takes about 4.5 seconds to complete.

public class ArcLength {
public static void main(String args[]) {
    long n = 1 << 30;
    long x = 0;
    long y = n-1;
    long acc = 0;
    long norm2 = 0;
    long time = System.currentTimeMillis();

    while(x <= y) {
        if (norm2 < 0) {
            norm2 += 2*x + 1;
            x++;
        } else if (norm2 > 2*(n-1)) {
            norm2 += 2 - 2*(x+y);
            x--;
            y--;
        } else {
            norm2 += 2*x + 1;
            x++;
            acc++;
        }
    }

    time = System.currentTimeMillis() - time;
    System.err.println(acc);
    System.err.println(time);
}

}

EDIT: After the discussions in the comments I made som modifications in the Haskell code and did some performance tests. First I changed n to 2^29 to avoid overflows. Then I tried 6 different version: With Int64 or Int and with bangs before either norm2 or both and norm2 and acc in the declaration arcLength' x y !norm2 !acc. All are compiled with

ghc -O3 -prof -rtsopts -fforce-recomp -XBangPatterns arctest.hs

Here are the results:

(Int !norm2 !acc)
total time  =        3.00 secs   (150 ticks @ 20 ms)
total alloc =       2,892 bytes  (excludes profiling overheads)

(Int norm2 !acc)
total time  =        3.56 secs   (178 ticks @ 20 ms)
total alloc =       2,892 bytes  (excludes profiling overheads)

(Int norm2 acc)
total time  =        3.56 secs   (178 ticks @ 20 ms)
total alloc =       2,892 bytes  (excludes profiling overheads)

(Int64 norm2 acc)
arctest.exe: out of memory

(Int64 norm2 !acc)
total time  =       48.46 secs   (2423 ticks @ 20 ms)
total alloc = 26,246,173,228 bytes  (excludes profiling overheads)

(Int64 !norm2 !acc)
total time  =       31.46 secs   (1573 ticks @ 20 ms)
total alloc =       3,032 bytes  (excludes profiling overheads)

I'm using GHC 7.0.2 under a 64-bit Windows 7 (The Haskell platform binary distribution). According to the comments, the problem does not occur when compiling under other configurations. This makes me think that the Int64 type is broken in the Windows release.

Hm, I installed a fresh Haskell platform with 7.0.3, and get roughly the following core for your program (-ddump-simpl):

Main.$warcLength' =
  \ (ww_s1my :: GHC.Prim.Int64#) (ww1_s1mC :: GHC.Prim.Int64#)
    (ww2_s1mG :: GHC.Prim.Int64#) (ww3_s1mK :: GHC.Prim.Int64#) ->
    case {__pkg_ccall ghc-prim hs_gtInt64 [...]
           ww_s1my ww1_s1mC GHC.Prim.realWorld#
[...]

So GHC has realized that it can unpack your integers, which is good. But this hs_getInt64 call looks suspiciously like a C call. Looking at the assembler output (-ddump-asm), we see stuff like:

pushl %eax
movl 76(%esp),%eax
pushl %eax
call _hs_gtInt64
addl $16,%esp

So this looks very much like every operation on the Int64 get turned into a full-blown C call in the backend. Which is slow, obviously.

The source code of GHC.IntWord64 seems to verify that: In a 32-bit build (like the one currently shipped with the platform), you will have only emulation via the FFI interface.

Create a small and concise windows service using Delphi

10 votes

I have created very simple windows service app updates some data files chronologically using Delphi. The service app compiles, and works well, but I am not happy with final exe file size. Its over 900K. The service itself do not use Forms, Dialogs, but yet I see SvcMgr is referencing Forms and other large crap I am not using.

Name           Size Group Package
------------ ------ ----- -------
Controls     80,224 CODE
Forms        61,204 CODE
Classes      46,081 CODE
Graphics     37,054 CODE

Is there a way I can make the service app smaller? or is there another service template I can use without using forms etc?

Here is the code I used to create a very small service based on pure API. The size of the exe is only 50K. Probably could be even smaller, I used some other units that could be omited. The compiler used was Delphi 7. Probably will be larger with new compilers but I did not check.

The code is very old and I did not check it. I wrote that years ago. So take it as an example, do not copy and paste please.

{
  NT Service  model based completely on API calls. Version 0.1
  Inspired by NT service skeleton from Aphex
  Adapted by Runner
}

program PureAPIService;

{$APPTYPE CONSOLE}

{$IF CompilerVersion > 20}
  {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
  {$WEAKLINKRTTI ON}
{$IFEND}

uses
  Windows,
  WinSvc;

const
  ServiceName     = 'PureAPIService';
  DisplayName     = 'Pure Windows API Service';
  NUM_OF_SERVICES = 2;

var
  ServiceStatus : TServiceStatus;
  StatusHandle  : SERVICE_STATUS_HANDLE;
  ServiceTable  : array [0..NUM_OF_SERVICES] of TServiceTableEntry;
  Stopped       : Boolean;
  Paused        : Boolean;

var
  ghSvcStopEvent: Cardinal;

procedure OnServiceCreate;
begin
  // do your stuff here;
end;

procedure AfterUninstall;
begin
  // do your stuff here;
end;


procedure ReportSvcStatus(dwCurrentState, dwWin32ExitCode, dwWaitHint: DWORD);
begin
  // fill in the SERVICE_STATUS structure.
  ServiceStatus.dwCurrentState := dwCurrentState;
  ServiceStatus.dwWin32ExitCode := dwWin32ExitCode;
  ServiceStatus.dwWaitHint := dwWaitHint;

  case dwCurrentState of
    SERVICE_START_PENDING: ServiceStatus.dwControlsAccepted := 0;
    else
      ServiceStatus.dwControlsAccepted := SERVICE_ACCEPT_STOP;
  end;

  case (dwCurrentState = SERVICE_RUNNING) or (dwCurrentState = SERVICE_STOPPED) of
    True: ServiceStatus.dwCheckPoint := 0;
    False: ServiceStatus.dwCheckPoint := 1;
  end;

  // Report the status of the service to the SCM.
  SetServiceStatus(StatusHandle, ServiceStatus);
end;

procedure MainProc;
begin
  // we have to do something or service will stop
  ghSvcStopEvent := CreateEvent(nil, True, False, nil);

  if ghSvcStopEvent = 0 then
  begin
    ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
    Exit;
  end;

  // Report running status when initialization is complete.
  ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 );

  // Perform work until service stops.
  while True do
  begin
    // Check whether to stop the service.
    WaitForSingleObject(ghSvcStopEvent, INFINITE);
    ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
    Exit;
  end;
end;

procedure ServiceCtrlHandler(Control: DWORD); stdcall;
begin
  case Control of
    SERVICE_CONTROL_STOP:
      begin
        Stopped := True;
        SetEvent(ghSvcStopEvent);
        ServiceStatus.dwCurrentState := SERVICE_STOP_PENDING;
        SetServiceStatus(StatusHandle, ServiceStatus);
      end;
    SERVICE_CONTROL_PAUSE:
      begin
        Paused := True;
        ServiceStatus.dwcurrentstate := SERVICE_PAUSED;
        SetServiceStatus(StatusHandle, ServiceStatus);
      end;
    SERVICE_CONTROL_CONTINUE:
      begin
        Paused := False;
        ServiceStatus.dwCurrentState := SERVICE_RUNNING;
        SetServiceStatus(StatusHandle, ServiceStatus);
      end;
    SERVICE_CONTROL_INTERROGATE: SetServiceStatus(StatusHandle, ServiceStatus);
    SERVICE_CONTROL_SHUTDOWN: Stopped := True;
  end;
end;

procedure RegisterService(dwArgc: DWORD; var lpszArgv: PChar); stdcall;
begin
  ServiceStatus.dwServiceType := SERVICE_WIN32_OWN_PROCESS;
  ServiceStatus.dwCurrentState := SERVICE_START_PENDING;
  ServiceStatus.dwControlsAccepted := SERVICE_ACCEPT_STOP or SERVICE_ACCEPT_PAUSE_CONTINUE;
  ServiceStatus.dwServiceSpecificExitCode := 0;
  ServiceStatus.dwWin32ExitCode := 0;
  ServiceStatus.dwCheckPoint := 0;
  ServiceStatus.dwWaitHint := 0;

  StatusHandle := RegisterServiceCtrlHandler(ServiceName, @ServiceCtrlHandler);

  if StatusHandle <> 0 then
  begin
    ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0);
    try
      Stopped := False;
      Paused  := False;
      MainProc;
    finally
      ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
    end;
  end;
end;

procedure UninstallService(const ServiceName: PChar; const Silent: Boolean);
const
  cRemoveMsg = 'Your service was removed sucesfuly!';
var
  SCManager: SC_HANDLE;
  Service: SC_HANDLE;
begin
  SCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if SCManager = 0 then
    Exit;
  try
    Service := OpenService(SCManager, ServiceName, SERVICE_ALL_ACCESS);
    ControlService(Service, SERVICE_CONTROL_STOP, ServiceStatus);
    DeleteService(Service);
    CloseServiceHandle(Service);
    if not Silent then
      MessageBox(0, cRemoveMsg, ServiceName, MB_ICONINFORMATION or MB_OK or MB_TASKMODAL or MB_TOPMOST);
  finally
    CloseServiceHandle(SCManager);
    AfterUninstall;
  end;
end;

procedure InstallService(const ServiceName, DisplayName, LoadOrder: PChar;
  const FileName: string; const Silent: Boolean);
const
  cInstallMsg = 'Your service was Installed sucesfuly!';
  cSCMError = 'Error trying to open SC Manager';
var
  SCMHandle  : SC_HANDLE;
  SvHandle   : SC_HANDLE;
begin
  SCMHandle := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);

  if SCMHandle = 0 then
  begin
    MessageBox(0, cSCMError, ServiceName, MB_ICONERROR or MB_OK or MB_TASKMODAL or MB_TOPMOST);
    Exit;
  end;

  try
    SvHandle := CreateService(SCMHandle,
                              ServiceName,
                              DisplayName,
                              SERVICE_ALL_ACCESS,
                              SERVICE_WIN32_OWN_PROCESS,
                              SERVICE_AUTO_START,
                              SERVICE_ERROR_IGNORE,
                              pchar(FileName),
                              LoadOrder,
                              nil,
                              nil,
                              nil,
                              nil);
    CloseServiceHandle(SvHandle);

    if not Silent then
      MessageBox(0, cInstallMsg, ServiceName, MB_ICONINFORMATION or MB_OK or MB_TASKMODAL or MB_TOPMOST);
  finally
    CloseServiceHandle(SCMHandle);
  end;
end;

procedure WriteHelpContent;
begin
  WriteLn('To install your service please type <service name> /install');
  WriteLn('To uninstall your service please type <service name> /remove');
  WriteLn('For help please type <service name> /? or /h');
end;

begin
  if (ParamStr(1) = '/h') or (ParamStr(1) = '/?') then
    WriteHelpContent
  else if ParamStr(1) = '/install' then
    InstallService(ServiceName, DisplayName, 'System Reserved', ParamStr(0), ParamStr(2) = '/s')
  else if ParamStr(1) = '/remove' then
    UninstallService(ServiceName, ParamStr(2) = '/s')
  else if ParamCount = 0 then
  begin
    OnServiceCreate;

    ServiceTable[0].lpServiceName := ServiceName;
    ServiceTable[0].lpServiceProc := @RegisterService;
    ServiceTable[1].lpServiceName := nil;
    ServiceTable[1].lpServiceProc := nil;

    StartServiceCtrlDispatcher(ServiceTable[0]);
  end
  else
    WriteLn('Wrong argument!');
end.

EDIT:

I compiled the above code without resources and SysUtils. I got 32KB executable under Delphi XE and 22KB executable under Delphi 2006. Under XE I removed the RTTI information. I will blog about this because it is interesting. I want to know how large is the C++ executable.

EDIT2:

I updated the code. It is a working code now. Most of the larger bugs should be gone. It is still by no means production quality.

Screen capture with C# and Remote Desktop problems

9 votes

Hello all,

I have a C sharp console application that captures a screenshot of a MS Word document serveral times. It works great, but when I place this application on a remote windows XP machine it works fine whilst I am remoted in i.e. my remote desktop is visible but if I run my app and leave remote desktop (minimize it, not even log off which I want to do) the screenshots it takes are blank!

The Screenshot app is being run by a service that runs as SYSTEM user.

How can I keep the GUI alive for windows even when there are no users connected?

Here is the code I use:

public Image CaptureWindow(IntPtr handle)
{
    // get te hDC of the target window
    IntPtr hdcSrc = User32.GetWindowDC(handle);
    // get the size
    User32.RECT windowRect = new User32.RECT();
    User32.GetWindowRect(handle, ref windowRect);
    int width = windowRect.right - windowRect.left;
    int height = windowRect.bottom - windowRect.top;
    // create a device context we can copy to
    IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
    // create a bitmap we can copy it to,
    // using GetDeviceCaps to get the width/height
    IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
    // select the bitmap object
    IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
    // bitblt over
    GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
    // restore selection
    GDI32.SelectObject(hdcDest, hOld);
    // clean up 
    GDI32.DeleteDC(hdcDest);
    User32.ReleaseDC(handle, hdcSrc);

    // get a .NET image object for it
    Image img = Image.FromHbitmap(hBitmap);
    // free up the Bitmap object
    GDI32.DeleteObject(hBitmap);

    return img;
}

Thanks all for any help.

Update

I am currently making use of PrintWindow which is the only thing that has come the closest as it manages to capture the window frame (i.e the minimise, maxmise and close buttons) but the inner part is black.

Although it hasn't fully worked, its proved to me that it is possible to create an image from a window handle whilst the application isn't even visible to a user.

Some time ago we were doing something similar, and we found that when RDC is minimized, the remote desktop session is not redrawn or accept keys or mouse events. Everything was working fine until we minimized the RDC screen. A colleague found out that this is done for performance reasons.

Some days ago I stumbled upon this, but I haven't had the chance to try it. If you try and it works, please let me know :)

Interacting with remote desktop when RDC is minimized

Regarding your comments: I think this is another kind of issue... I understand that you need your application to work even if no one is logged into the machine. I've implemented services that are allowed to interact with the desktop, for example, to launch an application and automate it. Even no one is logged in the machine, you can still manipulate the UI, for example, with an UI automation library (or your code, I assume).

After starting the machine, when my service and automated application are running everything works fine. Later on, the UI being automated will appear on the desktop of the first person who logs in (I was a machine administrator, I don't know what will happen when somebody with less privileges logs in).

I don't know what will happen if the first login is done through RDC. Maybe you could try changing those RDC settings id this affects the behavior of your application. Another option is:

  1. Disable RDC and configure windows to Autologin with an specified account
  2. Connect to this machine using another remote desktop application (e.g. TightVNC)

Does this help?

Terminate application AND call the destructors of local objects

8 votes

Hi, there!

I have some objects on the stack in main function:

int main(...)
{
   CFoo foo;
   CBar bar;
}

Also, I have a function, that keeps track of errors in my application:

void Err(std::string msg)
{
   SomehowLogErrorMessage(msg);
   exit(1);
}

Err function is definitely useful when I have to report a fatal error. I just log the error and terminate the application - it cannot recover after such errors. However, terminating with "exit()" does not invoke foo and bar destructors - a behavior, that I actually expected (but was wrong). "abort()" doesn't help either. Also, I cannot use exceptions to catch them in main(). Is there any other way to implement Err function so, that it terminates the app and correctly cleans the stack objects? Or should I somehow redesign my error handling?

Thanks!


p.s. By the way, can't I send WM_QUIT message to my main window? I am not good with WinAPI, but my app is pure Win32 and my Err() function can get a handle to my main window. Will it work?

Not without exceptions or returning normally from Err all the way up the callstack. You need to unwind the stack.

Programming In C + Win API: How To Get Windows 7 Look For Controls?

8 votes

I am programming strictly in C and WinAPI, no C++ or C#. I am a beginner and just learning to draw controls etc. The thing is that when I create Windows or other controls like Command Buttons, they have Windows Native look. Take a look at this:

This is look I am getting!

But in Windows 7, the command buttons look like this:

enter image description here

Now, how do I get command buttons in my program to look like that. Is it even possible? I am following this tutorial, for reference: http://www.zetcode.com/tutorials/winapi/

Thanks.

You enable visual styles for your app by providing an XML manifest, either as a separate file or as an embedded resource. See Enabling Visual Styles for details.

Which version of PHP should I install?

8 votes

Hi there, I'm currently about to install PHP for an Apache/Windows-based development environment, but it seems I'm about to fall at the first hurdle: Choosing a package to install.

PHP is available in no less than four flavours:

  • VC9 x86 Non Thread Safe
  • VC9 x86 Thread Safe
  • VC6 x86 Non Thread Safe
  • VC6 x86 Thread Safe

If this wasn't complicated enough, version 5.3 of PHP is only available in VC9 (with 5.2 coming with the VC6 packages). And yet, according to the PHP site, you should not use VC9 with Apache... So why does Apache get the older version?

It's all very confusing and I'd really appreciate some help understanding the choices. Thanks!

Link: http://windows.php.net/download/

After a lot of research, I've managed to find my own answers to this question.

In its most basic form, the answer is: What version of PHP you should install comes down what webserver you are running.

Here's a deeper explanation of the terms used in picking a version of PHP based on what I learned:

VC6 vs VC9
Firstly, different versions of Apache for Windows are compiled with different compilers. For example, the versions on Apache.org are designed to be compiled using Microsoft Visual C++ 6, also known as VC6. This compiler is very popular, but also very old. (It dates back to 1998.)

There are different versions of Apache made for different compilers. For example, the versions available for download from ApacheLounge.com are designed to be compiled with the popular and more much recent compiler, Microsoft Visual C++ 9 from 2008. Also known as VC9.

(Note: These two compilers are the two most popular options. So while it's possible to have a VC7, VC8, etc. compiled version of Apache, it's unlikely that you'll come across them.)

The use of this more recent compiler (VC9) is important because the latest versions of PHP are only being distributed in VC9 form (although older versions are still available for VC6).

On top of that, according to ApacheLounge there are numerous improvements when using a version of Apache compiled with VC9, "in areas like Performance, MemoryManagement and Stability".

If that wasn't enough, the developers of PHP made the following statement on their site:

Windows users: please mind that we do no longer provide builds created with Visual Studio C++ 6 (VC6). It is impossible to maintain a high quality and safe build of PHP for Windows using this unmaintained compiler.

We recommend the VC9 Apache builds as provided by ApacheLounge.

All PHP users should note that the PHP 5.2 series is NOT supported anymore. All users are strongly encouraged to upgrade to PHP 5.3.6.

In all, this is an extremely compelling argument to use VC9 versions of Apache and PHP, if you ask me.

So if you're using a version of Apache from the official Apache site, it will be compiled with VC6, and as such, you should use the older version of PHP for that compiler. If you're using a version of Apache compiled with VC9, like the one available on ApacheLounge.com, you can use the latest version of PHP (for VC9).

For me, running a local development environment, it would be preferable to have the latest version of PHP, so a VC9 version of Apache is required, so I can use the VC9 version of PHP.

Thread Safe vs Non Thread Safe
Once again this comes down to your webserver. By default Apache is installed on Windows as Module, but it can be changed to run as FastCGI. There's plenty of differences between the two, but essentially FastCGI is more modern, faster, more robust, and more resource hungry. For someone running a local development environment, FastCGI might be overkill, but apparently lots of hosting companies run as FastCGI for the reasons I've stated, so there are good arguments for doing so in a development environment.

If you're running Apache (or IIS) as FastCGI (or CGI) then you want the Non Thread Safe version of PHP. If you're running Apache as default (as a Module), then you'll want the more traditional Thread Safe version.

Please note: This all only applies to Windows users.

I'm not going to bother with FastCGI (unless someone convinces me otherwise), so for me, I want the VC9 Thread Safe version of PHP.

And that's it.

Further reading:

Tabs in title bar: what's the secret?

7 votes

Chrome and Firefox 4, among other applications, now put some of their user interface in the title bar. In Windows, the OS normally controls the entire title bar. An application can create a custom title bar by removing the OS title bar and drawing a "fake" title bar instead (like WinAmp), but only the OS knows how to draw the non-customized elements of the title bar (e.g. Close/Minimize/Maximize), which vary by OS version.

By what mechanism do apps like Chrome and Firefox "share" the title bar with the OS (put custom elements in the title bar while keeping the original OS visual theme)?

enter image description here

In Chrome, the tabs encroach upon the title bar so that there is not enough space for title text.

Microsoft has a very detailed explanation in the article Custom Window Frame Using DWM.

7 votes

How to programmatically add an application or port to Windows Firewall.

Try this code extracted from our open source SQlite3UI.pas unit:

function GetXPFirewall(var fwMgr, profile: OleVariant): boolean;
begin
  Result := (Win32Platform=VER_PLATFORM_WIN32_NT) and
    (Win32MajorVersion>5) or ((Win32MajorVersion=5) and (Win32MinorVersion>0));
  if result then // need Windows XP at least
  try 
    fwMgr := CreateOleObject('HNetCfg.FwMgr');
    profile := fwMgr.LocalPolicy.CurrentProfile;
  except
    on E: Exception do
      result := false;
  end;
end;

const
  NET_FW_PROFILE_DOMAIN = 0;
  NET_FW_PROFILE_STANDARD = 1;
  NET_FW_IP_VERSION_ANY = 2;
  NET_FW_IP_PROTOCOL_UDP = 17;
  NET_FW_IP_PROTOCOL_TCP = 6;
  NET_FW_SCOPE_ALL = 0;
  NET_FW_SCOPE_LOCAL_SUBNET = 1;

procedure AddApplicationToXPFirewall(const EntryName, ApplicationPathAndExe: string);
var fwMgr, profile, app: OleVariant;
begin
  if GetXPFirewall(fwMgr,profile) then
  try
    if profile.FirewallEnabled then begin
      app := CreateOLEObject('HNetCfg.FwAuthorizedApplication');
      try
        app.ProcessImageFileName := ApplicationPathAndExe;
        app.Name := EntryName;
        app.Scope := NET_FW_SCOPE_ALL;
        app.IpVersion := NET_FW_IP_VERSION_ANY;
        app.Enabled :=true;
        profile.AuthorizedApplications.Add(app);
      finally
        app := varNull;
      end;
    end;
  finally
    profile := varNull;
    fwMgr := varNull;
  end;
end;

procedure AddPortToXPFirewall(const EntryName: string; PortNumber: cardinal);
var fwMgr, profile, port: OleVariant;
begin
  if GetXPFirewall(fwMgr,profile) then
  try
    if profile.FirewallEnabled then begin
      port := CreateOLEObject('HNetCfg.FWOpenPort');
      port.Name := EntryName;
      port.Protocol := NET_FW_IP_PROTOCOL_TCP;
      port.Port := PortNumber;
      port.Scope := NET_FW_SCOPE_ALL;
      port.Enabled := true;
      profile.GloballyOpenPorts.Add(port);
    end;
  finally
    port := varNull;
    profile := varNull;
    fwMgr := varNull;
  end;
end;

It will allow you to add an application or a port to the XP firewall. Should work from Delphi 6 up to XE.

Why does GetCurrentProcess return -1?

7 votes

In this small program, why does GetCurrentProcess() return -1?

int _tmain(int argc, _TCHAR* argv[]) {
    HANDLE h = GetCurrentProcess(); // ret -1 
    printf("0x%x\n",(DWORD)h); 
    return 0;
}

What's wrong?

In Kernel32.GetCurrentProcess I see this:

OR EAX,FFFFFFFF  ; EAX - ?
RETN

That is correct, see this API reference for GetCurrentProcess.

The GetCurrentProcess function retrieves a pseudo-handle for the current process, which is currently defined as (HANDLE)-1. However, because you should not assume that the value will never change, the GetCurrentProcess function is provided as an alternative to hard-coding the constant into your code.

Why would our software run so much slower under virtualization?

6 votes

I'm trying to figure out why our software runs so much slower when run under virtualization. Most of the stats I've seen, say it should be only a 10% performance penalty in the worst case, but on a Windows virtual server, the performance penalty can is 100-400%. I've been trying to profile the differences, but the profile results don't make a lot of sense to me. Here's what I see when I profile on my Vista 32-bit box with no virtualization: enter image description here

And here's one run on a Windows 2008 64-bit server with virtualization:enter image description here

The slow one is spending a very large amount of it's time in RtlInitializeExceptionChain which shows as 0.0s on the fast one. Any idea what that does? Also, when I attach to the process my machine, there is only a single thread, PulseEvent however when I connect on the server, there are two threads, GetDurationFormatEx and RtlInitializeExceptionChain. As far as I know, the code as we've written in uses only a single thread. Also, for what it's worth this is a console only application written in pure C with no UI at all.

Can anybody shed any light on any of this for me? Even just information on what some of these ntdll and kernel32 calls are doing? I'm also unsure how much of the differences are 64/32-bit related and how many are virtual/not-virtual related. Unfortunately, I don't have easy access to other configurations to determine the difference.

I suppose we could divide reasons for slower performance on a virtual machine into two classes:

1. Configuration Skew

This category is for all the things that have nothing to do with virtualization per se but where the configured virtual machine is not as good as the real one. A really easy thing to do is to give the virtual machine just one CPU core and then compare it to an application running on a 2-CPU 8-core 16-hyperthread Intel Core i7 monster. In your case, at a minimum you did not run the same OS. Most likely there is other skew as well.

2. Bad Virtualization Fit

Things like databases that do a lot of locking do not virtualize well and so the typical overhead may not apply to the test case. It's not your exact case, but I've been told the penalty is 30-40% for MySQL. I notice an entry point called ...semaphore in your list. That's a sign of something that will virtualize slowly.

The basic problem is that constructs that can't be executed natively in user mode will require traps (slow, all by themselves) and then further overhead in hypervisor emulation code.

IOCP C++ TCP client

6 votes

Hi All,

I am having some trouble implementing TCP IOCP client. I have implemented kqueue on Mac OSX so was looking to do something similar on windows and my understanding is that IOCP is the closest thing. The main problem is that GetCompetetionStatus is never returning and always timeouts out. I assume I am missing something when creating the handle to monitor, but not sure what. This is where I have gotten so far:

My connect routine: (remove some error handling for clarity )

struct sockaddr_in server;
struct hostent *hp;
SOCKET sckfd;
WSADATA wsaData;

int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );


if ((hp = gethostbyname(host)) == NULL)
    return NULL;
WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED)
if ((sckfd = WSASocket(AF_INET,SOCK_STREAM,0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
    printf("Error at socket(): Socket\n");
    WSACleanup();
    return NULL;
}

server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr = *((struct in_addr *)hp->h_addr);
memset(&(server.sin_zero), 0, 8);

//non zero means non blocking. 0 is blocking.
u_long iMode = -1;
iResult = ioctlsocket(sckfd, FIONBIO, &iMode);
if (iResult != NO_ERROR)
    printf("ioctlsocket failed with error: %ld\n", iResult);


HANDLE hNewIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, ulKey, 0);
CreateIoCompletionPort((HANDLE)sckfd, hNewIOCP , ulKey, 0);

connect(sckfd, (struct sockaddr *)&server, sizeof(struct sockaddr));

//WSAConnect(sckfd, (struct sockaddr *)&server, sizeof(struct sockaddr),NULL,NULL,NULL,NULL);

return sckfd;   

Here is the send routine: ( also remove some error handling for clarity )

IOPortConnect(int ServerSocket,int timeout,string& data){

char buf[BUFSIZE];
strcpy(buf,data.c_str());
WSABUF buffer = { BUFSIZE,buf };
DWORD bytes_recvd;
int r;
ULONG_PTR ulKey = 0;
OVERLAPPED overlapped;
 OVERLAPPED* pov = NULL;
HANDLE port;

HANDLE hNewIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, ulKey, 0);
CreateIoCompletionPort((HANDLE)ServerSocket, hNewIOCP , ulKey, 0);


BOOL get = GetQueuedCompletionStatus(hNewIOCP,&bytes_recvd,&ulKey,&pov,timeout*1000);

if(!get)
    printf("waiton server failed. Error: %d\n",WSAGetLastError());
if(!pov)
    printf("waiton server failed. Error: %d\n",WSAGetLastError());

port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, (u_long)0, 0);

SecureZeroMemory((PVOID) & overlapped, sizeof (WSAOVERLAPPED));

r = WSASend(ServerSocket, &buffer, 1, &bytes_recvd, NULL, &overlapped, NULL);
printf("WSA returned: %d WSALastError: %d\n",r,WSAGetLastError());
if(r != 0)
{
    printf("WSASend failed %d\n",GetLastError());
    printf("Bytes transfered: %d\n",bytes_recvd);
}
if (WSAGetLastError() == WSA_IO_PENDING)
    printf("we are async.\n");
CreateIoCompletionPort(port, &overlapped.hEvent,ulKey, 0);

BOOL test = GetQueuedCompletionStatus(port,&bytes_recvd,&ulKey,&pov,timeout*1000); 

CloseHandle(port);
return true;

}

Any insight would be appreciated.

You are associating the same socket with multiple IOCompletionPorts. I'm sure thats not valid. In your IOPortConnect function (Where you do the write) you call CreateIOCompletionPort 4 times passing in one shot handles.

My advice:

  • Create a single IOCompletion Port (that, ultimately, you associate numerous sockets with).
  • Create a pool of worker threads (by calling CreateThread) that each then block on the IOCompletionPort handle by calling GetQueuedCompletionStatus in a loop.
  • Create one or more WSA_OVERLAPPED sockets, and associate each one with the IOCompletionPort.
  • Use the WSA socket functions that take an OVERLAPPED* to trigger overlapped operations.
  • Process the completion of the issued requests as the worker threads return from GetQueuedCompletionStatus with the OVERLAPPED* you passed in to start the operation.

Note: WSASend returns both 0, and SOCKET_ERROR with WSAGetLastError() as WSA_IO_PENDING as codes to indicate that you will get an IO Completion Packet arriving at GetQueuedCompletionStatus. Any other error code means you should process the error immediately as an IO operation was not queued so there will be no further callbacks.

Note2: The OVERLAPPED* passed to the WSASend (or whatever) function is the OVERLAPPED* returned from GetQueuedCompletionStatus. You can use this fact to pass more context information with the call:

struct MYOVERLAPPED {
  OVERLAPPED ovl;
};
MYOVERLAPPED ctx;
WSASend(...,&ctx.ovl);
...
OVERLAPPED* pov;
if(GetQueuedCompletionStatus(...,&pov,...)){
  MYOVERLAPPED* pCtx = (MYOVERLAPPED*)pov;

swf to exe, real world experience

5 votes

hi there

i'm facing a challenge of rebrushing and updating an almost 10-years old Screenweaver project, and looking for a decent modern swf-exe convertor. Don't have much time to evaluate all the options, therefore i'd like to hear responses with actual working experience with such a tool.

Since WinAPI interaction is a must, the default projector is not an option.

Similar questions (no concrete answers there)

Package SWF into an EXE or APP

Create an EXE from a SWF using Flex 3 without requiring AIR?

Many thanks

UPD: 300 bounty for anyone who can help me with a practical answer.

I've been experimenting with different SWF projectors for a long time now, and so far I think I've tried most if not all of them. I've explained in more detail the best projectors I have used below.

MDM Zinc

http://www.multidmedia.com/software/zinc/

I remember back in when I had Vista that MDM had quite a few bugs running under that OS. It took a while for them to fix those bugs - the bugs didn't stop it from running, but really interfered with the functioning of some methods in the program. For this reason, I decided not to continue testing Zinc and moved on to another projector. Saying that though, I'm certain they have fixed those bugs now.

The program itself has a nice intuitive interface, and allows you create screensaver as well as EXEs (which is obviously good for you).

The product is pricey - currently at $349.99, so this put me off. You can also generate Mac and Linux projectors which is very attractive, but requires an additional license for each which does cost a lot of money.

SWF Studio

http://www.northcode.com/

This was one of the projectors I really enjoyed working with. It's fully featured, has great community support and the developers are always on hand to help. The projectors it generates are compatible with all Windows operating systems, and I've never had any problems with bugs on this one.

Northcode also offer a student license for SWF Studio for $49. I nearly purchased a license with these guys but the only reason why I didn't was because I found another projector which was better for my scenario which I will come onto in a moment.

I can tell you that one of the reasons why I didn't use this projector (it does sound trivial) is because it had a large file size. SWF Studio allows you to select what size projector you want in terms of filesize - with options like tiny and compact I think but the smaller file types might have dependencies with other files in the directory. This means that you would have to bundle your application with some folders and additional files as well as the EXE itself.

SWF Studio also has the option to create screensavers.

mProjector

http://www.screentime.com/software/flash-projector

mProjector has gone up a version (from 3 to 4) since I last used it, so it may incorporate a lot more features in this version. I remember that the product is very good with transparency, and showcases some 'screen buddies' which use transparency to virtually walk about your screen. The reason why I didn't use this projector is because it didn't have as many Actionscript functions as I would have liked, but I believe it has a lot more nowadays. In your project this wouldn't be so much of a problem because you want a screensaver.

It is reasonably priced at $399 for both Windows and Mac compatibility, but you can buy just Windows or Mac if you wish for a cheaper price.

Janus Flash

I was going to explain this product in more detail but I have now realised that the website no longer exists! Janus is the projector I liked the most and ended up using because of the sheer amount of features available for use in your code.

Like all the projectors I have mentioned above, each one adds functionality to flash which you don't usually get with an SWF. Each product includes pre-built actionscript methods which can interface with the operating system itself to do things you can't do in the Flash sandbox. For example, each one of these projectors allows you to manipulate files (add, edit, delete e.t.c.) on the computer. Janus had the most methods available out of all the projectors I tried. This is partially because Janus used the .NET framework (which meant that .NET 2.0 was required on the system you were executing the projector on).

Also like MDM Zinc, this product allowed you to create applications for the Mac too. I managed to get a cheaper price too when I contacted them directly explaining that I was a student. I recently contacted Janus-Flash to ask about the future of the product, and they said that they may re-release Janus in the future, but for now it's off the market.

Some other products I have used which are worth a mention but I haven't explained in detail: SWFKit, Jugglor, F-IN-BOX (more developer releated as it required cutting code).

A quick search brings up these which might be worth a look: Flash2Me, Flash EXE Builder and SWF to Screensaver.

For your project I think the best option would be SWF Studio. It has lots of nice scripting features you can use to interface with the OS, and is nicely priced too at $299 for a full license.

I hope this helps in your decision for what projector to use, and will save you from trying out many different projectors like I did over several months!

How to do Heroku-like Delayed Jobs in C#.NET?

5 votes

Would like to implement something similar to this for our C#.NET Web App. http://devcenter.heroku.com/articles/queueing

What pre-existing solutions are already out there that will work with .NET?

Even I am looking for something similar. The library closest to DelayedJob seems to be Quartz.net http://quartznet.sourceforge.net/features.html

Obviously we wont get certain features from DJ, like prepend a function name with delayed to delay the execution of the function, in the .Net world...