Best windows questions in May 2012

Is it possible to call a non-exported function that resides in an exe?

13 votes

I'd like to call a function that resides in a 3rd-party .exe and obtain its result. It seems like there should be a way, as long as I know the function address, calling-convention, etc... but I don't know how.

Does anyone know how I would do this?

I realize that any solution would be a non-standard hack, but there must be a way!


My non-nefarious use-case: I'm reverse engineering a file-format for my software. The calculations in this function are too complex for my tiny brain to figure out; I've been able to pull the assembly-code directly into my own DLL for testing, but of course I can't release that, as that would be stealing. I will be assuming users already have this particular application pre-installed so my software will run.

OK, I've put together a prototype.

This program creates another instance of itself as a debugged child process.

An automatic breakpoint will be encountered before main() and CRT initialization code. This is when we can change the memory and registers of the debugged process to make it execute a function of interest. And that's what the program does.

It tries to catch and handle all the bad situations (e.g. unexpected exceptions) and reports them as errors.

One bad situation is actually a good one. It's the #UD exception from the UD2 instruction that the program places into the debugged process. It uses this #UD to stop the process execution after the function of interest has returned.

A few more notes:

  1. This code is 32-bit only. I didn't even try to make it 64-bit compilable or support 64-bit child processes.

  2. This code will likely leak handles. See the Windows Debug API function descriptions on MSDN to find out where they need to be closed.

  3. This code is a proof of concept only and does not support passing and returning data via pointers or registers other than EAX, ECX and EDX. You'll have to extend it as necessary.

  4. This code requires some privileges in order to be able to create and fully debug a process. You may have to worry about this if your program's users aren't admins.

Enjoy.

Code:

// file: unexported.c
//
// compile with Open Watcom C/C++: wcl386 /q /wx /we /s unexported.c
//   (Note: "/s" is needed to avoid stack check calls from the "unexported"
//    functions, these calls are through a pointer, and it'll be
//    uninitialized in our case.)
//
// compile with MinGW gcc 4.6.2: gcc unexported.c -o unexported.exe
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <limits.h>

#ifndef C_ASSERT
#define C_ASSERT(expr) extern char CAssertExtern[(expr)?1:-1]
#endif

// Compile as a 32-bit app only.
C_ASSERT(sizeof(void*) * CHAR_BIT == 32);

#define EXC_CODE_AND_NAME(X) { X, #X }

