August 14, 2016

Open/create directory

To open an existing directory, use CreateFile() with the FILE_FLAG_BACKUP_SEMANTICS attribute:

To create directory:

  1. If you don't need to create intermediate directories, use CreateDirectory():

  2. Otherwise, use SHCreateDirectoryEx().

    In Visual C++ 6.0, you'll have to use LoadLibrary() and GetProcAddress() with shell32.dll; as a procedure name, specify either SHCreateDirectoryExW() or SHCreateDirectoryExA(), not just SHCreateDirectoryEx().

ATL Service registration failure: CO_E_WRONG_SERVER_IDENTITY

CO_E_WRONG_SERVER_IDENTITY (0x80004015, "The class is configured to run as a security ID different from the caller") returned from a registration function (IRunningObjectTable::Register()) can be the result of the following issues:

  1. Incorrect service registration settings. Find the key named HKEY_CLASSES_ROOT\AppID\{<service_app_GUID>}, delete the value named LocalService (if there is one), and add the value named RunAs (type REG_SZ, value Interactive User).
  2. Wrong service GUID (if you've changed it, which is a bad idea in general). Ensure that the following data ('@' means the default value)

    [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{yourServiceGuid}]
    @="yourServiceName"
    

    matches these data:

    [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\yourServiceName.exe]
    @="yourServiceName.Application"
    "AppId"="{yourServiceGuid}"
    

    Sometimes, the default value can be "(value not set)", but the GUID should match.

  3. Wrong service executable name. Check the registry entry for your service AppID (search in the HKEY_CLASSES_ROOT hive using part of your service executable name):

    HKEY_CLASSES_ROOT\AppID\<executable_name>.EXE
    

    Suppose our service executable is named SomeService100ud.exe but in the registry we see the following entry instead:

    HKEY_CLASSES_ROOT\AppID\SomeService.EXE
    

    In this case, check the registrar script files (.rgs) of your service project. Probably the executable name in these scripts is incorrect.

ATL services: turning off error dialogs

To prevent error dialogs from appearing when the Release version of your ATL service fails, add the following code to WinMain():

Alternatively, you can suppress the Windows Error Reporting UI for all programs by creating/setting the registry value

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting
DontShowUI (REG_DWORD) = 1

WARNING: the registry location should be of the correct bitness (64- or 32-bit).

It's also a good idea to set filter for unhandled exceptions:

wglMakeCurrent(): 0xc0070006 error

Don't use a global window's handle to initialize your window DC like shown below. The problem is, WM_CREATE will be sent before your global variable will be initialized ‒ i.e. before returning from CreateWindowW(). Thus, the global variable will be NULL at the moment when window DC is created.

Note that both GetDC() and wglCreateContext() will return non-NULL handles. The problem will become apparent on calling wglMakeCurrent() ‒ it will fail with 0xc0070006, where 6 means "invalid handle".

To deal with this, note that the window procedure has a window handle which you can use. Instead of the global window handle variable, pass the window procedure's hWnd argument to your OpenGL initialization function.

Code demonstrating the problem: