WineHQ
WineHQ

3.3. The Spec file

3.3.1. Introduction

In Windows, applications and libraries contain some information which are necessary to make APIs such as GetProcAddress work. So it is necessary to duplicate these data structures in the Unix world to make these same APIs work with Winelib applications and libraries.

The spec file is there to solve the semantic gap described above. It provides information about each API exported from a DLL so that the appropriate tables can be generated. Further the information is used to for better relay logging.

A typical spec file will look something like this:

@ stdcall -private DllCanUnloadNow()
@ stdcall -private DllGetClassObject(ptr ptr ptr)
@ stdcall -private DllRegisterServer()
@ stdcall -private DllUnregisterServer()

3.3.2. More details

Here is a more detailed description of the spec file format.

# comment text

Anything after a '#' will be ignored as comments.

ORDINAL FUNCTYPE OPTIONS EXPORTNAME([ARGTYPE [ARGTYPE [...]]]) HANDLERNAME
@ stdcall CreateDesktopW(wstr wstr ptr long long ptr)
@ stdcall CM_Get_Parent(ptr long long) setupapi.CM_Get_Parent
@ cdecl -arch=x86_64 ceilf(float) MSVCRT_ceilf

This field can be present zero or more times. Each instance defines a function entry point. The prototype defined by EXPORTNAME ([ARGTYPE [ARGTYPE [...]]]) specifies the name available for dynamic linking and the format of the arguments. ORDINAL is replaced by the ordinal number corresponding to the function, or @ for automatic ordinal allocation (Win32 only).

FUNCTYPE should be one of:

pascal

for a Win16 function

stdcall

for a normal Win32 function

cdecl

for a Win32 function using the C calling convention

varargs

for a Win32 function taking a variable number of arguments

thiscall

for a Win32 function using the C++ calling convention

ARGTYPE should be one of:

word

for a 16-bit word

s_word

for a 16-bit signed word

segptr

for a segmented pointer

segstr

for a segmented pointer to a null-terminated string

long

a 32-bit value

ptr

for a linear pointer

str

for a linear pointer to a null-terminated string

wstr

for a linear pointer to a null-terminated wide (16-bit Unicode) string

int64

a 64-bit value

int128

a 128-bit value

float

a 32-bit floating-point value

double

a 64-bit floating-point value

For Win32 functions word, s_word, segptr and segstr are not valid. HANDLERNAME is the name of the actual Wine function that will process the request in 32-bit mode.

Strings should almost always map to str, wide strings to wstr. As the general rule it depends on whether the parameter is IN, OUT or IN/OUT.

  • IN: str/wstr

  • OUT: ptr

  • IN/OUT: str/wstr

It is for debug messages. If the parameter is OUT it might not be initialized and thus it should not be printed as a string.

To declare a function using a variable number of arguments in Win16, specify the function as taking no arguments. The arguments are then available with CURRENT_STACK16->args. In Win32, specify the function as varargs and declare it with a "..." parameter in the C file. See the wsprintf* functions in user.spec and user32.spec for an example.

ORDINAL stub EXPORTNAME

This field can be present zero or more times. Each instance defines a stub function. It makes the ordinal available for dynamic linking, but will terminate execution with an error message if the function is ever called.

ORDINAL extern EXPORTNAME SYMBOLNAME

This field can be present zero or more times. Each instance defines an entry that simply maps to a Wine symbol (variable or function); EXPORTNAME will point to the symbol SYMBOLNAME that must be defined in C code. This type only works with Win32.