The Big Picture: The Official Instruction Manual

A new TV comes with a manual. The manual lists every button and what it does. The maker promises that if you press "Volume Up", the volume goes up. The maker may change the circuit boards inside next year, but the button will keep working the same way.

The Win32 API is that manual for Windows. It is the documented, official way for a program to ask Windows to do things. Microsoft publishes every function, its inputs, its result and its errors. And Microsoft promises that programs written to this manual keep working as Windows changes.

2.1 What Win32 Covers

What it is: Win32 is the main Windows API. The name is old. It started with 32-bit Windows. Today it is used by both 32-bit and 64-bit programs, and the name stuck. (Sometimes people say "the Windows API" or "WinAPI". They mean the same thing.)

Win32 is huge. It is organised into areas:

AreaWhat programs do with itExample functions
Files and disksCreate, read, write, delete filesCreateFileW, ReadFile, WriteFile, DeleteFileW
Processes and threadsStart programs, run code in parallelCreateProcessW, CreateThread, ExitProcess
MemoryAsk for, release and protect memoryVirtualAlloc, VirtualFree, HeapAlloc
Windows and messagesShow windows, buttons, menus, react to clicksCreateWindowExW, MessageBoxW, GetMessageW
GraphicsDraw lines, text and imagesBitBlt, TextOutW, CreateCompatibleDC
Registry and securityRead settings, check who you areRegOpenKeyExW, OpenProcessToken
Time and system infoAsk the clock and the PCGetTickCount64, GetSystemInfo
NetworkingSend and receive dataWSAStartup, connect, send
LibrariesLoad DLLs and find functionsLoadLibraryW, GetProcAddress

The last row ties to Chapter 22: loading DLLs is itself an API call.

Naming habits. Win32 names are long and clear. Most are in the form Verb + Thing: CreateFile, GetTickCount, SetWindowText. They follow PascalCase, which means each word starts with a capital letter and there are no spaces.

2.2 The DLL Role Split: kernel32, user32, gdi32 and Friends

What it is: Win32 is not one file. It is split across several DLLs, each with a theme. This is just like a department store. Clothes are on one floor, electronics on another.

DLLThemePlain meaningExamples
kernel32.dllCore system servicesFiles, processes, threads, memory, timeCreateFileW, CreateThread, VirtualAlloc
kernelbase.dllThe same core, deeperSince Windows 7 most of the real code moved here. kernel32 often just forwards to itSame functions, hidden behind kernel32
user32.dllUser interfaceWindows, menus, mouse, keyboard, messagesCreateWindowExW, MessageBoxW, GetMessageW
gdi32.dllGraphics (GDI)Drawing shapes, fonts and bitmaps. GDI means Graphics Device InterfaceBitBlt, CreateFontW
advapi32.dll"Advanced" servicesRegistry, security tokens, services, event logRegOpenKeyExW, OpenSCManagerW
shell32.dllThe Windows shellFolders, the Recycle Bin, icons, file launchingShellExecuteW
ws2_32.dllNetworkingSockets, TCP and UDPsocket, connect
ole32.dll, combase.dllCOM objectsA way for programs to share objectsCoCreateInstance

Tip. kernel32.dll used to hold the real code. Today many of its functions are thin forwarders. They point to kernelbase.dll. The name kernel32 stays because old programs expect it. This is the compatibility promise at work.

How the split shows up in a crash or error message. When a program fails, you may see "faulting module: KERNELBASE.dll". That tells you the failing call was a core Win32 function. It does not mean KERNELBASE.dll is broken. It is usually just where the error was reported.

Program ──► user32.dll   (window, buttons)
        ──► gdi32.dll    (drawing)
        ──► kernel32.dll (files, memory, threads) ──► kernelbase.dll
        ──► advapi32.dll (registry, security)

Despite the "32" in the file names, these DLLs on a 64-bit Windows are 64-bit files. The name is historical.

2.3 Win32 as the Documented, Stable Contract

What it is: A contract is a promise both sides agree on. For Win32:

  • Microsoft promises that a function's name, inputs and behaviour stay the same.
  • Programmers promise to use only the documented functions in the documented way.

The result is backward compatibility. A program built long ago keeps working, because the contract has not changed even though the internals have been rebuilt many times.

RuleWhy it helps you
Functions are never renamed or removed lightlyOld programs do not break
Each function has a public documentation pageYou know what to expect, including errors
New features arrive as new functions (for example CreateFile2)The old ones keep working
Microsoft tests huge numbers of old programs on new WindowsUpgrades are safer

Microsoft recommends that programs call Win32 (or a language runtime that does) and not the deeper Native API. Section 3 explains why. In short: the layer below Win32 may change between Windows versions. Win32 is the layer Microsoft has promised to keep steady.

2.4 ANSI and Unicode: Why Two Versions of Many Functions

What it is: Many Win32 functions that take text come in two versions, with a letter at the end:

SuffixStands forText format
AANSIOne byte per character (using a code page, a table that maps numbers to letters)
WWideUnicode, two bytes per character (UTF-16)