const struct
{
  DWORD Code;
  PCSTR Name;
} ExcCodesAndNames[] =
{
  EXC_CODE_AND_NAME(EXCEPTION_ACCESS_VIOLATION),
  EXC_CODE_AND_NAME(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
  EXC_CODE_AND_NAME(EXCEPTION_BREAKPOINT),
  EXC_CODE_AND_NAME(EXCEPTION_DATATYPE_MISALIGNMENT),
  EXC_CODE_AND_NAME(EXCEPTION_FLT_DENORMAL_OPERAND),
  EXC_CODE_AND_NAME(EXCEPTION_FLT_DIVIDE_BY_ZERO),
  EXC_CODE_AND_NAME(EXCEPTION_FLT_INEXACT_RESULT),
  EXC_CODE_AND_NAME(EXCEPTION_FLT_INVALID_OPERATION),
  EXC_CODE_AND_NAME(EXCEPTION_FLT_OVERFLOW),
  EXC_CODE_AND_NAME(EXCEPTION_FLT_STACK_CHECK),
  EXC_CODE_AND_NAME(EXCEPTION_FLT_UNDERFLOW),
  EXC_CODE_AND_NAME(EXCEPTION_ILLEGAL_INSTRUCTION),
  EXC_CODE_AND_NAME(EXCEPTION_IN_PAGE_ERROR),
  EXC_CODE_AND_NAME(EXCEPTION_INT_DIVIDE_BY_ZERO),
  EXC_CODE_AND_NAME(EXCEPTION_INT_OVERFLOW),
  EXC_CODE_AND_NAME(EXCEPTION_INVALID_DISPOSITION),
  EXC_CODE_AND_NAME(EXCEPTION_NONCONTINUABLE_EXCEPTION),
  EXC_CODE_AND_NAME(EXCEPTION_PRIV_INSTRUCTION),
  EXC_CODE_AND_NAME(EXCEPTION_SINGLE_STEP),
  EXC_CODE_AND_NAME(EXCEPTION_STACK_OVERFLOW),
  EXC_CODE_AND_NAME(EXCEPTION_GUARD_PAGE),
  EXC_CODE_AND_NAME(DBG_CONTROL_C),
  { 0xE06D7363, "C++ EH exception" }
};

PCSTR GetExceptionName(DWORD code)
{
  DWORD i;

  for (i = 0; i < sizeof(ExcCodesAndNames) / sizeof(ExcCodesAndNames[0]); i++)
  {
    if (ExcCodesAndNames[i].Code == code)
    {
      return ExcCodesAndNames[i].Name;
    }
  }

  return "?";
}

typedef enum tCallConv
{
  CallConvCdecl,    // Params on stack; caller removes params
  CallConvStdCall,  // Params on stack; callee removes params
  CallConvFastCall  // Params in ECX, EDX and on stack; callee removes params
} tCallConv;

DWORD Execute32bitFunctionFromExe(PCSTR ExeName,
                                  int FunctionAddressIsRelative,
                                  DWORD FunctionAddress,
                                  tCallConv CallConvention,
                                  DWORD CodeDataStackSize,
                                  ULONG64* ResultEdxEax,
                                  DWORD DwordParamsCount,
                                  .../* DWORD params */)
{
  STARTUPINFO startupInfo;
  PROCESS_INFORMATION processInfo;
  DWORD dwContinueStatus = DBG_CONTINUE; // exception continuation
  DEBUG_EVENT dbgEvt;
  UCHAR* procMem = NULL;
  DWORD breakPointCount = 0;
  DWORD err = ERROR_SUCCESS;
  DWORD ecxEdxParams[2] = { 0, 0 };
  DWORD imageBase = 0;
  CONTEXT ctx;
  va_list ap;

  va_start(ap, DwordParamsCount);

  *ResultEdxEax = 0;

  memset(&startupInfo, 0, sizeof(startupInfo));
  startupInfo.cb = sizeof(startupInfo);
  memset(&processInfo, 0, sizeof(processInfo));

  if (!CreateProcess(
    NULL,
    (LPSTR)ExeName,
    NULL,
    NULL,
    FALSE,
    DEBUG_ONLY_THIS_PROCESS, // DEBUG_PROCESS,
    NULL,
    NULL,
    &startupInfo,
    &processInfo))
  {
    printf("CreateProcess() failed with error 0x%08X\n",
           err = GetLastError());
    goto Cleanup;
  }

  printf("Process 0x%08X (0x%08X) \"%s\" created,\n"
         "  Thread 0x%08X (0x%08X) created\n",
         processInfo.dwProcessId,
         processInfo.hProcess,
         ExeName,
         processInfo.dwThreadId,
         processInfo.hThread);

  procMem = VirtualAllocEx(
    processInfo.hProcess,
    NULL,
    CodeDataStackSize,
    MEM_COMMIT | MEM_RESERVE,
    PAGE_EXECUTE_READWRITE);

  if (procMem == NULL)
  {
    printf("VirtualAllocEx() failed with error 0x%08X\n",
           err = GetLastError());
    goto Cleanup;
  }

  printf("Allocated RWX memory in process 0x%08X (0x%08X) "
         "at address 0x%08X\n",
         processInfo.dwProcessId,
         processInfo.hProcess,
         procMem);

  while (dwContinueStatus)
  {
    // Wait for a debugging event to occur. The second parameter indicates
    // that the function does not return until a debugging event occurs.
    if (!WaitForDebugEvent(&dbgEvt, INFINITE))
    {
      printf("WaitForDebugEvent() failed with error 0x%08X\n",
             err = GetLastError());
      goto Cleanup;
    }

    // Process the debugging event code.
    switch (dbgEvt.dwDebugEventCode)
    {
    case EXCEPTION_DEBUG_EVENT:
    // Process the exception code. When handling
    // exceptions, remember to set the continuation
    // status parameter (dwContinueStatus). This value
    // is used by the ContinueDebugEvent function.

      printf("%s (%s) Exception in process 0x%08X, thread 0x%08X\n"
             "  Exc. Code = 0x%08X (%s), Instr. Address = 0x%08X",
             dbgEvt.u.Exception.dwFirstChance ?
               "First Chance" : "Last Chance",
             dbgEvt.u.Exception.ExceptionRecord.ExceptionFlags ?
               "non-continuable" : "continuable",
             dbgEvt.dwProcessId,
             dbgEvt.dwThreadId,
             dbgEvt.u.Exception.ExceptionRecord.ExceptionCode,
             GetExceptionName(dbgEvt.u.Exception.ExceptionRecord.ExceptionCode),
             dbgEvt.u.Exception.ExceptionRecord.ExceptionAddress);

      if (dbgEvt.u.Exception.ExceptionRecord.ExceptionCode ==
          EXCEPTION_ACCESS_VIOLATION)
      {
        ULONG_PTR* info = dbgEvt.u.Exception.ExceptionRecord.ExceptionInformation;
        printf(",\n  Access Address = 0x%08X, Access = 0x%08X (%s)",
               (DWORD)info[1],
               (DWORD)info[0],
               (info[0] == 0) ?
                 "read" : ((info[0] == 1) ? "write" : "execute")); // 8 = DEP
      }

      printf("\n");

      // Get the thread context (register state).
      // We'll need to either display it (in case of unexpected exceptions) or
      // modify it (to execute our code) or read it (to get the results of
      // execution).
      memset(&ctx, 0, sizeof(ctx));
      ctx.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
      if (!GetThreadContext(processInfo.hThread, &ctx))
      {
        printf("GetThreadContext() failed with error 0x%08X\n",
               err = GetLastError());
        goto Cleanup;
      }

#if 0
      printf("  EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X EFLAGS=0x%08X\n"
             "  ESI=0x%08X EDI=0x%08X EBP=0x%08X ESP=0x%08X EIP=0x%08X\n",
             ctx.Eax, ctx.Ebx, ctx.Ecx, ctx.Edx, ctx.EFlags, 
             ctx.Esi, ctx.Edi, ctx.Ebp, ctx.Esp, ctx.Eip);
#endif

      if (dbgEvt.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT &&
          breakPointCount == 0)
      {
        // Update the context so our code can be executed
        DWORD mem, i, data;
        SIZE_T numberOfBytesCopied;

        mem = (DWORD)procMem + CodeDataStackSize;

        // Child process memory layout (inside the procMem[] buffer):
        //
        //    higher
        //  addresses
        //      .
        //      .     UD2 instruction (causes #UD, indicator of successful
        //      .     completion of FunctionAddress())
        //      .
        //      .     last on-stack parameter for FunctionAddress()
        //      .     ...
        //      .     first on-stack parameter for FunctionAddress()
        //      .
        //      .     address of UD2 instruction (as if "call FunctionAddress"
        //      .     executed just before it and is going to return to UD2)
        //      .     (ESP will point here)
        //      .
        //      .     FunctionAddress()'s stack
        //      .
        //    lower
        //  addresses

        mem -= 2;
        data = 0x0B0F; // 0x0F, 0x0B = UD2 instruction
        if (!WriteProcessMemory(processInfo.hProcess,
                                (PVOID)mem,
                                &data,
                                2,
                                &numberOfBytesCopied))
        {
ErrWriteMem1:
          printf("WriteProcessMemory() failed with error 0x%08X\n",
                 err = GetLastError());
          goto Cleanup;
        }
        else if (numberOfBytesCopied != 2)
        {
ErrWriteMem2:
          printf("WriteProcessMemory() failed with error 0x%08X\n",
                 err = ERROR_BAD_LENGTH);
          goto Cleanup;
        }

        // Copy function parameters.

        mem &= 0xFFFFFFFC; // align the address for the stack

        for (i = 0; i < DwordParamsCount; i++)
        {
          if (CallConvention == CallConvFastCall && i < 2)
          {
            ecxEdxParams[i] = va_arg(ap, DWORD);
          }
          else
          {
            data = va_arg(ap, DWORD);
            if (!WriteProcessMemory(processInfo.hProcess,
                                    (DWORD*)mem - DwordParamsCount + i,
                                    &data,
                                    sizeof(data),
                                    &numberOfBytesCopied))
            {
              goto ErrWriteMem1;
            }
            else if (numberOfBytesCopied != sizeof(data))
            {
              goto ErrWriteMem2;
            }
          }
        }

        // Adjust what will become ESP according to the number of on-stack parameters.
        for (i = 0; i < DwordParamsCount; i++)
        {
          if (CallConvention != CallConvFastCall || i >= 2)
          {
            mem -= 4;
          }
        }

        // Store the function return address.
        mem -= 4;
        data = (DWORD)procMem + CodeDataStackSize - 2; // address of UD2
        if (!WriteProcessMemory(processInfo.hProcess,
                                (PVOID)mem,
                                &data,
                                sizeof(data),
                                &numberOfBytesCopied))
        {
          goto ErrWriteMem1;
        }
        else if (numberOfBytesCopied != sizeof(data))
        {
          goto ErrWriteMem2;
        }

        // Last-minute preparations for execution...
        // Set up the registers (ECX, EDX, EFLAGS, EIP, ESP).

        if (CallConvention == CallConvFastCall)
        {
          if (DwordParamsCount >= 1) ctx.Ecx = ecxEdxParams[0];
          if (DwordParamsCount >= 2) ctx.Edx = ecxEdxParams[1];
        }

        ctx.EFlags &= ~(1 << 10); // clear DF for string instructions
        ctx.Eip = FunctionAddress + imageBase * !!FunctionAddressIsRelative;
        ctx.Esp = mem;

        if (!SetThreadContext(processInfo.hThread, &ctx))
        {
          printf("SetThreadContext() failed with error 0x%08X\n",
                 err = GetLastError());
          goto Cleanup;
        }

        printf("Copied code/data to the process\n");

#if 0
        for (i = esp; i < (DWORD)procMem + CodeDataStackSize; i++)
        {
          data = 0;
          ReadProcessMemory(processInfo.hProcess,
                            (void*)i,
                            &data,
                            1,
                            &numberOfBytesCopied);
          printf("E[SI]P = 0x%08X: 0x%02X\n", i, data);
        }
#endif

        breakPointCount++;
        dwContinueStatus = DBG_CONTINUE; // continue execution of our code
      }
      else if (dbgEvt.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION &&
               breakPointCount == 1 &&
               ctx.Eip == (DWORD)procMem + CodeDataStackSize - 2/*UD2 size*/)
      {
        // The code has finished execution as expected.
        // Collect the results.

        *ResultEdxEax = ((ULONG64)ctx.Edx << 32) | ctx.Eax;

        printf("Copied code/data from the process\n");

        dwContinueStatus = 0; // stop debugging
      }
      else
      {
        // Unexpected event. Do not continue execution.

        printf("  EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X EFLAGS=0x%08X\n"
               "  ESI=0x%08X EDI=0x%08X EBP=0x%08X ESP=0x%08X EIP=0x%08X\n",
               ctx.Eax, ctx.Ebx, ctx.Ecx, ctx.Edx, ctx.EFlags, 
               ctx.Esi, ctx.Edi, ctx.Ebp, ctx.Esp, ctx.Eip);

        err = dbgEvt.u.Exception.ExceptionRecord.ExceptionCode;
        goto Cleanup;
      }
      break; // case EXCEPTION_DEBUG_EVENT:

    case CREATE_PROCESS_DEBUG_EVENT:
    // As needed, examine or change the registers of the
    // process's initial thread with the GetThreadContext and
    // SetThreadContext functions; read from and write to the
    // process's virtual memory with the ReadProcessMemory and
    // WriteProcessMemory functions; and suspend and resume
    // thread execution with the SuspendThread and ResumeThread
    // functions. Be sure to close the handle to the process image
    // file with CloseHandle.
      printf("Process 0x%08X (0x%08X) "
             "created, base = 0x%08X,\n"
             "  Thread 0x%08X (0x%08X) created, start = 0x%08X\n",
             dbgEvt.dwProcessId,
             dbgEvt.u.CreateProcessInfo.hProcess,
             dbgEvt.u.CreateProcessInfo.lpBaseOfImage,
             dbgEvt.dwThreadId,
             dbgEvt.u.CreateProcessInfo.hThread,
             dbgEvt.u.CreateProcessInfo.lpStartAddress);
      // Found image base!
      imageBase = (DWORD)dbgEvt.u.CreateProcessInfo.lpBaseOfImage;
      dwContinueStatus = DBG_CONTINUE;
      break;

    case EXIT_PROCESS_DEBUG_EVENT:
    // Display the process's exit code.
      printf("Process 0x%08X exited, exit code = 0x%08X\n",
             dbgEvt.dwProcessId,
             dbgEvt.u.ExitProcess.dwExitCode);
      // Unexpected event. Do not continue execution.
      err = ERROR_PROC_NOT_FOUND;
      goto Cleanup;

    case CREATE_THREAD_DEBUG_EVENT:
    case EXIT_THREAD_DEBUG_EVENT:
    case LOAD_DLL_DEBUG_EVENT:
    case UNLOAD_DLL_DEBUG_EVENT:
    case OUTPUT_DEBUG_STRING_EVENT:
      dwContinueStatus = DBG_CONTINUE;
      break;

    case RIP_EVENT:
      printf("RIP: Error = 0x%08X, Type = 0x%08X\n",
             dbgEvt.u.RipInfo.dwError,
             dbgEvt.u.RipInfo.dwType);
      // Unexpected event. Do not continue execution.
      err = dbgEvt.u.RipInfo.dwError;
      goto Cleanup;
    } // end of switch (dbgEvt.dwDebugEventCode)

    // Resume executing the thread that reported the debugging event.
    if (dwContinueStatus)
    {
      if (!ContinueDebugEvent(dbgEvt.dwProcessId,
                              dbgEvt.dwThreadId,
                              dwContinueStatus))
      {
        printf("ContinueDebugEvent() failed with error 0x%08X\n",
               err = GetLastError());
        goto Cleanup;
      }
    }
  } // end of while (dwContinueStatus)

  err = ERROR_SUCCESS;

Cleanup:

  if (processInfo.hProcess != NULL)
  {
    if (procMem != NULL)
    {
      VirtualFreeEx(processInfo.hProcess, procMem, 0, MEM_RELEASE);
    }
    TerminateProcess(processInfo.hProcess, 0);
    CloseHandle(processInfo.hThread);
    CloseHandle(processInfo.hProcess);
  }

  va_end(ap);

  return err;
}

int __cdecl FunctionCdecl(int x, int y, int z)
{
  return x + y + z;
}

int __stdcall FunctionStdCall(int x, int y, int z)
{
  return x * y * z;
}

ULONG64 __fastcall FunctionFastCall(DWORD x, DWORD y, DWORD z)
{
  return (ULONG64)x * y + z;
}

int main(int argc, char** argv)
{
  DWORD err;
  ULONG64 resultEdxEax;

  err = Execute32bitFunctionFromExe(argv[0]/*ExeName*/,
                                    1/*FunctionAddressIsRelative*/,
                                    (DWORD)&FunctionCdecl -
                                      (DWORD)GetModuleHandle(NULL),
                                    CallConvCdecl,
                                    4096/*CodeDataStackSize*/,
                                    &resultEdxEax,
                                    3/*DwordParamsCount*/,
                                    2, 3, 4);
  if (err == ERROR_SUCCESS)
    printf("2 + 3 + 4 = %d\n", (int)resultEdxEax);

  err = Execute32bitFunctionFromExe(argv[0]/*ExeName*/,
                                    1/*FunctionAddressIsRelative*/,
                                    (DWORD)&FunctionStdCall -
                                      (DWORD)GetModuleHandle(NULL),
                                    CallConvStdCall,
                                    4096/*CodeDataStackSize*/,
                                    &resultEdxEax,
                                    3/*DwordParamsCount*/,
                                    -2, 3, 4);
  if (err == ERROR_SUCCESS)
    printf("-2 * 3 * 4 = %d\n", (int)resultEdxEax);

  err = Execute32bitFunctionFromExe(argv[0]/*ExeName*/,
                                    1/*FunctionAddressIsRelative*/,
                                    (DWORD)&FunctionFastCall -
                                      (DWORD)GetModuleHandle(NULL),
                                    CallConvFastCall,
                                    4096/*CodeDataStackSize*/,
                                    &resultEdxEax,
                                    3/*DwordParamsCount*/,
                                    -1, -1, -1);
  if (err == ERROR_SUCCESS)
    printf("0xFFFFFFFF * 0xFFFFFFFF + 0xFFFFFFFF = 0x%llX\n",
           (unsigned long long)resultEdxEax);

  return 0;
}

Output:

Process 0x00001514 (0x00000040) "C:\MinGW\msys\1.0\home\Alex\unexported.exe" cre
ated,
  Thread 0x00000CB0 (0x0000003C) created
Allocated RWX memory in process 0x00001514 (0x00000040) at address 0x002B0000
Process 0x00001514 (0x00000044) created, base = 0x00400000,
  Thread 0x00000CB0 (0x00000048) created, start = 0x0040126C
First Chance (continuable) Exception in process 0x00001514, thread 0x00000CB0
  Exc. Code = 0x80000003 (EXCEPTION_BREAKPOINT), Instr. Address = 0x77090FAB
Copied code/data to the process
First Chance (continuable) Exception in process 0x00001514, thread 0x00000CB0
  Exc. Code = 0xC000001D (EXCEPTION_ILLEGAL_INSTRUCTION), Instr. Address = 0x002
B0FFE
Copied code/data from the process
2 + 3 + 4 = 9
Process 0x00001828 (0x0000003C) "C:\MinGW\msys\1.0\home\Alex\unexported.exe" cre
ated,
  Thread 0x00001690 (0x00000040) created
Allocated RWX memory in process 0x00001828 (0x0000003C) at address 0x002B0000
Process 0x00001828 (0x0000006C) created, base = 0x00400000,
  Thread 0x00001690 (0x00000074) created, start = 0x0040126C
First Chance (continuable) Exception in process 0x00001828, thread 0x00001690
  Exc. Code = 0x80000003 (EXCEPTION_BREAKPOINT), Instr. Address = 0x77090FAB
Copied code/data to the process
First Chance (continuable) Exception in process 0x00001828, thread 0x00001690
  Exc. Code = 0xC000001D (EXCEPTION_ILLEGAL_INSTRUCTION), Instr. Address = 0x002
B0FFE
Copied code/data from the process
-2 * 3 * 4 = -24
Process 0x00001388 (0x00000040) "C:\MinGW\msys\1.0\home\Alex\unexported.exe" cre
ated,
  Thread 0x00001098 (0x0000003C) created
Allocated RWX memory in process 0x00001388 (0x00000040) at address 0x002B0000
Process 0x00001388 (0x0000008C) created, base = 0x00400000,
  Thread 0x00001098 (0x00000090) created, start = 0x0040126C
First Chance (continuable) Exception in process 0x00001388, thread 0x00001098
  Exc. Code = 0x80000003 (EXCEPTION_BREAKPOINT), Instr. Address = 0x77090FAB
Copied code/data to the process
First Chance (continuable) Exception in process 0x00001388, thread 0x00001098
  Exc. Code = 0xC000001D (EXCEPTION_ILLEGAL_INSTRUCTION), Instr. Address = 0x002
B0FFE
Copied code/data from the process
0xFFFFFFFF * 0xFFFFFFFF + 0xFFFFFFFF = 0xFFFFFFFF00000000

Unicode console I/O in Haskell on Windows

10 votes

It seems rather difficult to get console I/O to work with Unicode characters in Haskell under windows. Here is the tale of woe:

  1. (Preliminary.) Before you even consider doing Unicode I/O in the console under windows, you need to make sure that you're using a console font which can render the characters you want. The raster fonts (the default) have infinitely poor coverage (and don't allow copy pasting of characters they can't represent), and the truetype options MS provides (consolas, lucida console) have not-great coverage (though these will allow copy/pasting of characters they cannot represent). You might consider installing DejaVu Sans Mono (follow the instructions at the bottom here; you may have to reboot before it works). Until this is sorted, no apps will be able to do much Unicode I/O; not just Haskell.
  2. Having done this, you will notice that some apps will be able to do console I/O under windows. But getting it to work remains quite complicated. There are basically two ways to write to the console under windows. (What follows is true for any language, not just Haskell; don't worry, Haskell will enter the picture in a bit!)...
  3. Option A is to use the usual c-library style byte-based i/o functions; the hope is that the OS will interpret these bytes according to some encoding which can encode all the weird and wonderful characters you want. For instance, using the equivalent technique on Mac OS X, where the standard system encoding is usually UTF8, this works great; you send out utf8 output, you see pretty symbols.
  4. On windows, it works less well. The default encoding that windows expects will generally not be an encoding covering all the Unicode symbols. So if you want to see pretty symbols this way, one way or another, you need to change the encoding. One possibility would be for your program to use the SetConsoleCP win32 command. (So then you need to bind to the Win32 library.) Or, if you'd rather not do that, you can expect your program's user to change the code page for you (they would then have to call the chcp command before they run your program).
  5. Option B is to use the Unicode-aware win32 console API commands like WriteConsoleW. Here you send UTF16 direct to windows, which renders it happily: there's no danger of an encoding mismatch because windows always expects UTF16 with these functions.

Unfortunately, neither of these options works very well from Haskell. First, there are no libraries that I know of that use Option B, so that's not very easy. This leaves option A. If you use Haskell's I/O library (putStrLn and so on), this is what the library will do. In modern versions of Haskell, it will carefully ask windows what the current code page is, and output your strings in the proper encoding. There are two problems with this approach:

  • One is not a showstopper, but is annoying. As mentioned above, the default encoding will almost never encode the characters you want: you are the user need to change to an encoding which does. Thus your user needs to chcp cp65001 before they run your program (you may find it distasteful to force your users to do this). Or you need to bind to SetConsoleCP and do the equivalent inside your program (and then use hSetEncoding so that the Haskell libraries will send output using the new encoding), which means you need to wrap the relevant part of the win32 libraries to make them Haskell-visible.
  • Much more seriously, there is a bug in windows (resolution: won't fix) which leads to a bug in Haskell which means that if you have selected any code page like cp65001 which can cover all of Unicode, Haskell's I/O routines will malfunction and fail. So essentially, even if you (or your user) set the encoding properly to some encoding which covers all the wonderful Unicode characters, and then 'do everything right' in telling Haskell to output things using that encoding, you still lose.

The bug listed above is still unresolved and listed as low priority; the basic conclusion there is that Option A (in my classification above) is unworkable and one needs to switch to Option B to get reliable results. It is not clear what the timeframe will be for this being resolved, as it looks like some considerable work.

The question is: in the meantime, can anyone suggest a workaround to allow the use of Unicode console I/O in Haskell under windows.

See also this python bug tracker database entry, grappling with the same problem in Python 3 (fix proposed, but not yet accepted into the codebase), and this stackoverflow answer, giving a workaround for this problem in Python (based on 'option B' in my classification).

I thought I would answer my own question, and list as one possible answer, the following, which is what I'm actually doing at the moment. It is quite possible that one can do better, which is why I'm asking the question! But I thought it would make sense to make the following available to people. It's basically a translation from Python to Haskell of this python workaround for the same issue. It uses 'option B' mentioned in the question.

The basic idea is that you create a module IOUtil.hs, with the following content:

{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE NoImplicitPrelude #-}
module IOUtil (
  IOUtil.interact,
  IOUtil.putChar, IOUtil.putStr, IOUtil.putStrLn, IOUtil.print,
  IOUtil.getChar, IOUtil.getLine, IOUtil.getContents, IOUtil.readIO,
  IOUtil.readLn,
  ePutChar, ePutStr, ePutStrLn, ePrint,
  trace, traceIO
  ) where

#ifdef mingw32_HOST_OS

import System.Win32.Types (BOOL, HANDLE, DWORD, LPDWORD, LPWSTR, LPCWSTR, LPVOID)
import Foreign.C.Types (CWchar)
import Foreign
import Prelude hiding (getContents, putStr, putStrLn) --(IO, Read, Show, String)
--import qualified System.IO
import qualified System.IO (getContents)
import System.IO hiding (getContents, putStr, putStrLn)
import Data.Char (ord)

 {- <http://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx>
    HANDLE WINAPI GetStdHandle(DWORD nStdHandle);
    returns INVALID_HANDLE_VALUE, NULL, or a valid handle -}

foreign import stdcall unsafe "GetStdHandle" win32GetStdHandle :: DWORD -> IO (HANDLE)

std_OUTPUT_HANDLE = -11 :: DWORD  -- all DWORD arithmetic is performed modulo 2^n
std_ERROR_HANDLE  = -12 :: DWORD

 {- <http://msdn.microsoft.com/en-us/library/aa364960(VS.85).aspx>
    DWORD WINAPI GetFileType(HANDLE hFile); -}

foreign import stdcall unsafe "GetFileType" win32GetFileType :: HANDLE -> IO (DWORD)
_FILE_TYPE_CHAR   = 0x0002 :: DWORD
_FILE_TYPE_REMOTE = 0x8000 :: DWORD

 {- <http://msdn.microsoft.com/en-us/library/ms683167(VS.85).aspx>
    BOOL WINAPI GetConsoleMode(HANDLE hConsole, LPDWORD lpMode); -}

foreign import stdcall unsafe "GetConsoleMode" win32GetConsoleMode :: HANDLE -> LPDWORD -> IO (BOOL)
_INVALID_HANDLE_VALUE = (intPtrToPtr $ -1) :: HANDLE

is_a_console :: HANDLE -> IO (Bool)
is_a_console handle
  = if (handle == _INVALID_HANDLE_VALUE) then return False
      else do ft <- win32GetFileType handle
              if ((ft .&. complement _FILE_TYPE_REMOTE) /= _FILE_TYPE_CHAR) then return False
                else do ptr <- malloc
                        cm  <- win32GetConsoleMode handle ptr
                        free ptr
                        return cm

real_stdout :: IO (Bool)
real_stdout = is_a_console =<< win32GetStdHandle std_OUTPUT_HANDLE

real_stderr :: IO (Bool)
real_stderr = is_a_console =<< win32GetStdHandle std_ERROR_HANDLE

 {- BOOL WINAPI WriteConsoleW(HANDLE hOutput, LPWSTR lpBuffer, DWORD nChars,
                              LPDWORD lpCharsWritten, LPVOID lpReserved); -}

foreign import stdcall unsafe "WriteConsoleW" win32WriteConsoleW
  :: HANDLE -> LPWSTR -> DWORD -> LPDWORD -> LPVOID -> IO (BOOL)

data ConsoleInfo = ConsoleInfo Int (Ptr CWchar) (Ptr DWORD) HANDLE

writeConsole :: ConsoleInfo -> [Char] -> IO ()
writeConsole (ConsoleInfo bufsize buf written handle) string
  = let fillbuf :: Int -> [Char] -> IO ()
        fillbuf i [] = emptybuf buf i []
        fillbuf i remain@(first:rest)
          | i + 1 < bufsize && ordf <= 0xffff = do pokeElemOff buf i asWord
                                                   fillbuf (i+1) rest
          | i + 1 < bufsize && ordf >  0xffff = do pokeElemOff buf i word1
                                                   pokeElemOff buf (i+1) word2
                                                   fillbuf (i+2) rest
          | otherwise                         = emptybuf buf i remain
          where ordf   = ord first
                asWord = fromInteger (toInteger ordf) :: CWchar
                sub    = ordf - 0x10000
                word1' = ((shiftR sub 10) .&. 0x3ff) + 0xD800
                word2' = (sub .&. 0x3FF)             + 0xDC00
                word1  = fromInteger . toInteger $ word1'
                word2  = fromInteger . toInteger $ word2'


        emptybuf :: (Ptr CWchar) -> Int -> [Char] -> IO ()
        emptybuf _ 0 []     = return ()
        emptybuf _ 0 remain = fillbuf 0 remain
        emptybuf ptr nLeft remain
          = do let nLeft'    = fromInteger . toInteger $ nLeft
               ret          <- win32WriteConsoleW handle ptr nLeft' written nullPtr
               nWritten     <- peek written
               let nWritten' = fromInteger . toInteger $ nWritten
               if ret && (nWritten > 0)
                  then emptybuf (ptr `plusPtr` (nWritten' * szWChar)) (nLeft - nWritten') remain
                  else fail "WriteConsoleW failed.\n"

    in  fillbuf 0 string

szWChar = sizeOf (0 :: CWchar)

makeConsoleInfo :: DWORD -> Handle -> IO (Either ConsoleInfo Handle)
makeConsoleInfo nStdHandle fallback
  = do handle     <- win32GetStdHandle nStdHandle
       is_console <- is_a_console handle
       let bufsize = 10000
       if not is_console then return $ Right fallback
         else do buf     <- mallocBytes (szWChar * bufsize)
                 written <- malloc
                 return . Left $ ConsoleInfo bufsize buf written handle

{-# NOINLINE stdoutConsoleInfo #-}
stdoutConsoleInfo :: Either ConsoleInfo Handle
stdoutConsoleInfo = unsafePerformIO $ makeConsoleInfo std_OUTPUT_HANDLE stdout

{-# NOINLINE stderrConsoleInfo #-}
stderrConsoleInfo :: Either ConsoleInfo Handle
stderrConsoleInfo = unsafePerformIO $ makeConsoleInfo std_ERROR_HANDLE stderr

interact     :: (String -> String) -> IO ()
interact f   = do s <- getContents
                  putStr (f s)

conPutChar ci  = writeConsole ci . replicate 1
conPutStr      = writeConsole
conPutStrLn ci = writeConsole ci . ( ++ "\n")

putChar      :: Char -> IO ()
putChar      = (either conPutChar  hPutChar ) stdoutConsoleInfo

putStr       :: String -> IO ()
putStr       = (either conPutStr   hPutStr  ) stdoutConsoleInfo

putStrLn     :: String -> IO ()
putStrLn     = (either conPutStrLn hPutStrLn) stdoutConsoleInfo

print        :: Show a => a -> IO ()
print        = putStrLn . show

getChar      = System.IO.getChar
getLine      = System.IO.getLine
getContents  = System.IO.getContents

readIO       :: Read a => String -> IO a
readIO       = System.IO.readIO

readLn       :: Read a => IO a
readLn       = System.IO.readLn

ePutChar     :: Char -> IO ()
ePutChar     = (either conPutChar  hPutChar ) stderrConsoleInfo

ePutStr     :: String -> IO ()
ePutStr      = (either conPutStr   hPutStr  ) stderrConsoleInfo

ePutStrLn   :: String -> IO ()
ePutStrLn    = (either conPutStrLn hPutStrLn) stderrConsoleInfo

ePrint       :: Show a => a -> IO ()
ePrint       = ePutStrLn . show

#else

import qualified System.IO
import Prelude (IO, Read, Show, String)

interact     = System.IO.interact
putChar      = System.IO.putChar
putStr       = System.IO.putStr
putStrLn     = System.IO.putStrLn
getChar      = System.IO.getChar
getLine      = System.IO.getLine
getContents  = System.IO.getContents
ePutChar     = System.IO.hPutChar System.IO.stderr
ePutStr      = System.IO.hPutStr System.IO.stderr
ePutStrLn    = System.IO.hPutStrLn System.IO.stderr

print        :: Show a => a -> IO ()
print        = System.IO.print

readIO       :: Read a => String -> IO a
readIO       = System.IO.readIO

readLn       :: Read a => IO a
readLn       = System.IO.readLn

ePrint       :: Show a => a -> IO ()
ePrint       = System.IO.hPrint System.IO.stderr

#endif

trace :: String -> a -> a
trace string expr = unsafePerformIO $ do
    traceIO string
    return expr

traceIO :: String -> IO ()
traceIO = ePutStrLn

then, you use the I/O functions therein contained instead of the standard library ones. They will detect whether output is redirected; if not (i.e. if we're writing to a 'real' console) then we'll bypass the usual Haskell I/O functions and write directly to the win32 console using WriteConsoleW, the unicode-aware win32 console function. On non-windows platforms, conditional compilation means that the functions here just call the standard-library ones.

If you need to print to stderr, you should use (e.g.) ePutStrLn, not hPutStrLn stderr; we don't define a hPutStrLn. (Defining one is an exercise for the reader!)

How to make JFileChooser Default to Computer View instead of My Documents

7 votes

In the Windows Look and Feel for JFileChooser, the left hand side of the JFileChooser dialog shows five buttons: Recent Items, Desktop, My Documents, Computer, and Network. These each represent Views of the file system as Windows Explorer would show them. It appears that JFileChooser defaults to the My Documents View unless the setSelectedFile() or setCurrentDirectory() methods are called.

I am attempting to make it easy for the user to select one of a number of mapped network drives, which should appear in the "Computer" View. Is there a way to set the JFileChooser to open the "Computer" view by default?

I have tried a couple methods to force it, the most recent being to find the root directory and set it as the currentDirectory, but this shows the contents of that root node. The most recent code is included below.

private File originalServerRoot;
private class SelectOriginalUnitServerDriveListener implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            JFileChooser origDriveChooser = new JFileChooser();
            origDriveChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            File startFile = new File(System.getProperty("user.dir")); //Get the current directory

            // Find System Root
            while (!FileSystemView.getFileSystemView().isFileSystemRoot(startFile))
            {
                startFile = startFile.getParentFile();
            }

            origDriveChooser.setCurrentDirectory(startFile);
            origDriveChooser.setDialogTitle("Select the Mapped Network Drive");
            int origDriveChooserRetVal = origDriveChooser.showDialog(contentPane,"Open");
            if (origDriveChooserRetVal == JFileChooser.APPROVE_OPTION)
            {
                originalUnitServerRoot = origDriveChooser.getSelectedFile();

            }
        }
    }

Is there a method that allows me to select the "Computer" view by default (or the Network, or any other view), or any way to trick the JFileChooser?

EDIT
Thanks for the quick and thorough answers. I combined Hovercraft Full Of Eels' and Guillaume Polet's answers to try and make the code work on any drive letter. The resulting code is as follows. Once again, thanks.

private File originalServerRoot;
private class SelectOriginalUnitServerDriveListener implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            JFileChooser origDriveChooser = new JFileChooser();
            origDriveChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            File startFile = new File(System.getProperty("user.dir")); //Get the current directory

            // Find System Root
            while (!FileSystemView.getFileSystemView().isFileSystemRoot(startFile))
            {
                startFile = startFile.getParentFile();
            }
            //Changed the next line
            origDriveChooser.setCurrentDirectory(origDriveChooser.getFileSystemView().getParentDirectory(rootFile));
            origDriveChooser.setDialogTitle("Select the Mapped Network Drive");
            int origDriveChooserRetVal = origDriveChooser.showDialog(contentPane,"Open");
            if (origDriveChooserRetVal == JFileChooser.APPROVE_OPTION)
            {
                originalUnitServerRoot = origDriveChooser.getSelectedFile();

            }
        }
    }

Here is a working example. It makes the assumption that C:\ is a valid path. It uses the FileSystemView.getParentDir(File)

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Test().initUI();
            }
        });
    }

    protected void initUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        final JButton button = new JButton("Select files...");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                final JFileChooser chooser = new JFileChooser();
                chooser.setCurrentDirectory(
                                 chooser.getFileSystemView().getParentDirectory(
                                     new File("C:\\")));  
                            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                chooser.showDialog(button, "Select file");
            }
        });
        panel.add(button);
        frame.add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

