Showing posts with label Windows API. Show all posts
Showing posts with label Windows API. Show all posts

October 21, 2009

DLL (Dynamic-Link Library) Search Order

Are you sure that your program loads the DLLs expected? You may want to check the search order for loading the proper DLLs.

Standard Search Order (SafeDllSearchMode is enabled)
1. The directory from which the application loaded.
2. The system directory. Use the GetSystemDirectory function to get the path of this directory.
3. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
4. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
5. The current directory.
6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

More Detail Information
Dynamic-Link Library Search Order

August 26, 2009

How To: Get the Content of Certain Environment Variable, ie: %ProgramFiles%

Code Snippet

#include <windows.h>
#include <string>

using namespace std;

wstring GetContentFromEnvironmentVariable(const wstring& wstrVariable)
{
  // Get the content of %ProgramFiles%

  wstring wstrRtn;
  DWORD dwSize = ::GetEnvironmentVariableW(wstrVariable.c_str(), NULL, NULL);
  if(dwSize > 0)
  {
    wchar_t* wszContent = new wchar_t [dwSize];
    dwSize = ::GetEnvironmentVariableW(wstrVariable.c_str(), wszContent, dwSize);

    wstrRtn = wszContent;

    delete [] wszContent;
    wszContent = NULL;
 }

 return wstrRtn;
}

Reference on MSDN
GetEnvironmentVariable Function

June 12, 2009

How To: Disable General Protection Fault Dialog for Your Program

Abstraction
Are you using any 3rd-party componet or ActiveX, which is not stable enough, in your program? You will get a GPF dialog if the componet in your program goes abnormal. That is not your problem totally, but actually your program crashed. There's a Windows API to prevent showing GPF dialog, you may adapt this solution if the crash can be ignored.

Code Snippet

UINT uPrevErrMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);

Do you not know what GPF is?

Windows Calendar Crash

Reference on MSDN

June 06, 2009

Read/Write Windows Registry on Windows 64-Bits Platforms (C# Version)

Abstraction
How does a 32-bits(x64) program running on Windows 64-bits(x64) access the 64-bits registry? In C#, you can use P/Invoke to call RegOpenKeyEx function with KEY_WOW64_KEY to access the 64-bits registry.

Code Snippet

//
// This is a C# example to get the version of Windows Media Center on Windows 7 64-bits.
//

class RegQueryValueDemo
{
  [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegOpenKeyExW", SetLastError = true)]
  public static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, uint options, int sam, out UIntPtr phkResult);
  public static UIntPtr HKEY_CURRENT_USER = (UIntPtr)0x80000001;
  public static UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002;
  public static int KEY_QUERY_VALUE = 0x0001;
  public static int KEY_SET_VALUE = 0x0002;
  public static int KEY_CREATE_SUB_KEY = 0x0004;
  public static int KEY_ENUMERATE_SUB_KEYS = 0x0008;
  public static int KEY_WOW64_64KEY = 0x0100;
  public static int KEY_WOW64_32KEY = 0x0200;

  [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegQueryValueExW", SetLastError = true)]
  public static extern int RegQueryValueEx(UIntPtr hKey, string lpValueName, int lpReserved, out uint lpType,
    StringBuilder lpData, ref int lpcbData);

  public string GetMCEIdent()
  {
    UIntPtr regKeyHandle;
    if (RegOpenKeyEx(
    HKEY_LOCAL_MACHINE,
    "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Media Center",
    0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, out regKeyHandle) == 0)
    {
      uint type;

      StringBuilder stringBuilder = new StringBuilder(2048);
      int cbData = stringBuilder.Capacity;
      if (RegQueryValueEx(regKeyHandle, "Ident", 0, out type, stringBuilder, ref cbData) == 0)
      {
        return stringBuilder.ToString();
      }
    }

    return string.Empty;
  }
}


Find a C++ version?
Read/Write Windows Registry on Windows 64-Bits Platforms

Reference on MSDN:
RegOpenKeyEx Function
32-bit and 64-bit Application Data in the Registry

April 10, 2009

How To: Detect Windows Media Center Version

If your program is depending on a specified version of Windows Media Center, just try the following code to identify Windows Media Center versions.

Sample Code:

//
// Get Windows Media Center version from registry
// Function return false if no media center is installed on your windows
//
// Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center
// Registry value name: Ident
// Registry value data type: REG_SZ
//

bool GetMediaCenterIdent(wstring& wstrIdent)
{
  bool bRtn = false;

  HKEY hkResult = NULL;
  LONG lRetOpen = ::RegOpenKeyExW(
    HKEY_LOCAL_MACHINE,
    L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Media Center",
    NULL, KEY_READ, &hkResult);

  if(lRetOpen == ERROR_SUCCESS)
  {
    WCHAR wszRet[2048] = {0};
    DWORD type_1 = REG_SZ;
    DWORD cbData = sizeof(wszRet);

    LONG lRetQuery = ::RegQueryValueExW(hkResult, L"Ident", NULL,
      &type_1, (unsigned char *)wszRet, &cbData);
    if(lRetQuery == ERROR_SUCCESS)
    {
      wstrIdent = wszRet;
      bRtn = true;
    }
  }

  if(hkResult)
  {
    ::RegCloseKey(hkResult);
    hkResult = NULL;
  }

  return bRtn;
}

Ident value v.s Windows Media Center version

< 2.7 = Windows XP Media Center Edition 2002
2.7 or 2.8 = Windows XP Media Center Edition 2004
3.0 = Windows XP Media Center Edition 2005
3.1 = Windows XP Media Center Edition 2005 with Update Rollup 1
4.0 = Windows XP Media Center Edition 2005 with Update Rollup 2
5.0 = Windows Vista
5.1 = Windows Vista with Media Center TV Pack 2008
6.0 = Windows 7

Reference on MSDN:
Identifying Windows Media Center Versions

April 06, 2009

How To: Determine whether a 32-bits application is running on Windows 64-bits platform

WOW64 is the x86 emulator that allows 32-bit Windows-based applications to run seamlessly on 64-bit Windows.

Sample Code:

bool IsRunningOnWow64()
{
  BOOL bIsWow64 = FALSE;

  BOOL (WINAPI *fnIsWow64Process)(HANDLE, PBOOL);
  fnIsWow64Process = (BOOL(WINAPI*)(HANDLE, PBOOL))::GetProcAddress(
    ::GetModuleHandleW(L"kernel32"), "IsWow64Process");

  if(NULL != fnIsWow64Process)
    fnIsWow64Process(GetCurrentProcess(), &bIsWow64);

  return bIsWow64 ? true : false;
}

Reference on MSDN:
IsWow64Process Function

April 02, 2009

Read/Write Windows Registry on Windows 64-Bits Platforms

On Windows Vista 64-bits, there's a 32-bits emulator called WOW64 for 32-bits applications. A 32-bits application running on WOW64 uses the registry redirector, because the 64-bit version of an application may use different registry keys and values than the 32-bit version.

For 32-bits application:
On 64-bit platforms, it runs on WOW64 and accesses 32-bit registry (inside Wow6432Node).

For 64-bits application:
On 64-bit platforms, it runs natively and accesses 64-bit registry (not inside Wow6432Node).

Whatever, you can explicitly indicate which version of registry you want to access, just use RegOpenKeyEx function with KEY_WOW64_32KEY or KEY_WOW64_64KEY in the desired access rights parameter.

Example: A 32-bit application running on WOW64 accesses the 64-bit registry

HKEY hkResult = NULL;
REGSAM samDesired = KEY_READ | KEY_WOW64_64KEY;
LONG lRetOpen = ::RegOpenKeyExW(
  HKEY_LOCAL_MACHINE,
  L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Media Center",
  NULL, samDesired, &hkResult);


Reference on MSDN:
32-bit and 64-bit Application Data in the Registry

January 10, 2009

How to correctly call HttpOpenRequest() with specified accept types?

Windows API: (Wininet)

HINTERNET HttpOpenRequest(
  __in  HINTERNET hConnect,
  __in  LPCTSTR lpszVerb,
  __in  LPCTSTR lpszObjectName,
  __in  LPCTSTR lpszVersion,
  __in  LPCTSTR lpszReferer,
  __in  LPCTSTR *lplpszAcceptTypes,
  __in  DWORD dwFlags,
  __in  DWORD_PTR dwContext
);

Tips:
lplpszAcceptTypes is not a pointer to a null-terminated string, it is a pointer to a null-terminated array of strings. 

Sample Code:

// A null-terminated array of null-terminated strings
const char* lplpszAcceptTypes[] = {"text/*", NULL}; // Accept only text documents

HINTERNET  hHttpFile = HttpOpenRequestA(
  hConnect,
  "GET",
  "/TextDocument",
  HTTP_VERSION,
  NULL,
  lplpszAcceptTypes,
  INTERNET_FLAG_DONT_CACHE, 1);

Reference in MSDN:

January 01, 2009

How to get the last modified date of a file in C++?

On Win32 platform, you can get the attribute information of a file easily by just calling GetFileAttributesEx().
The information you got includes creation time, last access time, and last write time (last modified date).

Windows API:

BOOL WINAPI GetFileAttributesEx(
  __in   LPCTSTR lpFileName,
  __in   GET_FILEEX_INFO_LEVELS fInfoLevelId,
  __out  LPVOID lpFileInformation
);

Sample Code:

WIN32_FILE_ATTRIBUTE_DATA fileAttrData = {0};
GetFileAttributesExW(L"C:\\abc.txt, GetFileExInfoStandard, &fileAttrData);
// GetFileAttributesExA for non-unicode

FILETIME ftLastModifiedDate = fileAttrData.ftLastWriteTime;

Reference in This Site:

Reference in MSDN:

December 19, 2008

How to create a file that will be deleted automatically after close its handle?

Use CreateFile() API with the flag: FILE_FLAG_DELETE_ON_CLOSE

If we want to create a file when the process starts and delete it when the process exits, CreateFile() is convenient to you.

FILE_FLAG_DELETE_ON_CLOSE means the file will be deleted automatically after close hanlde. Even if the process was crashed, it would also be deleted.

Reference in MSDN:

November 08, 2008

What happened to LocalFileTimeToFileTime() / FileTimeToLocalFileTime()?

When you want to convert a time between UTC and local, you may choose the API LocalFileTimeToFileTime() or FileTimeToLocalFileTime() for this job.

Do you know you may get an unexpected result if it is daylight saving time?

LocalFileTimeToFileTime() and FileTimeToLocalFileTime() use the current settings for the time zone and daylight saving time. Therefore, if it is daylight saving time, these functions will take daylight saving time into account, even if the time you are converting is in standard time.

Solution:
You can use SystemTimeToTzSpecificLocalTime() and TzSpecificLocalTimeToSystemTime() instead.

Reference in This Site:

Reference in MSDN:

October 12, 2008

How to raise an user break exception (int 3) dynamically in my code?

The embedded assembly code way:
_asm int 3

The Windows API way:
DebugBreak()

After raised an user break exception in your code, the program can be attached to a debugger. For some situation, this is a good way to debug your buggy problem.

Reference in MSDN:
http://msdn.microsoft.com/en-us/library/ms679297.aspx

August 29, 2008

Why did the RegQueryValueEx() return ERROR_MORE_DATA?

Q: Why does the RegQueryValueEx() always return ERROR_MORE_DATA?

A: If the lpData buffer is too small to receive the data, the function returns ERROR_MORE_DATA.

Windows API:

LONG WINAPI RegQueryValueEx(
  __in HKEY hKey,
  __in_opt LPCTSTR lpValueName,
  __reserved LPDWORD lpReserved,
  __out_opt LPDWORD lpType,
  __out_opt LPBYTE lpData,
  __inout_opt LPDWORD lpcbData
);

Tips:
When you are using RegQueryValueExW(), the parameter of lpcbData
SHOULD be the array size in BYTES, not in characters.

MSDN Reference:

July 18, 2008

How to generate UUID (GUID) in C++?

Sample Code:

#include <Rpc.h>
#pragma comment(lib, "Rpcrt4.lib")

UUID uuid;
::ZeroMemory(&uuid, sizeof(UUID));

// Create uuid or load from a string by UuidFromString() function
::UuidCreate(&uuid);

// If you want to convert uuid to string, use UuidToString() function
WCHAR* wszUuid = NULL;
::UuidToStringW(&uuid, &wszUuid);
if(wszUuid != NULL)
{
  ::RpcStringFree(&wszUuid);
  wszUuid = NULL;
}


Reference in MSDN:

July 17, 2008

How to use named system events (global events) in C#?

There are three classes relating to windows events, EventWaitHandle, AutoResetEvent, and ManualResetEvent.

EventWaitHandle
The EventWaitHandle class can represent either automatic or manual reset events and either local events or named system events.

AutoResetEvent
The AutoResetEvent class derives from EventWaitHandle and represents a local event that resets automatically.

ManualResetEvent
The ManualResetEvent class derives from EventWaitHandle and represents a local event that must be reset manually.

Tips:
According to above description, you should use EventWaitHanlde class to represent named system events, of course it can be either automatic or manual reset events.

MSDN reference:
http://msdn.microsoft.com/en-us/library/ksb7zs2x.aspx

April 26, 2008

Call Windows API in Ruby

Sample Code:
# Close WMP by Window Message
require 'Win32API'

FindWindow = Win32API.new('user32', 'FindWindow', ["P", "P"], "L")
SendMessage = Win32API.new('user32', 'SendMessage', ["L", "L", "P", "P"], "L")
WM_CLOSE = 0x0010

def CloseWMP()
  hwnd = FindWindow.call(nil, "Windows Media Player")
  if hwnd != 0 then
    id = SendMessage.call(hwnd, WM_CLOSE, nil, nil)
  end
end
# End of Close WMP by Window Message


Reference:
http://www.rubycentral.com/pickaxe/lib_windows.html

January 19, 2008

Microsoft Win32 to Microsoft .NET Framework API Map

Microsoft Win32 to Microsoft .NET Framework API Map
http://msdn2.microsoft.com/en-us/library/aa302340.aspx

This is a very useful article for C# programmer.

December 26, 2007

How to get the maximum length of full path in windows?

_MAX_DIR = Maximum length of directory component
_MAX_DRIVE = Maximum length of drive component
_MAX_EXT = Maximum length of extension component
_MAX_FNAME = Maximum length of filename component
_MAX_PATH = Maximum length of full path.

The sum of the fields should not exceed _MAX_PATH.
(The sizes include space for 0-terminator.)

December 25, 2007

How to get the special folders of windows?

(For Windows XP)
SHGetFolderPath Function
http://msdn2.microsoft.com/en-us/library/bb762181.aspx

(For Windows Vista and later)
SHGetKnownFolderPath Function
http://msdn2.microsoft.com/en-us/library/bb762188.aspx

December 09, 2007

How to use critical section?

// Declaration
CRITICAL_SECTION CriticalSection;

// Initialize
::InitializeCriticalSection(&CriticalSection);

// Implementation
::EnterCriticalSection(&CriticalSection);
/* Code block */
::LeaveCriticalSection(&CriticalSection);

// Uninitialize
::DeleteCriticalSection(&CriticalSection);