Example: CreateFileA("notes.txt") and CreateFileW(L"notes.txt").

Why two? History.

  1. Old Windows (the 1990s) used ANSI. One byte gives only 256 characters. That is enough for English, but not for Chinese, Hindi or Arabic. A code page tried to work around it, and files from one country's PC could look broken on another's.
  2. Windows NT introduced Unicode. Unicode gives every character in every language its own number, so one text can hold all of them.
  3. Microsoft kept the old A functions so old programs would not break.

What really happens inside: Windows itself works in Unicode. When you call the A version, it quietly converts your text to Unicode and calls the W version. So the W version is the "real" one and slightly faster.

CreateFileA("notes.txt") ──► converts text to UTF-16 ──┐
                                                       ├──► real work
CreateFileW(L"notes.txt") ─────────────────────────────┘

When a programmer writes just CreateFile in C or C++, a macro (an automatic text replacement) picks A or W depending on a build setting. Modern programs almost always pick W.

Why it matters for you. If a file name contains a Hindi, Chinese or emoji character, only the W path can handle it fully. Always prefer W.

2.5 API Sets: Umbrella DLLs

What it is: If you look at a program's imports (Chapter 22) you may see odd names like api-ms-win-core-file-l1-1-0.dll. These are API sets, sometimes called "umbrella" or "contract" DLLs.

An API set name is a promise that says "a group of functions, such as basic file functions, exists." It is not a real file full of code. When the program starts, Windows reads a map and swaps the umbrella name for the real DLL that holds the code (for example kernelbase.dll).

Program says:   api-ms-win-core-file-l1-1-0.dll  (umbrella name)
                              │
                       Windows' map (the "API set schema")
                              ▼
Real code is in:  kernelbase.dll

Why bother? It lets Microsoft move code between real DLLs (and between Windows editions such as desktop and phone or IoT) without breaking programs. The program asks for the umbrella name. Windows decides where it really lives.

The exact map differs between Windows versions. You do not need to memorise it. You only need to know that these names exist and that they forward to real DLLs.

2.6 Error Handling in Win32

What it is: When a Win32 call fails it usually returns a special value, such as FALSE, NULL or INVALID_HANDLE_VALUE. To learn why, the program then calls GetLastError(), which returns a number, the error code.

Value returnedCommon meaning
FALSE (0)The function failed (for functions that return true or false)
NULLNo object or memory was given back
INVALID_HANDLE_VALUECreateFileW could not open the file

Some of the most common error codes:

CodeNamePlain meaning
0ERROR_SUCCESSIt worked
2ERROR_FILE_NOT_FOUNDNo such file
3ERROR_PATH_NOT_FOUNDNo such folder
5ERROR_ACCESS_DENIEDYou are not allowed
32ERROR_SHARING_VIOLATIONAnother program is using the file
87ERROR_INVALID_PARAMETERA bad input was passed

Tip: translate any number yourself. Open Command Prompt:

net helpmsg 5

It prints: Access is denied. Try net helpmsg 2 and net helpmsg 32 as well.

Two warnings:

  • The error is stored per thread. Each thread has its own "last error" note. So call GetLastError() right after the failing call, before anything else can overwrite it.
  • The note is only meaningful after a failure. A successful call may leave an old value behind.

Win32 error codes are different from the Native API's codes (called NTSTATUS). Section 3.4 shows how Windows translates one to the other.

2.7 Trying Win32 Yourself: A Safe PowerShell Call

What it is: PowerShell can call a Win32 function directly. This technique is called P/Invoke (Platform Invoke). It is a read-only, harmless way to see a real Win32 call.

Add-Type -MemberDefinition '[DllImport("kernel32.dll")] public static extern ulong GetTickCount64();' -Name Native -Namespace Win32
[Win32.Native]::GetTickCount64()

What each part means:

PartMeaning
Add-TypeTell PowerShell to build a small helper from the text below
[DllImport("kernel32.dll")]"The function lives in kernel32.dll" (Chapter 22: this is the DLL lookup)
GetTickCount64()The Win32 function that returns milliseconds since Windows started
[Win32.Native]::GetTickCount64()Run it

You will see a big number. Divide by 1000 for seconds, and by 3,600,000 for hours. It should roughly match your PC's uptime. The call went application (PowerShell) → Win32 (kernel32.dll) → and onward down the stack. You can also run Get-Command Get-Process to see which module a PowerShell command comes from.

Note: GetTickCount64 is a good first example because it changes nothing. It only reads the clock.

Summary

TermPlain meaning
Win32 APIThe documented, stable set of Windows functions
kernel32 / kernelbaseFiles, processes, threads, memory, time
user32Windows, menus, keyboard, mouse, messages
gdi32Drawing and fonts
advapi32Registry, security, services
ContractMicrosoft's promise that names and behaviour stay the same
A / W suffixANSI (1 byte) and Unicode (2 bytes) versions
API setAn umbrella DLL name that Windows redirects to a real DLL
GetLastErrorAsks why the last call failed; translate with net helpmsg
P/InvokeCalling a Win32 function from PowerShell or .NET