WaitForSingleObject - do threads waiting form a queue?

6 votes

If I set 3 threads to wait for a mutex to be release, do they form a queue based on the order they requested it in or is it undefined behaviour (i.e. we don't know which one will pick it up first)?

It is explicitly documented in the SDK article:

If more than one thread is waiting on a mutex, a waiting thread is selected. Do not assume a first-in, first-out (FIFO) order. External events such as kernel-mode APCs can change the wait order.

These kind of events are entirely out of your control. So "undefined behavior" is an appropriate way to describe it.

C# - How to know when Windows is "settled" after startup?

6 votes

I'm writing an application that will have an option to run on Windows Startup.

I can't stand when applications bog my PC down before it has really settled, and this is a non-critical application. I'd like my application to politely wait for all other startup items to finish and settle so that the user's PC becomes responsive before it starts doing any work.

How would I go about detecting this condition? I suppose I could traverse the registry and look for all startup processes to be running, or use a longish timer. I'm just hoping there is another less hackish trick I might use.

EDIT: The application has a UI and cannot run as a service. It does have a tray mode. It does some image rendering.

A 'longish' timer is the best route. I wouldn't touch the registry with a bargepole.

One thing you will want to consider though is what happens if a user wants to launch your program themselves? Obviously you don't want to be causing the delay then.

I assume your application has a UI? If not, you could consider a Service with its start type set to "Automatic (Delayed)" on Vista/7

Please also see this related question: How to create delay startup application in c#?

A final point, if your program is non-critical, and you are worried it might slow things down, consider lowering the priority of the application.

javascript incorrectly determines daylight savings time line -- an example out of 2006

6 votes

I have read many StackOverflow questions on the javascript new Date() object when it comes to daylight savings time lines -- as in when they are crossed. However, I haven't seen an answer about this particular problem or a way to work around it while still relying on 'unix time'.

I have personally chosen to work around this issue by passing the javascript date as a date to my PHP code rather than the unix time. Yet, the nagging question still remains! I have confirmed this behavior on IE8, Chrome, and FF so I'm assuming it will behave the same for you. (Update: OSX users might not be able to generate this behavior)

My Research; the closest questions to my issue:

  • This user was working on the particular hours right around the DST change.
  • This user was worried about the presentation of the time depending on the user's time zone. The accepted answer on that page mentioned that getTimezoneOffset is "flaky" which led me to not delve into that.
  • See my answer below on other questions that have some great insights

I have generated a test scenario around November 1st, 2006. This may or may not work the same for you depending on the time zone you are in. If I understand the javascript aspect correctly, you will need to synchronize your PC's clock to

Eastern Time (US & Canada) and check the 'Automatically adjust clock for Daylight Saving Time'.

I am basing this experiment off of the "Indianapolis" time zone in PHP. My javascript result, when I find the unix time for November 1st, 2006 is one hour off of what the PHP generates (3600 seconds). According to this page (Thanks Jon!) javascript is wrong.

The two languages results' come back into agreement on 11/06/2006!

This and other research causes me to believe that Javascript got its history wrong and picked the wrong Sunday to 'Fall back' out of DST -- thereby causing the discrepancy I am seeing.

I have tried to simplify this as much as possible but there are still quite a few gears in motion.

1) Here is the PHP code and output that shows the CORRECT number of milliseconds until the date 11/01/2006.

date_default_timezone_set("America/Indiana/Indianapolis");
echo "Unixtime for November 1, 2006 is: ".strtotime("11/01/2006")."\n";
echo "Unixtime for November 6, 2006 is: ".strtotime("11/06/2006");

The result is:

Unixtime for November 1, 2006 is: 1162357200 (where the disagreement lies)
Unixtime for November 6, 2006 is: 1162789200

Both of them are based off of GMT-0500.

2) In Javascript, (see my jsfiddle**), I call new Date and then getTime() upon it like so (and remove the milliseconds):

new Date("2006/11/01").getTime()/1000
new Date("2006/11/06").getTime()/1000

This generates the values

1162353600 <-- PHP outputs: 1162357200
1162789200 <-- the same as PHP for '2006/11/06'; congruence is restored

which is a difference (for 2006/11/01) from the output via PHP of 3600 seconds -- or one hour. This value (one hour earlier) when processed in my PHP application generated the prior day (2006/10/31) which was unacceptable since it broke my navigation forward. (see more explanation of my particular scenario)

Outputting in Javascript: Date("2006/11/01") without calling getTime() clears up some of the mystery because javascript reveals the offset it was using GMT-0400.

My jsfiddle** experiment (also listed above) shows these results.

**(you may need to change your computer's timezone to see the identical behavior).

Possibly coming into play is that according to Wikipedia 2006 was the first year that Indiana began using DST. A curious puzzle either way.

Since I have already worked out my solution (by avoiding relying on unix time in my javascript) I thought I should post this for posterity and hopefully someone might know how to correct the value javascript is showing.

The question is this: How does one bring the two 'unix time' results between PHP and javascript into alignment? I would be grateful to learn how around the DST 'line' or in general. (I'm currently assuming the DST line is the problem).

Update: an iMac running Chrome generated the results that PHP is generating. What??? Wild. Any javascript-side fix to this behavior looks like it would be a great undertaking (or at least ugly). Perhaps this is not a javascript problem since it generates the correct answer depending on the OS (or other factors?).

Notably, on this iMac I did not force the timezone and I'm not sure this Apple computer would allow it. The settings for "Set date and time automatically" was checked (true) and disabled. The time zone was set to Eastern Daylight Time. The box to 'Set timezone automatically' was unchecked (false) and disabled.

I added the Windows tag to highlight that it doesn't seem to be a problem in OSX.

Update: According to the site linked above, I verified that all the following dates crossed into a new GMT offset on the appropriate dates (updated fiddle) -- unlike how the 2006 response was one week off. I.e., on November 4th, 2007, it was GMT-4 and November 5th, 2007, it returned GMT-5.

  • 2007 Sunday, March 11 at 2:00 AM Sunday, November 4 at 2:00 AM
  • 2008 Sunday, March 9 at 2:00 AM Sunday, November 2 at 2:00 AM
  • 2009 Sunday, March 8 at 2:00 AM Sunday, November 1 at 2:00 AM
  • 2010 Sunday, March 14 at 2:00 AM Sunday, November 7 at 2:00 AM
  • 2011 Sunday, March 13 at 2:00 AM Sunday, November 6 at 2:00 AM

Lastly, if you know the proper channels to submit this error in 2006 to whatever timezone source Javascript is relying on, please do so and let me know about it.

Firstly, time in Indiana is very complicated.

But in this case, I believe Javascript is wrong. The output of your Javascript on my machine (having set the time zone) is "Wed Nov 01 2006 00:00:00 GMT-0400 (Eastern Daylight Time)" on Chrome and "Wed Nov 1 00:00:00 EDT 2006" on Internet Explorer - but daylight saving time ended in Indianapolis in 2006 on October 29th.

.NET's TimeZoneInfo class gives the same result:

// Ignore the daft ID; it really means Eastern time
var zone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var local = new DateTime(2006, 11, 1);
Console.WriteLine(zone.GetUtcOffset(local));

Output:

-5:00:00

(So it knows it's not in daylight saving time then.)

Likewise in Noda Time (my own date and time library, which uses the tzdb database):

var zone = DateTimeZone.ForId("America/Indiana/Indianapolis");
var instant = new Instant(1162357200 * NodaConstants.TicksPerSecond);
var zoned = new ZonedDateTime(instant, zone);
Console.WriteLine(zoned);

Result:

Local: 01/11/2006 00:00:00 Offset: -05 Zone: America/Indiana/Indianapolis

How to disable the beep in emacs on Windows

6 votes

Hi I'm new to Emacs and I downloaded GNU emacs on my windows machine. I just finished the short tutorial but I found there's a beep sound whenever I hit the beginning/end of a file and in many other cases, which is a little disturbing to me.

I searched online and I found people saying putting this

(setq visible-bell 1)

in my .emacs file, but I don't know how to do that. First, where is my .emacs file and what is it? Or is there another way to do it? I mean in the emacs window menu there is Options -> Customize Emacs but I couldn't find where the setting is. I feel like it's kind of hard to find things in there unless you already know where it is.

You have a couple of options, one of which doesn't require you to know where the file is; however in due course you're almost certainly going to want to make changes to the file, so let's start there.

First, where is my .emacs file and what is it?

You also have some options for the name of that file. ~/.emacs is the default, but it could also be ~/.emacs.el or ~/.emacs.d/init.el. (Personally I prefer the latter, so as to keep all Emacs related files under that same .emacs.d directory, but we'll go with the default, and you can always rename the file later.)

So first, check to see if you have an existing file.

C-hv user-init-file RET

By default it will show you a file path ending in /.emacs (even if that file doesn't exist), but on the (unlikely, in your case) offchance that it ends in /.emacs.el or /.emacs.d/init.el then it would mean that you have an existing init file at that location.

Load that file with the appropriate one of the following:

  • C-xC-f ~/.emacs RET
  • C-xC-f ~/.emacs.el RET
  • C-xC-f ~/.emacs.d/init.el RET

Or you could load it regardless of where it was with:
M-: (find-file user-init-file) RET

Then you can simply add that line of code to the file:

(setq visible-bell 1)

Save the file:

C-xC-s

And the next time you start Emacs, it will use that setting.

You can also evaluate the setting immediately by typing C-xC-e with the cursor after the closing parenthesis.

Now that you know how to do that, the other approach is:

  • M-x customize-variable RET visible-bell RET
  • Click the "Toggle" button to turn the setting on.
  • Click the "Save for future sessions" button to save it to your init file.

If you then look at your init file, you will see that it has been added to the (custom-set-variables ...) section.

As for what your .emacs file is, it's a personal library of Emacs Lisp (elisp) code which is automatically loaded and evaluated when you start Emacs. All Emacs configuration and customization is written in this language (as indeed is the majority of the editor itself).

You can read more about the init file and customizing Emacs in the built-in manual, by typing:

M-: (info "(emacs) Customization") RET
or C-hig (emacs) Customization RET

You may need to learn how to use the info reader first. From the *info* buffer you can type h to start its tutorial, and d to return to the top level page (which has some useful notes at the top).

Or is there another way to do it? I mean in the emacs window menu there is Options -> Customize Emacs but I couldn't find where the setting is.

"Specific Option" -> "visible-bell" was the answer for that approach. But do take note that not everything is available through those menus, so that won't always be the answer, and lots of people disable the menu bar entirely, because everything can be accessed without it. (I'm more inclined to suggest browsing through the menus as a way of discovering some of the options which people thought were useful enough to put in there, but make sure you're not reliant on them.)

I feel like it's kind of hard to find things in there unless you already know where it is.

That's certainly true to an extent, but the self-documentation aspect of Emacs means that even if you don't know where to look, you can almost always find out if you know how to look.

Admittedly there's a definite learning curve even on doing that, but I recommend learning as much as you can about this aspect of Emacs as soon as possible. This will get you started:

http://emacswiki.org/emacs/SelfDocumentation

FindFirstFile returns access denied

6 votes

I'm trying to create a robust recursive folder deleter function.

With normal directories works pretty fine.

The problem appears when I create a "hardcore" direcory, like:

C:\test\x\x\x\x\x\x\x\x\x\x\x\x\x\x\x\x\x\x\x\x\ ... \x\x\x

The length of this is around 25000 (less then the MSDN limit: 32,767). Basically I created this directory recursively until the CreatDirectory function failed.

Now, the strangest thing is, that my function is able to delete 2 directories then the FindFirstFile fails with 0x5:

\\?\C:\test\x\ ... \x\x\x\*.*    < no error
\\?\C:\test\x\ ... \x\x\*.*      < no error
\\?\C:\test\x\ ... \x\*.*        < access denied

(I can rerun the it, the app is slowly chews up the folder, 2 by 2, probably until the path length gets pretty small)

I'm running FindFirstFile to check if the folder is empty.

  • Is there any sort of limitation that is less documented?
  • The FindFirstFile just simply doesn't work? (buggy?)
  • Am I missing some sort of NTFS permission thing?
  • Something else ...

EDIT: IMPORTANT NOTE: If I run the program step by step slowly ... then nothing will fail.

You are probably experiencing something like a virus scanner, indexer or continuous-backup solution holding a handle to the directory. If the Indexing Service is configured to index that folder for example.

Trying to delete a folder or file which is open other than with FILE_SHARE_DELETE flag will cause ACCESS_DENIED.

To confirm this, use Process Monitor to see opens and closes on anything matching your path.

(Of course also confirm you called FindClose).

Handling events with C# Extension Methods

6 votes

I recently learned about using C# extension methods to make calling events easier and I've been using them more and more. I recently hit a strange issue that I don't understand though, and I was wondering if someone could explain it.

The issue occurs when trying to set an eventhandler extension method as an event handler of another event. Here is an example of what I'm doing:

public static class EventHandlerExtensions
{
    public static void Raise<TEventArgs>(
        this EventHandler<TEventArgs> eventHandler, 
        object sender, TEventArgs args)  where TEventArgs:EventArgs
    {
        if (eventHandler != null)
        {
            eventHandler(sender, args);
        }
    }
}

public class Test
{
    private event EventHandler<EventArgs> EventA;
    private event EventHandler<EventArgs> EventB;

    public Test()
    {
        Console.WriteLine("::Start");
        EventB += EventA.Raise;
        EventA += (s, a) => Console.WriteLine("Event A raised");
        EventB.Raise(this, EventArgs.Empty);
        Console.WriteLine("::End");
    }
}

In this example, EventA should be triggered as a result of EventB being triggered. However, when I run this code, EventB fires, but the extension method on A doesn't find any listeners for it.

If I change the order around, everything works fine:

Console.WriteLine("::Start");
EventA += (s, a) => Console.WriteLine("Event A raised");
EventB += EventA.Raise;
EventB.Raise(this, EventArgs.Empty);
Console.WriteLine("::End");

Also, calling EventA.Raise from a lambda works fine:

Console.WriteLine("::Start");
EventB += (s, a) => EventA.Raise(s, a);
EventA += (s, a) => Console.WriteLine("Event A raised");
EventB.Raise(this, EventArgs.Empty);
Console.WriteLine("::End");

This is just a simple example, but I'm trying to create a class which can re-dispatch events of event sources added to it in the cleanest way possible. I don't want to create named methods just for redispatching the same events, and I'd rather not store lists of lambda functions that I can unhook from the event handlers later. Mostly, I'm just curious as to why this is happening?

Any ideas?

You capture old value of EventA into the closure by your Raise function. Since later you use += it changes value of EventA, but your closure still have an old value.

You code:

EventB += EventA.Raise;
EventA += (s, a) => Console.WriteLine("Event A raised"); 

Can be expanded into equivalent code which makes it clear why you get old delegate:

var oldEventA = EventA;
EventB += oldEventA.Raise; // captures old value here
// now EventA changed to new value 
EventA = oldEventA + ((s, a) => Console.WriteLine("Event A raised");)

You can add following to before EventB += EventA.Raise to verify that code actually raises old event for A:

EventA += (s, a) => Console.WriteLine("Old Event A raised");

Screenshot of form whose dimensions are greater than screen dimensions

6 votes

I have a TForm object whose height is greater than the required vertical resolution of my screen.

For some reason, Windows doesn't allow the visible (client?) area of the form to exceed the screen resolution, so vertical scrollbars appear on my form.

How would I get a TBitmap image or screenshot of the entire form (no scrollbars, all form components visible) so that all content of the form is visible?

At first you have to make sure the form has no scrollbars. For that you can write an event handler for FormConstrainedResize and adjust MaxWidth and MaxHeight to your needs. If the form size is restricted during design, set the required Width and Height in the FormCreate event to the desired values.

Now you can use GetFormImage to get the screenshot.

Why does this error keep messing up the XE2 IDE Toolbars?

5 votes

Screen Shot

enter image description here

The following source code was used to produce the error above. All you have to do is compile the program and make sure the IDE is still running (the error does NOT happen if the IDE is closed), click the button 12 to 15 times and the error will popup.

Once the error has occurred, switch back to the IDE, all the toolbars for the IDE have then disappeared. You have to shut down the IDE and run again, for them to reappear.

Source Code

unit MainUnit;

interface

uses
  Winapi.Windows, Winapi.Messages, Winapi.ShlObj, System.SysUtils,
  System.Variants, System.Classes, System.StrUtils, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.StdCtrls;

type
  TMainFrm = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainFrm: TMainFrm;
  hDesktop: HWND;

implementation

{$R *.dfm}

function GetHandle(theHandle: HWND; NotUsed: NativeInt): LongBool; stdcall;
begin
  if (theHandle <> 0) then
  begin
    hDesktop := FindWindowEx(FindWindowEx(theHandle, 0, 'SHELLDLL_DefView',
      nil), 0, 'SysListView32', nil);
  end;
  Result := (hDesktop = 0);
end;

procedure TMainFrm.FormCreate(Sender: TObject);
var
  lpss: TShellState;
begin
  ZeroMemory(@lpss, SizeOf(lpss));
  try
    SHGetSetSettings(lpss, SSF_HIDEICONS, False);
  finally
    Button1.Caption := IfThen(lpss.fHideIcons, 'Show Icons', 'Hide Icons');
  end;
  EnumWindows(@GetHandle, 0);
  Button1.Enabled := (hDesktop <> 0);
end;

procedure TMainFrm.Button1Click(Sender: TObject);
const
  nCmdShow: array [Boolean] of NativeInt = (SW_HIDE, SW_SHOW);
var
  lpss: TShellState;
begin
  ZeroMemory(@lpss, SizeOf(lpss));
  try
    SHGetSetSettings(lpss, SSF_HIDEICONS, False);
    ShowWindow(hDesktop, nCmdShow[lpss.fHideIcons]);

    lpss.fHideIcons := (not BOOL(lpss.fHideIcons));
    Button1.Caption := IfThen(lpss.fHideIcons, 'Show Icons', 'Hide Icons');
  finally
    SHGetSetSettings(lpss, SSF_HIDEICONS, True);
  end;
end;

end.

Application Screen Shot

enter image description here

Any help would be greatly appreciated.

UPDATE

The IDE toolbars no longer disappear, and the error doesn't appear anymore, thanks to TOndrej for the information about turning off the "Profiler toolbar". Now I get a very annoying flicker that sometimes takes 10 to 15 seconds to return back to normal.

Do you have AQTime installed? The problem seems to disappear if you simply hide the Profiler toolbar.

Measure CPU frequency (x86 / x64)

5 votes

I'm looking for some kind of a library that gives me accurate CPU frequency values periodically on both Intel and AMD processors, on 32-bit and 64-bit Windows.

The purpose of this is to accuratly measure CPU load on a given computer. The problem is that calling QueryPerformanceCounter() returns clock ticks (used to measure the duration of an activity) but the underlying CPU frequency is not constant because of SpeedStep or TurboBoost. I've found several computers where turning off SpeedStep / TurboBoost in the BIOS and doesn't prevent CPU frequency scaling based on load.

I'm trying to see if there are any libraries available that could be used to detect CPU frequency changes (much like how Throttlestop / CPU-Z or even the Overview tab of Resource Monitor in Windows 7) so that I could query and save this information along with my other measurements. Performance counters don't seem to return reliable information, as I have computers that always return 100% CPU frequency, even when other tools show dynamic frequency changes.

I searched for such libraries but most results come back with gadgets, etc., that are not useful.

You can combine a high-resolution timer with a clock cycle counter to compute the current clock rate. On modern CPUs, the cycle counter can be read with this function:

static inline uint64_t get_cycles()
{
  uint64_t t;
  asm volatile ("rdtsc" : "=A"(t));
  return t;
}

Note that this is per CPU, so if your program gets moved around CPUs, you're in trouble. If you know about CPU pinning techniques on your platform, you might like to try those.

For high resolution time measurement, you can use the tools in <chrono>; here's a semi-useful post of mine on the topic.

Delphi Windows Service Design

5 votes

Delphi Windows Service Design

I've never created a windows service but have been reading everything I've found. All the articles or examples I've run across are very basic in implementation and limited in their scope. Haven't seen anything that goes beyond this or that address specific scenarios. So, I have all the theory I'm probably going to find, and now I'm ready to dive into this project. I like to layout my ideas and get some feedback on what people think. I'll describe what I need from the application and how I intend to build it. I'd appreciate comments from anyone who has experience building windows services and any advice they would care to share.

[SCENARIO] Right now I have an application (I'll call this UPDATEAPPLICATION) that provides updates to all our other applications. In order to run any of our applications you first have to run this UPDATEAPPLICATION program and pass it a parameter of the desired application. The UPDATEAPPLICATION calls a WebService that returns XML information as to whether the desired application has any updates.

If there is an update, the UPDATEAPPLICATION downloads the update in EXE or ZIP format, and replaces the appropriate files to update the targeted application. Afterwards the UPDATEAPPLICATION does a ShellExecute to start the desired application and then the UPDATEAPPLICATION closes.

It's a fairly basic process that has worked well over the years. The UPDATEAPPLICATION program is a Delphi application, our other applications are mixed: Delphi, VB6, MS Access, .NET.

[THE PROBLEM] With the move to Vista and Windows 7, the security has changed dramatically. Because of the nature of the UPDATEAPPLICATION UAC won't allow the application to run under without Admin acces or UAC completely turned off. We are in the process of upgrading many of our applications to .NET and during this process I'd like the applications as well as the UPDATEAPPLICATION be UAC compliant. From what I've researched the only way to do this is by creating the UPDATEAPPLICATION as Windows Service. So, essentially, I need to duplicate the functionality of the UPDATEAPPLICATION into a Windows Service architecture.

[MY DESIGN] I'm using DelphiXE2. My design will consist of 3 parts to form a single solution: a Windows Service, a small tray Application to interact with the Windows Service, and my redesigned applications that will send messages to the Windows Service.

  1. My Windows Service (which I will call the UPDATESERVICE) will run as a Windows Service and create a TCP server to listen for requests.
  2. The tray application (which I will call TRAYAPP) will use TCP Client to configure/manage the UPDATESERVICE.
  3. My USERAPPLICATION, when started, will send a TCP message to UPDATESERVICE that's says "THIS APPLICATION" has started.

[UPDATESERVICE] Will listen for messages. If it receives a message that a USERAPPLICATION has started will it will call the web service to see if there are updates. If there are, the user will be notified to close the application and allow the UPDATESERVICE to update the application. The UPDATESERVICE will download the appropriate files and update the application.

Now that I've explained the basics of what I'm trying to do, I can ask my specific questions I need answered. These all have to do with how I should build my Windows Service. I also plan on using OmniThread for my thread management.

When my service starts, I need to create the TCP Server.

  1. Should the TCP Service be created on it's own thread?
  2. If the TCP Service is it's own thread, how do I keep the thread alive? Otherwise, I can start the TCP Service but I'm not sure what code I would use within the TCP Service unit to keep the thread running?
  3. What Windows Services event should create the TCP Service? OnExecute? OnStart? OnCreate? After all I've read it's unclear what event should be used.
  4. When the TCP Service receives a message to do something, should the work be executed within TCP Service thread or a new thread spawned off the main UPDATESERVICE? For example:
    • if the TCP Service gets a message to check for an update using HTTP should the TCP Service thread spawn a new thread to do this work
    • Or, should the TCP Service thread send a message to the UPDATESERVICE to spawn a new thread to do this work
    • Does it even matter?
  5. Is it possible to Start/Stop/Register/Unregister a windows service in Delphi Code?

This is all my questions. There probably isn't a right/wrong answer for this but simply a preference based on experience. If you've built services with Delphi you probably have some input that I would find useful. If you have a project that is more robust then a basic "start a service and sleep" and are willing to share it - even if I doesn't run or just psuedo code - I'm sure this would be invaluable. Thanks for reading my long-winded question. If you can think of a better way to go about this please share your thoughts. I'll add that several of our applications can be downloaded and run by the general public, so I don't have complete control over the expected environments. Any advice/comments/help would be appreciated.

fast answers:

1&3) Yes. As a rule of thumb do not implement the OnExecute service event. Spawn your own thread from the OnStart service event. The thread can be terminated when you receive the OnStop service event.

2) you keep your thread alive like this (execute method):

while not Terminated do
begin
  // do something
end;

4) normally each client connection will live on it's own thread. (ie the TCP server spawns a new thread for each client). Use a well known stack like Indy or ICS. Concerning the HTTP update, you can do this in the spawned client connection thread.

5) yes, be aware that you need elevated rights to do this.

I have made quite a few services in my career and I always use the same skeleton for the service application up till now:

unit u_svc_main;

interface

uses
  // Own units
  u_globals, u_eventlog, u_MyThread, 
  // Third party units
  // Delphi units
  Windows, Messages, Registry, SysUtils, Classes, SvcMgr;

type
  TMyService = class(TService)
    procedure ServiceCreate(Sender: TObject);
    procedure ServiceAfterUninstall(Sender: TService);
    procedure ServiceAfterInstall(Sender: TService);
    procedure ServiceShutdown(Sender: TService);
    procedure ServiceStop(Sender: TService; var Stopped: Boolean);
    procedure ServiceStart(Sender: TService; var Started: Boolean);
  private
    { Private declarations }
    MyThread : TMyThread;
  public
    { Public declarations }
    function GetServiceController: TServiceController; override;
  end;

var MyService : TMyService;

implementation

{$R *.DFM}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  MyService.Controller(CtrlCode);
end;

function TMyService.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

procedure TMyService.ServiceCreate(Sender: TObject);
begin
  DisplayName := 'myservice';
end;

procedure TMyService.ServiceAfterInstall(Sender: TService);
var
  Reg        : TRegistry;
  ImagePath  : string;
begin
  // create needed registry entries after service installation
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    // set service description
    if Reg.OpenKey(STR_REGKEY_SVC,False) then
    begin
      ImagePath := Reg.ReadString(STR_REGVAL_IMAGEPATH);
      Reg.WriteString(STR_REGVAL_DESCRIPTION, STR_INFO_SVC_DESC);
      Reg.CloseKey;
    end;
    // set message resource for eventlog
    if Reg.OpenKey(STR_REGKEY_EVENTMSG, True) then
    begin
      Reg.WriteString(STR_REGVAL_EVENTMESSAGEFILE, ImagePath);
      Reg.WriteInteger(STR_REGVAL_TYPESSUPPORTED, 7);
      Reg.CloseKey;
    end;
    // set installdir
    if ImagePath <> '' then
      if Reg.OpenKey(STR_REGKEY_FULL,True) then
      begin
        Reg.WriteString(STR_REGVAL_INSTALLDIR, ExtractFilePath(ImagePath));
        Reg.CloseKey;
      end;
  finally
    FreeAndNil(Reg);
  end;
end;

procedure TMyService.ServiceAfterUninstall(Sender: TService);
var
  Reg : TRegistry;
begin
  Reg := TRegistry.Create;
  try
    // delete self created registry keys
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    Reg.DeleteKey(STR_REGKEY_EVENTMSG);
  finally
    FreeAndNil(Reg);
  end;
end;

procedure TMyService.ServiceShutdown(Sender: TService);
var
  Stopped : boolean;
begin
  // is called when windows shuts down
  ServiceStop(Self, Stopped);
end;

procedure TMyService.ServiceStart(Sender: TService; var Started: Boolean);
begin
  Started := False;
  try
    MyThread := TMyThread.Create;
    MyThread.Resume;
    NTEventLog.Add(Eventlog_Success, STR_INFO_SVC_STARTED);
    Started := True;
  except
    on E : Exception do
    begin
      // add event in eventlog with reason why the service couldn't start
      NTEventLog.Add(Eventlog_Error_Type, Format(STR_INFO_SVC_STARTFAIL, [E.Message]));
    end;
  end;
end;

procedure TMyService.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
  try
    Stopped := True; // always stop service, even if we had exceptions, this is to prevent "stuck" service (must reboot then)
    MyThread.Terminate;
    // give MyThread 60 seconds to terminate
    if WaitForSingleObject(MyThread.ThreadEvent, 60000) = WAIT_OBJECT_0 then
    begin
      FreeAndNil(MyThread);
      NTEventLog.Add(Eventlog_Success,STR_INFO_SVC_STOPPED);
    end;
  except
    on E : Exception do
    begin
      // add event in eventlog with reason why the service couldn't stop
      NTEventLog.Add(Eventlog_Error_Type, Format(STR_INFO_SVC_STOPFAIL, [E.Message]));
    end;
  end;
end;

end.

looking for a MAC address of a physical adapter

5 votes

I would like to use a unique identifier to determine whether my application moved to a different computer. The MAC address seems to be suitable for this purpose. The code I use is this:

Procedure TForm4.GetMacAddress;
var item: TListItem;
    objWMIService : OLEVariant;
    colItems      : OLEVariant;
    colItem       : OLEVariant;
    oEnum         : IEnumvariant;
    iValue        : LongWord;
    wmiHost, root, wmiClass: string;
    i: Int32;

  function GetWMIObject(const objectName: String): IDispatch;
  var
    chEaten: Integer;
    BindCtx: IBindCtx;//for access to a bind context
    Moniker: IMoniker;//Enables you to use a moniker object
  begin
    OleCheck(CreateBindCtx(0, bindCtx));
    OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker));//Converts a string into a moniker that identifies the object named by the string
    OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));//Binds to the specified object
  end;

begin
   wmiHost       := '.';
   root          := 'root\CIMV2';
   wmiClass      := 'Win32_NetworkAdapterConfiguration';
   objWMIService := GetWMIObject(Format('winmgmts:\\%s\%s',[wmiHost,root]));
   colItems      := objWMIService.ExecQuery(Format('SELECT * FROM %s',[wmiClass]),'WQL',0);
   oEnum         := IUnknown(colItems._NewEnum) as IEnumVariant;
   i := 0;
   while oEnum.Next(1, colItem, iValue) = 0 do
   begin
      Item := View.Items.Add;
      item.Caption := Copy (colItem.Caption, 2, 8);

      Item.SubItems.Add (colItem.Description);
      Item.SubItems.Add (colItem.ServiceName);
      Item.SubItems.Add (VarToStrNil (colItem.MACAddress));
      if (VarToStrNil(colItem.MACAddress) <> '')
         then Item.SubItems.Add ('yes')
         else Item.SubItems.Add ('no');
      if colItem.IPEnabled
         then Item.SubItems.Add ('yes')
         else Item.SubItems.Add ('no');
     Item.SubItems.Add (VarToStrNil (colItem.SettingID));
     Item.SubItems.Add (IntToStr (colItem.InterfaceIndex));
   end; // if
end; // GetMacAddress //

My machine has one network port, but this code finds 18 network related ports/things/whatever. Among them there are four MAC adresses. I presume that a network port should be IP enabled so that leaves two left (labeled MAC in the image). Is it correct to assume that of the ports thus filtered, the one with the lowest index is the hardware port?

enter image description here

Edit in the snapshot above the Realtek adapter is the only physical adapter in the machine. The other adapter is the VirtualBox virtual adapter. The answer of TLama identifies these two adapters, but is there a way to find the address of the only Physical (Realtek) adapter?

Update 1 EJP pointed out that the MAC address can be changed. This somewhat undermines my purpose, but as I am looking for a solution that fits most situations I decided to live with it.

TLama and TOndrej pointed to several solutions. Both end up with a situation that a physical adapter could not be found without any doubt.

Update 2 TLama's excellent reading list shows that there is probably not a certain way to determine the physical adapter. The article mentioned in the first bullet shows how to shrink the amount of adapters based on some simple assumptions. The article in the third bullet shows how to select the adapter connected to the PCI bus, which is in fact exactly what I wanted to know. There are some weird exceptions mentioned in the article but I think this will provide an answer in most cases.

Thank you all for your contributions!

Use the Win32_NetworkAdapter class instead. It has the PhysicalAdapter member. The following example should list you the MAC addresses of physical adapters:

program Program1;

{$APPTYPE CONSOLE}

uses
  SysUtils, ActiveX, ComObj, Variants;

procedure GetWin32_NetworkAdapterInfo;
const
  WbemUser = '';
  WbemPassword = '';
  WbemComputer = 'localhost';
  wbemFlagForwardOnly = $00000020;
var
  ElementCount: LongWord;
  FWMIService: OleVariant;
  FWbemObject: OleVariant;
  EnumVariant: IEnumVARIANT;
  FSWbemLocator: OleVariant;
  FWbemObjectSet: OleVariant;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM Win32_NetworkAdapter WHERE PhysicalAdapter = 1', 'WQL', wbemFlagForwardOnly);
  EnumVariant := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  while EnumVariant.Next(1, FWbemObject, ElementCount) = 0 do
  begin
    Writeln(Format('MACAddress %s', [VarToStr(FWbemObject.MACAddress)]));
    FWbemObject := Unassigned;
  end;
end;

begin
  try
    CoInitialize(nil);
    try
      GetWin32_NetworkAdapterInfo;
    finally
      CoUninitialize;
    end;
  except
    on E:EOleException do
      Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
    on E:Exception do
      Writeln(E.Classname, ':', E.Message);
  end;
  Writeln('Press Enter to exit');
  Readln;
end.

Based on the code generated by the WMI Delphi Code Creator.

Update:

You are actually trying to filter out the adapters which belongs to virtual machines, what is not that easy since they are simulated like to be as physical ones (you can even see them in Device Manager as the physical adapters), so you cannot distinguish them e.g.:

  • by the DHCPEnabled member of the Win32_NetworkAdapter class, because even virtual machines might be configured so they get IP address from a DHCP server
  • by the AdapterTypeId member of the Win32_NetworkAdapter class, since there is no special type for virtual adapters
  • by the PhysicalAdapter member of the Win32_NetworkAdapter class, because they are being simulated to be physical

Additional reading:

call default windows executables in C program

5 votes

I used system() function to call certmgr.exe in my C code. Once I start my executable, a command promt appears showing certificate successfully installed.

But I dont want the command promt to be opened. How to do that??

any other ways available to call the "exe's" in C language..

thanks,,,

The easiest way to do this on Windows is to call ShellExecute. Pass SW_HIDE to make sure that no console window is shown.

You could alternatively use CreateProcess but it's a little trickier to call. Use the CREATE_NO_WINDOW flag to suppress the console window.

How to get the icon of another application?

5 votes

So in this application I'm making, the user clicks on a button, and that button launches a program. This button will have the title of the application and the icon. I just need to know how to get the icon, kind of like this: Windows

So what I want to know is this:

  1. Is there any REAL way to do this in Java
  2. If so, how would you do it?

Thanks in advance!

Do you have to get the icon associated to the exe file of the application ? If so it is possible in java, take a look at this tutorial, that explain several ways of extracting app icon from an executable binary file from a Java application.

Take a look at this code :

String s = "c:/windows/regedit.exe";
File file = new File(s);

// Get metadata and create an icon
sun.awt.shell.ShellFolder sf =
        sun.awt.shell.ShellFolder.getShellFolder(file);
Icon icon = new ImageIcon(sf.getIcon(true));

Making use of all available RAM in a Haskell program?

5 votes

I have 8 GB of RAM, but Haskell programs seemingly can only use 1.3 GB.

I'm using this simple program to determine how much memory a GHC program can allocate:

import System.Environment
import Data.Set as Set

main = do
         args <- getArgs
         let n = (read $ args !! 0) :: Int
             s = Set.fromList [0..n]
         do
           putStrLn $ "min: " ++ (show $ findMin s)
           putStrLn $ "max: " ++ (show $ findMax s)

Here's what I'm finding:

  • running ./mem.exe 40000000 +RTS -s succeeds and reports 1113 MB total memory in use
  • running ./mem.exe 42000000 +RTS -s fails with out of memory error
  • running ./mem.exe 42000000 +RTS -s -M4G errors out with -M4G: size outside allowed range
  • running ./mem.exe 42000000 +RTS -s -M3.9G fails with out of memory error

Monitoring the process via the Windows Task Manager shows that the max memory usage is about 1.2 GB.

My system: Win7, 8 GB RAM, Haskell Platform 2011.04.0.0, ghc 7.0.4.

I'm compiling with: ghc -O2 mem.hs -rtsopts

How can I make use of all of my available RAM? Am I missing something obvious?

Currently, on Windows, GHC is a 32-bit GHC - I think a 64-bit GHC for windows is supposed to be available when 7.6 comes.

One consequence of that is that on Windows, you can't use more than 4G - 1BLOCK of memory, since the maximum allowed as a size-parameter is HS_WORD_MAX:

decodeSize(rts_argv[arg], 2, BLOCK_SIZE, HS_WORD_MAX) / BLOCK_SIZE;

With 32-bit Words, HS_WORD_MAX = 2^32-1.

That explains

running ./mem.exe 42000000 +RTS -s -M4G errors out with -M4G: size outside allowed range

since decodeSize() decodes 4G as 2^32.

This limitation will remain also after upgrading your GHC, until finally a 64-bit GHC for Windows is released.

As a 32-bit process, the user-mode virtual address space is limited to 2 or 4 GB (depending on the status of the IMAGE_FILE_LARGE_ADDRESS_AWARE flag), cf Memory limits for Windows Releases.

Now, you are trying to construct a Set containing 42 million 4-byte Ints. A Data.Set.Set has five words of overhead per element (constructor, size, left and right subtree pointer, pointer to element), so the Set will take up about 0.94 GiB of memory (1.008 'metric' GB). But the process uses about twice that or more (it needs space for the garbage collection, at least the size of the live heap).

Running the programme on my 64-bit linux, with input 21000000 (to make up for the twice as large Ints and pointers), I get

$ ./mem +RTS -s -RTS 21000000
min: 0
max: 21000000
  31,330,814,200 bytes allocated in the heap
   4,708,535,032 bytes copied during GC
   1,157,426,280 bytes maximum residency (12 sample(s))
      13,669,312 bytes maximum slop
            2261 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0     59971 colls,     0 par    2.73s    2.73s     0.0000s    0.0003s
  Gen  1        12 colls,     0 par    3.31s   10.38s     0.8654s    8.8131s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time   12.12s  ( 13.33s elapsed)
  GC      time    6.03s  ( 13.12s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time   18.15s  ( 26.45s elapsed)

  %GC     time      33.2%  (49.6% elapsed)

  Alloc rate    2,584,429,494 bytes per MUT second

  Productivity  66.8% of total user, 45.8% of total elapsed

but top reports only 1.1g of memory use - top, and presumably the Task Manager, reports only live heap.

So it seems IMAGE_FILE_LARGE_ADDRESS_AWARE is not set, your process is limited to an address space of 2GB, and the 42 million Set needs more than that - unless you specify a maximum or suggested heap size that is smaller:

$ ./mem +RTS -s -M1800M -RTS 21000000
min: 0
max: 21000000
  31,330,814,200 bytes allocated in the heap
   3,551,201,872 bytes copied during GC
   1,157,426,280 bytes maximum residency (12 sample(s))
      13,669,312 bytes maximum slop
            1154 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0     59971 colls,     0 par    2.70s    2.70s     0.0000s    0.0002s
  Gen  1        12 colls,     0 par    4.23s    4.85s     0.4043s    3.3144s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time   11.99s  ( 12.00s elapsed)
  GC      time    6.93s  (  7.55s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time   18.93s  ( 19.56s elapsed)

  %GC     time      36.6%  (38.6% elapsed)

  Alloc rate    2,611,793,025 bytes per MUT second

  Productivity  63.4% of total user, 61.3% of total elapsed

Setting the maximal heap size below what it would use naturally, actually lets it fit in hardly more than the space needed for the Set, at the price of a slightly longer GC time, and suggesting a heap size of -H1800M lets it finish using only

1831 MB total memory in use (0 MB lost due to fragmentation)

So if you specify a maximal heap size below 2GB (but large enough for the Set to fit), it should work.