Added DivX ;-) support by using the wine .dll loader. you must unzip binaries.zip from http://divx.euro.ru/binaries.z...

Original commit message from CVS:
Added DivX ;-) support by using the wine .dll loader. you must unzip
binaries.zip from http://divx.euro.ru/binaries.zip into the win32
directory **of the source tree**.
Extended and bugfixed thr riff parser to support DivX ;-)
Extended the avi parser to support DivX ;-) and MPEG Layer 3.
Fixed a bug in mpg123. Sound still is seriously wrong with layer 3.
Fixed MPEG2 playback in gstplay.
Time indication in gstplay is temporarly broken.
This commit is contained in:
Wim Taymans 2000-07-15 12:06:18 +00:00
parent 2ab64206bb
commit 8df1c8a278
49 changed files with 17713 additions and 172 deletions

View file

@ -340,6 +340,7 @@ libs/colorspace/Makefile
libs/videoscale/Makefile
libs/getbits/Makefile
libs/putbits/Makefile
libs/winloader/Makefile
plugins/Makefile
plugins/au/Makefile
plugins/wav/Makefile

View file

@ -1,7 +1,4 @@
#define BUFFER 1
#define VIDEO_DECODER "mpeg_play"
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@ -9,74 +6,24 @@
#include <gnome.h>
#include <gst/gst.h>
extern GstElement *show;
extern GstElement *video_render_queue, *audio_render_queue;
void avi_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline)
{
GstElement *play;
GstElement *audio_queue, *video_queue;
GstElement *audio_thread, *video_thread;
g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
// connect to audio pad
//if (0) {
if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) {
// construct internal pipeline elements
play = gst_elementfactory_make("audiosink","play_audio");
g_return_if_fail(play != NULL);
// create the thread and pack stuff into it
audio_thread = gst_thread_new("audio_thread");
g_return_if_fail(audio_thread != NULL);
gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(play));
// set up pad connections
gst_element_add_ghost_pad(GST_ELEMENT(audio_thread),
gst_element_get_pad(play,"sink"));
// construct queue and connect everything in the main pipelie
audio_queue = gst_elementfactory_make("queue","audio_queue");
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_queue));
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_thread));
gst_pad_connect(pad,
gst_element_get_pad(audio_queue,"sink"));
gst_pad_connect(gst_element_get_pad(audio_queue,"src"),
gst_element_get_pad(audio_thread,"sink"));
gst_element_get_pad(audio_render_queue,"sink"));
// set up thread state and kick things off
gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL);
g_print("setting to RUNNING state\n");
gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_RUNNING);
g_print("setting to PLAYING state\n");
gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_PLAYING);
} else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
//} else if (0) {
//} else if (0) {
// create the thread and pack stuff into it
video_thread = gst_thread_new("video_thread");
g_return_if_fail(video_thread != NULL);
gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(show));
// set up pad connections
gst_element_add_ghost_pad(GST_ELEMENT(video_thread),
gst_element_get_pad(show,"sink"));
// construct queue and connect everything in the main pipeline
video_queue = gst_elementfactory_make("queue","video_queue");
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_queue));
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_thread));
gst_pad_connect(pad,
gst_element_get_pad(video_queue,"sink"));
gst_pad_connect(gst_element_get_pad(video_queue,"src"),
gst_element_get_pad(video_thread,"sink"));
// set up thread state and kick things off
gtk_object_set(GTK_OBJECT(video_thread),"create_thread",TRUE,NULL);
g_print("setting to RUNNING state\n");
gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_RUNNING);
g_print("setting to PLAYING state\n");
gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_PLAYING);
gst_element_get_pad(video_render_queue,"sink"));
}
g_print("\n");
}

View file

@ -41,6 +41,8 @@ static void frame_displayed(GstSrc *asrc)
guint mux_rate;
static int prev_time = -1;
if (!parse) return;
return;
DEBUG("gstplay: frame displayed %s\n", MUTEX_STATUS());
mux_rate = gst_util_get_int_arg(GTK_OBJECT(parse),"mux_rate");
@ -188,7 +190,9 @@ static void have_type(GstSink *sink) {
GTK_SIGNAL_FUNC(avi_new_pad_created),pipeline);
}
else if (strstr(gsttype->mime, "mpeg1")) {
mpeg1_setup_video_thread(gst_element_get_pad(src,"src"), show, GST_ELEMENT(pipeline));
mpeg1_setup_video_thread(gst_element_get_pad(src,"src"), video_render_queue, GST_ELEMENT(pipeline));
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
gst_clock_reset(gst_clock_get_system());
}
else {
g_print("unknown media type\n");
@ -238,7 +242,7 @@ main (int argc, char *argv[])
g_return_val_if_fail(video_render_thread != NULL, -1);
show = gst_elementfactory_make("videosink","show");
g_return_val_if_fail(show != NULL, -1);
//gtk_object_set(GTK_OBJECT(show),"xv_enabled",FALSE,NULL);
gtk_object_set(GTK_OBJECT(show),"xv_enabled",FALSE,NULL);
window1 = create_window1 (gst_util_get_widget_arg(GTK_OBJECT(show),"widget"));
gtk_widget_show (window1);
gtk_signal_connect(GTK_OBJECT(window1),"delete_event",

View file

@ -63,8 +63,7 @@ void mpeg1_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline)
gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL);
g_print("setting to RUNNING state\n");
gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_RUNNING);
//g_print("setting to PLAYING state\n");
//gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_PLAYING);
} else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
//} else if (0) {
mpeg1_setup_video_thread(pad, video_render_queue, pipeline);
@ -113,7 +112,5 @@ void mpeg1_setup_video_thread(GstPad *pad, GstElement *video_render_queue, GstEl
gtk_object_set(GTK_OBJECT(video_thread),"create_thread",TRUE,NULL);
g_print("setting to RUNNING state\n");
gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_RUNNING);
//g_print("setting to PLAYING state\n");
//gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_PLAYING);
}

View file

@ -24,8 +24,11 @@ void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline)
g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
// connect to audio pad
//if (0) {
if (strncmp(gst_pad_get_name(pad), "private_stream_1.0", 18) == 0) {
if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
mpeg2_setup_video_thread(pad, video_render_queue, pipeline);
return;
}
else if (strncmp(gst_pad_get_name(pad), "private_stream_1.0", 18) == 0) {
gst_plugin_load("ac3parse");
gst_plugin_load("ac3dec");
// construct internal pipeline elements
@ -33,39 +36,8 @@ void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline)
g_return_if_fail(parse_audio != NULL);
decode = gst_elementfactory_make("ac3dec","decode_audio");
g_return_if_fail(decode != NULL);
// create the thread and pack stuff into it
audio_thread = gst_thread_new("audio_thread");
g_return_if_fail(audio_thread != NULL);
gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(parse_audio));
gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(decode));
// set up pad connections
gst_element_add_ghost_pad(GST_ELEMENT(audio_thread),
gst_element_get_pad(parse_audio,"sink"));
gst_pad_connect(gst_element_get_pad(parse_audio,"src"),
gst_element_get_pad(decode,"sink"));
gst_pad_connect(gst_element_get_pad(decode,"src"),
gst_element_get_pad(audio_render_queue,"sink"));
// construct queue and connect everything in the main pipelie
audio_queue = gst_elementfactory_make("queue","audio_queue");
gtk_object_set(GTK_OBJECT(audio_queue),"max_level",30,NULL);
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_queue));
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_thread));
gst_pad_connect(pad,
gst_element_get_pad(audio_queue,"sink"));
gst_pad_connect(gst_element_get_pad(audio_queue,"src"),
gst_element_get_pad(audio_thread,"sink"));
// set up thread state and kick things off
gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL);
g_print("setting to RUNNING state\n");
gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_RUNNING);
}
// connect to audio pad
//if (0) {
if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) {
}
else if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) {
gst_plugin_load("mp3parse");
gst_plugin_load("mpg123");
// construct internal pipeline elements
@ -73,39 +45,41 @@ void mpeg2_new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline)
g_return_if_fail(parse_audio != NULL);
decode = gst_elementfactory_make("mpg123","decode_audio");
g_return_if_fail(decode != NULL);
// create the thread and pack stuff into it
audio_thread = gst_thread_new("audio_thread");
g_return_if_fail(audio_thread != NULL);
gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(parse_audio));
gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(decode));
// set up pad connections
gst_element_add_ghost_pad(GST_ELEMENT(audio_thread),
gst_element_get_pad(parse_audio,"sink"));
gst_pad_connect(gst_element_get_pad(parse_audio,"src"),
gst_element_get_pad(decode,"sink"));
gst_pad_connect(gst_element_get_pad(decode,"src"),
gst_element_get_pad(audio_render_queue,"sink"));
// construct queue and connect everything in the main pipelie
audio_queue = gst_elementfactory_make("queue","audio_queue");
gtk_object_set(GTK_OBJECT(audio_queue),"max_level",BUFFER,NULL);
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_queue));
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_thread));
gst_pad_connect(pad,
gst_element_get_pad(audio_queue,"sink"));
gst_pad_connect(gst_element_get_pad(audio_queue,"src"),
gst_element_get_pad(audio_thread,"sink"));
// set up thread state and kick things off
gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL);
g_print("setting to RUNNING state\n");
gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_RUNNING);
} else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
//} else if (0) {
mpeg2_setup_video_thread(pad, video_render_queue, pipeline);
}
else return;
// create the thread and pack stuff into it
audio_thread = gst_thread_new("audio_thread");
g_return_if_fail(audio_thread != NULL);
gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(parse_audio));
gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(decode));
// set up pad connections
gst_element_add_ghost_pad(GST_ELEMENT(audio_thread),
gst_element_get_pad(parse_audio,"sink"));
gst_pad_connect(gst_element_get_pad(parse_audio,"src"),
gst_element_get_pad(decode,"sink"));
gst_pad_connect(gst_element_get_pad(decode,"src"),
gst_element_get_pad(audio_render_queue,"sink"));
// construct queue and connect everything in the main pipelie
audio_queue = gst_elementfactory_make("queue","audio_queue");
gtk_object_set(GTK_OBJECT(audio_queue),"max_level",30,NULL);
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_queue));
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audio_thread));
gst_pad_connect(pad,
gst_element_get_pad(audio_queue,"sink"));
gst_pad_connect(gst_element_get_pad(audio_queue,"src"),
gst_element_get_pad(audio_thread,"sink"));
// set up thread state and kick things off
gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL);
g_print("setting to RUNNING state\n");
gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_RUNNING);
g_print("setting to PLAYING state\n");
gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_PLAYING);
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
}
void mpeg2_setup_video_thread(GstPad *pad, GstElement *show, GstElement *pipeline)
@ -150,6 +124,7 @@ void mpeg2_setup_video_thread(GstPad *pad, GstElement *show, GstElement *pipelin
gtk_object_set(GTK_OBJECT(video_thread),"create_thread",TRUE,NULL);
g_print("setting to RUNNING state\n");
gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_RUNNING);
gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_PLAYING);
g_print("\n");
}

7
include/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
Makefile
Makefile.in
*.o
*.lo
*.la
.deps
.libs

234
include/avifmt.h Normal file
View file

@ -0,0 +1,234 @@
/****************************************************************************
*
* AVIFMT - AVI file format definitions
*
****************************************************************************/
#ifndef NOAVIFMT
#ifndef __WINE_WINDEF_H
#include <wine/windef.h>
#endif
#ifndef __WINE_MMSYSTEM_H
typedef DWORD FOURCC;
#endif
#ifdef _MSC_VER
#pragma warning(disable:4200)
#endif
/* The following is a short description of the AVI file format. Please
* see the accompanying documentation for a full explanation.
*
* An AVI file is the following RIFF form:
*
* RIFF('AVI'
* LIST('hdrl'
* avih(<MainAVIHeader>)
* LIST ('strl'
* strh(<Stream header>)
* strf(<Stream format>)
* ... additional header data
* LIST('movi'
* { LIST('rec'
* SubChunk...
* )
* | SubChunk } ....
* )
* [ <AVIIndex> ]
* )
*
* The main file header specifies how many streams are present. For
* each one, there must be a stream header chunk and a stream format
* chunk, enlosed in a 'strl' LIST chunk. The 'strf' chunk contains
* type-specific format information; for a video stream, this should
* be a BITMAPINFO structure, including palette. For an audio stream,
* this should be a WAVEFORMAT (or PCMWAVEFORMAT) structure.
*
* The actual data is contained in subchunks within the 'movi' LIST
* chunk. The first two characters of each data chunk are the
* stream number with which that data is associated.
*
* Some defined chunk types:
* Video Streams:
* ##db: RGB DIB bits
* ##dc: RLE8 compressed DIB bits
* ##pc: Palette Change
*
* Audio Streams:
* ##wb: waveform audio bytes
*
* The grouping into LIST 'rec' chunks implies only that the contents of
* the chunk should be read into memory at the same time. This
* grouping is used for files specifically intended to be played from
* CD-ROM.
*
* The index chunk at the end of the file should contain one entry for
* each data chunk in the file.
*
* Limitations for the current software:
* Only one video stream and one audio stream are allowed.
* The streams must start at the beginning of the file.
*
*
* To register codec types please obtain a copy of the Multimedia
* Developer Registration Kit from:
*
* Microsoft Corporation
* Multimedia Systems Group
* Product Marketing
* One Microsoft Way
* Redmond, WA 98052-6399
*
*/
#ifndef mmioFOURCC
#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \
( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
#endif
/* Macro to make a TWOCC out of two characters */
#ifndef aviTWOCC
#define aviTWOCC(ch0, ch1) ((WORD)(BYTE)(ch0) | ((WORD)(BYTE)(ch1) << 8))
#endif
typedef WORD TWOCC;
/* form types, list types, and chunk types */
#define formtypeAVI mmioFOURCC('A', 'V', 'I', ' ')
#define listtypeAVIHEADER mmioFOURCC('h', 'd', 'r', 'l')
#define ckidAVIMAINHDR mmioFOURCC('a', 'v', 'i', 'h')
#define listtypeSTREAMHEADER mmioFOURCC('s', 't', 'r', 'l')
#define ckidSTREAMHEADER mmioFOURCC('s', 't', 'r', 'h')
#define ckidSTREAMFORMAT mmioFOURCC('s', 't', 'r', 'f')
#define ckidSTREAMHANDLERDATA mmioFOURCC('s', 't', 'r', 'd')
#define ckidSTREAMNAME mmioFOURCC('s', 't', 'r', 'n')
#define listtypeAVIMOVIE mmioFOURCC('m', 'o', 'v', 'i')
#define listtypeAVIRECORD mmioFOURCC('r', 'e', 'c', ' ')
#define ckidAVINEWINDEX mmioFOURCC('i', 'd', 'x', '1')
/*
** Stream types for the <fccType> field of the stream header.
*/
#define streamtypeVIDEO mmioFOURCC('v', 'i', 'd', 's')
#define streamtypeAUDIO mmioFOURCC('a', 'u', 'd', 's')
#define streamtypeMIDI mmioFOURCC('m', 'i', 'd', 's')
#define streamtypeTEXT mmioFOURCC('t', 'x', 't', 's')
/* Basic chunk types */
#define cktypeDIBbits aviTWOCC('d', 'b')
#define cktypeDIBcompressed aviTWOCC('d', 'c')
#define cktypePALchange aviTWOCC('p', 'c')
#define cktypeWAVEbytes aviTWOCC('w', 'b')
/* Chunk id to use for extra chunks for padding. */
#define ckidAVIPADDING mmioFOURCC('J', 'U', 'N', 'K')
/*
** Useful macros
**
** Warning: These are nasty macro, and MS C 6.0 compiles some of them
** incorrectly if optimizations are on. Ack.
*/
/* Macro to get stream number out of a FOURCC ckid */
#define FromHex(n) (((n) >= 'A') ? ((n) + 10 - 'A') : ((n) - '0'))
#define StreamFromFOURCC(fcc) ((WORD) ((FromHex(LOBYTE(LOWORD(fcc))) << 4) + \
(FromHex(HIBYTE(LOWORD(fcc))))))
/* Macro to get TWOCC chunk type out of a FOURCC ckid */
#define TWOCCFromFOURCC(fcc) HIWORD(fcc)
/* Macro to make a ckid for a chunk out of a TWOCC and a stream number
** from 0-255.
*/
#define ToHex(n) ((BYTE) (((n) > 9) ? ((n) - 10 + 'A') : ((n) + '0')))
#define MAKEAVICKID(tcc, stream) \
MAKELONG((ToHex((stream) & 0x0f) << 8) | \
(ToHex(((stream) & 0xf0) >> 4)), tcc)
/*
** Main AVI File Header
*/
/* flags for use in <dwFlags> in AVIFileHdr */
#define AVIF_HASINDEX 0x00000010 // Index at end of file?
#define AVIF_MUSTUSEINDEX 0x00000020
#define AVIF_ISINTERLEAVED 0x00000100
#define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames?
#define AVIF_WASCAPTUREFILE 0x00010000
#define AVIF_COPYRIGHTED 0x00020000
/* The AVI File Header LIST chunk should be padded to this size */
#define AVI_HEADERSIZE 2048 // size of AVI header list
typedef struct
{
DWORD dwMicroSecPerFrame; // frame display rate (or 0L)
DWORD dwMaxBytesPerSec; // max. transfer rate
DWORD dwPaddingGranularity; // pad to multiples of this
// size; normally 2K.
DWORD dwFlags; // the ever-present flags
DWORD dwTotalFrames; // # frames in file
DWORD dwInitialFrames;
DWORD dwStreams;
DWORD dwSuggestedBufferSize;
DWORD dwWidth;
DWORD dwHeight;
DWORD dwReserved[4];
} MainAVIHeader;
/*
** Stream header
*/
#define AVISF_DISABLED 0x00000001
#define AVISF_VIDEO_PALCHANGES 0x00010000
typedef struct {
FOURCC fccType;
FOURCC fccHandler;
DWORD dwFlags; /* Contains AVITF_* flags */
WORD wPriority;
WORD wLanguage;
DWORD dwInitialFrames;
DWORD dwScale;
DWORD dwRate; /* dwRate / dwScale == samples/second */
DWORD dwStart;
DWORD dwLength; /* In units above... */
DWORD dwSuggestedBufferSize;
DWORD dwQuality;
DWORD dwSampleSize;
RECT rcFrame;
} AVIStreamHeader;
/* Flags for index */
#define AVIIF_LIST 0x00000001L // chunk is a 'LIST'
#define AVIIF_KEYFRAME 0x00000010L // this frame is a key frame.
#define AVIIF_NOTIME 0x00000100L // this frame doesn't take any time
#define AVIIF_COMPUSE 0x0FFF0000L // these bits are for compressor use
typedef struct
{
DWORD ckid;
DWORD dwFlags;
DWORD dwChunkOffset; // Position of chunk
DWORD dwChunkLength; // Length of chunk
} AVIINDEXENTRY;
/*
** Palette change chunk
**
** Used in video streams.
*/
#endif /* NOAVIFMT */

15
include/default.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef _DEFAULT_H
#define _DEFAULT_H
typedef long HRESULT;
typedef unsigned int offset_t;
#define E_NOTIMPL -158
#define E_FAIL -1
#define E_ERROR -2
#define fccDIV3 mmioFOURCC('D', 'I', 'V', '3')
#define fccDIV4 mmioFOURCC('D', 'I', 'V', '4')
#define fccIV50 mmioFOURCC('I', 'V', '5', '0')
#endif

16
include/registry.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef REGISTRY_H
#define REGISTRY_H
#ifdef __cplusplus
extern "C" {
#endif
long RegOpenKeyExA(long key, char* subkey, long reserved, long access, int* newkey);
long RegCloseKey(long key);
long RegQueryValueExA(long key, char* value, int* reserved, int* type, int* data, int* count);
long RegCreateKeyExA(long key, char* name, long reserved,
void* classs, long options, long security,
void* sec_attr, int* newkey, int* status) ;
long RegSetValueExA(long key, char* name, long v1, long v2, void* data, long size);
#ifdef __cplusplus
};
#endif
#endif

7
include/wine/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
Makefile
Makefile.in
*.o
*.lo
*.la
.deps
.libs

145
include/wine/basetsd.h Normal file
View file

@ -0,0 +1,145 @@
/*
* Compilers that uses ILP32, LP64 or P64 type models
* for both Win32 and Win64 are supported by this file.
*/
#ifndef __WINE_BASETSD_H
#define __WINE_BASETSD_H
#ifdef __WINE__
#include "config.h"
#endif /* defined(__WINE__) */
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
/*
* Win32 was easy to implement under Unix since most (all?) 32-bit
* Unices uses the same type model (ILP32) as Win32, where int, long
* and pointer are 32-bit.
*
* Win64, however, will cause some problems when implemented under Unix.
* Linux/{Alpha, Sparc64} and most (all?) other 64-bit Unices uses
* the LP64 type model where int is 32-bit and long and pointer are
* 64-bit. Win64 on the other hand uses the P64 (sometimes called LLP64)
* type model where int and long are 32 bit and pointer is 64-bit.
*/
/* Type model indepent typedefs */
typedef char __int8;
typedef unsigned char __uint8;
typedef short __int16;
typedef unsigned short __uint16;
typedef int __int32;
typedef unsigned int __uint32;
typedef long long __int64;
typedef unsigned long long __uint64;
#if defined(_WIN64)
typedef __uint32 __ptr32;
typedef void *__ptr64;
#else /* FIXME: defined(_WIN32) */
typedef void *__ptr32;
typedef __uint64 __ptr64;
#endif
/* Always signed and 32 bit wide */
typedef __int32 LONG32;
typedef __int32 INT32;
typedef LONG32 *PLONG32;
typedef INT32 *PINT32;
/* Always unsigned and 32 bit wide */
typedef __uint32 ULONG32;
typedef __uint32 DWORD32;
typedef __uint32 UINT32;
typedef ULONG32 *PULONG32;
typedef DWORD32 *PDWORD32;
typedef UINT32 *PUINT32;
/* Always signed and 64 bit wide */
typedef __int64 LONG64;
typedef __int64 INT64;
typedef LONG64 *PLONG64;
typedef INT64 *PINT64;
/* Always unsigned and 64 bit wide */
typedef __uint64 ULONG64;
typedef __uint64 DWORD64;
typedef __uint64 UINT64;
typedef ULONG64 *PULONG64;
typedef DWORD64 *PDWORD64;
typedef UINT64 *PUINT64;
/* Win32 or Win64 dependent typedef/defines. */
#ifdef _WIN64
typedef __int64 INT_PTR, *PINT_PTR;
typedef __uint64 UINT_PTR, *PUINT_PTR;
#define MAXINT_PTR 0x7fffffffffffffff
#define MININT_PTR 0x8000000000000000
#define MAXUINT_PTR 0xffffffffffffffff
typedef __int32 HALF_PTR, *PHALF_PTR;
typedef __int32 UHALF_PTR, *PUHALF_PTR;
#define MAXHALF_PTR 0x7fffffff
#define MINHALF_PTR 0x80000000
#define MAXUHALF_PTR 0xffffffff
typedef __int64 LONG_PTR, *PLONG_PTR;
typedef __uint64 ULONG_PTR, *PULONG_PTR;
typedef __uint64 DWORD_PTR, *PDWORD_PTR;
#else /* FIXME: defined(_WIN32) */
typedef __int32 INT_PTR, *PINT_PTR;
typedef __uint32 UINT_PTR, *PUINT_PTR;
#define MAXINT_PTR 0x7fffffff
#define MININT_PTR 0x80000000
#define MAXUINT_PTR 0xffffffff
typedef __int16 HALF_PTR, *PHALF_PTR;
typedef __uint16 UHALF_PTR, *PUHALF_PTR;
#define MAXUHALF_PTR 0xffff
#define MAXHALF_PTR 0x7fff
#define MINHALF_PTR 0x8000
typedef __int32 LONG_PTR, *PLONG_PTR;
typedef __uint32 ULONG_PTR, *PULONG_PTR;
typedef __uint32 DWORD_PTR, *PDWORD_PTR;
#endif /* defined(_WIN64) || defined(_WIN32) */
typedef INT_PTR SSIZE_T, *PSSIZE_T;
typedef UINT_PTR SIZE_T, *PSIZE_T;
#ifdef __cplusplus
} /* extern "C" */
#endif /* defined(__cplusplus) */
#endif /* !defined(__WINE_BASETSD_H) */

442
include/wine/config.h Normal file
View file

@ -0,0 +1,442 @@
/* include/config.h. Generated automatically by configure. */
/* include/config.h.in. Generated automatically from configure.in by autoheader. */
/* Define if using alloca.c. */
/* #undef C_ALLOCA */
/* Define to empty if the keyword does not work. */
/* #undef const */
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
This function is required for alloca.c support on those systems. */
/* #undef CRAY_STACKSEG_END */
/* Define if you have alloca, as a function or macro. */
#define HAVE_ALLOCA 1
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
#define HAVE_ALLOCA_H 1
/* Define as __inline if that's what the C compiler calls it. */
/* #undef inline */
/* Define to `unsigned' if <sys/types.h> doesn't define. */
/* #undef size_t */
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown
*/
/* #undef STACK_DIRECTION */
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
/* #undef STAT_MACROS_BROKEN */
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if your processor stores words with the most significant
byte first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */
/* Define if the X Window System is missing or not being used. */
/* #undef X_DISPLAY_MISSING */
/* Define if symbols declared in assembly code need an underscore prefix */
/* #undef NEED_UNDERSCORE_PREFIX */
/* Define to use .string instead of .ascii */
#define HAVE_ASM_STRING 1
/* Define if struct msghdr contains msg_accrights */
/* #undef HAVE_MSGHDR_ACCRIGHTS */
/* Define if struct sockaddr_un contains sun_len */
/* #undef HAVE_SOCKADDR_SUN_LEN */
/* Define if you have the Xxf86dga library (-lXxf86dga). */
#define HAVE_LIBXXF86DGA 1
/* Define if you have the Xxf86dga library version 2.0 (-lXxf86dga). */
/* #undef HAVE_LIBXXF86DGA2 */
/* Define if you have the X Shm extension */
#define HAVE_LIBXXSHM 1
/* Define if you have the Xxf86vm library */
#define HAVE_LIBXXF86VM 1
/* Define if you have the Xpm library */
#define HAVE_LIBXXPM 1
/* Define if you have the Open Sound system. */
#define HAVE_OSS 1
/* Define if you have the Open Sound system (MIDI interface). */
#define HAVE_OSS_MIDI 1
/* Define if X libraries are not reentrant (compiled without -D_REENTRANT). */
/* #undef NO_REENTRANT_X11 */
/* Define if libc is not reentrant */
/* #undef NO_REENTRANT_LIBC */
/* Define if libc uses __errno_location for reentrant errno */
#define HAVE__ERRNO_LOCATION 1
/* Define if libc uses __error for reentrant errno */
/* #undef HAVE__ERROR */
/* Define if libc uses ___errno for reentrant errno */
/* #undef HAVE___ERRNO */
/* Define if libc uses __thr_errno for reentrant errno */
/* #undef HAVE__THR_ERRNO */
/* Define if all debug messages are to be compiled out */
/* #undef NO_DEBUG_MSGS */
/* Define if TRACE messages are to be compiled out */
/* #undef NO_TRACE_MSGS */
/* Define if the struct statfs has the member bavail */
#define STATFS_HAS_BAVAIL 1
/* Define if the struct statfs has the member bfree */
#define STATFS_HAS_BFREE 1
/* Define if the struct statfs is defined by <sys/vfs.h> */
#define STATFS_DEFINED_BY_SYS_VFS 1
/* Define if the struct statfs is defined by <sys/statfs.h> */
#define STATFS_DEFINED_BY_SYS_STATFS 1
/* Define if the struct statfs is defined by <sys/mount.h> */
/* #undef STATFS_DEFINED_BY_SYS_MOUNT */
/* Define if ncurses have the new resizeterm function */
#define HAVE_RESIZETERM 1
/* Define if ncurses have the new getbkgd function */
#define HAVE_GETBKGD 1
/* Define if IPX should use netipx/ipx.h from libc */
#define HAVE_IPX_GNU 1
/* Define if IPX includes are taken from Linux kernel */
/* #undef HAVE_IPX_LINUX */
/* Define if Mesa is present on the system or not */
/* #undef HAVE_LIBMESAGL */
/* Define if the system has dynamic link library support with the dl* API */
#define HAVE_DL_API 1
/* Define if <linux/joystick.h> defines the Linux 2.2 joystick API */
#define HAVE_LINUX_22_JOYSTICK_API 1
/* Define if the OpenGL implementation supports the GL_EXT_color_table extension */
/* #undef HAVE_GL_COLOR_TABLE */
/* Define if the OpenGL implementation supports the GL_EXT_paletted_texture extension */
/* #undef HAVE_GL_PALETTED_TEXTURE */
/* The number of bytes in a long long. */
#define SIZEOF_LONG_LONG 8
/* Define if you have the __libc_fork function. */
/* #undef HAVE___LIBC_FORK */
/* Define if you have the _lwp_create function. */
/* #undef HAVE__LWP_CREATE */
/* Define if you have the clone function. */
#define HAVE_CLONE 1
/* Define if you have the connect function. */
#define HAVE_CONNECT 1
/* Define if you have the dlopen function. */
/* #undef HAVE_DLOPEN */
/* Define if you have the gethostbyname function. */
#define HAVE_GETHOSTBYNAME 1
/* Define if you have the getnetbyaddr function. */
#define HAVE_GETNETBYADDR 1
/* Define if you have the getnetbyname function. */
#define HAVE_GETNETBYNAME 1
/* Define if you have the getpagesize function. */
#define HAVE_GETPAGESIZE 1
/* Define if you have the getprotobyname function. */
#define HAVE_GETPROTOBYNAME 1
/* Define if you have the getprotobynumber function. */
#define HAVE_GETPROTOBYNUMBER 1
/* Define if you have the getservbyport function. */
#define HAVE_GETSERVBYPORT 1
/* Define if you have the getsockopt function. */
#define HAVE_GETSOCKOPT 1
/* Define if you have the inet_network function. */
#define HAVE_INET_NETWORK 1
/* Define if you have the memmove function. */
#define HAVE_MEMMOVE 1
/* Define if you have the openpty function. */
#define HAVE_OPENPTY 1
/* Define if you have the rfork function. */
/* #undef HAVE_RFORK */
/* Define if you have the select function. */
#define HAVE_SELECT 1
/* Define if you have the sendmsg function. */
#define HAVE_SENDMSG 1
/* Define if you have the settimeofday function. */
#define HAVE_SETTIMEOFDAY 1
/* Define if you have the sigaltstack function. */
#define HAVE_SIGALTSTACK 1
/* Define if you have the statfs function. */
#define HAVE_STATFS 1
/* Define if you have the strcasecmp function. */
#define HAVE_STRCASECMP 1
/* Define if you have the strerror function. */
#define HAVE_STRERROR 1
/* Define if you have the strncasecmp function. */
#define HAVE_STRNCASECMP 1
/* Define if you have the tcgetattr function. */
#define HAVE_TCGETATTR 1
/* Define if you have the timegm function. */
#define HAVE_TIMEGM 1
/* Define if you have the usleep function. */
#define HAVE_USLEEP 1
/* Define if you have the vfscanf function. */
#define HAVE_VFSCANF 1
/* Define if you have the wait4 function. */
#define HAVE_WAIT4 1
/* Define if you have the waitpid function. */
#define HAVE_WAITPID 1
/* Define if you have the <GL/gl.h> header file. */
/* #undef HAVE_GL_GL_H */
/* Define if you have the <GL/glx.h> header file. */
/* #undef HAVE_GL_GLX_H */
/* Define if you have the <X11/Xlib.h> header file. */
#define HAVE_X11_XLIB_H 1
/* Define if you have the <X11/extensions/XShm.h> header file. */
#define HAVE_X11_EXTENSIONS_XSHM_H 1
/* Define if you have the <X11/extensions/xf86dga.h> header file. */
#define HAVE_X11_EXTENSIONS_XF86DGA_H 1
/* Define if you have the <X11/extensions/xf86vmode.h> header file. */
#define HAVE_X11_EXTENSIONS_XF86VMODE_H 1
/* Define if you have the <X11/xpm.h> header file. */
#define HAVE_X11_XPM_H 1
/* Define if you have the <a.out.h> header file. */
#define HAVE_A_OUT_H 1
/* Define if you have the <a_out.h> header file. */
#define HAVE_A_OUT_H 1
/* Define if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define if you have the <arpa/nameser.h> header file. */
#define HAVE_ARPA_NAMESER_H 1
/* Define if you have the <curses.h> header file. */
/* #undef HAVE_CURSES_H */
/* Define if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define if you have the <elf.h> header file. */
#define HAVE_ELF_H 1
/* Define if you have the <float.h> header file. */
#define HAVE_FLOAT_H 1
/* Define if you have the <libio.h> header file. */
#define HAVE_LIBIO_H 1
/* Define if you have the <link.h> header file. */
#define HAVE_LINK_H 1
/* Define if you have the <linux/cdrom.h> header file. */
#define HAVE_LINUX_CDROM_H 1
/* Define if you have the <linux/joystick.h> header file. */
#define HAVE_LINUX_JOYSTICK_H 1
/* Define if you have the <linux/ucdrom.h> header file. */
/* #undef HAVE_LINUX_UCDROM_H */
/* Define if you have the <machine/soundcard.h> header file. */
/* #undef HAVE_MACHINE_SOUNDCARD_H */
/* Define if you have the <ncurses.h> header file. */
#define HAVE_NCURSES_H 1
/* Define if you have the <net/if.h> header file. */
#define HAVE_NET_IF_H 1
/* Define if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define if you have the <netinet/tcp.h> header file. */
#define HAVE_NETINET_TCP_H 1
/* Define if you have the <pty.h> header file. */
#define HAVE_PTY_H 1
/* Define if you have the <resolv.h> header file. */
#define HAVE_RESOLV_H 1
/* Define if you have the <sched.h> header file. */
#define HAVE_SCHED_H 1
/* Define if you have the <socket.h> header file. */
/* #undef HAVE_SOCKET_H */
/* Define if you have the <soundcard.h> header file. */
/* #undef HAVE_SOUNDCARD_H */
/* Define if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define if you have the <sys/cdio.h> header file. */
/* #undef HAVE_SYS_CDIO_H */
/* Define if you have the <sys/errno.h> header file. */
#define HAVE_SYS_ERRNO_H 1
/* Define if you have the <sys/file.h> header file. */
#define HAVE_SYS_FILE_H 1
/* Define if you have the <sys/filio.h> header file. */
/* #undef HAVE_SYS_FILIO_H */
/* Define if you have the <sys/ipc.h> header file. */
#define HAVE_SYS_IPC_H 1
/* Define if you have the <sys/lwp.h> header file. */
/* #undef HAVE_SYS_LWP_H */
/* Define if you have the <sys/mman.h> header file. */
#define HAVE_SYS_MMAN_H 1
/* Define if you have the <sys/modem.h> header file. */
/* #undef HAVE_SYS_MODEM_H */
/* Define if you have the <sys/mount.h> header file. */
#define HAVE_SYS_MOUNT_H 1
/* Define if you have the <sys/msg.h> header file. */
#define HAVE_SYS_MSG_H 1
/* Define if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define if you have the <sys/reg.h> header file. */
#define HAVE_SYS_REG_H 1
/* Define if you have the <sys/shm.h> header file. */
#define HAVE_SYS_SHM_H 1
/* Define if you have the <sys/signal.h> header file. */
#define HAVE_SYS_SIGNAL_H 1
/* Define if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define if you have the <sys/sockio.h> header file. */
/* #undef HAVE_SYS_SOCKIO_H */
/* Define if you have the <sys/soundcard.h> header file. */
#define HAVE_SYS_SOUNDCARD_H 1
/* Define if you have the <sys/statfs.h> header file. */
#define HAVE_SYS_STATFS_H 1
/* Define if you have the <sys/strtio.h> header file. */
/* #undef HAVE_SYS_STRTIO_H */
/* Define if you have the <sys/syscall.h> header file. */
#define HAVE_SYS_SYSCALL_H 1
/* Define if you have the <sys/v86.h> header file. */
/* #undef HAVE_SYS_V86_H */
/* Define if you have the <sys/v86intr.h> header file. */
/* #undef HAVE_SYS_V86INTR_H */
/* Define if you have the <sys/vfs.h> header file. */
#define HAVE_SYS_VFS_H 1
/* Define if you have the <sys/vm86.h> header file. */
#define HAVE_SYS_VM86_H 1
/* Define if you have the <sys/wait.h> header file. */
#define HAVE_SYS_WAIT_H 1
/* Define if you have the <syscall.h> header file. */
#define HAVE_SYSCALL_H 1
/* Define if you have the <ucontext.h> header file. */
#define HAVE_UCONTEXT_H 1
/* Define if you have the <wctype.h> header file. */
#define HAVE_WCTYPE_H 1
/* Define if you have the curses library (-lcurses). */
/* #undef HAVE_LIBCURSES */
/* Define if you have the i386 library (-li386). */
/* #undef HAVE_LIBI386 */
/* Define if you have the m library (-lm). */
#define HAVE_LIBM 1
/* Define if you have the mmap library (-lmmap). */
/* #undef HAVE_LIBMMAP */
/* Define if you have the ncurses library (-lncurses). */
#define HAVE_LIBNCURSES 1
/* Define if you have the ossaudio library (-lossaudio). */
/* #undef HAVE_LIBOSSAUDIO */
/* Define if you have the w library (-lw). */
/* #undef HAVE_LIBW */
/* Define if you have the xpg4 library (-lxpg4). */
/* #undef HAVE_LIBXPG4 */

93
include/wine/debugtools.h Normal file
View file

@ -0,0 +1,93 @@
#ifndef __WINE_DEBUGTOOLS_H
#define __WINE_DEBUGTOOLS_H
#ifdef __WINE__ /* Debugging interface is internal to Wine */
#include <stdarg.h>
#include "config.h"
#include "windef.h"
struct _GUID;
/* Internal definitions (do not use these directly) */
enum __DEBUG_CLASS { __DBCL_FIXME, __DBCL_ERR, __DBCL_WARN, __DBCL_TRACE, __DBCL_COUNT };
#ifndef NO_TRACE_MSGS
# define __GET_DEBUGGING_trace(dbch) ((dbch)[0] & (1 << __DBCL_TRACE))
#else
# define __GET_DEBUGGING_trace(dbch) 0
#endif
#ifndef NO_DEBUG_MSGS
# define __GET_DEBUGGING_warn(dbch) ((dbch)[0] & (1 << __DBCL_WARN))
# define __GET_DEBUGGING_fixme(dbch) ((dbch)[0] & (1 << __DBCL_FIXME))
#else
# define __GET_DEBUGGING_warn(dbch) 0
# define __GET_DEBUGGING_fixme(dbch) 0
#endif
/* define error macro regardless of what is configured */
#define __GET_DEBUGGING_err(dbch) ((dbch)[0] & (1 << __DBCL_ERR))
#define __GET_DEBUGGING(dbcl,dbch) __GET_DEBUGGING_##dbcl(dbch)
#define __SET_DEBUGGING(dbcl,dbch,on) \
((on) ? ((dbch)[0] |= 1 << (dbcl)) : ((dbch)[0] &= ~(1 << (dbcl))))
#ifndef __GNUC__
#define __FUNCTION__ ""
#endif
#define __DPRINTF(dbcl,dbch) \
(!__GET_DEBUGGING(dbcl,(dbch)) || (dbg_header_##dbcl((dbch),__FUNCTION__),0)) ? \
(void)0 : (void)dbg_printf
/* Exported definitions and macros */
/* These function return a printable version of a string, including
quotes. The string will be valid for some time, but not indefinitely
as strings are re-used. */
extern LPCSTR debugstr_an (LPCSTR s, int n);
extern LPCSTR debugstr_wn (LPCWSTR s, int n);
extern LPCSTR debugres_a (LPCSTR res);
extern LPCSTR debugres_w (LPCWSTR res);
extern LPCSTR debugstr_guid( const struct _GUID *id );
extern LPCSTR debugstr_hex_dump (const void *ptr, int len);
extern int dbg_header_err( const char *dbg_channel, const char *func );
extern int dbg_header_warn( const char *dbg_channel, const char *func );
extern int dbg_header_fixme( const char *dbg_channel, const char *func );
extern int dbg_header_trace( const char *dbg_channel, const char *func );
extern int dbg_vprintf( const char *format, va_list args );
static inline LPCSTR debugstr_a( LPCSTR s ) { return debugstr_an( s, 80 ); }
static inline LPCSTR debugstr_w( LPCWSTR s ) { return debugstr_wn( s, 80 ); }
#ifdef __GNUC__
extern int dbg_printf(const char *format, ...) __attribute__((format (printf,1,2)));
#else
extern int dbg_printf(const char *format, ...);
#endif
#define TRACE_(X) TRACE
#define WARN_(X) TRACE
#define WARN TRACE
#define ERR_(X) printf
#define ERR printf
#define FIXME_(X) TRACE
#define FIXME TRACE
#define TRACE_ON(X) 1
#define ERR_ON(X) 1
#define DECLARE_DEBUG_CHANNEL(ch) \
extern char dbch_##ch[];
#define DEFAULT_DEBUG_CHANNEL(ch) \
extern char dbch_##ch[]; static char * const __dbch_default = dbch_##ch;
#define DPRINTF dbg_printf
#define MESSAGE dbg_printf
#endif /* __WINE__ */
#endif /* __WINE_DEBUGTOOLS_H */

112
include/wine/driver.h Normal file
View file

@ -0,0 +1,112 @@
/*
* Drivers definitions
*/
#ifndef __WINE_DRIVER_H
#define __WINE_DRIVER_H
#include "windef.h"
#define MMSYSERR_BASE 0
#define MMSYSERR_NOERROR 0 /* no error */
#define MMSYSERR_ERROR (MMSYSERR_BASE + 1) /* unspecified error */
#define MMSYSERR_BADDEVICEID (MMSYSERR_BASE + 2) /* device ID out of range */
#define MMSYSERR_NOTENABLED (MMSYSERR_BASE + 3) /* driver failed enable */
#define MMSYSERR_ALLOCATED (MMSYSERR_BASE + 4) /* device already allocated */
#define MMSYSERR_INVALHANDLE (MMSYSERR_BASE + 5) /* device handle is invalid */
#define MMSYSERR_NODRIVER (MMSYSERR_BASE + 6) /* no device driver present */
#define MMSYSERR_NOMEM (MMSYSERR_BASE + 7) /* memory allocation error */
#define MMSYSERR_NOTSUPPORTED (MMSYSERR_BASE + 8) /* function isn't supported */
#define MMSYSERR_BADERRNUM (MMSYSERR_BASE + 9) /* error value out of range */
#define MMSYSERR_INVALFLAG (MMSYSERR_BASE + 10) /* invalid flag passed */
#define MMSYSERR_INVALPARAM (MMSYSERR_BASE + 11) /* invalid parameter passed */
#define MMSYSERR_LASTERROR (MMSYSERR_BASE + 11) /* last error in range */
#define DRV_LOAD 0x0001
#define DRV_ENABLE 0x0002
#define DRV_OPEN 0x0003
#define DRV_CLOSE 0x0004
#define DRV_DISABLE 0x0005
#define DRV_FREE 0x0006
#define DRV_CONFIGURE 0x0007
#define DRV_QUERYCONFIGURE 0x0008
#define DRV_INSTALL 0x0009
#define DRV_REMOVE 0x000A
#define DRV_EXITSESSION 0x000B
#define DRV_EXITAPPLICATION 0x000C
#define DRV_POWER 0x000F
#define DRV_RESERVED 0x0800
#define DRV_USER 0x4000
#define DRVCNF_CANCEL 0x0000
#define DRVCNF_OK 0x0001
#define DRVCNF_RESTART 0x0002
#define DRVEA_NORMALEXIT 0x0001
#define DRVEA_ABNORMALEXIT 0x0002
#define DRV_SUCCESS 0x0001
#define DRV_FAILURE 0x0000
#define GND_FIRSTINSTANCEONLY 0x00000001
#define GND_FORWARD 0x00000000
#define GND_REVERSE 0x00000002
typedef struct {
DWORD dwDCISize;
LPCSTR lpszDCISectionName;
LPCSTR lpszDCIAliasName;
} DRVCONFIGINFO16, *LPDRVCONFIGINFO16;
typedef struct {
DWORD dwDCISize;
LPCWSTR lpszDCISectionName;
LPCWSTR lpszDCIAliasName;
} DRVCONFIGINFO, *LPDRVCONFIGINFO;
/* GetDriverInfo16 references this structure, so this a struct defined
* in the Win16 API.
* GetDriverInfo has been deprecated in Win32.
*/
typedef struct
{
UINT16 length;
HDRVR16 hDriver;
HINSTANCE16 hModule;
CHAR szAliasName[128];
} DRIVERINFOSTRUCT16, *LPDRIVERINFOSTRUCT16;
LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg,
LPARAM dwParam1, LPARAM dwParam2);
LRESULT WINAPI DefDriverProc(DWORD dwDriverIdentifier, HDRVR hdrvr,
UINT Msg, LPARAM lParam1, LPARAM lParam2);
HDRVR16 WINAPI OpenDriver16(LPCSTR szDriverName, LPCSTR szSectionName,
LPARAM lParam2);
HDRVR WINAPI OpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName,
LPARAM lParam2);
HDRVR WINAPI OpenDriverW(LPCWSTR szDriverName, LPCWSTR szSectionName,
LPARAM lParam2);
#define OpenDriver WINELIB_NAME_AW(OpenDriver)
LRESULT WINAPI CloseDriver16(HDRVR16 hDriver, LPARAM lParam1, LPARAM lParam2);
LRESULT WINAPI CloseDriver(HDRVR hDriver, LPARAM lParam1, LPARAM lParam2);
LRESULT WINAPI SendDriverMessage16( HDRVR16 hDriver, UINT16 message,
LPARAM lParam1, LPARAM lParam2 );
LRESULT WINAPI SendDriverMessage( HDRVR hDriver, UINT message,
LPARAM lParam1, LPARAM lParam2 );
HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDriver);
HMODULE WINAPI GetDriverModuleHandle(HDRVR hDriver);
DWORD WINAPI GetDriverFlags( HDRVR hDriver );
#ifdef __WINE__
/* this call (GetDriverFlags) is not documented, nor the flags returned.
* here are Wine only definitions
*/
#define WINE_GDF_EXIST 0x80000000
#define WINE_GDF_16BIT 0x10000000
#endif
#endif /* __WINE_DRIVER_H */

14
include/wine/elfdll.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef __WINE_ELFDLL_H
#define __WINE_ELFDLL_H
#include "module.h"
#include "windef.h"
WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR libname, DWORD flags);
HINSTANCE16 ELFDLL_LoadModule16(LPCSTR libname);
void ELFDLL_UnloadLibrary(WINE_MODREF *wm);
void *ELFDLL_dlopen(const char *libname, int flags);
extern char *extra_ld_library_path;
#endif

56
include/wine/heap.h Normal file
View file

@ -0,0 +1,56 @@
/*
* Win32 heap definitions
*
* Copyright 1996 Alexandre Julliard
*/
#ifndef __WINE_HEAP_H
#define __WINE_HEAP_H
#include "config.h"
#include "winbase.h"
extern HANDLE SystemHeap;
extern HANDLE SegptrHeap;
extern int HEAP_IsInsideHeap( HANDLE heap, DWORD flags, LPCVOID ptr );
extern SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr );
extern LPSTR HEAP_strdupA( HANDLE heap, DWORD flags, LPCSTR str );
extern LPWSTR HEAP_strdupW( HANDLE heap, DWORD flags, LPCWSTR str );
extern LPWSTR HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str );
extern LPSTR HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str );
/* SEGPTR helper macros */
#define SEGPTR_ALLOC(size) \
(HeapAlloc( SegptrHeap, 0, (size) ))
#define SEGPTR_NEW(type) \
((type *)HeapAlloc( SegptrHeap, 0, sizeof(type) ))
#define SEGPTR_STRDUP(str) \
(HIWORD(str) ? HEAP_strdupA( SegptrHeap, 0, (str) ) : (LPSTR)(str))
#define SEGPTR_STRDUP_WtoA(str) \
(HIWORD(str) ? HEAP_strdupWtoA( SegptrHeap, 0, (str) ) : (LPSTR)(str))
/* define an inline function, a macro won't do */
static inline SEGPTR WINE_UNUSED SEGPTR_Get(LPCVOID ptr) {
return (HIWORD(ptr) ? HEAP_GetSegptr( SegptrHeap, 0, ptr ) : (SEGPTR)ptr);
}
#define SEGPTR_GET(ptr) SEGPTR_Get(ptr)
#define SEGPTR_FREE(ptr) \
(HIWORD(ptr) ? HeapFree( SegptrHeap, 0, (ptr) ) : 0)
/* system heap private data */
/* you must lock the system heap before using this structure */
typedef struct
{
void *gdi; /* GDI heap */
void *user; /* USER handle table */
void *cursor; /* cursor information */
void *queue; /* message queues descriptor */
void *win; /* windows descriptor */
void *root; /* X11 root window */
} SYSTEM_HEAP_DESCR;
extern SYSTEM_HEAP_DESCR *SystemHeapDescr;
#endif /* __WINE_HEAP_H */

198
include/wine/module.h Normal file
View file

@ -0,0 +1,198 @@
/*
* Module definitions
*
* Copyright 1995 Alexandre Julliard
*/
#ifndef __WINE_MODULE_H
#define __WINE_MODULE_H
#include "windef.h"
//#include "dosexe.h"
#include "pe_image.h"
typedef struct {
BYTE type;
BYTE flags;
BYTE segnum;
WORD offs WINE_PACKED;
} ET_ENTRY;
typedef struct {
WORD first; /* ordinal */
WORD last; /* ordinal */
WORD next; /* bundle */
} ET_BUNDLE;
/* In-memory segment table */
typedef struct
{
WORD filepos; /* Position in file, in sectors */
WORD size; /* Segment size on disk */
WORD flags; /* Segment flags */
WORD minsize; /* Min. size of segment in memory */
HANDLE16 hSeg; /* Selector or handle (selector - 1) */
/* of segment in memory */
} SEGTABLEENTRY;
/* Self-loading modules contain this structure in their first segment */
#include "pshpack1.h"
typedef struct
{
WORD version; /* Must be "A0" (0x3041) */
WORD reserved;
FARPROC16 BootApp; /* startup procedure */
FARPROC16 LoadAppSeg; /* procedure to load a segment */
FARPROC16 reserved2;
FARPROC16 MyAlloc; /* memory allocation procedure,
* wine must write this field */
FARPROC16 EntryAddrProc;
FARPROC16 ExitProc; /* exit procedure */
WORD reserved3[4];
FARPROC16 SetOwner; /* Set Owner procedure, exported by wine */
} SELFLOADHEADER;
/* Parameters for LoadModule() */
typedef struct
{
HGLOBAL16 hEnvironment; /* Environment segment */
SEGPTR cmdLine WINE_PACKED; /* Command-line */
SEGPTR showCmd WINE_PACKED; /* Code for ShowWindow() */
SEGPTR reserved WINE_PACKED;
} LOADPARAMS16;
typedef struct
{
LPSTR lpEnvAddress;
LPSTR lpCmdLine;
UINT16 *lpCmdShow;
DWORD dwReserved;
} LOADPARAMS;
#include "poppack.h"
/* internal representation of 32bit modules. per process. */
typedef enum {
MODULE32_PE = 1,
MODULE32_ELF,
MODULE32_ELFDLL
} MODULE32_TYPE;
typedef struct _wine_modref
{
struct _wine_modref *next;
struct _wine_modref *prev;
MODULE32_TYPE type;
union {
PE_MODREF pe;
ELF_MODREF elf;
} binfmt;
HMODULE module;
int nDeps;
struct _wine_modref **deps;
int flags;
int refCount;
char *filename;
char *modname;
char *short_filename;
char *short_modname;
} WINE_MODREF;
#define WINE_MODREF_INTERNAL 0x00000001
#define WINE_MODREF_NO_DLL_CALLS 0x00000002
#define WINE_MODREF_PROCESS_ATTACHED 0x00000004
#define WINE_MODREF_LOAD_AS_DATAFILE 0x00000010
#define WINE_MODREF_DONT_RESOLVE_REFS 0x00000020
#define WINE_MODREF_MARKER 0x80000000
/* Resource types */
typedef struct resource_typeinfo_s NE_TYPEINFO;
typedef struct resource_nameinfo_s NE_NAMEINFO;
#define NE_SEG_TABLE(pModule) \
((SEGTABLEENTRY *)((char *)(pModule) + (pModule)->seg_table))
#define NE_MODULE_TABLE(pModule) \
((WORD *)((char *)(pModule) + (pModule)->modref_table))
#define NE_MODULE_NAME(pModule) \
(((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName)
/* module.c */
extern FARPROC MODULE_GetProcAddress( HMODULE hModule, LPCSTR function, WIN_BOOL snoop );
extern WINE_MODREF *MODULE32_LookupHMODULE( HMODULE hModule );
extern WIN_BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved );
extern void MODULE_DllProcessDetach( WINE_MODREF *wm, WIN_BOOL bForceDetach, LPVOID lpReserved );
extern void MODULE_DllThreadAttach( LPVOID lpReserved );
extern void MODULE_DllThreadDetach( LPVOID lpReserved );
extern WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags );
extern WIN_BOOL MODULE_FreeLibrary( WINE_MODREF *wm );
extern WINE_MODREF *MODULE_FindModule( LPCSTR path );
extern HMODULE MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 );
extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE hmodule, LPCSTR name );
extern SEGPTR WINAPI HasGPHandler16( SEGPTR address );
extern void MODULE_WalkModref( DWORD id );
/* resource.c */
extern INT WINAPI AccessResource(HMODULE,HRSRC);
/*
/ loader/ne/module.c
extern NE_MODULE *NE_GetPtr( HMODULE16 hModule );
extern void NE_DumpModule( HMODULE16 hModule );
extern void NE_WalkModules(void);
extern void NE_RegisterModule( NE_MODULE *pModule );
extern WORD NE_GetOrdinal( HMODULE16 hModule, const char *name );
extern FARPROC16 WINAPI NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal );
extern FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, WIN_BOOL16 snoop );
extern WIN_BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset );
extern int NE_OpenFile( NE_MODULE *pModule );
extern WIN_BOOL NE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env,
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
WIN_BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info );
extern WIN_BOOL NE_InitProcess( NE_MODULE *pModule );
/ loader/ne/resource.c
extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16);
extern WIN_BOOL NE_InitResourceHandler( HMODULE16 hModule );
extern HRSRC16 NE_FindResource( NE_MODULE *pModule, LPCSTR name, LPCSTR type );
extern INT16 NE_AccessResource( NE_MODULE *pModule, HRSRC16 hRsrc );
extern DWORD NE_SizeofResource( NE_MODULE *pModule, HRSRC16 hRsrc );
extern HGLOBAL16 NE_LoadResource( NE_MODULE *pModule, HRSRC16 hRsrc );
extern WIN_BOOL16 NE_FreeResource( NE_MODULE *pModule, HGLOBAL16 handle );
extern NE_TYPEINFO *NE_FindTypeSection( LPBYTE pResTab, NE_TYPEINFO *pTypeInfo, LPCSTR typeId );
extern NE_NAMEINFO *NE_FindResourceFromType( LPBYTE pResTab, NE_TYPEINFO *pTypeInfo, LPCSTR resId );
// loader/ne/segment.c
extern WIN_BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum );
extern WIN_BOOL NE_LoadAllSegments( NE_MODULE *pModule );
extern WIN_BOOL NE_CreateSegment( NE_MODULE *pModule, int segnum );
extern WIN_BOOL NE_CreateAllSegments( NE_MODULE *pModule );
extern HINSTANCE16 NE_GetInstance( NE_MODULE *pModule );
extern void NE_InitializeDLLs( HMODULE16 hModule );
extern void NE_DllProcessAttach( HMODULE16 hModule );
// loader/ne/convert.c
HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size );
*/
/* relay32/builtin.c */
extern WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags);
extern HMODULE BUILTIN32_LoadExeModule( LPCSTR *filename );
extern void BUILTIN32_UnloadLibrary(WINE_MODREF *wm);
extern void *BUILTIN32_dlopen( const char *name );
extern int BUILTIN32_dlclose( void *handle );
#endif /* __WINE_MODULE_H */

101
include/wine/ntdef.h Normal file
View file

@ -0,0 +1,101 @@
#ifndef __WINE_NTDEF_H
#define __WINE_NTDEF_H
#include "basetsd.h"
#include "windef.h"
#include "pshpack1.h"
#ifdef __cplusplus
extern "C" {
#endif
#define NTAPI __stdcall
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
#ifndef OPTIONAL
#define OPTIONAL
#endif
#ifndef VOID
#define VOID void
#endif
typedef LONG NTSTATUS;
typedef NTSTATUS *PNTSTATUS;
typedef short CSHORT;
typedef CSHORT *PCSHORT;
typedef WCHAR * PWCHAR;
/* NT lowlevel Strings (handled by Rtl* functions in NTDLL)
* If they are zero terminated, Length does not include the terminating 0.
*/
typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PSTR Buffer;
} STRING,*PSTRING,ANSI_STRING,*PANSI_STRING;
typedef struct _CSTRING {
USHORT Length;
USHORT MaximumLength;
PCSTR Buffer;
} CSTRING,*PCSTRING;
typedef struct _UNICODE_STRING {
USHORT Length; /* bytes */
USHORT MaximumLength; /* bytes */
PWSTR Buffer;
} UNICODE_STRING,*PUNICODE_STRING;
/*
Objects
*/
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_KERNEL_HANDLE 0x00000200L
#define OBJ_VALID_ATTRIBUTES 0x000003F2L
typedef struct _OBJECT_ATTRIBUTES
{ ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; /* type SECURITY_DESCRIPTOR */
PVOID SecurityQualityOfService; /* type SECURITY_QUALITY_OF_SERVICE */
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
#define InitializeObjectAttributes(p,n,a,r,s) \
{ (p)->Length = sizeof(OBJECT_ATTRIBUTES); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#ifdef __cplusplus
}
#endif
#include "poppack.h"
#endif

81
include/wine/pe_image.h Normal file
View file

@ -0,0 +1,81 @@
#ifndef __WINE_PE_IMAGE_H
#define __WINE_PE_IMAGE_H
#include "windef.h"
#include "winbase.h"
#define PE_HEADER(module) \
((IMAGE_NT_HEADERS*)((LPBYTE)(module) + \
(((IMAGE_DOS_HEADER*)(module))->e_lfanew)))
#define PE_SECTIONS(module) \
((IMAGE_SECTION_HEADER*)((LPBYTE)&PE_HEADER(module)->OptionalHeader + \
PE_HEADER(module)->FileHeader.SizeOfOptionalHeader))
#define RVA_PTR(module,field) ((LPBYTE)(module) + PE_HEADER(module)->field)
/* modreference used for attached processes
* all section are calculated here, relocations etc.
*/
typedef struct {
PIMAGE_IMPORT_DESCRIPTOR pe_import;
PIMAGE_EXPORT_DIRECTORY pe_export;
PIMAGE_RESOURCE_DIRECTORY pe_resource;
int tlsindex;
} PE_MODREF;
struct _wine_modref;
extern int PE_unloadImage(HMODULE hModule);
extern FARPROC PE_FindExportedFunction(struct _wine_modref *wm, LPCSTR funcName, WIN_BOOL snoop);
extern WIN_BOOL PE_EnumResourceTypesA(HMODULE,ENUMRESTYPEPROCA,LONG);
extern WIN_BOOL PE_EnumResourceTypesW(HMODULE,ENUMRESTYPEPROCW,LONG);
extern WIN_BOOL PE_EnumResourceNamesA(HMODULE,LPCSTR,ENUMRESNAMEPROCA,LONG);
extern WIN_BOOL PE_EnumResourceNamesW(HMODULE,LPCWSTR,ENUMRESNAMEPROCW,LONG);
extern WIN_BOOL PE_EnumResourceLanguagesA(HMODULE,LPCSTR,LPCSTR,ENUMRESLANGPROCA,LONG);
extern WIN_BOOL PE_EnumResourceLanguagesW(HMODULE,LPCWSTR,LPCWSTR,ENUMRESLANGPROCW,LONG);
extern HRSRC PE_FindResourceExW(struct _wine_modref*,LPCWSTR,LPCWSTR,WORD);
extern DWORD PE_SizeofResource(HMODULE,HRSRC);
extern struct _wine_modref *PE_LoadLibraryExA(LPCSTR, DWORD);
extern void PE_UnloadLibrary(struct _wine_modref *);
extern HGLOBAL PE_LoadResource(struct _wine_modref *wm,HRSRC);
extern HMODULE PE_LoadImage( int hFile, LPCSTR filename, WORD *version );
extern struct _wine_modref *PE_CreateModule( HMODULE hModule, LPCSTR filename,
DWORD flags, WIN_BOOL builtin );
extern WIN_BOOL PE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env,
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
WIN_BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
LPPROCESS_INFORMATION info );
extern void PE_InitTls(void);
extern WIN_BOOL PE_InitDLL(struct _wine_modref *wm, DWORD type, LPVOID lpReserved);
extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(PIMAGE_RESOURCE_DIRECTORY,LPCSTR,DWORD,WIN_BOOL);
extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY,LPCWSTR,DWORD,WIN_BOOL);
typedef DWORD CALLBACK (*DLLENTRYPROC)(HMODULE,DWORD,LPVOID);
typedef struct {
WORD popl WINE_PACKED; /* 0x8f 0x05 */
DWORD addr_popped WINE_PACKED;/* ... */
BYTE pushl1 WINE_PACKED; /* 0x68 */
DWORD newret WINE_PACKED; /* ... */
BYTE pushl2 WINE_PACKED; /* 0x68 */
DWORD origfun WINE_PACKED; /* original function */
BYTE ret1 WINE_PACKED; /* 0xc3 */
WORD addesp WINE_PACKED; /* 0x83 0xc4 */
BYTE nrofargs WINE_PACKED; /* nr of arguments to add esp, */
BYTE pushl3 WINE_PACKED; /* 0x68 */
DWORD oldret WINE_PACKED; /* Filled out from popl above */
BYTE ret2 WINE_PACKED; /* 0xc3 */
} ELF_STDCALL_STUB;
typedef struct {
void* dlhandle;
ELF_STDCALL_STUB *stubs;
} ELF_MODREF;
extern struct _wine_modref *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags);
extern void ELF_UnloadLibrary(struct _wine_modref *);
extern FARPROC ELF_FindExportedFunction(struct _wine_modref *wm, LPCSTR funcName);
#endif /* __WINE_PE_IMAGE_H */

15
include/wine/poppack.h Normal file
View file

@ -0,0 +1,15 @@
#ifdef __WINE_PSHPACK_H
#undef __WINE_PSHPACK_H
#if defined(__GNUC__) || defined(__SUNPRO_C)
#pragma pack()
#elif defined(__SUNPRO_CC)
#warning "Assumes default alignment is 4"
#pragma pack(4)
#elif !defined(RC_INVOKED)
#error "Restoration of the previous alignment isn't supported by the compiler"
#endif /* defined(__GNUC__) || defined(__SUNPRO_C) ; !defined(RC_INVOKED) */
#else /* defined(__WINE_PSHPACK_H) */
#error "Popping alignment isn't possible since no alignment has been pushed"
#endif /* defined(__WINE_PSHPACK_H) */

13
include/wine/pshpack1.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef __WINE_PSHPACK_H
#define __WINE_PSHPACK_H 1
#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
#pragma pack(1)
#elif !defined(RC_INVOKED)
#error "1 as alignment isn't supported by the compiler"
#endif /* defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */
#else /* !defined(__WINE_PSHPACK_H) */
#error "Nested pushing of alignment isn't supported by the compiler"
#endif /* !defined(__WINE_PSHPACK_H) */

12
include/wine/pshpack2.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef __WINE_PSHPACK_H
#define __WINE_PSHPACK_H 2
#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
#pragma pack(2)
#elif !defined(RC_INVOKED)
#error "2 as alignment isn't supported by the compiler"
#endif /* defined(__GNUC__) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */
#else /* !defined(__WINE_PSHPACK_H) */
#error "Nested pushing of alignment isn't supported by the compiler"
#endif /* !defined(__WINE_PSHPACK_H) */

15
include/wine/pshpack4.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef __WINE_PSHPACK_H
#define __WINE_PSHPACK_H 4
#if defined(__GNUC__) || defined(__SUNPRO_CC)
#pragma pack(4)
#elif defined(__SUNPRO_C)
#pragma pack()
#elif !defined(RC_INVOKED)
#error "4 as alignment isn't supported by the compiler"
#endif /* defined(__GNUC__) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */
#else /* !defined(__WINE_PSHPACK_H) */
#error "Nested pushing of alignment isn't supported by the compiler"
#endif /* !defined(__WINE_PSHPACK_H) */

12
include/wine/pshpack8.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef __WINE_PSHPACK_H
#define __WINE_PSHPACK_H 8
#if 0
#pragma pack(8)
#elif !defined(RC_INVOKED)
#error "8 as alignment is not supported"
#endif /* 0 ; !defined(RC_INVOKED) */
#else /* !defined(__WINE_PSHPACK_H) */
#error "Nested pushing of alignment isn't supported by the compiler"
#endif /* !defined(__WINE_PSHPACK_H) */

641
include/wine/vfw.h Normal file
View file

@ -0,0 +1,641 @@
#ifndef __WINE_VFW_H
#define __WINE_VFW_H
#include "pshpack1.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __WINE_WINGDI_H
typedef struct
{
short bfType;
long bfSize;
short bfReserved1;
short bfReserved2;
long bfOffBits;
} BITMAPFILEHEADER;
typedef struct
{
long biSize;
long biWidth;
long biHeight;
short biPlanes;
short biBitCount;
long biCompression;
long biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
long biClrUsed;
long biClrImportant;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER, *LPBITMAPINFOHEADER;
typedef struct {
BITMAPINFOHEADER bmiHeader;
int bmiColors[1];
} BITMAPINFO, *LPBITMAPINFO;
#endif
#define VFWAPI
#define VFWAPIV
#ifndef __WINE_WINDEF_H
typedef long (__stdcall__ *DRIVERPROC)(long,HDRVR,unsigned int,long,long);
#endif
#ifndef mmioFOURCC
#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
( (long)(unsigned char)(ch0) | ( (long)(unsigned char)(ch1) << 8 ) | \
( (long)(unsigned char)(ch2) << 16 ) | ( (long)(unsigned char)(ch3) << 24 ) )
#endif
#ifndef aviTWOCC
#define aviTWOCC(ch0, ch1) ((short)(unsigned char)(ch0) | ((short)(unsigned char)(ch1) << 8))
#endif
#define ICTYPE_VIDEO mmioFOURCC('v', 'i', 'd', 'c')
#define ICTYPE_AUDIO mmioFOURCC('a', 'u', 'd', 'c')
/* Installable Compressor M? */
/* HIC struct (same layout as Win95 one) */
typedef struct tagWINE_HIC {
long magic; /* 00: 'Smag' */
HANDLE curthread; /* 04: */
long type; /* 08: */
long handler; /* 0C: */
HDRVR hdrv; /* 10: */
#ifndef __cplusplus
long private; /* 14:(handled by SendDriverMessage)*/
#else
long _private; /* 14:(handled by SendDriverMessage)*/
#endif
DRIVERPROC driverproc; /* 18:(handled by SendDriverMessage)*/
long x1; /* 1c: name? */
short x2; /* 20: */
long x3; /* 22: */
/* 26: */
} WINE_HIC;
/* error return codes */
#define ICERR_OK 0
#define ICERR_DONTDRAW 1
#define ICERR_NEWPALETTE 2
#define ICERR_GOTOKEYFRAME 3
#define ICERR_STOPDRAWING 4
#define ICERR_UNSUPPORTED -1
#define ICERR_BADFORMAT -2
#define ICERR_MEMORY -3
#define ICERR_INTERNAL -4
#define ICERR_BADFLAGS -5
#define ICERR_BADPARAM -6
#define ICERR_BADSIZE -7
#define ICERR_BADHANDLE -8
#define ICERR_CANTUPDATE -9
#define ICERR_ABORT -10
#define ICERR_ERROR -100
#define ICERR_BADBITDEPTH -200
#define ICERR_BADIMAGESIZE -201
#define ICERR_CUSTOM -400
/* ICM Messages */
#define ICM_USER (DRV_USER+0x0000)
/* ICM driver message range */
#define ICM_RESERVED_LOW (DRV_USER+0x1000)
#define ICM_RESERVED_HIGH (DRV_USER+0x2000)
#define ICM_RESERVED ICM_RESERVED_LOW
#define ICM_GETSTATE (ICM_RESERVED+0)
#define ICM_SETSTATE (ICM_RESERVED+1)
#define ICM_GETINFO (ICM_RESERVED+2)
#define ICM_CONFIGURE (ICM_RESERVED+10)
#define ICM_ABOUT (ICM_RESERVED+11)
/* */
#define ICM_GETDEFAULTQUALITY (ICM_RESERVED+30)
#define ICM_GETQUALITY (ICM_RESERVED+31)
#define ICM_SETQUALITY (ICM_RESERVED+32)
#define ICM_SET (ICM_RESERVED+40)
#define ICM_GET (ICM_RESERVED+41)
/* 2 constant FOURCC codes */
#define ICM_FRAMERATE mmioFOURCC('F','r','m','R')
#define ICM_KEYFRAMERATE mmioFOURCC('K','e','y','R')
#define ICM_COMPRESS_GET_FORMAT (ICM_USER+4)
#define ICM_COMPRESS_GET_SIZE (ICM_USER+5)
#define ICM_COMPRESS_QUERY (ICM_USER+6)
#define ICM_COMPRESS_BEGIN (ICM_USER+7)
#define ICM_COMPRESS (ICM_USER+8)
#define ICM_COMPRESS_END (ICM_USER+9)
#define ICM_DECOMPRESS_GET_FORMAT (ICM_USER+10)
#define ICM_DECOMPRESS_QUERY (ICM_USER+11)
#define ICM_DECOMPRESS_BEGIN (ICM_USER+12)
#define ICM_DECOMPRESS (ICM_USER+13)
#define ICM_DECOMPRESS_END (ICM_USER+14)
#define ICM_DECOMPRESS_SET_PALETTE (ICM_USER+29)
#define ICM_DECOMPRESS_GET_PALETTE (ICM_USER+30)
#define ICM_DRAW_QUERY (ICM_USER+31)
#define ICM_DRAW_BEGIN (ICM_USER+15)
#define ICM_DRAW_GET_PALETTE (ICM_USER+16)
#define ICM_DRAW_START (ICM_USER+18)
#define ICM_DRAW_STOP (ICM_USER+19)
#define ICM_DRAW_END (ICM_USER+21)
#define ICM_DRAW_GETTIME (ICM_USER+32)
#define ICM_DRAW (ICM_USER+33)
#define ICM_DRAW_WINDOW (ICM_USER+34)
#define ICM_DRAW_SETTIME (ICM_USER+35)
#define ICM_DRAW_REALIZE (ICM_USER+36)
#define ICM_DRAW_FLUSH (ICM_USER+37)
#define ICM_DRAW_RENDERBUFFER (ICM_USER+38)
#define ICM_DRAW_START_PLAY (ICM_USER+39)
#define ICM_DRAW_STOP_PLAY (ICM_USER+40)
#define ICM_DRAW_SUGGESTFORMAT (ICM_USER+50)
#define ICM_DRAW_CHANGEPALETTE (ICM_USER+51)
#define ICM_GETBUFFERSWANTED (ICM_USER+41)
#define ICM_GETDEFAULTKEYFRAMERATE (ICM_USER+42)
#define ICM_DECOMPRESSEX_BEGIN (ICM_USER+60)
#define ICM_DECOMPRESSEX_QUERY (ICM_USER+61)
#define ICM_DECOMPRESSEX (ICM_USER+62)
#define ICM_DECOMPRESSEX_END (ICM_USER+63)
#define ICM_COMPRESS_FRAMES_INFO (ICM_USER+70)
#define ICM_SET_STATUS_PROC (ICM_USER+72)
/* structs */
typedef struct {
long dwSize; /* 00: size */
long fccType; /* 04: type 'vidc' usually */
long fccHandler; /* 08: */
long dwVersion; /* 0c: version of compman opening you */
long dwFlags; /* 10: LOshort is type specific */
LRESULT dwError; /* 14: */
void* pV1Reserved; /* 18: */
void* pV2Reserved; /* 1c: */
long dnDevNode; /* 20: */
/* 24: */
} ICOPEN,*LPICOPEN;
#define ICCOMPRESS_KEYFRAME 0x00000001L
typedef struct {
long dwFlags;
LPBITMAPINFOHEADER lpbiOutput;
void* lpOutput;
LPBITMAPINFOHEADER lpbiInput;
void* lpInput;
long* lpckid;
long* lpdwFlags;
long lFrameNum;
long dwFrameSize;
long dwQuality;
LPBITMAPINFOHEADER lpbiPrev;
void* lpPrev;
} ICCOMPRESS;
long VFWAPIV ICCompress(
HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpData,
LPBITMAPINFOHEADER lpbiInput,void* lpBits,long* lpckid,
long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality,
LPBITMAPINFOHEADER lpbiPrev,void* lpPrev
);
#define ICCompressGetFormat(hic, lpbiInput, lpbiOutput) \
ICSendMessage( \
hic,ICM_COMPRESS_GET_FORMAT,(long)(void*)(lpbiInput), \
(long)(void*)(lpbiOutput) \
)
#define ICCompressGetFormatSize(hic,lpbi) ICCompressGetFormat(hic,lpbi,NULL)
#define ICCompressBegin(hic, lpbiInput, lpbiOutput) \
ICSendMessage( \
hic, ICM_COMPRESS_BEGIN, (long)(void*)(lpbiInput), \
(long)(void*)(lpbiOutput) \
)
#define ICCompressGetSize(hic, lpbiInput, lpbiOutput) \
ICSendMessage( \
hic, ICM_COMPRESS_GET_SIZE, (long)(void*)(lpbiInput), \
(long)(void*)(lpbiOutput) \
)
#define ICCompressQuery(hic, lpbiInput, lpbiOutput) \
ICSendMessage( \
hic, ICM_COMPRESS_QUERY, (long)(void*)(lpbiInput), \
(long)(void*)(lpbiOutput) \
)
#define ICCompressEnd(hic) ICSendMessage(hic, ICM_COMPRESS_END, 0, 0)
/* ICCOMPRESSFRAMES.dwFlags */
#define ICCOMPRESSFRAMES_PADDING 0x00000001
typedef struct {
long dwFlags;
LPBITMAPINFOHEADER lpbiOutput;
LPARAM lOutput;
LPBITMAPINFOHEADER lpbiInput;
LPARAM lInput;
long lStartFrame;
long lFrameCount;
long lQuality;
long lDataRate;
long lKeyRate;
long dwRate;
long dwScale;
long dwOverheadPerFrame;
long dwReserved2;
long CALLBACK (*GetData)(LPARAM lInput,long lFrame,void* lpBits,long len);
long CALLBACK (*PutData)(LPARAM lOutput,long lFrame,void* lpBits,long len);
} ICCOMPRESSFRAMES;
/* Values for wMode of ICOpen() */
#define ICMODE_COMPRESS 1
#define ICMODE_DECOMPRESS 2
#define ICMODE_FASTDECOMPRESS 3
#define ICMODE_QUERY 4
#define ICMODE_FASTCOMPRESS 5
#define ICMODE_DRAW 8
/* quality flags */
#define ICQUALITY_LOW 0
#define ICQUALITY_HIGH 10000
#define ICQUALITY_DEFAULT -1
typedef struct {
long dwSize; /* 00: */
long fccType; /* 04:compressor type 'vidc' 'audc' */
long fccHandler; /* 08:compressor sub-type 'rle ' 'jpeg' 'pcm '*/
long dwFlags; /* 0c:flags LOshort is type specific */
long dwVersion; /* 10:version of the driver */
long dwVersionICM; /* 14:version of the ICM used */
/*
* under Win32, the driver always returns UNICODE strings.
*/
WCHAR szName[16]; /* 18:short name */
WCHAR szDescription[128]; /* 38:long name */
WCHAR szDriver[128]; /* 138:driver that contains compressor*/
/* 238: */
} ICINFO;
/* ICINFO.dwFlags */
#define VIDCF_QUALITY 0x0001 /* supports quality */
#define VIDCF_CRUNCH 0x0002 /* supports crunching to a frame size */
#define VIDCF_TEMPORAL 0x0004 /* supports inter-frame compress */
#define VIDCF_COMPRESSFRAMES 0x0008 /* wants the compress all frames message */
#define VIDCF_DRAW 0x0010 /* supports drawing */
#define VIDCF_FASTTEMPORALC 0x0020 /* does not need prev frame on compress */
#define VIDCF_FASTTEMPORALD 0x0080 /* does not need prev frame on decompress */
#define VIDCF_QUALITYTIME 0x0040 /* supports temporal quality */
#define VIDCF_FASTTEMPORAL (VIDCF_FASTTEMPORALC|VIDCF_FASTTEMPORALD)
/* function shortcuts */
/* ICM_ABOUT */
#define ICMF_ABOUT_QUERY 0x00000001
#define ICQueryAbout(hic) \
(ICSendMessage(hic,ICM_ABOUT,(long)-1,ICMF_ABOUT_QUERY)==ICERR_OK)
#define ICAbout(hic, hwnd) ICSendMessage(hic,ICM_ABOUT,(long)(unsigned int)(hwnd),0)
/* ICM_CONFIGURE */
#define ICMF_CONFIGURE_QUERY 0x00000001
#define ICQueryConfigure(hic) \
(ICSendMessage(hic,ICM_CONFIGURE,(long)-1,ICMF_CONFIGURE_QUERY)==ICERR_OK)
#define ICConfigure(hic,hwnd) \
ICSendMessage(hic,ICM_CONFIGURE,(long)(unsigned int)(hwnd),0)
/* Decompression stuff */
#define ICDECOMPRESS_HURRYUP 0x80000000 /* don't draw just buffer (hurry up!) */
#define ICDECOMPRESS_UPDATE 0x40000000 /* don't draw just update screen */
#define ICDECOMPRESS_PREROL 0x20000000 /* this frame is before real start */
#define ICDECOMPRESS_NULLFRAME 0x10000000 /* repeat last frame */
#define ICDECOMPRESS_NOTKEYFRAME 0x08000000 /* this frame is not a key frame */
typedef struct {
long dwFlags; /* flags (from AVI index...) */
LPBITMAPINFOHEADER lpbiInput; /* BITMAPINFO of compressed data */
void* lpInput; /* compressed data */
LPBITMAPINFOHEADER lpbiOutput; /* DIB to decompress to */
void* lpOutput;
long ckid; /* ckid from AVI file */
} ICDECOMPRESS;
typedef struct {
long dwFlags;
LPBITMAPINFOHEADER lpbiSrc;
void* lpSrc;
LPBITMAPINFOHEADER lpbiDst;
void* lpDst;
/* changed for ICM_DECOMPRESSEX */
INT xDst; /* destination rectangle */
INT yDst;
INT dxDst;
INT dyDst;
INT xSrc; /* source rectangle */
INT ySrc;
INT dxSrc;
INT dySrc;
} ICDECOMPRESSEX;
long VFWAPIV ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits);
#define ICDecompressBegin(hic, lpbiInput, lpbiOutput) \
ICSendMessage( \
hic, ICM_DECOMPRESS_BEGIN, (long)(void*)(lpbiInput), \
(long)(void*)(lpbiOutput) \
)
#define ICDecompressQuery(hic, lpbiInput, lpbiOutput) \
ICSendMessage( \
hic,ICM_DECOMPRESS_QUERY, (long)(void*)(lpbiInput), \
(long) (void*)(lpbiOutput) \
)
#define ICDecompressGetFormat(hic, lpbiInput, lpbiOutput) \
((long)ICSendMessage( \
hic,ICM_DECOMPRESS_GET_FORMAT, (long)(void*)(lpbiInput), \
(long)(void*)(lpbiOutput) \
))
#define ICDecompressGetFormatSize(hic, lpbi) \
ICDecompressGetFormat(hic, lpbi, NULL)
#define ICDecompressGetPalette(hic, lpbiInput, lpbiOutput) \
ICSendMessage( \
hic, ICM_DECOMPRESS_GET_PALETTE, (long)(void*)(lpbiInput), \
(long)(void*)(lpbiOutput) \
)
#define ICDecompressSetPalette(hic,lpbiPalette) \
ICSendMessage( \
hic,ICM_DECOMPRESS_SET_PALETTE, \
(long)(void*)(lpbiPalette),0 \
)
#define ICDecompressEnd(hic) ICSendMessage(hic, ICM_DECOMPRESS_END, 0, 0)
#define ICDRAW_QUERY 0x00000001L /* test for support */
#define ICDRAW_FULLSCREEN 0x00000002L /* draw to full screen */
#define ICDRAW_HDC 0x00000004L /* draw to a HDC/HWND */
WIN_BOOL VFWAPI ICInfo(long fccType, long fccHandler, ICINFO * lpicinfo);
LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo, long cb);
HIC VFWAPI ICOpen(long fccType, long fccHandler, UINT wMode);
HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode, void* lpfnHandler);
LRESULT VFWAPI ICClose(HIC hic);
LRESULT VFWAPI ICSendMessage(HIC hic, unsigned int msg, long dw1, long dw2);
HIC VFWAPI ICLocate(long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, short wFlags);
int VFWAPI ICDoSomething();
long VFWAPIV ICDrawBegin(
HIC hic,
long dwFlags,/* flags */
HPALETTE hpal, /* palette to draw with */
HWND hwnd, /* window to draw to */
HDC hdc, /* HDC to draw to */
INT xDst, /* destination rectangle */
INT yDst,
INT dxDst,
INT dyDst,
LPBITMAPINFOHEADER lpbi, /* format of frame to draw */
INT xSrc, /* source rectangle */
INT ySrc,
INT dxSrc,
INT dySrc,
long dwRate, /* frames/second = (dwRate/dwScale) */
long dwScale
);
/* as passed to ICM_DRAW_BEGIN (FIXME: correct only for Win32?) */
typedef struct {
long dwFlags;
HPALETTE hpal;
HWND hwnd;
HDC hdc;
INT xDst;
INT yDst;
INT dxDst;
INT dyDst;
LPBITMAPINFOHEADER lpbi;
INT xSrc;
INT ySrc;
INT dxSrc;
INT dySrc;
long dwRate;
long dwScale;
} ICDRAWBEGIN;
#define ICDRAW_HURRYUP 0x80000000L /* don't draw just buffer (hurry up!) */
#define ICDRAW_UPDATE 0x40000000L /* don't draw just update screen */
#define ICDRAW_PREROLL 0x20000000L /* this frame is before real start */
#define ICDRAW_NULLFRAME 0x10000000L /* repeat last frame */
#define ICDRAW_NOTKEYFRAME 0x08000000L /* this frame is not a key frame */
typedef struct {
long dwFlags;
void* lpFormat;
void* lpData;
long cbData;
long lTime;
} ICDRAW;
long VFWAPIV ICDraw(HIC hic,long dwFlags,void* lpFormat,void* lpData,long cbData,long lTime);
#define AVIGETFRAMEF_BESTDISPLAYFMT 1
typedef struct _AVISTREAMINFOA {
long fccType;
long fccHandler;
long dwFlags; /* AVIIF_* */
long dwCaps;
short wPriority;
short wLanguage;
long dwScale;
long dwRate; /* dwRate / dwScale == samples/second */
long dwStart;
long dwLength; /* In units above... */
long dwInitialFrames;
long dwSuggestedBufferSize;
long dwQuality;
long dwSampleSize;
RECT rcFrame;
long dwEditCount;
long dwFormatChangeCount;
char szName[64];
} AVISTREAMINFOA, * LPAVISTREAMINFOA, *PAVISTREAMINFOA;
typedef struct _AVISTREAMINFOW {
long fccType;
long fccHandler;
long dwFlags;
long dwCaps;
short wPriority;
short wLanguage;
long dwScale;
long dwRate; /* dwRate / dwScale == samples/second */
long dwStart;
long dwLength; /* In units above... */
long dwInitialFrames;
long dwSuggestedBufferSize;
long dwQuality;
long dwSampleSize;
RECT rcFrame;
long dwEditCount;
long dwFormatChangeCount;
short szName[64];
} AVISTREAMINFOW, * LPAVISTREAMINFOW, *PAVISTREAMINFOW;
DECL_WINELIB_TYPE_AW(AVISTREAMINFO)
DECL_WINELIB_TYPE_AW(LPAVISTREAMINFO)
DECL_WINELIB_TYPE_AW(PAVISTREAMINFO)
#define AVISTREAMINFO_DISABLED 0x00000001
#define AVISTREAMINFO_FORMATCHANGES 0x00010000
/* AVIFILEINFO.dwFlags */
#define AVIFILEINFO_HASINDEX 0x00000010
#define AVIFILEINFO_MUSTUSEINDEX 0x00000020
#define AVIFILEINFO_ISINTERLEAVED 0x00000100
#define AVIFILEINFO_WASCAPTUREFILE 0x00010000
#define AVIFILEINFO_COPYRIGHTED 0x00020000
/* AVIFILEINFO.dwCaps */
#define AVIFILECAPS_CANREAD 0x00000001
#define AVIFILECAPS_CANWRITE 0x00000002
#define AVIFILECAPS_ALLKEYFRAMES 0x00000010
#define AVIFILECAPS_NOCOMPRESSION 0x00000020
typedef struct _AVIFILEINFOW {
long dwMaxBytesPerSec;
long dwFlags;
long dwCaps;
long dwStreams;
long dwSuggestedBufferSize;
long dwWidth;
long dwHeight;
long dwScale;
long dwRate;
long dwLength;
long dwEditCount;
short szFileType[64];
} AVIFILEINFOW, * LPAVIFILEINFOW, *PAVIFILEINFOW;
typedef struct _AVIFILEINFOA {
long dwMaxBytesPerSec;
long dwFlags;
long dwCaps;
long dwStreams;
long dwSuggestedBufferSize;
long dwWidth;
long dwHeight;
long dwScale;
long dwRate;
long dwLength;
long dwEditCount;
char szFileType[64];
} AVIFILEINFOA, * LPAVIFILEINFOA, *PAVIFILEINFOA;
DECL_WINELIB_TYPE_AW(AVIFILEINFO)
DECL_WINELIB_TYPE_AW(PAVIFILEINFO)
DECL_WINELIB_TYPE_AW(LPAVIFILEINFO)
/* AVICOMPRESSOPTIONS.dwFlags. determines presence of fields in below struct */
#define AVICOMPRESSF_INTERLEAVE 0x00000001
#define AVICOMPRESSF_DATARATE 0x00000002
#define AVICOMPRESSF_KEYFRAMES 0x00000004
#define AVICOMPRESSF_VALID 0x00000008
typedef struct {
long fccType; /* stream type, for consistency */
long fccHandler; /* compressor */
long dwKeyFrameEvery; /* keyframe rate */
long dwQuality; /* compress quality 0-10,000 */
long dwBytesPerSecond; /* unsigned chars per second */
long dwFlags; /* flags... see below */
void* lpFormat; /* save format */
long cbFormat;
void* lpParms; /* compressor options */
long cbParms;
long dwInterleaveEvery; /* for non-video streams only */
} AVICOMPRESSOPTIONS, *LPAVICOMPRESSOPTIONS,*PAVICOMPRESSOPTIONS;
typedef struct {
long cbSize; // set to sizeof(COMPVARS) before
// calling ICCompressorChoose
long dwFlags; // see below...
HIC hic; // HIC of chosen compressor
long fccType; // basically ICTYPE_VIDEO
long fccHandler; // handler of chosen compressor or
// "" or "DIB "
LPBITMAPINFO lpbiIn; // input format
LPBITMAPINFO lpbiOut; // output format - will compress to this
void* lpBitsOut;
void* lpBitsPrev;
long lFrame;
long lKey; // key frames how often?
long lDataRate; // desired data rate KB/Sec
long lQ; // desired quality
long lKeyCount;
void* lpState; // state of compressor
long cbState; // size of the state
} COMPVARS, *PCOMPVARS;
// FLAGS for dwFlags element of COMPVARS structure:
#define AVIERR_OK 0
#define MAKE_AVIERR(error) MAKE_SCODE(SEVERITY_ERROR,FACILITY_ITF,0x4000+error)
#define AVIERR_UNSUPPORTED MAKE_AVIERR(101)
#define AVIERR_BADFORMAT MAKE_AVIERR(102)
#define AVIERR_MEMORY MAKE_AVIERR(103)
#define AVIERR_INTERNAL MAKE_AVIERR(104)
#define AVIERR_BADFLAGS MAKE_AVIERR(105)
#define AVIERR_BADPARAM MAKE_AVIERR(106)
#define AVIERR_BADSIZE MAKE_AVIERR(107)
#define AVIERR_BADHANDLE MAKE_AVIERR(108)
#define AVIERR_FILEREAD MAKE_AVIERR(109)
#define AVIERR_FILEWRITE MAKE_AVIERR(110)
#define AVIERR_FILEOPEN MAKE_AVIERR(111)
#define AVIERR_COMPRESSOR MAKE_AVIERR(112)
#define AVIERR_NOCOMPRESSOR MAKE_AVIERR(113)
#define AVIERR_READONLY MAKE_AVIERR(114)
#define AVIERR_NODATA MAKE_AVIERR(115)
#define AVIERR_BUFFERTOOSMALL MAKE_AVIERR(116)
#define AVIERR_CANTCOMPRESS MAKE_AVIERR(117)
#define AVIERR_USERABORT MAKE_AVIERR(198)
#define AVIERR_ERROR MAKE_AVIERR(199)
#ifdef __cplusplus
}
#endif
#endif /* __WINE_VFW_H */

1874
include/wine/winbase.h Normal file

File diff suppressed because it is too large Load diff

656
include/wine/windef.h Normal file
View file

@ -0,0 +1,656 @@
/*
* Basic types definitions
*
* Copyright 1996 Alexandre Julliard
*/
#ifndef __WINE_WINDEF_H
#define __WINE_WINDEF_H
#ifdef __WINE__
# include "config.h"
# undef UNICODE
#endif
#ifdef _EGCS_
#define __stdcall
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Misc. constants. */
#ifdef FALSE
#undef FALSE
#endif
#define FALSE 0
#ifdef TRUE
#undef TRUE
#endif
#define TRUE 1
#ifdef NULL
#undef NULL
#endif
#define NULL 0
/* Macros to map Winelib names to the correct implementation name */
/* depending on __WINE__ and UNICODE macros. */
/* Note that Winelib is purely Win32. */
#ifdef __WINE__
# define WINELIB_NAME_AW(func) \
func##_must_be_suffixed_with_W_or_A_in_this_context \
func##_must_be_suffixed_with_W_or_A_in_this_context
#else /* __WINE__ */
# ifdef UNICODE
# define WINELIB_NAME_AW(func) func##W
# else
# define WINELIB_NAME_AW(func) func##A
# endif /* UNICODE */
#endif /* __WINE__ */
#ifdef __WINE__
# define DECL_WINELIB_TYPE_AW(type) /* nothing */
#else /* __WINE__ */
# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type;
#endif /* __WINE__ */
#ifndef NONAMELESSSTRUCT
# if defined(__WINE__) || !defined(_FORCENAMELESSSTRUCT)
# define NONAMELESSSTRUCT
# endif
#endif /* !defined(NONAMELESSSTRUCT) */
#ifndef NONAMELESSUNION
# if defined(__WINE__) || !defined(_FORCENAMELESSUNION) || !defined(__cplusplus)
# define NONAMELESSUNION
# endif
#endif /* !defined(NONAMELESSUNION) */
#ifndef NONAMELESSSTRUCT
#define DUMMYSTRUCTNAME
#define DUMMYSTRUCTNAME1
#define DUMMYSTRUCTNAME2
#define DUMMYSTRUCTNAME3
#define DUMMYSTRUCTNAME4
#define DUMMYSTRUCTNAME5
#else /* !defined(NONAMELESSSTRUCT) */
#define DUMMYSTRUCTNAME s
#define DUMMYSTRUCTNAME1 s1
#define DUMMYSTRUCTNAME2 s2
#define DUMMYSTRUCTNAME3 s3
#define DUMMYSTRUCTNAME4 s4
#define DUMMYSTRUCTNAME5 s5
#endif /* !defined(NONAMELESSSTRUCT) */
#ifndef NONAMELESSUNION
#define DUMMYUNIONNAME
#define DUMMYUNIONNAME1
#define DUMMYUNIONNAME2
#define DUMMYUNIONNAME3
#define DUMMYUNIONNAME4
#define DUMMYUNIONNAME5
#else /* !defined(NONAMELESSUNION) */
#define DUMMYUNIONNAME u
#define DUMMYUNIONNAME1 u1
#define DUMMYUNIONNAME2 u2
#define DUMMYUNIONNAME3 u3
#define DUMMYUNIONNAME4 u4
#define DUMMYUNIONNAME5 u5
#endif /* !defined(NONAMELESSUNION) */
/* Calling conventions definitions */
#ifdef __i386__
# if defined(__GNUC__) && ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)))
# ifndef _EGCS_
#define __stdcall __attribute__((__stdcall__))
#define __cdecl __attribute__((__cdecl__))
# define __RESTORE_ES __asm__ __volatile__("pushl %ds\n\tpopl %es")
# endif
# else
# error You need gcc >= 2.7 to build Wine on a 386
# endif
#else
# define __stdcall
# define __cdecl
# define __RESTORE_ES
#endif
#define CALLBACK __stdcall
#define WINAPI __stdcall
#define APIPRIVATE __stdcall
#define PASCAL __stdcall
#define pascal __stdcall
#define _pascal __stdcall
#define _stdcall __stdcall
#define _fastcall __stdcall
#define __fastcall __stdcall
#define __export __stdcall
#define CDECL __cdecl
#define _CDECL __cdecl
#define cdecl __cdecl
#define _cdecl __cdecl
#define WINAPIV __cdecl
#define APIENTRY WINAPI
#define __declspec(x)
#define dllimport
#define dllexport
#define CONST const
/* Standard data types. These are the same for emulator and library. */
typedef void VOID;
typedef int INT;
typedef unsigned int UINT;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef unsigned long ULONG;
typedef unsigned char BYTE;
typedef long LONG;
typedef short SHORT;
typedef unsigned short USHORT;
#ifdef CHAR
#warning CHAR defined as $(CHAR)
#endif
typedef char CHAR;
typedef unsigned char UCHAR;
/* Some systems might have wchar_t, but we really need 16 bit characters */
typedef unsigned short WCHAR;
typedef int WIN_BOOL;
typedef double DATE;
typedef double DOUBLE;
typedef double LONGLONG;
typedef double ULONGLONG;
/* FIXME: Wine does not compile with strict on, therefore strict
* handles are presently only usable on machines where sizeof(UINT) ==
* sizeof(void*). HANDLEs are supposed to be void* but a large amount
* of WINE code operates on HANDLES as if they are UINTs. So to WINE
* they exist as UINTs but to the Winelib user who turns on strict,
* they exist as void*. If there is a size difference between UINT and
* void* then things get ugly. */
#ifdef STRICT
typedef VOID* HANDLE;
#else
typedef UINT HANDLE;
#endif
typedef HANDLE *LPHANDLE;
/* Integer types. These are the same for emulator and library. */
typedef UINT WPARAM;
typedef LONG LPARAM;
typedef LONG HRESULT;
typedef LONG LRESULT;
typedef WORD ATOM;
typedef WORD CATCHBUF[9];
typedef WORD *LPCATCHBUF;
typedef HANDLE HHOOK;
typedef HANDLE HMONITOR;
typedef DWORD LCID;
typedef WORD LANGID;
typedef DWORD LCTYPE;
typedef float FLOAT;
/* Pointers types. These are the same for emulator and library. */
/* winnt types */
typedef VOID *PVOID;
typedef const void *PCVOID;
typedef CHAR *PCHAR;
typedef UCHAR *PUCHAR;
typedef BYTE *PBYTE;
typedef WORD *PWORD;
typedef USHORT *PUSHORT;
typedef SHORT *PSHORT;
typedef ULONG *PULONG;
typedef LONG *PLONG;
typedef DWORD *PDWORD;
/* common win32 types */
typedef CHAR *LPSTR;
typedef CHAR *PSTR;
typedef const CHAR *LPCSTR;
typedef const CHAR *PCSTR;
typedef WCHAR *LPWSTR;
typedef WCHAR *PWSTR;
typedef const WCHAR *LPCWSTR;
typedef const WCHAR *PCWSTR;
typedef BYTE *LPBYTE;
typedef WORD *LPWORD;
typedef DWORD *LPDWORD;
typedef LONG *LPLONG;
typedef VOID *LPVOID;
typedef const VOID *LPCVOID;
typedef INT *PINT;
typedef INT *LPINT;
typedef UINT *PUINT;
typedef UINT *LPUINT;
typedef FLOAT *PFLOAT;
typedef FLOAT *LPFLOAT;
typedef WIN_BOOL *PWIN_BOOL;
typedef WIN_BOOL *LPWIN_BOOL;
/* Special case: a segmented pointer is just a pointer in the user's code. */
#ifdef __WINE__
typedef DWORD SEGPTR;
#else
typedef void* SEGPTR;
#endif /* __WINE__ */
/* Handle types that exist both in Win16 and Win32. */
#ifdef STRICT
#define DECLARE_HANDLE(a) \
typedef struct a##__ { int unused; } *a; \
typedef a *P##a; \
typedef a *LP##a
#else /*STRICT*/
#define DECLARE_HANDLE(a) \
typedef HANDLE a; \
typedef a *P##a; \
typedef a *LP##a
#endif /*STRICT*/
DECLARE_HANDLE(HACMDRIVERID);
DECLARE_HANDLE(HACMDRIVER);
DECLARE_HANDLE(HACMOBJ);
DECLARE_HANDLE(HACMSTREAM);
DECLARE_HANDLE(HMETAFILEPICT);
DECLARE_HANDLE(HACCEL);
DECLARE_HANDLE(HBITMAP);
DECLARE_HANDLE(HBRUSH);
DECLARE_HANDLE(HCOLORSPACE);
DECLARE_HANDLE(HCURSOR);
DECLARE_HANDLE(HDC);
DECLARE_HANDLE(HDROP);
DECLARE_HANDLE(HDRVR);
DECLARE_HANDLE(HDWP);
DECLARE_HANDLE(HENHMETAFILE);
DECLARE_HANDLE(HFILE);
DECLARE_HANDLE(HFONT);
DECLARE_HANDLE(HICON);
DECLARE_HANDLE(HINSTANCE);
DECLARE_HANDLE(HKEY);
DECLARE_HANDLE(HMENU);
DECLARE_HANDLE(HMETAFILE);
DECLARE_HANDLE(HMIDI);
DECLARE_HANDLE(HMIDIIN);
DECLARE_HANDLE(HMIDIOUT);
DECLARE_HANDLE(HMIDISTRM);
DECLARE_HANDLE(HMIXER);
DECLARE_HANDLE(HMIXEROBJ);
DECLARE_HANDLE(HMMIO);
DECLARE_HANDLE(HPALETTE);
DECLARE_HANDLE(HPEN);
DECLARE_HANDLE(HQUEUE);
DECLARE_HANDLE(HRGN);
DECLARE_HANDLE(HRSRC);
DECLARE_HANDLE(HTASK);
DECLARE_HANDLE(HWAVE);
DECLARE_HANDLE(HWAVEIN);
DECLARE_HANDLE(HWAVEOUT);
DECLARE_HANDLE(HWINSTA);
DECLARE_HANDLE(HDESK);
DECLARE_HANDLE(HWND);
DECLARE_HANDLE(HKL);
DECLARE_HANDLE(HIC);
DECLARE_HANDLE(HRASCONN);
/* Handle types that must remain interchangeable even with strict on */
typedef HINSTANCE HMODULE;
typedef HANDLE HGDIOBJ;
typedef HANDLE HGLOBAL;
typedef HANDLE HLOCAL;
typedef HANDLE GLOBALHANDLE;
typedef HANDLE LOCALHANDLE;
/* Callback function pointers types */
//WIN_BOOL CALLBACK DATEFMT_ENUMPROCA(LPSTR);
typedef WIN_BOOL CALLBACK (* DATEFMT_ENUMPROCA)(LPSTR);
typedef WIN_BOOL CALLBACK (* DATEFMT_ENUMPROCW)(LPWSTR);
DECL_WINELIB_TYPE_AW(DATEFMT_ENUMPROC)
typedef WIN_BOOL CALLBACK (*DLGPROC)(HWND,UINT,WPARAM,LPARAM);
typedef LRESULT CALLBACK (*DRIVERPROC)(DWORD,HDRVR,UINT,LPARAM,LPARAM);
typedef INT CALLBACK (*EDITWORDBREAKPROCA)(LPSTR,INT,INT,INT);
typedef INT CALLBACK (*EDITWORDBREAKPROCW)(LPWSTR,INT,INT,INT);
DECL_WINELIB_TYPE_AW(EDITWORDBREAKPROC)
typedef LRESULT CALLBACK (*FARPROC)();
typedef INT CALLBACK (*PROC)();
typedef WIN_BOOL CALLBACK (*GRAYSTRINGPROC)(HDC,LPARAM,INT);
typedef LRESULT CALLBACK (*HOOKPROC)(INT,WPARAM,LPARAM);
typedef WIN_BOOL CALLBACK (*PROPENUMPROCA)(HWND,LPCSTR,HANDLE);
typedef WIN_BOOL CALLBACK (*PROPENUMPROCW)(HWND,LPCWSTR,HANDLE);
DECL_WINELIB_TYPE_AW(PROPENUMPROC)
typedef WIN_BOOL CALLBACK (*PROPENUMPROCEXA)(HWND,LPCSTR,HANDLE,LPARAM);
typedef WIN_BOOL CALLBACK (*PROPENUMPROCEXW)(HWND,LPCWSTR,HANDLE,LPARAM);
DECL_WINELIB_TYPE_AW(PROPENUMPROCEX)
typedef WIN_BOOL CALLBACK (* TIMEFMT_ENUMPROCA)(LPSTR);
typedef WIN_BOOL CALLBACK (* TIMEFMT_ENUMPROCW)(LPWSTR);
DECL_WINELIB_TYPE_AW(TIMEFMT_ENUMPROC)
typedef VOID CALLBACK (*TIMERPROC)(HWND,UINT,UINT,DWORD);
typedef WIN_BOOL CALLBACK (*WNDENUMPROC)(HWND,LPARAM);
typedef LRESULT CALLBACK (*WNDPROC)(HWND,UINT,WPARAM,LPARAM);
/*----------------------------------------------------------------------------
** FIXME: Better isolate Wine's reliance on the xxx16 type definitions.
** For now, we just isolate them to make the situation clear.
**--------------------------------------------------------------------------*/
/*
* Basic type definitions for 16 bit variations on Windows types.
* These types are provided mostly to insure compatibility with
* 16 bit windows code.
*/
#ifndef __WINE_WINDEF16_H
#define __WINE_WINDEF16_H
#include "windef.h"
/* Standard data types */
typedef short INT16;
typedef unsigned short UINT16;
typedef unsigned short WIN_BOOL16;
typedef UINT16 HANDLE16;
typedef HANDLE16 *LPHANDLE16;
typedef UINT16 WPARAM16;
typedef INT16 *LPINT16;
typedef UINT16 *LPUINT16;
#define DECLARE_HANDLE16(a) \
typedef HANDLE16 a##16; \
typedef a##16 *P##a##16; \
typedef a##16 *NP##a##16; \
typedef a##16 *LP##a##16
DECLARE_HANDLE16(HACMDRIVERID);
DECLARE_HANDLE16(HACMDRIVER);
DECLARE_HANDLE16(HACMOBJ);
DECLARE_HANDLE16(HACMSTREAM);
DECLARE_HANDLE16(HMETAFILEPICT);
DECLARE_HANDLE16(HACCEL);
DECLARE_HANDLE16(HBITMAP);
DECLARE_HANDLE16(HBRUSH);
DECLARE_HANDLE16(HCOLORSPACE);
DECLARE_HANDLE16(HCURSOR);
DECLARE_HANDLE16(HDC);
DECLARE_HANDLE16(HDROP);
DECLARE_HANDLE16(HDRVR);
DECLARE_HANDLE16(HDWP);
DECLARE_HANDLE16(HENHMETAFILE);
DECLARE_HANDLE16(HFILE);
DECLARE_HANDLE16(HFONT);
DECLARE_HANDLE16(HICON);
DECLARE_HANDLE16(HINSTANCE);
DECLARE_HANDLE16(HKEY);
DECLARE_HANDLE16(HMENU);
DECLARE_HANDLE16(HMETAFILE);
DECLARE_HANDLE16(HMIDI);
DECLARE_HANDLE16(HMIDIIN);
DECLARE_HANDLE16(HMIDIOUT);
DECLARE_HANDLE16(HMIDISTRM);
DECLARE_HANDLE16(HMIXER);
DECLARE_HANDLE16(HMIXEROBJ);
DECLARE_HANDLE16(HMMIO);
DECLARE_HANDLE16(HPALETTE);
DECLARE_HANDLE16(HPEN);
DECLARE_HANDLE16(HQUEUE);
DECLARE_HANDLE16(HRGN);
DECLARE_HANDLE16(HRSRC);
DECLARE_HANDLE16(HTASK);
DECLARE_HANDLE16(HWAVE);
DECLARE_HANDLE16(HWAVEIN);
DECLARE_HANDLE16(HWAVEOUT);
DECLARE_HANDLE16(HWINSTA);
DECLARE_HANDLE16(HDESK);
DECLARE_HANDLE16(HWND);
DECLARE_HANDLE16(HKL);
DECLARE_HANDLE16(HIC);
DECLARE_HANDLE16(HRASCONN);
#undef DECLARE_HANDLE16
typedef HINSTANCE16 HMODULE16;
typedef HANDLE16 HGDIOBJ16;
typedef HANDLE16 HGLOBAL16;
typedef HANDLE16 HLOCAL16;
/* The SIZE structure */
typedef struct
{
INT16 cx;
INT16 cy;
} SIZE16, *PSIZE16, *LPSIZE16;
/* The POINT structure */
typedef struct
{
INT16 x;
INT16 y;
} POINT16, *PPOINT16, *LPPOINT16;
/* The RECT structure */
typedef struct
{
INT16 left;
INT16 top;
INT16 right;
INT16 bottom;
} RECT16, *LPRECT16;
/* Callback function pointers types */
typedef LRESULT CALLBACK (*DRIVERPROC16)(DWORD,HDRVR16,UINT16,LPARAM,LPARAM);
typedef WIN_BOOL16 CALLBACK (*DLGPROC16)(HWND16,UINT16,WPARAM16,LPARAM);
typedef INT16 CALLBACK (*EDITWORDBREAKPROC16)(LPSTR,INT16,INT16,INT16);
typedef LRESULT CALLBACK (*FARPROC16)();
typedef INT16 CALLBACK (*PROC16)();
typedef WIN_BOOL16 CALLBACK (*GRAYSTRINGPROC16)(HDC16,LPARAM,INT16);
typedef LRESULT CALLBACK (*HOOKPROC16)(INT16,WPARAM16,LPARAM);
typedef WIN_BOOL16 CALLBACK (*PROPENUMPROC16)(HWND16,SEGPTR,HANDLE16);
typedef VOID CALLBACK (*TIMERPROC16)(HWND16,UINT16,UINT16,DWORD);
typedef LRESULT CALLBACK (*WNDENUMPROC16)(HWND16,LPARAM);
typedef LRESULT CALLBACK (*WNDPROC16)(HWND16,UINT16,WPARAM16,LPARAM);
#endif /* __WINE_WINDEF16_H */
/* Define some empty macros for compatibility with Windows code. */
#ifndef __WINE__
#define NEAR
#define FAR
#define near
#define far
#define _near
#define _far
#define IN
#define OUT
#define OPTIONAL
#endif /* __WINE__ */
/* Macro for structure packing. */
#ifdef __GNUC__
#ifndef _EGCS_
#define WINE_PACKED __attribute__((packed))
#define WINE_UNUSED __attribute__((unused))
#define WINE_NORETURN __attribute__((noreturn))
#endif
#else
#define WINE_PACKED /* nothing */
#define WINE_UNUSED /* nothing */
#define WINE_NORETURN /* nothing */
#endif
/* Macros to split words and longs. */
#define LOBYTE(w) ((BYTE)(WORD)(w))
#define HIBYTE(w) ((BYTE)((WORD)(w) >> 8))
#define LOWORD(l) ((WORD)(DWORD)(l))
#define HIWORD(l) ((WORD)((DWORD)(l) >> 16))
#define SLOWORD(l) ((INT16)(LONG)(l))
#define SHIWORD(l) ((INT16)((LONG)(l) >> 16))
#define MAKEWORD(low,high) ((WORD)(((BYTE)(low)) | ((WORD)((BYTE)(high))) << 8))
#define MAKELONG(low,high) ((LONG)(((WORD)(low)) | (((DWORD)((WORD)(high))) << 16)))
#define MAKELPARAM(low,high) ((LPARAM)MAKELONG(low,high))
#define MAKEWPARAM(low,high) ((WPARAM)MAKELONG(low,high))
#define MAKELRESULT(low,high) ((LRESULT)MAKELONG(low,high))
#define MAKEINTATOM(atom) ((LPCSTR)MAKELONG((atom),0))
#define SELECTOROF(ptr) (HIWORD(ptr))
#define OFFSETOF(ptr) (LOWORD(ptr))
#ifdef __WINE__
/* macros to set parts of a DWORD (not in the Windows API) */
#define SET_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD(val))
#define SET_LOBYTE(dw,val) ((dw) = ((dw) & 0xffffff00) | LOBYTE(val))
#define SET_HIBYTE(dw,val) ((dw) = ((dw) & 0xffff00ff) | (LOWORD(val) & 0xff00))
#define ADD_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD((DWORD)(dw)+(val)))
#endif
/* Macros to access unaligned or wrong-endian WORDs and DWORDs. */
/* Note: These macros are semantically broken, at least for wrc. wrc
spits out data in the platform's current binary format, *not* in
little-endian format. These macros are used throughout the resource
code to load and store data to the resources. Since it is unlikely
that we'll ever be dealing with little-endian resource data, the
byte-swapping nature of these macros has been disabled. Rather than
remove the use of these macros from the resource loading code, the
macros have simply been disabled. In the future, someone may want
to reactivate these macros for other purposes. In that case, the
resource code will have to be modified to use different macros. */
#if 1
#define PUT_WORD(ptr,w) (*(WORD *)(ptr) = (w))
#define GET_WORD(ptr) (*(WORD *)(ptr))
#define PUT_DWORD(ptr,dw) (*(DWORD *)(ptr) = (dw))
#define GET_DWORD(ptr) (*(DWORD *)(ptr))
#else
#define PUT_WORD(ptr,w) (*(BYTE *)(ptr) = LOBYTE(w), \
*((BYTE *)(ptr) + 1) = HIBYTE(w))
#define GET_WORD(ptr) ((WORD)(*(BYTE *)(ptr) | \
(WORD)(*((BYTE *)(ptr)+1) << 8)))
#define PUT_DWORD(ptr,dw) (PUT_WORD((ptr),LOWORD(dw)), \
PUT_WORD((WORD *)(ptr)+1,HIWORD(dw)))
#define GET_DWORD(ptr) ((DWORD)(GET_WORD(ptr) | \
((DWORD)GET_WORD((WORD *)(ptr)+1) << 16)))
#endif /* 1 */
/* min and max macros */
#define __max(a,b) (((a) > (b)) ? (a) : (b))
#define __min(a,b) (((a) < (b)) ? (a) : (b))
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#define _MAX_PATH 260
#define MAX_PATH 260
#define _MAX_DRIVE 3
#define _MAX_DIR 256
#define _MAX_FNAME 255
#define _MAX_EXT 256
#define HFILE_ERROR16 ((HFILE16)-1)
#define HFILE_ERROR ((HFILE)-1)
/* The SIZE structure */
typedef struct tagSIZE
{
INT cx;
INT cy;
} SIZE, *PSIZE, *LPSIZE;
typedef SIZE SIZEL, *PSIZEL, *LPSIZEL;
#define CONV_SIZE16TO32(s16,s32) \
((s32)->cx = (INT)(s16)->cx, (s32)->cy = (INT)(s16)->cy)
#define CONV_SIZE32TO16(s32,s16) \
((s16)->cx = (INT16)(s32)->cx, (s16)->cy = (INT16)(s32)->cy)
/* The POINT structure */
typedef struct tagPOINT
{
LONG x;
LONG y;
} POINT, *PPOINT, *LPPOINT;
typedef struct _POINTL
{
LONG x;
LONG y;
} POINTL;
#define CONV_POINT16TO32(p16,p32) \
((p32)->x = (INT)(p16)->x, (p32)->y = (INT)(p16)->y)
#define CONV_POINT32TO16(p32,p16) \
((p16)->x = (INT16)(p32)->x, (p16)->y = (INT16)(p32)->y)
#define MAKEPOINT16(l) (*((POINT16 *)&(l)))
/* The POINTS structure */
typedef struct tagPOINTS
{
SHORT x;
SHORT y;
} POINTS, *PPOINTS, *LPPOINTS;
#define MAKEPOINTS(l) (*((POINTS *)&(l)))
/* The RECT structure */
typedef struct tagRECT
{
short left;
short top;
short right;
short bottom;
} RECT, *PRECT, *LPRECT;
typedef const RECT *LPCRECT;
typedef struct tagRECTL
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECTL, *PRECTL, *LPRECTL;
typedef const RECTL *LPCRECTL;
#define CONV_RECT16TO32(r16,r32) \
((r32)->left = (INT)(r16)->left, (r32)->top = (INT)(r16)->top, \
(r32)->right = (INT)(r16)->right, (r32)->bottom = (INT)(r16)->bottom)
#define CONV_RECT32TO16(r32,r16) \
((r16)->left = (INT16)(r32)->left, (r16)->top = (INT16)(r32)->top, \
(r16)->right = (INT16)(r32)->right, (r16)->bottom = (INT16)(r32)->bottom)
#ifdef __cplusplus
}
#endif
#endif /* __WINE_WINDEF_H */

38
include/wine/windows.h Normal file
View file

@ -0,0 +1,38 @@
#ifndef __WINE_WINDOWS_H
#define __WINE_WINDOWS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "shell.h"
#include "winreg.h"
#include "winnetwk.h"
#include "winver.h"
#include "lzexpand.h"
#include "shellapi.h"
#include "ole2.h"
#include "winnls.h"
#include "objbase.h"
#include "winspool.h"
#if 0
Where does this belong? Nobody uses this stuff anyway.
typedef struct {
BYTE i; /* much more .... */
} KANJISTRUCT;
typedef KANJISTRUCT *LPKANJISTRUCT;
typedef KANJISTRUCT *NPKANJISTRUCT;
typedef KANJISTRUCT *PKANJISTRUCT;
#endif /* 0 */
#ifdef __cplusplus
}
#endif
#endif /* __WINE_WINDOWS_H */

1658
include/wine/winerror.h Normal file

File diff suppressed because it is too large Load diff

13
include/wine/winestring.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef __WINE_WINE_WINESTRING_H
#define __WINE_WINE_WINESTRING_H
#include "windef.h"
LPWSTR WINAPI lstrcpyAtoW(LPWSTR,LPCSTR);
LPSTR WINAPI lstrcpyWtoA(LPSTR,LPCWSTR);
LPWSTR WINAPI lstrcpynAtoW(LPWSTR,LPCSTR,INT);
LPSTR WINAPI lstrcpynWtoA(LPSTR,LPCWSTR,INT);
#define lstrncmpiA strncasecmp
#endif /* __WINE_WINE_WINESTRING_H */

2665
include/wine/winnt.h Normal file

File diff suppressed because it is too large Load diff

57
include/wine/winreg.h Normal file
View file

@ -0,0 +1,57 @@
/*
* Win32 registry defines (see also winnt.h)
*/
#ifndef __WINE_WINREG_H
#define __WINE_WINREG_H
#include "winbase.h"
#include "winnt.h"
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
/*
#define SHELL_ERROR_SUCCESS 0L
#define SHELL_ERROR_BADDB 1L
#define SHELL_ERROR_BADKEY 2L
#define SHELL_ERROR_CANTOPEN 3L
#define SHELL_ERROR_CANTREAD 4L
#define SHELL_ERROR_CANTWRITE 5L
#define SHELL_ERROR_OUTOFMEMORY 6L
#define SHELL_ERROR_INVALID_PARAMETER 7L
#define SHELL_ERROR_ACCESS_DENIED 8L
*/
#define HKEY_CLASSES_ROOT ((HKEY) 0x80000000)
#define HKEY_CURRENT_USER ((HKEY) 0x80000001)
#define HKEY_LOCAL_MACHINE ((HKEY) 0x80000002)
#define HKEY_USERS ((HKEY) 0x80000003)
#define HKEY_PERFORMANCE_DATA ((HKEY) 0x80000004)
#define HKEY_CURRENT_CONFIG ((HKEY) 0x80000005)
#define HKEY_DYN_DATA ((HKEY) 0x80000006)
/*
* registry provider structs
*/
typedef struct value_entA
{ LPSTR ve_valuename;
DWORD ve_valuelen;
DWORD_PTR ve_valueptr;
DWORD ve_type;
} VALENTA, *PVALENTA;
typedef struct value_entW {
LPWSTR ve_valuename;
DWORD ve_valuelen;
DWORD_PTR ve_valueptr;
DWORD ve_type;
} VALENTW, *PVALENTW;
typedef ACCESS_MASK REGSAM;
#ifdef __cplusplus
} /* extern "C" */
#endif /* defined(__cplusplus) */
#endif /* __WINE_WINREG_H */

2929
include/wine/winuser.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,3 @@
SUBDIRS = riff colorspace getbits putbits videoscale
SUBDIRS = riff colorspace getbits putbits videoscale winloader
DIST_SUBDIRS = riff colorspace getbits putbits videoscale
DIST_SUBDIRS = riff colorspace getbits putbits videoscale winloader

View file

@ -273,6 +273,7 @@ struct _gst_riff_strf_auds { /* == WaveHeader (?) */
#define GST_RIFF_WAVE_FORMAT_YAMAHA_ADPCM (0x0020)
#define GST_RIFF_WAVE_FORMAT_DSP_TRUESPEECH (0x0022)
#define GST_RIFF_WAVE_FORMAT_GSM610 (0x0031)
#define GST_RIFF_WAVE_FORMAT_MPEG (0x0055)
#define GST_RIFF_IBM_FORMAT_MULAW (0x0101)
#define GST_RIFF_IBM_FORMAT_ALAW (0x0102)
#define GST_RIFF_IBM_FORMAT_ADPCM (0x0103)

View file

@ -17,13 +17,10 @@
* Boston, MA 02111-1307, USA.
*/
//#define DEBUG_ENABLED
#include <gst/gst.h>
#include <gstriff.h>
//#define debug(format,args...) g_print(format,##args)
#define debug(format,args...)
GstRiff *gst_riff_parser_new(GstRiffCallback function, gpointer data) {
GstRiff *riff;
@ -54,12 +51,12 @@ gint gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) {
size = GST_BUFFER_SIZE(buf);
last = off + size;
debug("gst_riff_parser: offset new buffer 0x%08lx size 0x%08x\n", off, GST_BUFFER_SIZE(buf));
DEBUG("gst_riff_parser: offset new buffer 0x%08lx size 0x%08x\n", off, GST_BUFFER_SIZE(buf));
if (riff->dataleft) {
gulong newsize;
debug("gst_riff_parser: recovering left data\n");
DEBUG("gst_riff_parser: recovering left data\n");
newsize = riff->dataleft_size + size;
riff->dataleft = g_realloc(riff->dataleft, newsize);
memcpy(riff->dataleft+riff->dataleft_size, GST_BUFFER_DATA(buf), size);
@ -98,12 +95,12 @@ gint gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) {
// if we have an incomplete chunk from the previous buffer
if (riff->incomplete_chunk) {
guint leftover;
debug("gst_riff_parser: have incomplete chunk %08x filled\n", riff->incomplete_chunk_size);
DEBUG("gst_riff_parser: have incomplete chunk %08x filled\n", riff->incomplete_chunk_size);
leftover = riff->incomplete_chunk->size - riff->incomplete_chunk_size;
if (leftover <= size) {
debug("gst_riff_parser: we can fill it from %08x with %08x bytes = %08x\n",
riff->incomplete_chunk_size, leftover,
riff->incomplete_chunk_size+leftover);
DEBUG("gst_riff_parser: we can fill it from %08x with %08x bytes = %08x\n",
riff->incomplete_chunk_size, leftover,
riff->incomplete_chunk_size+leftover);
memcpy(riff->incomplete_chunk->data+riff->incomplete_chunk_size, GST_BUFFER_DATA(buf), leftover);
if (riff->new_tag_found) {
@ -114,26 +111,15 @@ gint gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) {
riff->incomplete_chunk = NULL;
}
else {
debug("gst_riff_parser: we cannot fill it %08x >= %08lx\n", leftover, size);
DEBUG("gst_riff_parser: we cannot fill it %08x >= %08lx\n", leftover, size);
memcpy(riff->incomplete_chunk->data+riff->incomplete_chunk_size, GST_BUFFER_DATA(buf), size);
riff->incomplete_chunk_size += size;
return 0;
}
}
if ((riff->nextlikely+12) > last) {
guint left = last - riff->nextlikely;
debug("gst_riff_parser: not enough data next 0x%08x last 0x%08lx %08x %08x\n",riff->nextlikely,
last, left, off);
riff->dataleft = g_malloc(left);
riff->dataleft_size = left;
memcpy(riff->dataleft, GST_BUFFER_DATA(buf)+size-left, left);
return 0;
}
debug("gst_riff_parser: next 0x%08x last 0x%08lx offset %08x\n",riff->nextlikely, last, off);
DEBUG("gst_riff_parser: next 0x%08x last 0x%08lx offset %08x\n",riff->nextlikely, last, off);
/* loop while the next likely chunk header is in this buffer */
while ((riff->nextlikely+12) <= last) {
gulong *words = (gulong *)((guchar *)GST_BUFFER_DATA(buf) + riff->nextlikely - off );
@ -142,17 +128,17 @@ gint gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) {
while (riff->chunks) {
chunk = g_list_nth_data(riff->chunks, 0);
debug("gst_riff_parser: next 0x%08x offset 0x%08lx size 0x%08x\n",riff->nextlikely,
DEBUG("gst_riff_parser: next 0x%08x offset 0x%08lx size 0x%08x\n",riff->nextlikely,
chunk->offset, chunk->size);
if (riff->nextlikely >= chunk->offset+chunk->size) {
debug("gst_riff_parser: found END LIST\n");
// we have the end of the chunk on the stack, remove it
riff->chunks = g_list_remove(riff->chunks, chunk);
}
else break;
if (riff->nextlikely >= chunk->offset+chunk->size) {
DEBUG("gst_riff_parser: found END LIST\n");
// we have the end of the chunk on the stack, remove it
riff->chunks = g_list_remove(riff->chunks, chunk);
}
else break;
}
debug("gst_riff_parser: next likely chunk is at offset 0x%08x\n",riff->nextlikely);
DEBUG("gst_riff_parser: next likely chunk is at offset 0x%08x\n",riff->nextlikely);
chunk = (GstRiffChunk *)g_malloc(sizeof(GstRiffChunk));
g_return_val_if_fail(chunk != NULL, GST_RIFF_ENOMEM);
@ -162,12 +148,12 @@ gint gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) {
chunk->size = words[1];
chunk->data = (gchar *)(words+2);
// we need word alignment
//if (chunk->size & 0x01) chunk->size++;
if (chunk->size & 0x01) chunk->size++;
chunk->form = words[2]; /* fill in the form, might not be valid */
if (chunk->id == GST_RIFF_TAG_LIST) {
//g_print("found LIST %s\n", gst_riff_id_to_fourcc(chunk->form));
DEBUG("found LIST %s\n", gst_riff_id_to_fourcc(chunk->form));
riff->nextlikely += 12;
// we push the list chunk on our 'stack'
riff->chunks = g_list_prepend(riff->chunks,chunk);
@ -178,20 +164,20 @@ gint gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) {
}
else {
debug("gst_riff_parser: chunk id offset %08x is 0x%08lx '%s' and is 0x%08lx long\n",
DEBUG("gst_riff_parser: chunk id offset %08x is 0x%08lx '%s' and is 0x%08lx long\n",
riff->nextlikely, words[0],
gst_riff_id_to_fourcc(words[0]),words[1]);
riff->nextlikely += 8 + chunk->size; /* doesn't include hdr */
// if this buffer is incomplete
if (riff->nextlikely > last) {
guint left = size - (riff->nextlikely - chunk->size - off);
guint left = size - (riff->nextlikely - chunk->size - off);
//g_print("make incomplete buffer %08x\n", left);
chunk->data = g_malloc(chunk->size);
DEBUG("make incomplete buffer %08x\n", left);
chunk->data = g_malloc(chunk->size);
memcpy(chunk->data, (gchar *)(words+2), left);
riff->incomplete_chunk = chunk;
riff->incomplete_chunk_size = left;
riff->incomplete_chunk = chunk;
riff->incomplete_chunk_size = left;
}
else {
// send the buffer to the listener if we have received a function
@ -204,6 +190,17 @@ gint gst_riff_parser_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) {
//riff->chunks = g_list_prepend(riff->chunks,chunk);
}
}
if ((riff->nextlikely+12) > last && !riff->incomplete_chunk) {
guint left = last - riff->nextlikely;
DEBUG("gst_riff_parser: not enough data next 0x%08x last 0x%08lx %08x %08x\n",riff->nextlikely,
last, left, off);
riff->dataleft = g_malloc(left);
riff->dataleft_size = left;
memcpy(riff->dataleft, GST_BUFFER_DATA(buf)+size-left, left);
return 0;
}
return 0;
}

7
libs/winloader/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
Makefile
Makefile.in
*.o
*.lo
*.la
.deps
.libs

View file

@ -0,0 +1,16 @@
filterdir = $(libdir)/gst
filter_LTLIBRARIES = libwinloader.la
libwinloader_la_SOURCES = driver.c elfdll.c ext.c externals.c module.c pe_image.c pe_resource.c registry.c resource.c stubs.s vfl.c
libwinloaderincludedir = $(includedir)/gst/libs/winloader.h
libwinloaderinclude_HEADERS =
noinst_HEADERS = externals.h
DEFINES=-rdynamic -fPIC -g -D__WINE__ -Ddbg_printf=__vprintf -DTRACE=__vprintf
CFLAGS += $(DEFINES)
INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir) -I$(top_srcdir)/include
LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_srcdir)/gst/libgst.la

215
libs/winloader/driver.c Normal file
View file

@ -0,0 +1,215 @@
#include <stdio.h>
#include <malloc.h>
#include <wine/driver.h>
#include <wine/pe_image.h>
#include <wine/winreg.h>
#include <wine/vfw.h>
#include <registry.h>
#include <config.h>
#define STORE_ALL \
__asm__ ( \
"push %%ebx\n\t" \
"push %%ecx\n\t" \
"push %%edx\n\t" \
"push %%esi\n\t" \
"push %%edi\n\t"::)
#define REST_ALL \
__asm__ ( \
"pop %%edi\n\t" \
"pop %%esi\n\t" \
"pop %%edx\n\t" \
"pop %%ecx\n\t" \
"pop %%ebx\n\t"::)
typedef struct {
UINT uDriverSignature;
HINSTANCE hDriverModule;
DRIVERPROC DriverProc;
DWORD dwDriverID;
} DRVR;
typedef DRVR *PDRVR;
typedef DRVR *NPDRVR;
typedef DRVR *LPDRVR;
static DWORD dwDrvID = 0;
static NPDRVR DrvAlloc(HDRVR*lpDriver, LPUINT lpDrvResult)
{
NPDRVR npDriver;
/* allocate and lock handle */
if (lpDriver)
{
if (*lpDriver = (HDRVR) malloc(sizeof(DRVR)) )
{
if (npDriver = (NPDRVR) *lpDriver)
{
*lpDrvResult = MMSYSERR_NOERROR;
return (npDriver);
}
free((NPDRVR)*lpDriver);
}
return (*lpDrvResult = MMSYSERR_NOMEM, (NPDRVR) 0);
}
return (*lpDrvResult = MMSYSERR_INVALPARAM, (NPDRVR) 0);
}
typedef struct
{
HMODULE handle;
char name[64];
int usage;
}codec_t;
static codec_t codecs[3]={
{0, PLUGINS_SRCDIR "/win32/divxc32.dll", 0},
{0, PLUGINS_SRCDIR "/win32/ir50_32.dll", 0},
// {0, "./mpg4c32.dll", 0},
{0, PLUGINS_SRCDIR "/win32/libvideodll.so", 0},
};
static void DrvFree(HDRVR hDriver)
{
int i;
FreeLibrary(((DRVR*)hDriver)->hDriverModule);
if(hDriver)
for(i=0; i<sizeof(codecs)/sizeof(codecs[0]); i++)
if(codecs[i].handle==((DRVR*)hDriver)->hDriverModule)
{
codecs[i].handle=0;
codecs[i].usage--;
if (hDriver)
free((NPDRVR)hDriver);
return;
}
}
void DrvClose(HDRVR hdrvr)
{
DrvFree(hdrvr);
}
HDRVR
//DrvOpen(LPCSTR lpszDriverName, LPCSTR lpszSectionName, LPARAM lParam2)
DrvOpen(LPARAM lParam2)
{
int drv_id;
char filename[MAX_PATH], *f;
UINT uDrvResult;
HDRVR hDriver;
NPDRVR npDriver;
char unknown[0x24];
int seg;
int qwe;
int regs[10];
int fccHandler=*((int*)lParam2+2);
switch(fccHandler)
{
case mmioFOURCC('D', 'I', 'V', '3'):
case mmioFOURCC('D', 'I', 'V', '4'):
case mmioFOURCC('d', 'i', 'v', '3'):
case mmioFOURCC('d', 'i', 'v', '4'):
drv_id=0;
break;
case mmioFOURCC('I', 'V', '5', '0'):
case mmioFOURCC('i', 'v', '5', '0'):
drv_id=1;
break;
case mmioFOURCC('m', 'p', '4', '3'):
case mmioFOURCC('M', 'P', 'G', '4'):
drv_id=2;
break;
default:
printf("Unknown codec %X='%c%c%c%c'\n", fccHandler,
fccHandler&0xFF, (fccHandler&0xFF00)>>8,
(fccHandler&0xFF0000)>>16, (fccHandler&0xFF000000)>>24);
return (HDRVR)0;
}
if (!(npDriver = DrvAlloc(&hDriver, &uDrvResult)))
return ((HDRVR) 0);
if(codecs[drv_id].handle==0)
{
if (!(codecs[drv_id].handle=npDriver->hDriverModule = LoadLibraryA(codecs[drv_id].name)))
{
DrvFree(hDriver);
return ((HDRVR) 0);
}
else codecs[drv_id].usage=1;
}
else
{
npDriver->hDriverModule=codecs[drv_id].handle;
codecs[drv_id].usage++;
}
// 14c0
if(drv_id==0)
{
int newkey;
int bitrate;
int count=4;
if(RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\LinuxLoader\\Divx", 0, 0, &newkey)!=0)
goto no_reg;
if(RegQueryValueExA(newkey, "BitRate", 0, 0, &bitrate, &count)!=0)
{
RegCloseKey(newkey);
goto no_reg;
}
// printf("Setting default bitrate from %f to %d\n",
// *(double*)((char*)npDriver->hDriverModule+0x14c0), bitrate);
*(double*)((char*)npDriver->hDriverModule+0x14c0)=bitrate;
RegCloseKey(newkey);
no_reg:
;
}
if (!(npDriver->DriverProc = (DRIVERPROC)
GetProcAddress(npDriver->hDriverModule, "DriverProc")))
{
FreeLibrary(npDriver->hDriverModule);
DrvFree(hDriver);
return ((HDRVR) 0);
}
//printf("DriverProc == %X\n", npDriver->DriverProc);
npDriver->dwDriverID = ++dwDrvID;
if (codecs[drv_id].usage==1)
{
STORE_ALL;
(npDriver->DriverProc)(0, hDriver, DRV_LOAD, 0, 0);
REST_ALL;
//printf("DRV_LOAD Ok!\n");
STORE_ALL;
(npDriver->DriverProc)(0, hDriver, DRV_ENABLE, 0, 0);
REST_ALL;
//printf("DRV_ENABLE Ok!\n");
}
// open driver
STORE_ALL;
npDriver->dwDriverID=(npDriver->DriverProc)(npDriver->dwDriverID, hDriver, DRV_OPEN,
(LPARAM) (LPSTR) unknown, lParam2);
REST_ALL;
//printf("DRV_OPEN Ok!(%X)\n", npDriver->dwDriverID);
if (uDrvResult)
{
DrvFree(hDriver);
hDriver = (HDRVR) 0;
}
return (hDriver);
}

300
libs/winloader/elfdll.c Normal file
View file

@ -0,0 +1,300 @@
/*
* Elf-dll loader functions
*
* Copyright 1999 Bertho A. Stultiens
*/
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <wine/config.h>
#include <wine/windef.h>
//#include <wine/global.h>
//#include <wine/process.h>
#include <wine/module.h>
#include <wine/heap.h>
#include <wine/elfdll.h>
#include <wine/debugtools.h>
#include <wine/winerror.h>
//DEFAULT_DEBUG_CHANNEL(elfdll)
#include <dlfcn.h>
struct modref_list_t;
typedef struct modref_list_t
{
WINE_MODREF* wm;
struct modref_list_t *next;
struct modref_list_t *prev;
}
modref_list;
//WINE_MODREF *local_wm=NULL;
extern modref_list* local_wm;
/*------------------ HACKS -----------------*/
extern DWORD fixup_imports(WINE_MODREF *wm);
extern void dump_exports(HMODULE hModule);
/*---------------- END HACKS ---------------*/
char *extra_ld_library_path = NULL; /* The extra search-path set in wine.conf */
struct elfdll_image
{
HMODULE pe_module_start;
DWORD pe_module_size;
};
/****************************************************************************
* ELFDLL_dlopen
*
* Wrapper for dlopen to search the EXTRA_LD_LIBRARY_PATH from wine.conf
* manually because libdl.so caches the environment and does not accept our
* changes.
*/
void *ELFDLL_dlopen(const char *libname, int flags)
{
char buffer[256];
int namelen;
void *handle;
char *ldpath;
/* First try the default path search of dlopen() */
handle = dlopen(libname, flags);
if(handle)
return handle;
/* Now try to construct searches through our extra search-path */
namelen = strlen(libname);
ldpath = extra_ld_library_path;
while(ldpath && *ldpath)
{
int len;
char *cptr;
char *from;
from = ldpath;
cptr = strchr(ldpath, ':');
if(!cptr)
{
len = strlen(ldpath);
ldpath = NULL;
}
else
{
len = cptr - ldpath;
ldpath = cptr + 1;
}
if(len + namelen + 1 >= sizeof(buffer))
{
ERR("Buffer overflow! Check EXTRA_LD_LIBRARY_PATH or increase buffer size.\n");
return NULL;
}
strncpy(buffer, from, len);
if(len)
{
buffer[len] = '/';
strcpy(buffer + len + 1, libname);
}
else
strcpy(buffer + len, libname);
TRACE("Trying dlopen('%s', %d)\n", buffer, flags);
handle = dlopen(buffer, flags);
if(handle)
return handle;
}
return NULL;
}
/****************************************************************************
* get_sobasename (internal)
*
*/
static LPSTR get_sobasename(LPCSTR path, LPSTR name)
{
char *cptr;
/* Strip the path from the library name */
if((cptr = strrchr(path, '/')))
{
char *cp = strrchr(cptr+1, '\\');
if(cp && cp > cptr)
cptr = cp;
}
else
cptr = strrchr(path, '\\');
if(!cptr)
cptr = (char *)path; /* No '/' nor '\\' in path */
else
cptr++;
strcpy(name, cptr);
cptr = strrchr(name, '.');
if(cptr)
*cptr = '\0'; /* Strip extension */
/* Convert to lower case.
* This must be done manually because it is not sure that
* other modules are accessible.
*/
for(cptr = name; *cptr; cptr++)
*cptr = tolower(*cptr);
return name;
}
/****************************************************************************
* ELFDLL_CreateModref (internal)
*
* INPUT
* hModule - the header from the elf-dll's data-segment
* path - requested path from original call
*
* OUTPUT
* A WINE_MODREF pointer to the new object
*
* BUGS
* - Does not handle errors due to dependencies correctly
* - path can be wrong
*/
#define RVA(base, va) (((DWORD)base) + ((DWORD)va))
static WINE_MODREF *ELFDLL_CreateModref(HMODULE hModule, LPCSTR path)
{
// IMAGE_NT_HEADERS *nt = PE_HEADER(hModule);
IMAGE_DATA_DIRECTORY *dir;
IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL;
WINE_MODREF *wm;
int len;
HANDLE procheap = GetProcessHeap();
wm = (WINE_MODREF *)HeapAlloc(procheap, HEAP_ZERO_MEMORY, sizeof(*wm));
if(!wm)
return NULL;
wm->module = hModule;
wm->type = MODULE32_ELF; /* FIXME */
// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT;
// if(dir->Size)
// wm->binfmt.pe.pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(hModule, dir->VirtualAddress);
// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT;
// if(dir->Size)
// pe_import = wm->binfmt.pe.pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(hModule, dir->VirtualAddress);
// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE;
// if(dir->Size)
// wm->binfmt.pe.pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(hModule, dir->VirtualAddress);
wm->filename = strdup( path );
wm->modname = strrchr( wm->filename, '\\' );
if (!wm->modname) wm->modname = wm->filename;
else wm->modname++;
/*
len = GetShortPathNameA( wm->filename, NULL, 0 );
wm->short_filename = (char *)HeapAlloc( procheap, 0, len+1 );
GetShortPathNameA( wm->filename, wm->short_filename, len+1 );
wm->short_modname = strrchr( wm->short_filename, '\\' );
if (!wm->short_modname) wm->short_modname = wm->short_filename;
else wm->short_modname++;
*/
/* Link MODREF into process list */
// EnterCriticalSection( &PROCESS_Current()->crit_section );
if(local_wm)
{
local_wm->next=malloc(sizeof(modref_list));
local_wm->next->prev=local_wm;
local_wm->next->next=NULL;
local_wm->next->wm=wm;
local_wm=local_wm->next;
}
else
{
local_wm=malloc(sizeof(modref_list));
local_wm->next=local_wm->prev=NULL;
local_wm->wm=wm;
}
// LeaveCriticalSection( &PROCESS_Current()->crit_section );
return wm;
}
/****************************************************************************
* ELFDLL_LoadLibraryExA (internal)
*
* Implementation of elf-dll loading for PE modules
*/
WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR path, DWORD flags)
{
LPVOID dlhandle;
struct elfdll_image *image;
char name[129];
char soname[129];
WINE_MODREF *wm;
get_sobasename(path, name);
strcpy(soname, name);
strcat(soname, ".so");
/* Try to open the elf-dll */
dlhandle = ELFDLL_dlopen(soname, RTLD_LAZY);
if(!dlhandle)
{
WARN("Could not load %s (%s)\n", soname, dlerror());
SetLastError( ERROR_FILE_NOT_FOUND );
return NULL;
}
/* Get the 'dllname_elfdll_image' variable */
/* strcpy(soname, name);
strcat(soname, "_elfdll_image");
image = (struct elfdll_image *)dlsym(dlhandle, soname);
if(!image)
{
ERR("Could not get elfdll image descriptor %s (%s)\n", soname, dlerror());
dlclose(dlhandle);
SetLastError( ERROR_BAD_FORMAT );
return NULL;
}
*/
wm = ELFDLL_CreateModref(dlhandle, path);
if(!wm)
{
ERR("Could not create WINE_MODREF for %s\n", path);
dlclose(dlhandle);
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
return wm;
}
/****************************************************************************
* ELFDLL_UnloadLibrary (internal)
*
* Unload an elf-dll completely from memory and deallocate the modref
*/
void ELFDLL_UnloadLibrary(WINE_MODREF *wm)
{
}

478
libs/winloader/ext.c Normal file
View file

@ -0,0 +1,478 @@
/********************************************************
*
*
* Stub functions for Wine module
*
*
********************************************************/
#include <malloc.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <wine/windef.h>
int dbg_header_err( const char *dbg_channel, const char *func )
{
return 0;
}
int dbg_header_warn( const char *dbg_channel, const char *func )
{
return 0;
}
int dbg_header_fixme( const char *dbg_channel, const char *func )
{
return 0;
}
int dbg_header_trace( const char *dbg_channel, const char *func )
{
return 0;
}
int dbg_vprintf( const char *format, ... )
{
return 0;
}
int __vprintf( const char *format, ... )
{
return 0;
}
int GetProcessHeap()
{
return 1;
}
void* HeapAlloc(int heap, int flags, int size)
{
if(flags & 0x8)
return calloc(size, 1);
else
return malloc(size);
}
int HeapFree(int heap, int flags, void* mem)
{
free(mem);
return 1;
}
/*
void EnterCriticalSection(void* q)
{
return;
}
void LeaveCriticalSection(void* q)
{
return;
}
*/
static int last_error;
int GetLastError()
{
return last_error;
}
int SetLastError(int error)
{
return last_error=error;
}
int ReadFile(int handle, void* mem, unsigned long size, long* result, long flags)
{
*result=read(handle, mem, size);
return *result;
}
int lstrcmpiA(const char* c1, const char* c2)
{
return strcasecmp(c1,c2);
}
int lstrcpynA(char* dest, const char* src, int num)
{
return strncmp(dest,src,num);
}
int lstrlenA(const char* s)
{
return strlen(s);
}
int lstrlenW(const short* s)
{
int l;
if(!s)
return 0;
l=0;
while(s[l])
l++;
return l;
}
int lstrcpynWtoA(char* dest, const char* src, int count)
{
int moved=0;
if((dest==0) || (src==0))
return 0;
while(moved<count)
{
*dest=*src;
moved++;
if(*src==0)
return moved;
src++;
dest++;
}
}
int wcsnicmp(const unsigned short* s1, const unsigned short* s2, int n)
{
if(s1==0)
return;
if(s2==0)
return;
while(n>0)
{
if(*s1<*s2)
return -1;
else
if(*s1>*s2)
return 1;
else
if(*s1==0)
return 0;
s1++;
s2++;
n--;
}
return 0;
}
int IsBadReadPtr(void* data, int size)
{
if(size==0)
return 0;
if(data==NULL)
return 1;
return 0;
}
char* HEAP_strdupA(const char* string)
{
return strdup(string);
}
short* HEAP_strdupAtoW(void* heap, void* hz, const char* string)
{
int size, i;
short* answer;
if(string==0)
return 0;
size=strlen(string);
answer=malloc(size+size+2);
for(i=0; i<=size; i++)
answer[i]=(short)string[i];
return answer;
}
char* HEAP_strdupWtoA(void* heap, void* hz, const short* string)
{
int size, i;
char* answer;
if(string==0)
return 0;
size=0;
while(string[size])
size++;
answer=malloc(size+2);
for(i=0; i<=size; i++)
answer[i]=(char)string[i];
return answer;
}
/***********************************************************************
* FILE_dommap
*/
//#define MAP_PRIVATE
//#define MAP_SHARED
#undef MAP_ANON
LPVOID FILE_dommap( int unix_handle, LPVOID start,
DWORD size_high, DWORD size_low,
DWORD offset_high, DWORD offset_low,
int prot, int flags )
{
int fd = -1;
int pos;
LPVOID ret;
if (size_high || offset_high)
printf("offsets larger than 4Gb not supported\n");
if (unix_handle == -1)
{
#ifdef MAP_ANON
// printf("Anonymous\n");
flags |= MAP_ANON;
#else
static int fdzero = -1;
if (fdzero == -1)
{
if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1)
{
perror( "/dev/zero: open" );
exit(1);
}
}
fd = fdzero;
#endif /* MAP_ANON */
/* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */
#ifdef MAP_SHARED
flags &= ~MAP_SHARED;
#endif
#ifdef MAP_PRIVATE
flags |= MAP_PRIVATE;
#endif
}
else fd = unix_handle;
// printf("fd %x, start %x, size %x, pos %x, prot %x\n",fd,start,size_low, offset_low, prot);
// if ((ret = mmap( start, size_low, prot,
// flags, fd, offset_low )) != (LPVOID)-1)
if ((ret = mmap( start, size_low, prot,
MAP_PRIVATE | MAP_FIXED, fd, offset_low )) != (LPVOID)-1)
{
// printf("address %08x\n", *(int*)ret);
// printf("%x\n", ret);
return ret;
}
// printf("mmap %d\n", errno);
/* mmap() failed; if this is because the file offset is not */
/* page-aligned (EINVAL), or because the underlying filesystem */
/* does not support mmap() (ENOEXEC), we do it by hand. */
if (unix_handle == -1) return ret;
if ((errno != ENOEXEC) && (errno != EINVAL)) return ret;
if (prot & PROT_WRITE)
{
/* We cannot fake shared write mappings */
#ifdef MAP_SHARED
if (flags & MAP_SHARED) return ret;
#endif
#ifdef MAP_PRIVATE
if (!(flags & MAP_PRIVATE)) return ret;
#endif
}
/* printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/
/* Reserve the memory with an anonymous mmap */
ret = FILE_dommap( -1, start, size_high, size_low, 0, 0,
PROT_READ | PROT_WRITE, flags );
if (ret == (LPVOID)-1)
// {
// perror(
return ret;
/* Now read in the file */
if ((pos = lseek( fd, offset_low, SEEK_SET )) == -1)
{
FILE_munmap( ret, size_high, size_low );
// printf("lseek\n");
return (LPVOID)-1;
}
read( fd, ret, size_low );
lseek( fd, pos, SEEK_SET ); /* Restore the file pointer */
mprotect( ret, size_low, prot ); /* Set the right protection */
// printf("address %08x\n", *(int*)ret);
return ret;
}
/***********************************************************************
* FILE_munmap
*/
int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low )
{
if (size_high)
printf("offsets larger than 4Gb not supported\n");
return munmap( start, size_low );
}
static int mapping_size=0;
struct file_mapping_s;
typedef struct file_mapping_s
{
int mapping_size;
char* name;
HANDLE handle;
struct file_mapping_s* next;
struct file_mapping_s* prev;
}file_mapping;
static file_mapping* fm=0;
#define PAGE_NOACCESS 0x01
#define PAGE_READONLY 0x02
#define PAGE_READWRITE 0x04
#define PAGE_WRITECOPY 0x08
#define PAGE_EXECUTE 0x10
#define PAGE_EXECUTE_READ 0x20
#define PAGE_EXECUTE_READWRITE 0x40
#define PAGE_EXECUTE_WRITECOPY 0x80
#define PAGE_GUARD 0x100
#define PAGE_NOCACHE 0x200
HANDLE CreateFileMappingA(int hFile, void* lpAttr,
DWORD flProtect, DWORD dwMaxHigh, DWORD dwMaxLow, const char* name)
{
unsigned int len;
HANDLE answer;
int anon=0;
int mmap_access=0;
if(hFile<0)
{
anon=1;
hFile=open("/dev/zero", O_RDWR);
if(hFile<0)
return 0;
}
if(!anon)
{
len=lseek(hFile, 0, SEEK_END);
lseek(hFile, 0, SEEK_SET);
}
else len=dwMaxLow;
// len=min(len, dwMaxLow);
#warning fixme - should analyze flProtect
if(flProtect & PAGE_READONLY)
mmap_access |=PROT_READ;
else
mmap_access |=PROT_READ|PROT_WRITE;
answer=(HANDLE)mmap(NULL, len, mmap_access, MAP_PRIVATE, hFile, 0);
if(anon)
close(hFile);
if(answer!=(HANDLE)-1)
{
if(fm==0)
{
fm=malloc(sizeof(file_mapping));
fm->prev=NULL;
}
else
{
fm->next=malloc(sizeof(file_mapping));
fm->next->prev=fm;
fm=fm->next;
}
fm->next=NULL;
fm->handle=answer;
if(name)
fm->name=strdup(name);
else
fm->name=NULL;
fm->mapping_size=len;
if(anon)
close(hFile);
return answer;
}
return (HANDLE)0;
}
int UnmapViewOfFile(HANDLE handle)
{
file_mapping* p;
int result;
if(fm==0)
return (HANDLE)0;
for(p=fm; p; p=p->next)
{
if(p->handle==handle)
{
result=munmap((void*)handle, p->mapping_size);
if(p->next)p->next->prev=p->prev;
if(p->prev)p->prev->next=p->next;
if(p->name)
free(p->name);
if(p==fm)
fm=p->prev;
free(p);
return result;
}
}
return 0;
}
static int va_size=0;
void* VirtualAlloc(void* address, DWORD size, DWORD type, DWORD protection)
{
void* answer;
int fd=open("/dev/zero", O_RDWR);
size=(size+0xffff)&(~0xffff);
// printf("VirtualAlloc(0x%08X, %d)\n", address
answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC,
// ((address!=NULL) ? MAP_FIXED : MAP_SHARED), fd, 0);
MAP_PRIVATE, fd, 0);
// answer=FILE_dommap(-1, address, 0, size, 0, 0,
// PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
close(fd);
if(answer==(void*)-1)
{
printf("Error no %d\n", errno);
printf("VirtualAlloc(0x%08X, %d) failed\n", address, size);
return NULL;
}
else
{
if(va_size!=0)
printf("Multiple VirtualAlloc!\n");
// printf("answer=0x%08x\n", answer);
va_size=size;
return answer;
}
}
int VirtualFree(void* address, int t1, int t2)//not sure
{
int answer=munmap(address, va_size);
va_size=0;
return answer;
}
int WideCharToMultiByte(unsigned int codepage, long flags, const short* src,
int srclen,char* dest, int destlen, const char* defch, int* used_defch)
{
#warning FIXME
int i;
// printf("WCh2MB: Src string ");
// for(i=0; i<=srclen; i++)printf(" %04X", src[i]);
if(src==0)
return 0;
if(dest==0)
return 0;
if(used_defch)
*used_defch=0;
for(i=0; i<min(srclen, destlen); i++)
{
*dest=(char)*src;
dest++;
src++;
if(*dest==0)
return i+1;
}
return 0;
}
int MultiByteToWideChar(unsigned int codepage,long flags, const char* src, int srclen,
short* dest, int destlen)
{
return 0;
}
HANDLE OpenFileMappingA(long access, long prot, char* name)
{
file_mapping* p;
if(fm==0)
return (HANDLE)0;
if(name==0)
return (HANDLE)0;
for(p=fm; p; p=p->prev)
{
if(p->name==0)
continue;
if(strcmp(p->name, name)==0)
return p->handle;
}
return 0;
}

1109
libs/winloader/externals.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
int ext_unknown();

774
libs/winloader/module.c Normal file
View file

@ -0,0 +1,774 @@
/*
* Modules
*
* Copyright 1995 Alexandre Julliard
*/
#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <wine/windef.h>
#include <wine/winerror.h>
#include <wine/heap.h>
#include <wine/module.h>
#include <wine/pe_image.h>
#include <wine/debugtools.h>
struct modref_list_t;
typedef struct modref_list_t
{
WINE_MODREF* wm;
struct modref_list_t *next;
struct modref_list_t *prev;
}
modref_list;
//WINE_MODREF *local_wm=NULL;
modref_list* local_wm=NULL;
WINE_MODREF *MODULE_FindModule(LPCSTR m)
{
modref_list* list=local_wm;
TRACE("Module %s request\n", m);
if(list==NULL)
return NULL;
while(strcmp(m, list->wm->filename))
{
list=list->prev;
if(list==NULL)
return NULL;
}
TRACE("Resolved to %s\n", list->wm->filename);
return list->wm;
}
void MODULE_RemoveFromList(WINE_MODREF *mod)
{
modref_list* list=local_wm;
if(list==0)
return;
if(mod==0)
return;
if((list->prev==NULL)&&(list->next==NULL))
{
free(list);
local_wm=NULL;
return;
}
for(;list;list=list->prev)
{
if(list->wm==mod)
{
if(list->prev)
list->prev->next=list->next;
if(list->next)
list->next->prev=list->prev;
if(list==local_wm)
local_wm=list->prev;
free(list);
return;
}
}
}
WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m)
{
modref_list* list=local_wm;
TRACE("Module %X request\n", m);
if(list==NULL)
return NULL;
while(m!=list->wm->module)
{
// printf("Checking list %X wm %X module %X\n",
// list, list->wm, list->wm->module);
list=list->prev;
if(list==NULL)
return NULL;
}
TRACE("LookupHMODULE hit %X\n", list->wm);
return list->wm;
}
/*************************************************************************
* MODULE_InitDll
*/
static WIN_BOOL MODULE_InitDll( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
{
WIN_BOOL retv = TRUE;
static LPCSTR typeName[] = { "PROCESS_DETACH", "PROCESS_ATTACH",
"THREAD_ATTACH", "THREAD_DETACH" };
assert( wm );
/* Skip calls for modules loaded with special load flags */
if ( ( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS )
|| ( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) )
return TRUE;
TRACE("(%s,%s,%p) - CALL\n", wm->modname, typeName[type], lpReserved );
/* Call the initialization routine */
switch ( wm->type )
{
case MODULE32_PE:
retv = PE_InitDLL( wm, type, lpReserved );
break;
case MODULE32_ELF:
/* no need to do that, dlopen() already does */
break;
default:
ERR("wine_modref type %d not handled.\n", wm->type );
retv = FALSE;
break;
}
/* The state of the module list may have changed due to the call
to PE_InitDLL. We cannot assume that this module has not been
deleted. */
TRACE("(%p,%s,%p) - RETURN %d\n", wm, typeName[type], lpReserved, retv );
return retv;
}
/*************************************************************************
* MODULE_DllProcessAttach
*
* Send the process attach notification to all DLLs the given module
* depends on (recursively). This is somewhat complicated due to the fact that
*
* - we have to respect the module dependencies, i.e. modules implicitly
* referenced by another module have to be initialized before the module
* itself can be initialized
*
* - the initialization routine of a DLL can itself call LoadLibrary,
* thereby introducing a whole new set of dependencies (even involving
* the 'old' modules) at any time during the whole process
*
* (Note that this routine can be recursively entered not only directly
* from itself, but also via LoadLibrary from one of the called initialization
* routines.)
*
* Furthermore, we need to rearrange the main WINE_MODREF list to allow
* the process *detach* notifications to be sent in the correct order.
* This must not only take into account module dependencies, but also
* 'hidden' dependencies created by modules calling LoadLibrary in their
* attach notification routine.
*
* The strategy is rather simple: we move a WINE_MODREF to the head of the
* list after the attach notification has returned. This implies that the
* detach notifications are called in the reverse of the sequence the attach
* notifications *returned*.
*
* NOTE: Assumes that the process critical section is held!
*
*/
WIN_BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
{
WIN_BOOL retv = TRUE;
int i;
assert( wm );
/* prevent infinite recursion in case of cyclical dependencies */
if ( ( wm->flags & WINE_MODREF_MARKER )
|| ( wm->flags & WINE_MODREF_PROCESS_ATTACHED ) )
return retv;
TRACE("(%s,%p) - START\n", wm->modname, lpReserved );
/* Tag current MODREF to prevent recursive loop */
wm->flags |= WINE_MODREF_MARKER;
/* Recursively attach all DLLs this one depends on */
/* for ( i = 0; retv && i < wm->nDeps; i++ )
if ( wm->deps[i] )
retv = MODULE_DllProcessAttach( wm->deps[i], lpReserved );
*/
/* Call DLL entry point */
//local_wm=wm;
if(local_wm)
{
local_wm->next=malloc(sizeof(modref_list));
local_wm->next->prev=local_wm;
local_wm->next->next=NULL;
local_wm->next->wm=wm;
local_wm=local_wm->next;
}
else
{
local_wm=malloc(sizeof(modref_list));
local_wm->next=local_wm->prev=NULL;
local_wm->wm=wm;
}
/* Remove recursion flag */
wm->flags &= ~WINE_MODREF_MARKER;
if ( retv )
{
retv = MODULE_InitDll( wm, DLL_PROCESS_ATTACH, lpReserved );
if ( retv )
wm->flags |= WINE_MODREF_PROCESS_ATTACHED;
}
TRACE("(%s,%p) - END\n", wm->modname, lpReserved );
return retv;
}
/*************************************************************************
* MODULE_DllProcessDetach
*
* Send DLL process detach notifications. See the comment about calling
* sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag
* is set, only DLLs with zero refcount are notified.
*/
void MODULE_DllProcessDetach( WINE_MODREF* wm, WIN_BOOL bForceDetach, LPVOID lpReserved )
{
// WINE_MODREF *wm=local_wm;
wm->flags &= ~WINE_MODREF_PROCESS_ATTACHED;
MODULE_InitDll( wm, DLL_PROCESS_DETACH, lpReserved );
}
/*************************************************************************
* MODULE_DllThreadAttach
*
* Send DLL thread attach notifications. These are sent in the
* reverse sequence of process detach notification.
*
*/
/*
void MODULE_DllThreadAttach( LPVOID lpReserved )
{
WINE_MODREF *wm;
MODULE_InitDll( wm, DLL_THREAD_ATTACH, lpReserved );
}*/
/*************************************************************************
* MODULE_DllThreadDetach
*
* Send DLL thread detach notifications. These are sent in the
* same sequence as process detach notification.
*
*/
/*
void MODULE_DllThreadDetach( LPVOID lpReserved )
{
WINE_MODREF *wm;
MODULE_InitDll( wm, DLL_THREAD_DETACH, lpReserved );
}
*/
/***********************************************************************
* MODULE_CreateDummyModule
*
* Create a dummy NE module for Win32 or Winelib.
*/
HMODULE MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 )
{
printf("MODULE_CreateDummyModule:: Not implemented\n");
return 0;
}
/*
HMODULE MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 )
{
HMODULE hModule;
NE_MODULE *pModule;
SEGTABLEENTRY *pSegment;
char *pStr,*s;
unsigned int len;
const char* basename;
OFSTRUCT *ofs;
int of_size, size;
// Extract base filename
basename = strrchr(filename, '\\');
if (!basename) basename = filename;
else basename++;
len = strlen(basename);
if ((s = strchr(basename, '.'))) len = s - basename;
// Allocate module
of_size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName)
+ strlen(filename) + 1;
size = sizeof(NE_MODULE) +
// loaded file info
of_size +
// segment table: DS,CS
2 * sizeof(SEGTABLEENTRY) +
// name table
len + 2 +
// several empty tables
8;
hModule = GlobalAlloc16( GMEM_MOVEABLE | GMEM_ZEROINIT, size );
if (!hModule) return (HMODULE)11; // invalid exe
FarSetOwner16( hModule, hModule );
pModule = (NE_MODULE *)GlobalLock16( hModule );
// Set all used entries
pModule->magic = IMAGE_OS2_SIGNATURE;
pModule->count = 1;
pModule->next = 0;
pModule->flags = 0;
pModule->dgroup = 0;
pModule->ss = 1;
pModule->cs = 2;
pModule->heap_size = 0;
pModule->stack_size = 0;
pModule->seg_count = 2;
pModule->modref_count = 0;
pModule->nrname_size = 0;
pModule->fileinfo = sizeof(NE_MODULE);
pModule->os_flags = NE_OSFLAGS_WINDOWS;
pModule->self = hModule;
pModule->module32 = module32;
// Set version and flags
if (module32)
{
pModule->expected_version =
((PE_HEADER(module32)->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) |
(PE_HEADER(module32)->OptionalHeader.MinorSubsystemVersion & 0xff);
pModule->flags |= NE_FFLAGS_WIN32;
if (PE_HEADER(module32)->FileHeader.Characteristics & IMAGE_FILE_DLL)
pModule->flags |= NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA;
}
// Set loaded file information
ofs = (OFSTRUCT *)(pModule + 1);
memset( ofs, 0, of_size );
ofs->cBytes = of_size < 256 ? of_size : 255; // FIXME
strcpy( ofs->szPathName, filename );
pSegment = (SEGTABLEENTRY*)((char*)(pModule + 1) + of_size);
pModule->seg_table = (int)pSegment - (int)pModule;
// Data segment
pSegment->size = 0;
pSegment->flags = NE_SEGFLAGS_DATA;
pSegment->minsize = 0x1000;
pSegment++;
// Code segment
pSegment->flags = 0;
pSegment++;
// Module name
pStr = (char *)pSegment;
pModule->name_table = (int)pStr - (int)pModule;
assert(len<256);
*pStr = len;
lstrcpynA( pStr+1, basename, len+1 );
pStr += len+2;
// All tables zero terminated
pModule->res_table = pModule->import_table = pModule->entry_table =
(int)pStr - (int)pModule;
NE_RegisterModule( pModule );
return hModule;
}
*/
/***********************************************************************
* MODULE_GetBinaryType
*
* The GetBinaryType function determines whether a file is executable
* or not and if it is it returns what type of executable it is.
* The type of executable is a property that determines in which
* subsystem an executable file runs under.
*
* Binary types returned:
* SCS_32BIT_BINARY: A Win32 based application
* SCS_DOS_BINARY: An MS-Dos based application
* SCS_WOW_BINARY: A Win16 based application
* SCS_PIF_BINARY: A PIF file that executes an MS-Dos based app
* SCS_POSIX_BINARY: A POSIX based application ( Not implemented )
* SCS_OS216_BINARY: A 16bit OS/2 based application
*
* Returns TRUE if the file is an executable in which case
* the value pointed by lpBinaryType is set.
* Returns FALSE if the file is not an executable or if the function fails.
*
* To do so it opens the file and reads in the header information
* if the extended header information is not present it will
* assume that the file is a DOS executable.
* If the extended header information is present it will
* determine if the file is a 16 or 32 bit Windows executable
* by check the flags in the header.
*
* Note that .COM and .PIF files are only recognized by their
* file name extension; but Windows does it the same way ...
*/
/*
static WIN_BOOL MODULE_GetBinaryType( HANDLE hfile, LPCSTR filename,
LPDWORD lpBinaryType )
{
IMAGE_DOS_HEADER mz_header;
char magic[4], *ptr;
DWORD len;
// Seek to the start of the file and read the DOS header information.
if ( SetFilePointer( hfile, 0, NULL, SEEK_SET ) != -1
&& ReadFile( hfile, &mz_header, sizeof(mz_header), &len, NULL )
&& len == sizeof(mz_header) )
{
// Now that we have the header check the e_magic field
// to see if this is a dos image.
//
if ( mz_header.e_magic == IMAGE_DOS_SIGNATURE )
{
WIN_BOOL lfanewValid = FALSE;
// We do have a DOS image so we will now try to seek into
// the file by the amount indicated by the field
// "Offset to extended header" and read in the
// "magic" field information at that location.
// This will tell us if there is more header information
// to read or not.
//
// But before we do we will make sure that header
// structure encompasses the "Offset to extended header"
// field.
//
if ( (mz_header.e_cparhdr<<4) >= sizeof(IMAGE_DOS_HEADER) )
if ( ( mz_header.e_crlc == 0 ) ||
( mz_header.e_lfarlc >= sizeof(IMAGE_DOS_HEADER) ) )
if ( mz_header.e_lfanew >= sizeof(IMAGE_DOS_HEADER)
&& SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET ) != -1
&& ReadFile( hfile, magic, sizeof(magic), &len, NULL )
&& len == sizeof(magic) )
lfanewValid = TRUE;
if ( !lfanewValid )
{
// If we cannot read this "extended header" we will
// assume that we have a simple DOS executable.
//
*lpBinaryType = SCS_DOS_BINARY;
return TRUE;
}
else
{
// Reading the magic field succeeded so
// we will try to determine what type it is.
//
if ( *(DWORD*)magic == IMAGE_NT_SIGNATURE )
{
// This is an NT signature.
//
*lpBinaryType = SCS_32BIT_BINARY;
return TRUE;
}
else if ( *(WORD*)magic == IMAGE_OS2_SIGNATURE )
{
// The IMAGE_OS2_SIGNATURE indicates that the
// "extended header is a Windows executable (NE)
// header." This can mean either a 16-bit OS/2
// or a 16-bit Windows or even a DOS program
// (running under a DOS extender). To decide
// which, we'll have to read the NE header.
///
IMAGE_OS2_HEADER ne;
if ( SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET ) != -1
&& ReadFile( hfile, &ne, sizeof(ne), &len, NULL )
&& len == sizeof(ne) )
{
switch ( ne.ne_exetyp )
{
case 2: *lpBinaryType = SCS_WOW_BINARY; return TRUE;
case 5: *lpBinaryType = SCS_DOS_BINARY; return TRUE;
default: *lpBinaryType = SCS_OS216_BINARY; return TRUE;
}
}
// Couldn't read header, so abort.
return FALSE;
}
else
{
// Unknown extended header, but this file is nonetheless
// DOS-executable.
//
*lpBinaryType = SCS_DOS_BINARY;
return TRUE;
}
}
}
}
// If we get here, we don't even have a correct MZ header.
// Try to check the file extension for known types ...
//
ptr = strrchr( filename, '.' );
if ( ptr && !strchr( ptr, '\\' ) && !strchr( ptr, '/' ) )
{
if ( !lstrcmpiA( ptr, ".COM" ) )
{
*lpBinaryType = SCS_DOS_BINARY;
return TRUE;
}
if ( !lstrcmpiA( ptr, ".PIF" ) )
{
*lpBinaryType = SCS_PIF_BINARY;
return TRUE;
}
}
return FALSE;
}
*/
/***********************************************************************
* GetBinaryTypeA [KERNEL32.280]
*/
/*
WIN_BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType )
{
WIN_BOOL ret = FALSE;
HANDLE hfile;
TRACE_(win32)("%s\n", lpApplicationName );
// Sanity check.
if ( lpApplicationName == NULL || lpBinaryType == NULL )
return FALSE;
// Open the file indicated by lpApplicationName for reading.
hfile = CreateFileA( lpApplicationName, GENERIC_READ, 0,
NULL, OPEN_EXISTING, 0, -1 );
if ( hfile == INVALID_HANDLE_VALUE )
return FALSE;
// Check binary type
ret = MODULE_GetBinaryType( hfile, lpApplicationName, lpBinaryType );
// Close the file.
CloseHandle( hfile );
return ret;
}
*/
/***********************************************************************
* LoadLibraryExA (KERNEL32)
*/
HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
{
WINE_MODREF *wm;
if(!libname)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
wm = MODULE_LoadLibraryExA( libname, hfile, flags );
if ( wm )
{
if ( !MODULE_DllProcessAttach( wm, NULL ) )
{
WARN_(module)("Attach failed for module '%s', \n", libname);
MODULE_FreeLibrary(wm);
SetLastError(ERROR_DLL_INIT_FAILED);
MODULE_RemoveFromList(wm);
wm = NULL;
}
}
return wm ? wm->module : 0;
}
/***********************************************************************
* MODULE_LoadLibraryExA (internal)
*
* Load a PE style module according to the load order.
*
* The HFILE parameter is not used and marked reserved in the SDK. I can
* only guess that it should force a file to be mapped, but I rather
* ignore the parameter because it would be extremely difficult to
* integrate this with different types of module represenations.
*
*/
WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
{
DWORD err = GetLastError();
WINE_MODREF *pwm;
int i;
// module_loadorder_t *plo;
SetLastError( ERROR_FILE_NOT_FOUND );
TRACE("Trying native dll '%s'\n", libname);
pwm = PE_LoadLibraryExA(libname, flags);
if(!pwm)
{
TRACE("Trying ELF dll '%s'\n", libname);
pwm=ELFDLL_LoadLibraryExA(libname, flags);
}
// printf("0x%08x\n", pwm);
// break;
if(pwm)
{
/* Initialize DLL just loaded */
TRACE("Loaded module '%s' at 0x%08x, \n", libname, pwm->module);
/* Set the refCount here so that an attach failure will */
/* decrement the dependencies through the MODULE_FreeLibrary call. */
pwm->refCount++;
SetLastError( err ); /* restore last error */
return pwm;
}
WARN("Failed to load module '%s'; error=0x%08lx, \n", libname, GetLastError());
return NULL;
}
/***********************************************************************
* LoadLibraryA (KERNEL32)
*/
HMODULE WINAPI LoadLibraryA(LPCSTR libname) {
return LoadLibraryExA(libname,0,0);
}
/***********************************************************************
* FreeLibrary
*/
WIN_BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
{
WIN_BOOL retv = FALSE;
WINE_MODREF *wm;
wm=MODULE32_LookupHMODULE(hLibModule);
// wm=local_wm;
if ( !wm || !hLibModule )
{
SetLastError( ERROR_INVALID_HANDLE );
return 0;
}
else
retv = MODULE_FreeLibrary( wm );
MODULE_RemoveFromList(wm);
return retv;
}
/***********************************************************************
* MODULE_DecRefCount
*
* NOTE: Assumes that the process critical section is held!
*/
static void MODULE_DecRefCount( WINE_MODREF *wm )
{
int i;
if ( wm->flags & WINE_MODREF_MARKER )
return;
if ( wm->refCount <= 0 )
return;
--wm->refCount;
TRACE("(%s) refCount: %d\n", wm->modname, wm->refCount );
if ( wm->refCount == 0 )
{
wm->flags |= WINE_MODREF_MARKER;
for ( i = 0; i < wm->nDeps; i++ )
if ( wm->deps[i] )
MODULE_DecRefCount( wm->deps[i] );
wm->flags &= ~WINE_MODREF_MARKER;
}
}
/***********************************************************************
* MODULE_FreeLibrary
*
* NOTE: Assumes that the process critical section is held!
*/
WIN_BOOL MODULE_FreeLibrary( WINE_MODREF *wm )
{
TRACE("(%s) - START\n", wm->modname );
/* Recursively decrement reference counts */
//MODULE_DecRefCount( wm );
/* Call process detach notifications */
MODULE_DllProcessDetach( wm, FALSE, NULL );
PE_UnloadLibrary(wm);
TRACE("END\n");
return TRUE;
}
/***********************************************************************
* GetProcAddress (KERNEL32.257)
*/
FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function )
{
return MODULE_GetProcAddress( hModule, function, TRUE );
}
/***********************************************************************
* MODULE_GetProcAddress (internal)
*/
FARPROC MODULE_GetProcAddress(
HMODULE hModule, /* [in] current module handle */
LPCSTR function, /* [in] function to be looked up */
WIN_BOOL snoop )
{
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
// WINE_MODREF *wm=local_wm;
FARPROC retproc;
if (HIWORD(function))
TRACE_(win32)("(%08lx,%s)\n",(DWORD)hModule,function);
else
TRACE_(win32)("(%08lx,%p)\n",(DWORD)hModule,function);
if (!wm) {
SetLastError(ERROR_INVALID_HANDLE);
return (FARPROC)0;
}
switch (wm->type)
{
case MODULE32_PE:
retproc = PE_FindExportedFunction( wm, function, snoop );
if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND);
return retproc;
case MODULE32_ELF:
retproc = dlsym( wm->module, function);
if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND);
return retproc;
default:
ERR("wine_modref type %d not handled.\n",wm->type);
SetLastError(ERROR_INVALID_HANDLE);
return (FARPROC)0;
}
}

964
libs/winloader/pe_image.c Normal file
View file

@ -0,0 +1,964 @@
/*
* Copyright 1994 Eric Youndale & Erik Bos
* Copyright 1995 Martin von Löwis
* Copyright 1996-98 Marcus Meissner
*
* based on Eric Youndale's pe-test and:
*
* ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP
* make that:
* ftp.microsoft.com:/developr/MSDN/OctCD/PEFILE.ZIP
*/
/* Notes:
* Before you start changing something in this file be aware of the following:
*
* - There are several functions called recursively. In a very subtle and
* obscure way. DLLs can reference each other recursively etc.
* - If you want to enhance, speed up or clean up something in here, think
* twice WHY it is implemented in that strange way. There is usually a reason.
* Though sometimes it might just be lazyness ;)
* - In PE_MapImage, right before fixup_imports() all external and internal
* state MUST be correct since this function can be called with the SAME image
* AGAIN. (Thats recursion for you.) That means MODREF.module and
* NE_MODULE.module32.
* - Sometimes, we can't use Linux mmap() to mmap() the images directly.
*
* The problem is, that there is not direct 1:1 mapping from a diskimage and
* a memoryimage. The headers at the start are mapped linear, but the sections
* are not. Older x86 pe binaries are 512 byte aligned in file and 4096 byte
* aligned in memory. Linux likes them 4096 byte aligned in memory (due to
* x86 pagesize, this cannot be fixed without a rather large kernel rewrite)
* and 'blocksize' file-aligned (offsets). Since we have 512/1024/2048 (CDROM)
* and other byte blocksizes, we can't always do this. We *can* do this for
* newer pe binaries produced by MSVC 5 and later, since they are also aligned
* to 4096 byte boundaries on disk.
*/
#include <wine/config.h>
#include <errno.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <wine/windef.h>
#include <wine/winbase.h>
#include <wine/winerror.h>
#include <wine/heap.h>
#include <wine/pe_image.h>
#include <wine/module.h>
#include <wine/debugtools.h>
#include "externals.h"
#define RVA(x) ((void *)((char *)load_addr+(unsigned int)(x)))
#define AdjustPtr(ptr,delta) ((char *)(ptr) + (delta))
extern void* LookupExternal(const char* library, int ordinal);
extern void* LookupExternalByName(const char* library, const char* name);
void dump_exports( HMODULE hModule )
{
char *Module;
int i, j;
u_short *ordinal;
u_long *function,*functions;
u_char **name;
unsigned int load_addr = hModule;
DWORD rva_start = PE_HEADER(hModule)->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
DWORD rva_end = rva_start + PE_HEADER(hModule)->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
IMAGE_EXPORT_DIRECTORY *pe_exports = (IMAGE_EXPORT_DIRECTORY*)RVA(rva_start);
Module = (char*)RVA(pe_exports->Name);
TRACE("*******EXPORT DATA*******\n");
TRACE("Module name is %s, %ld functions, %ld names\n",
Module, pe_exports->NumberOfFunctions, pe_exports->NumberOfNames);
ordinal=(u_short*) RVA(pe_exports->AddressOfNameOrdinals);
functions=function=(u_long*) RVA(pe_exports->AddressOfFunctions);
name=(u_char**) RVA(pe_exports->AddressOfNames);
TRACE(" Ord RVA Addr Name\n" );
for (i=0;i<pe_exports->NumberOfFunctions;i++, function++)
{
if (!*function) continue;
if (TRACE_ON(win32))
{
DPRINTF( "%4ld %08lx %p", i + pe_exports->Base, *function, RVA(*function) );
for (j = 0; j < pe_exports->NumberOfNames; j++)
if (ordinal[j] == i)
{
DPRINTF( " %s", (char*)RVA(name[j]) );
break;
}
if ((*function >= rva_start) && (*function <= rva_end))
DPRINTF(" (forwarded -> %s)", (char *)RVA(*function));
DPRINTF("\n");
}
}
}
/* Look up the specified function or ordinal in the exportlist:
* If it is a string:
* - look up the name in the Name list.
* - look up the ordinal with that index.
* - use the ordinal as offset into the functionlist
* If it is a ordinal:
* - use ordinal-pe_export->Base as offset into the functionlist
*/
FARPROC PE_FindExportedFunction(
WINE_MODREF *wm,
LPCSTR funcName,
WIN_BOOL snoop )
{
u_short * ordinals;
u_long * function;
u_char ** name, *ename = NULL;
int i, ordinal;
PE_MODREF *pem = &(wm->binfmt.pe);
IMAGE_EXPORT_DIRECTORY *exports = pem->pe_export;
unsigned int load_addr = wm->module;
u_long rva_start, rva_end, addr;
char * forward;
if (HIWORD(funcName))
TRACE("(%s)\n",funcName);
else
TRACE("(%d)\n",(int)funcName);
if (!exports) {
/* Not a fatal problem, some apps do
* GetProcAddress(0,"RegisterPenApp") which triggers this
* case.
*/
WARN("Module %08x(%s)/MODREF %p doesn't have a exports table.\n",wm->module,wm->modname,pem);
return NULL;
}
ordinals= (u_short*) RVA(exports->AddressOfNameOrdinals);
function= (u_long*) RVA(exports->AddressOfFunctions);
name = (u_char **) RVA(exports->AddressOfNames);
forward = NULL;
rva_start = PE_HEADER(wm->module)->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
rva_end = rva_start + PE_HEADER(wm->module)->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
if (HIWORD(funcName))
{
int min = 0, max = exports->NumberOfNames - 1;
while (min <= max)
{
int res, pos = (min + max) / 2;
ename = RVA(name[pos]);
if (!(res = strcmp( ename, funcName )))
{
ordinal = ordinals[pos];
goto found;
}
if (res > 0) max = pos - 1;
else min = pos + 1;
}
for (i = 0; i < exports->NumberOfNames; i++)
{
ename = RVA(name[i]);
if (!strcmp( ename, funcName ))
{
ERR( "%s.%s required a linear search\n", wm->modname, funcName );
ordinal = ordinals[i];
goto found;
}
}
return NULL;
}
else
{
ordinal = LOWORD(funcName) - exports->Base;
if (snoop && name)
{
for (i = 0; i < exports->NumberOfNames; i++)
if (ordinals[i] == ordinal)
{
ename = RVA(name[i]);
break;
}
}
}
found:
if (ordinal >= exports->NumberOfFunctions)
{
TRACE(" ordinal %ld out of range!\n", ordinal + exports->Base );
return NULL;
}
addr = function[ordinal];
if (!addr) return NULL;
if ((addr < rva_start) || (addr >= rva_end))
{
FARPROC proc = RVA(addr);
if (snoop)
{
if (!ename) ename = "@";
// proc = SNOOP_GetProcAddress(wm->module,ename,ordinal,proc);
TRACE("SNOOP_GetProcAddress n/a\n");
}
return proc;
}
else
{
WINE_MODREF *wm;
char *forward = RVA(addr);
char module[256];
char *end = strchr(forward, '.');
if (!end) return NULL;
if (end - forward >= sizeof(module)) return NULL;
memcpy( module, forward, end - forward );
module[end-forward] = 0;
if (!(wm = MODULE_FindModule( module )))
{
ERR("module not found for forward '%s'\n", forward );
return NULL;
}
return MODULE_GetProcAddress( wm->module, end + 1, snoop );
}
}
DWORD fixup_imports( WINE_MODREF *wm )
{
IMAGE_IMPORT_DESCRIPTOR *pe_imp;
PE_MODREF *pem;
unsigned int load_addr = wm->module;
int i,characteristics_detection=1;
char *modname;
assert(wm->type==MODULE32_PE);
pem = &(wm->binfmt.pe);
if (pem->pe_export)
modname = (char*) RVA(pem->pe_export->Name);
else
modname = "<unknown>";
TRACE("Dumping imports list\n");
pe_imp = pem->pe_import;
if (!pe_imp) return 0;
/* We assume that we have at least one import with !0 characteristics and
* detect broken imports with all characteristsics 0 (notably Borland) and
* switch the detection off for them.
*/
for (i = 0; pe_imp->Name ; pe_imp++) {
if (!i && !pe_imp->u.Characteristics)
characteristics_detection = 0;
if (characteristics_detection && !pe_imp->u.Characteristics)
break;
i++;
}
if (!i) return 0;
wm->nDeps = i;
wm->deps = HeapAlloc( GetProcessHeap(), 0, i*sizeof(WINE_MODREF *) );
/* load the imported modules. They are automatically
* added to the modref list of the process.
*/
for (i = 0, pe_imp = pem->pe_import; pe_imp->Name ; pe_imp++) {
WINE_MODREF *wmImp;
IMAGE_IMPORT_BY_NAME *pe_name;
PIMAGE_THUNK_DATA import_list,thunk_list;
char *name = (char *) RVA(pe_imp->Name);
if (characteristics_detection && !pe_imp->u.Characteristics)
break;
//#warning FIXME: here we should fill imports
printf("Loading imports for %s\n", name);
if (pe_imp->u.OriginalFirstThunk != 0) {
TRACE("Microsoft style imports used\n");
import_list =(PIMAGE_THUNK_DATA) RVA(pe_imp->u.OriginalFirstThunk);
thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk);
while (import_list->u1.Ordinal) {
if (IMAGE_SNAP_BY_ORDINAL(import_list->u1.Ordinal)) {
int ordinal = IMAGE_ORDINAL(import_list->u1.Ordinal);
// TRACE("--- Ordinal %s,%d\n", name, ordinal);
thunk_list->u1.Function=LookupExternal(
name, ordinal);
} else {
pe_name = (PIMAGE_IMPORT_BY_NAME)RVA(import_list->u1.AddressOfData);
// TRACE("--- %s %s.%d\n", pe_name->Name, name, pe_name->Hint);
thunk_list->u1.Function=LookupExternalByName(
name, pe_name->Name);
}
import_list++;
thunk_list++;
}
} else {
TRACE("Borland style imports used\n");
thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk);
while (thunk_list->u1.Ordinal) {
if (IMAGE_SNAP_BY_ORDINAL(thunk_list->u1.Ordinal)) {
int ordinal = IMAGE_ORDINAL(thunk_list->u1.Ordinal);
TRACE("--- Ordinal %s.%d\n",name,ordinal);
thunk_list->u1.Function=LookupExternal(
name, ordinal);
} else {
pe_name=(PIMAGE_IMPORT_BY_NAME) RVA(thunk_list->u1.AddressOfData);
TRACE("--- %s %s.%d\n",
pe_name->Name,name,pe_name->Hint);
thunk_list->u1.Function=LookupExternalByName(
name, pe_name->Name);
}
thunk_list++;
}
}
}
return 0;
}
static int calc_vma_size( HMODULE hModule )
{
int i,vma_size = 0;
IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(hModule);
TRACE("Dump of segment table\n");
TRACE(" Name VSz Vaddr SzRaw Fileadr *Reloc *Lineum #Reloc #Linum Char\n");
for (i = 0; i< PE_HEADER(hModule)->FileHeader.NumberOfSections; i++)
{
TRACE("%8s: %4.4lx %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx %4.4x %4.4x %8.8lx\n",
pe_seg->Name,
pe_seg->Misc.VirtualSize,
pe_seg->VirtualAddress,
pe_seg->SizeOfRawData,
pe_seg->PointerToRawData,
pe_seg->PointerToRelocations,
pe_seg->PointerToLinenumbers,
pe_seg->NumberOfRelocations,
pe_seg->NumberOfLinenumbers,
pe_seg->Characteristics);
vma_size=max(vma_size, pe_seg->VirtualAddress+pe_seg->SizeOfRawData);
vma_size=max(vma_size, pe_seg->VirtualAddress+pe_seg->Misc.VirtualSize);
pe_seg++;
}
return vma_size;
}
static void do_relocations( unsigned int load_addr, IMAGE_BASE_RELOCATION *r )
{
int delta = load_addr - PE_HEADER(load_addr)->OptionalHeader.ImageBase;
int hdelta = (delta >> 16) & 0xFFFF;
int ldelta = delta & 0xFFFF;
if(delta == 0)
return;
while(r->VirtualAddress)
{
char *page = (char*) RVA(r->VirtualAddress);
int count = (r->SizeOfBlock - 8)/2;
int i;
TRACE_(fixup)("%x relocations for page %lx\n",
count, r->VirtualAddress);
for(i=0;i<count;i++)
{
int offset = r->TypeOffset[i] & 0xFFF;
int type = r->TypeOffset[i] >> 12;
TRACE_(fixup)("patching %x type %x\n", offset, type);
switch(type)
{
case IMAGE_REL_BASED_ABSOLUTE: break;
case IMAGE_REL_BASED_HIGH:
*(short*)(page+offset) += hdelta;
break;
case IMAGE_REL_BASED_LOW:
*(short*)(page+offset) += ldelta;
break;
case IMAGE_REL_BASED_HIGHLOW:
*(int*)(page+offset) += delta;
break;
case IMAGE_REL_BASED_HIGHADJ:
FIXME("Don't know what to do with IMAGE_REL_BASED_HIGHADJ\n");
break;
case IMAGE_REL_BASED_MIPS_JMPADDR:
FIXME("Is this a MIPS machine ???\n");
break;
default:
FIXME("Unknown fixup type\n");
break;
}
}
r = (IMAGE_BASE_RELOCATION*)((char*)r + r->SizeOfBlock);
}
}
/**********************************************************************
* PE_LoadImage
* Load one PE format DLL/EXE into memory
*
* Unluckily we can't just mmap the sections where we want them, for
* (at least) Linux does only support offsets which are page-aligned.
*
* BUT we have to map the whole image anyway, for Win32 programs sometimes
* want to access them. (HMODULE32 point to the start of it)
*/
HMODULE PE_LoadImage( int handle, LPCSTR filename, WORD *version )
{
HMODULE hModule;
HANDLE mapping;
IMAGE_NT_HEADERS *nt;
IMAGE_SECTION_HEADER *pe_sec;
IMAGE_DATA_DIRECTORY *dir;
BY_HANDLE_FILE_INFORMATION bhfi;
int i, rawsize, lowest_va, vma_size, file_size = 0;
DWORD load_addr = 0, aoep, reloc = 0;
// struct get_read_fd_request *req = get_req_buffer();
int unix_handle = handle;
int page_size = getpagesize();
// if ( GetFileInformationByHandle( hFile, &bhfi ) )
// file_size = bhfi.nFileSizeLow;
file_size=lseek(handle, 0, SEEK_END);
lseek(handle, 0, SEEK_SET);
//#warning fix CreateFileMappingA
mapping = CreateFileMappingA( handle, NULL, PAGE_READONLY | SEC_COMMIT,
0, 0, NULL );
if (!mapping)
{
WARN("CreateFileMapping error %ld\n", GetLastError() );
return 0;
}
// hModule = (HMODULE)MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
hModule=(HMODULE)mapping;
// CloseHandle( mapping );
if (!hModule)
{
WARN("MapViewOfFile error %ld\n", GetLastError() );
return 0;
}
if ( *(WORD*)hModule !=IMAGE_DOS_SIGNATURE)
{
WARN("%s image doesn't have DOS signature, but 0x%04x\n", filename,*(WORD*)hModule);
goto error;
}
nt = PE_HEADER( hModule );
if ( nt->Signature != IMAGE_NT_SIGNATURE )
{
WARN("%s image doesn't have PE signature, but 0x%08lx\n", filename, nt->Signature );
goto error;
}
if ( nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 )
{
MESSAGE("Trying to load PE image for unsupported architecture (");
switch (nt->FileHeader.Machine)
{
case IMAGE_FILE_MACHINE_UNKNOWN: MESSAGE("Unknown"); break;
case IMAGE_FILE_MACHINE_I860: MESSAGE("I860"); break;
case IMAGE_FILE_MACHINE_R3000: MESSAGE("R3000"); break;
case IMAGE_FILE_MACHINE_R4000: MESSAGE("R4000"); break;
case IMAGE_FILE_MACHINE_R10000: MESSAGE("R10000"); break;
case IMAGE_FILE_MACHINE_ALPHA: MESSAGE("Alpha"); break;
case IMAGE_FILE_MACHINE_POWERPC: MESSAGE("PowerPC"); break;
default: MESSAGE("Unknown-%04x", nt->FileHeader.Machine); break;
}
MESSAGE(")\n");
goto error;
}
pe_sec = PE_SECTIONS( hModule );
rawsize = 0; lowest_va = 0x10000;
for (i = 0; i < nt->FileHeader.NumberOfSections; i++)
{
if (lowest_va > pe_sec[i].VirtualAddress)
lowest_va = pe_sec[i].VirtualAddress;
if (pe_sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
continue;
if (pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData > rawsize)
rawsize = pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData;
}
if ( file_size && file_size < rawsize )
{
ERR("PE module is too small (header: %d, filesize: %d), "
"probably truncated download?\n",
rawsize, file_size );
goto error;
}
aoep = nt->OptionalHeader.AddressOfEntryPoint;
if (aoep && (aoep < lowest_va))
FIXME("VIRUS WARNING: '%s' has an invalid entrypoint (0x%08lx) "
"below the first virtual address (0x%08x) "
"(possibly infected by Tchernobyl/SpaceFiller virus)!\n",
filename, aoep, lowest_va );
/* FIXME: Hack! While we don't really support shared sections yet,
* this checks for those special cases where the whole DLL
* consists only of shared sections and is mapped into the
* shared address space > 2GB. In this case, we assume that
* the module got mapped at its base address. Thus we simply
* check whether the module has actually been mapped there
* and use it, if so. This is needed to get Win95 USER32.DLL
* to work (until we support shared sections properly).
*/
if ( nt->OptionalHeader.ImageBase & 0x80000000 )
{
HMODULE sharedMod = (HMODULE)nt->OptionalHeader.ImageBase;
IMAGE_NT_HEADERS *sharedNt = (PIMAGE_NT_HEADERS)
( (LPBYTE)sharedMod + ((LPBYTE)nt - (LPBYTE)hModule) );
/* Well, this check is not really comprehensive,
but should be good enough for now ... */
if ( !IsBadReadPtr( (LPBYTE)sharedMod, sizeof(IMAGE_DOS_HEADER) )
&& memcmp( (LPBYTE)sharedMod, (LPBYTE)hModule, sizeof(IMAGE_DOS_HEADER) ) == 0
&& !IsBadReadPtr( sharedNt, sizeof(IMAGE_NT_HEADERS) )
&& memcmp( sharedNt, nt, sizeof(IMAGE_NT_HEADERS) ) == 0 )
{
UnmapViewOfFile( (LPVOID)hModule );
return sharedMod;
}
}
load_addr = nt->OptionalHeader.ImageBase;
vma_size = calc_vma_size( hModule );
load_addr = (DWORD)VirtualAlloc( (void*)load_addr, vma_size,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
if (load_addr == 0)
{
FIXME("We need to perform base relocations for %s\n", filename);
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BASERELOC;
if (dir->Size)
reloc = dir->VirtualAddress;
else
{
FIXME( "FATAL: Need to relocate %s, but no relocation records present (%s). Try to run that file directly !\n",
filename,
(nt->FileHeader.Characteristics&IMAGE_FILE_RELOCS_STRIPPED)?
"stripped during link" : "unknown reason" );
goto error;
}
/* FIXME: If we need to relocate a system DLL (base > 2GB) we should
* really make sure that the *new* base address is also > 2GB.
* Some DLLs really check the MSB of the module handle :-/
*/
if ( nt->OptionalHeader.ImageBase & 0x80000000 )
ERR( "Forced to relocate system DLL (base > 2GB). This is not good.\n" );
load_addr = (DWORD)VirtualAlloc( NULL, vma_size,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
if (!load_addr) {
FIXME_(win32)(
"FATAL: Couldn't load module %s (out of memory, %d needed)!\n", filename, vma_size);
goto error;
}
}
TRACE("Load addr is %lx (base %lx), range %x\n",
load_addr, nt->OptionalHeader.ImageBase, vma_size );
TRACE_(segment)("Loading %s at %lx, range %x\n",
filename, load_addr, vma_size );
#if 0
*(PIMAGE_DOS_HEADER)load_addr = *(PIMAGE_DOS_HEADER)hModule;
*PE_HEADER( load_addr ) = *nt;
memcpy( PE_SECTIONS(load_addr), PE_SECTIONS(hModule),
sizeof(IMAGE_SECTION_HEADER) * nt->FileHeader.NumberOfSections );
memcpy( load_addr, hModule, lowest_fa );
#endif
if ((void*)FILE_dommap( handle, (void *)load_addr, 0, nt->OptionalHeader.SizeOfHeaders,
0, 0, PROT_EXEC | PROT_WRITE | PROT_READ,
MAP_PRIVATE | MAP_FIXED ) != (void*)load_addr)
{
ERR_(win32)( "Critical Error: failed to map PE header to necessary address.\n");
goto error;
}
pe_sec = PE_SECTIONS( hModule );
for (i = 0; i < nt->FileHeader.NumberOfSections; i++, pe_sec++)
{
if (!pe_sec->SizeOfRawData || !pe_sec->PointerToRawData) continue;
TRACE("%s: mmaping section %s at %p off %lx size %lx/%lx\n",
filename, pe_sec->Name, (void*)RVA(pe_sec->VirtualAddress),
pe_sec->PointerToRawData, pe_sec->SizeOfRawData, pe_sec->Misc.VirtualSize );
if ((void*)FILE_dommap( unix_handle, (void*)RVA(pe_sec->VirtualAddress),
0, pe_sec->SizeOfRawData, 0, pe_sec->PointerToRawData,
PROT_EXEC | PROT_WRITE | PROT_READ,
MAP_PRIVATE | MAP_FIXED ) != (void*)RVA(pe_sec->VirtualAddress))
{
ERR_(win32)( "Critical Error: failed to map PE section to necessary address.\n");
goto error;
}
if ((pe_sec->SizeOfRawData < pe_sec->Misc.VirtualSize) &&
(pe_sec->SizeOfRawData & (page_size-1)))
{
DWORD end = (pe_sec->SizeOfRawData & ~(page_size-1)) + page_size;
if (end > pe_sec->Misc.VirtualSize) end = pe_sec->Misc.VirtualSize;
TRACE("clearing %p - %p\n",
RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData,
RVA(pe_sec->VirtualAddress) + end );
memset( (char*)RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, 0,
end - pe_sec->SizeOfRawData );
}
}
if ( reloc )
do_relocations( load_addr, (IMAGE_BASE_RELOCATION *)RVA(reloc) );
*version = ( (nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 )
| (nt->OptionalHeader.MinorSubsystemVersion & 0xff);
UnmapViewOfFile( (LPVOID)hModule );
return (HMODULE)load_addr;
error:
if (unix_handle != -1) close( unix_handle );
if (load_addr) VirtualFree( (LPVOID)load_addr, 0, MEM_RELEASE );
UnmapViewOfFile( (LPVOID)hModule );
return 0;
}
/**********************************************************************
* PE_CreateModule
*
* Create WINE_MODREF structure for loaded HMODULE32, link it into
* process modref_list, and fixup all imports.
*
* Note: hModule must point to a correctly allocated PE image,
* with base relocations applied; the 16-bit dummy module
* associated to hModule must already exist.
*
* Note: This routine must always be called in the context of the
* process that is to own the module to be created.
*/
WINE_MODREF *PE_CreateModule( HMODULE hModule,
LPCSTR filename, DWORD flags, WIN_BOOL builtin )
{
DWORD load_addr = (DWORD)hModule;
IMAGE_NT_HEADERS *nt = PE_HEADER(hModule);
IMAGE_DATA_DIRECTORY *dir;
IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL;
IMAGE_EXPORT_DIRECTORY *pe_export = NULL;
IMAGE_RESOURCE_DIRECTORY *pe_resource = NULL;
WINE_MODREF *wm;
int result;
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT;
if (dir->Size)
pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress);
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT;
if (dir->Size)
pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(dir->VirtualAddress);
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE;
if (dir->Size)
pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(dir->VirtualAddress);
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXCEPTION;
if (dir->Size) FIXME("Exception directory ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_SECURITY;
if (dir->Size) FIXME("Security directory ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DEBUG;
if (dir->Size) TRACE("Debug directory ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COPYRIGHT;
if (dir->Size) FIXME("Copyright string ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_GLOBALPTR;
if (dir->Size) FIXME("Global Pointer (MIPS) ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG;
if (dir->Size) FIXME("Load Configuration directory ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT;
if (dir->Size) TRACE("Bound Import directory ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IAT;
if (dir->Size) TRACE("Import Address Table directory ignored\n" );
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT;
if (dir->Size)
{
TRACE("Delayed import, stub calls LoadLibrary\n" );
/*
* Nothing to do here.
*/
#ifdef ImgDelayDescr
/*
* This code is useful to observe what the heck is going on.
*/
{
ImgDelayDescr *pe_delay = NULL;
pe_delay = (PImgDelayDescr)RVA(dir->VirtualAddress);
TRACE_(delayhlp)("pe_delay->grAttrs = %08x\n", pe_delay->grAttrs);
TRACE_(delayhlp)("pe_delay->szName = %s\n", pe_delay->szName);
TRACE_(delayhlp)("pe_delay->phmod = %08x\n", pe_delay->phmod);
TRACE_(delayhlp)("pe_delay->pIAT = %08x\n", pe_delay->pIAT);
TRACE_(delayhlp)("pe_delay->pINT = %08x\n", pe_delay->pINT);
TRACE_(delayhlp)("pe_delay->pBoundIAT = %08x\n", pe_delay->pBoundIAT);
TRACE_(delayhlp)("pe_delay->pUnloadIAT = %08x\n", pe_delay->pUnloadIAT);
TRACE_(delayhlp)("pe_delay->dwTimeStamp = %08x\n", pe_delay->dwTimeStamp);
}
#endif
}
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR;
if (dir->Size) FIXME("Unknown directory 14 ignored\n" );
dir = nt->OptionalHeader.DataDirectory+15;
if (dir->Size) FIXME("Unknown directory 15 ignored\n" );
wm = (WINE_MODREF *)HeapAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(*wm) );
wm->module = hModule;
if ( builtin )
wm->flags |= WINE_MODREF_INTERNAL;
if ( flags & DONT_RESOLVE_DLL_REFERENCES )
wm->flags |= WINE_MODREF_DONT_RESOLVE_REFS;
if ( flags & LOAD_LIBRARY_AS_DATAFILE )
wm->flags |= WINE_MODREF_LOAD_AS_DATAFILE;
wm->type = MODULE32_PE;
wm->binfmt.pe.pe_export = pe_export;
wm->binfmt.pe.pe_import = pe_import;
wm->binfmt.pe.pe_resource = pe_resource;
wm->binfmt.pe.tlsindex = -1;
wm->filename = strdup( filename );
wm->modname = strrchr( wm->filename, '\\' );
if (!wm->modname) wm->modname = wm->filename;
else wm->modname++;
// result = GetShortPathNameA( wm->filename, NULL, 0 );
// wm->short_filename = (char *)HeapAlloc( GetProcessHeap(), 0, result+1 );
// GetShortPathNameA( wm->filename, wm->short_filename, result+1 );
// wm->short_modname = strrchr( wm->short_filename, '\\' );
// if (!wm->short_modname) wm->short_modname = wm->short_filename;
// else wm->short_modname++;
// return NULL;
// }
if ( pe_export )
dump_exports( hModule );
/* Fixup Imports */
if ( pe_import
&& !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE )
&& !( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS )
&& fixup_imports( wm ) )
{
/* remove entry from modref chain */
return NULL;
}
return wm;
return wm;
}
/******************************************************************************
* The PE Library Loader frontend.
* FIXME: handle the flags.
*/
WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags)
{
// struct load_dll_request *req = get_req_buffer();
HMODULE hModule32;
WINE_MODREF *wm;
char filename[256];
// HANDLE hFile;
int hFile;
WORD version = 0;
// if ( SearchPathA( NULL, name, ".DLL",
// sizeof(filename), filename, NULL ) == 0 ) return NULL;
strncpy(filename, name, sizeof(filename));
// hFile = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ,
// NULL, OPEN_EXISTING, 0, -1 );
hFile=open(filename, O_RDONLY);
// if ( hFile == INVALID_HANDLE_VALUE ) return NULL;
if(hFile==-1)
return NULL;
hModule32 = PE_LoadImage( hFile, filename, &version );
if (!hModule32)
{
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
// Create 16-bit dummy module
/*
if ((hModule16 = MODULE_CreateDummyModule( filename, hModule32 )) < 32)
{
CloseHandle( hFile );
SetLastError( (DWORD)hModule16 ); // This should give the correct error
return NULL;
}
*/
if ( !(wm = PE_CreateModule( hModule32, filename, flags, FALSE )) )
{
ERR( "can't load %s\n", filename );
// FreeLibrary16( hModule16 );
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
/*
if (wm->binfmt.pe.pe_export)
SNOOP_RegisterDLL(wm->module,wm->modname,wm->binfmt.pe.pe_export->NumberOfFunctions);
req->handle = hFile;
req->base = (void *)hModule32;
req->dbg_offset = 0;
req->dbg_size = 0;
req->name = &wm->modname;
server_call_noerr( REQ_LOAD_DLL );
*/
close(hFile);
return wm;
}
/*****************************************************************************
* PE_UnloadLibrary
*
* Unload the library unmapping the image and freeing the modref structure.
*/
void PE_UnloadLibrary(WINE_MODREF *wm)
{
TRACE(" unloading %s\n", wm->filename);
HeapFree( GetProcessHeap(), 0, wm->filename );
HeapFree( GetProcessHeap(), 0, wm->short_filename );
HeapFree( GetProcessHeap(), 0, wm );
}
/*****************************************************************************
* Load the PE main .EXE. All other loading is done by PE_LoadLibraryExA
* FIXME: this function should use PE_LoadLibraryExA, but currently can't
* due to the PROCESS_Create stuff.
*/
/* Called if the library is loaded or freed.
* NOTE: if a thread attaches a DLL, the current thread will only do
* DLL_PROCESS_ATTACH. Only new created threads do DLL_THREAD_ATTACH
* (SDK)
*/
WIN_BOOL PE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
{
WIN_BOOL retv = TRUE;
assert( wm->type == MODULE32_PE );
if ((PE_HEADER(wm->module)->FileHeader.Characteristics & IMAGE_FILE_DLL) &&
(PE_HEADER(wm->module)->OptionalHeader.AddressOfEntryPoint)
) {
DLLENTRYPROC entry ;
entry = (void*)PE_FindExportedFunction(wm, "DllMain", 0);
if(entry==NULL)
entry = (void*)RVA_PTR( wm->module,OptionalHeader.AddressOfEntryPoint );
TRACE_(relay)("CallTo32(entryproc=%p,module=%08x,type=%ld,res=%p)\n",
entry, wm->module, type, lpReserved );
printf("Entering DllMain()\n");
retv = entry( wm->module, type, lpReserved );
}
return retv;
}
/************************************************************************
* PE_InitTls (internal)
*
* If included, initialises the thread local storages of modules.
* Pointers in those structs are not RVAs but real pointers which have been
* relocated by do_relocations() already.
*/
static LPVOID
_fixup_address(PIMAGE_OPTIONAL_HEADER opt,int delta,LPVOID addr) {
if ( ((DWORD)addr>opt->ImageBase) &&
((DWORD)addr<opt->ImageBase+opt->SizeOfImage)
)
return (LPVOID)(((DWORD)addr)+delta);
else
return addr;
}

View file

@ -0,0 +1,390 @@
/*
* PE (Portable Execute) File Resources
*
* Copyright 1995 Thomas Sandford
* Copyright 1996 Martin von Loewis
*
* Based on the Win16 resource handling code in loader/resource.c
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Alexandre Julliard
* Copyright 1997 Marcus Meissner
*/
#include <stdlib.h>
#include <sys/types.h>
#include <wine/winestring.h>
#include <wine/windef.h>
#include <wine/pe_image.h>
#include <wine/module.h>
#include <wine/heap.h>
//#include "task.h"
//#include "process.h"
//#include "stackframe.h"
#include <wine/debugtools.h>
/**********************************************************************
* HMODULE32toPE_MODREF
*
* small helper function to get a PE_MODREF from a passed HMODULE32
*/
static PE_MODREF*
HMODULE32toPE_MODREF(HMODULE hmod) {
WINE_MODREF *wm;
wm = MODULE32_LookupHMODULE( hmod );
if (!wm || wm->type!=MODULE32_PE)
return NULL;
return &(wm->binfmt.pe);
}
/**********************************************************************
* GetResDirEntryW
*
* Helper function - goes down one level of PE resource tree
*
*/
PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
LPCWSTR name,DWORD root,
WIN_BOOL allowdefault)
{
int entrynum;
PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
int namelen;
if (HIWORD(name)) {
if (name[0]=='#') {
char buf[10];
lstrcpynWtoA(buf,name+1,10);
return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
}
entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
(BYTE *) resdirptr +
sizeof(IMAGE_RESOURCE_DIRECTORY));
namelen = lstrlenW(name);
for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
{
PIMAGE_RESOURCE_DIR_STRING_U str =
(PIMAGE_RESOURCE_DIR_STRING_U) (root +
entryTable[entrynum].u1.s.NameOffset);
if(namelen != str->Length)
continue;
if(wcsnicmp(name,str->NameString,str->Length)==0)
return (PIMAGE_RESOURCE_DIRECTORY) (
root +
entryTable[entrynum].u2.s.OffsetToDirectory);
}
return NULL;
} else {
entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
(BYTE *) resdirptr +
sizeof(IMAGE_RESOURCE_DIRECTORY) +
resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name)
return (PIMAGE_RESOURCE_DIRECTORY) (
root +
entryTable[entrynum].u2.s.OffsetToDirectory);
/* just use first entry if no default can be found */
if (allowdefault && !name && resdirptr->NumberOfIdEntries)
return (PIMAGE_RESOURCE_DIRECTORY) (
root +
entryTable[0].u2.s.OffsetToDirectory);
return NULL;
}
}
/**********************************************************************
* GetResDirEntryA
*/
PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr,
LPCSTR name, DWORD root,
WIN_BOOL allowdefault )
{
PIMAGE_RESOURCE_DIRECTORY retv;
LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name )
: (LPWSTR)name;
retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault );
if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW );
return retv;
}
/**********************************************************************
* PE_FindResourceEx32W
*/
HANDLE PE_FindResourceExW(
WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang
) {
PIMAGE_RESOURCE_DIRECTORY resdirptr;
DWORD root;
HANDLE result;
PE_MODREF *pem = &(wm->binfmt.pe);
if (!pem || !pem->pe_resource)
return 0;
resdirptr = pem->pe_resource;
root = (DWORD) resdirptr;
if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
return 0;
if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
return 0;
result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
/* Try LANG_NEUTRAL, too */
if(!result)
return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
return result;
}
/**********************************************************************
* PE_LoadResource32
*/
HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
{
if (!hRsrc || !wm || wm->type!=MODULE32_PE)
return 0;
return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
}
/**********************************************************************
* PE_SizeofResource32
*/
DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc )
{
/* we don't need hModule */
if (!hRsrc)
return 0;
return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
}
/**********************************************************************
* PE_EnumResourceTypes32A
*/
WIN_BOOL
PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) {
PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
PIMAGE_RESOURCE_DIRECTORY resdir;
PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
WIN_BOOL ret;
HANDLE heap = GetProcessHeap();
if (!pem || !pem->pe_resource)
return FALSE;
resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
LPSTR name;
if (et[i].u1.s.NameIsString)
name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
else
name = (LPSTR)(int)et[i].u1.Id;
ret = lpfun(hmod,name,lparam);
if (HIWORD(name))
HeapFree(heap,0,name);
if (!ret)
break;
}
return ret;
}
/**********************************************************************
* PE_EnumResourceTypes32W
*/
WIN_BOOL
PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) {
PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
PIMAGE_RESOURCE_DIRECTORY resdir;
PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
WIN_BOOL ret;
if (!pem || !pem->pe_resource)
return FALSE;
resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
LPWSTR type;
if (et[i].u1.s.NameIsString)
type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
else
type = (LPWSTR)(int)et[i].u1.Id;
ret = lpfun(hmod,type,lparam);
if (!ret)
break;
}
return ret;
}
/**********************************************************************
* PE_EnumResourceNames32A
*/
WIN_BOOL
PE_EnumResourceNamesA(
HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
) {
PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
PIMAGE_RESOURCE_DIRECTORY resdir;
PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
WIN_BOOL ret;
HANDLE heap = GetProcessHeap();
LPWSTR typeW;
if (!pem || !pem->pe_resource)
return FALSE;
resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
if (HIWORD(type))
typeW = HEAP_strdupAtoW(heap,0,type);
else
typeW = (LPWSTR)type;
resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
if (HIWORD(typeW))
HeapFree(heap,0,typeW);
if (!resdir)
return FALSE;
et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
LPSTR name;
if (et[i].u1.s.NameIsString)
name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
else
name = (LPSTR)(int)et[i].u1.Id;
ret = lpfun(hmod,type,name,lparam);
if (HIWORD(name)) HeapFree(heap,0,name);
if (!ret)
break;
}
return ret;
}
/**********************************************************************
* PE_EnumResourceNames32W
*/
WIN_BOOL
PE_EnumResourceNamesW(
HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
) {
PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
PIMAGE_RESOURCE_DIRECTORY resdir;
PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
WIN_BOOL ret;
if (!pem || !pem->pe_resource)
return FALSE;
resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
if (!resdir)
return FALSE;
et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
LPWSTR name;
if (et[i].u1.s.NameIsString)
name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
else
name = (LPWSTR)(int)et[i].u1.Id;
ret = lpfun(hmod,type,name,lparam);
if (!ret)
break;
}
return ret;
}
/**********************************************************************
* PE_EnumResourceNames32A
*/
WIN_BOOL
PE_EnumResourceLanguagesA(
HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
LONG lparam
) {
PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
PIMAGE_RESOURCE_DIRECTORY resdir;
PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
WIN_BOOL ret;
HANDLE heap = GetProcessHeap();
LPWSTR nameW,typeW;
if (!pem || !pem->pe_resource)
return FALSE;
resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
if (HIWORD(name))
nameW = HEAP_strdupAtoW(heap,0,name);
else
nameW = (LPWSTR)name;
resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
if (HIWORD(nameW))
HeapFree(heap,0,nameW);
if (!resdir)
return FALSE;
if (HIWORD(type))
typeW = HEAP_strdupAtoW(heap,0,type);
else
typeW = (LPWSTR)type;
resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
if (HIWORD(typeW))
HeapFree(heap,0,typeW);
if (!resdir)
return FALSE;
et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
/* languages are just ids... I hopem */
ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
if (!ret)
break;
}
return ret;
}
/**********************************************************************
* PE_EnumResourceLanguages32W
*/
WIN_BOOL
PE_EnumResourceLanguagesW(
HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
LONG lparam
) {
PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
PIMAGE_RESOURCE_DIRECTORY resdir;
PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
WIN_BOOL ret;
if (!pem || !pem->pe_resource)
return FALSE;
resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
if (!resdir)
return FALSE;
resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
if (!resdir)
return FALSE;
et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
if (!ret)
break;
}
return ret;
}

408
libs/winloader/registry.c Normal file
View file

@ -0,0 +1,408 @@
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/param.h>
#include <wine/winbase.h>
#include <wine/winreg.h>
#include <wine/winnt.h>
#include <wine/winerror.h>
#include <registry.h>
struct reg_value
{
int type;
char* name;
int len;
char* value;
};
static int reg_size=0;
static struct reg_value* regs=0;
struct reg_handle_s;
typedef struct reg_handle_s
{
int handle;
char* name;
struct reg_handle_s* next;
struct reg_handle_s* prev;
} reg_handle_t;
static reg_handle_t* head=0;
#define DIR -25
static void create_registry();
static void open_registry();
static void save_registry();
static void create_registry()
{
if(regs)
{
printf("Logic error: create_registry() called with existing registry\n");
save_registry();
return;
}
regs=(struct reg_value*)malloc(3*sizeof(struct reg_value));
regs[0].type=regs[1].type=DIR;
regs[0].name=strdup("HKLM");
regs[1].name=strdup("HKCU");
regs[0].value=regs[1].value=NULL;
regs[0].len=regs[1].len=0;
reg_size=2;
save_registry();
}
static void open_registry()
{
int fd;
int i;
int len;
char user_conf[PATH_MAX+1];
if(regs)
{
printf("Multiple open_registry(>\n");
return;
}
snprintf(user_conf, PATH_MAX, "%s/.gstreamer/win32/registry", getenv("HOME"));
fd=open(user_conf, O_RDONLY);
if(fd==-1)
{
printf("Creating new registry\n");
create_registry();
return;
}
read(fd, &reg_size, 4);
regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value));
for(i=0; i<reg_size; i++)
{
read(fd,&regs[i].type,4);
read(fd,&len,4);
regs[i].name=(char*)malloc(len+1);
if(regs[i].name==0)
{
reg_size=i+1;
goto error;
}
read(fd, regs[i].name, len);
regs[i].name[len]=0;
read(fd,&regs[i].len,4);
regs[i].value=(char*)malloc(len);
if(regs[i].value==0)
{
free(regs[i].name);
reg_size=i+1;
goto error;
}
read(fd, regs[i].value, regs[i].len);
}
error:
close(fd);
return;
}
static void save_registry()
{
int fd, i, len, res;
char user_conf[PATH_MAX+1];
snprintf(user_conf, PATH_MAX, "%s/.gstreamer/", getenv("HOME"));
res=mkdir(user_conf, 00777);
snprintf(user_conf, PATH_MAX, "%s/.gstreamer/win32/", getenv("HOME"));
res=mkdir(user_conf, 00777);
if (res == -1 && errno != EEXIST)
{
printf("Failed to create directory %s/.gstreamer/win32.\n", getenv("HOME"));
perror("mkdir");
return;
}
snprintf(user_conf, PATH_MAX, "%s/.gstreamer/win32/registry", getenv("HOME"));
fd=open(user_conf, O_WRONLY | O_CREAT, 00777);
if(fd==-1)
{
printf("Failed to open registry file for writing.\n");
return;
}
write(fd, &reg_size, 4);
for(i=0; i<reg_size; i++)
{
write(fd, &regs[i].type, 4);
len=strlen(regs[i].name);
write(fd, &len, 4);
write(fd, regs[i].name, len);
write(fd, &regs[i].len, 4);
write(fd, regs[i].value, regs[i].len);
}
close(fd);
}
static reg_handle_t* find_handle_by_name(const char* name)
{
reg_handle_t* t;
for(t=head; t; t=t->prev)
{
if(!strcmp(t->name, name))
{
return t;
}
}
return 0;
}
static struct reg_value* find_value_by_name(const char* name)
{
int i;
for(i=0; i<reg_size; i++)
if(!strcmp(regs[i].name, name))
return regs+i;
return 0;
}
static reg_handle_t* find_handle(int handle)
{
reg_handle_t* t;
for(t=head; t; t=t->prev)
{
if(t->handle==handle)
{
return t;
}
}
return 0;
}
static int generate_handle()
{
static int zz=249;
zz++;
while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER))
zz++;
return zz;
}
static reg_handle_t* insert_handle(long handle, const char* name)
{
reg_handle_t* t;
t=(reg_handle_t*)malloc(sizeof(reg_handle_t));
if(head==0)
{
t->prev=0;
}
else
{
head->next=t;
t->prev=head;
}
t->next=0;
t->name=strdup(name);
t->handle=handle;
head=t;
return t;
}
static char* build_keyname(long key, const char* subkey)
{
char* full_name;
reg_handle_t* t;
if((t=find_handle(key))==0)
{
printf("Invalid key\n");
return NULL;
}
if(subkey==NULL)
subkey="<default>";
full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
strcpy(full_name, t->name);
strcat(full_name, "\\");
strcat(full_name, subkey);
return full_name;
}
struct reg_value* insert_reg_value(int handle, const char* name, int type, void* value, int len)
{
reg_handle_t* t;
struct reg_value* v;
char* fullname;
if((fullname=build_keyname(handle, name))==NULL)
{
printf("Invalid handle\n");
return NULL;
}
if((v=find_value_by_name(fullname))==0)
//creating new value in registry
{
if(regs==0)
create_registry();
regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1));
v=regs+reg_size;
reg_size++;
}
else
//replacing old one
{
free(v->value);
free(v->name);
}
v->type=type;
v->len=len;
v->value=(char*)malloc(len);
memcpy(v->value, value, len);
v->name=strdup(fullname);
save_registry();
return v;
}
static void init_registry()
{
printf("Initializing registry\n");
open_registry();
insert_handle(HKEY_LOCAL_MACHINE, "HKLM");
insert_handle(HKEY_CURRENT_USER, "HKCU");
}
static reg_handle_t* find_handle_2(long key, char* subkey)
{
char* full_name;
reg_handle_t* t;
if((t=find_handle(key))==0)
{
printf("Invalid key\n");
return (reg_handle_t*)-1;
}
if(subkey==NULL)
return t;
full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
strcpy(full_name, t->name);
strcat(full_name, "\\");
strcat(full_name, subkey);
t=find_handle_by_name(full_name);
free(full_name);
return t;
}
long RegOpenKeyExA(long key, char* subkey, long reserved, long access, int* newkey)
{
char* full_name;
reg_handle_t* t;
struct reg_value* v;
printf("Opening key %s\n", subkey);
if(!regs)
init_registry();
/* t=find_handle_2(key, subkey);
if(t==0)
return -1;
if(t==(reg_handle_t*)-1)
return -1;
*/
full_name=build_keyname(key, subkey);
if(!full_name)
return -1;
v=find_value_by_name(full_name);
t=insert_handle(generate_handle(), full_name);
*newkey=t->handle;
free(full_name);
return 0;
}
long RegCloseKey(long key)
{
reg_handle_t *handle;
if(key==HKEY_LOCAL_MACHINE)
return 0;
if(key==HKEY_CURRENT_USER)
return 0;
handle=find_handle(key);
if(handle==0)
return 0;
if(handle->prev)
handle->prev->next=handle->next;
if(handle->next)
handle->next->prev=handle->prev;
if(handle->name)
free(handle->name);
if(handle==head)
head=head->prev;
free(handle);
return 1;
}
long RegQueryValueExA(long key, char* value, int* reserved, int* type, int* data, int* count)
{
struct reg_value* t;
char* c;
printf("Querying value %s\n", value);
if(!regs)
init_registry();
c=build_keyname(key, value);
if(c==NULL)
return 1;
if((t=find_value_by_name(c))==0)
{
free(c);
return 2;
}
free(c);
if(type)
*type=t->type;
if(data)
memcpy(data, t->value, (t->len<*count)?t->len:*count);
if(count)
{
if(*count<t->len)
{
*count=t->len;
return ERROR_MORE_DATA;
}else return 0;
}
return 0;
}
long RegCreateKeyExA(long key, char* name, long reserved,
void* classs, long options, long security,
void* sec_attr, int* newkey, int* status)
{
reg_handle_t* t;
char* fullname;
struct reg_value* v;
printf("Creating/Opening key %s\n", name);
if(!regs)
init_registry();
fullname=build_keyname(key, name);
if(fullname==NULL)
return 1;
v=find_value_by_name(fullname);
if(v==0)
{
int qw=45708;
v=insert_reg_value(key, name, DIR, &qw, 4);
*status=REG_CREATED_NEW_KEY;
// return 0;
}
else
*status=REG_OPENED_EXISTING_KEY;
t=insert_handle(generate_handle(), fullname);
*newkey=t->handle;
free(fullname);
return 0;
}
long RegSetValueExA(long key, char* name, long v1, long v2, void* data, long size)
{
struct reg_value* t;
char* c;
printf("Request to set value %s\n", name);
if(!regs)
init_registry();
c=build_keyname(key, name);
if(c==NULL)
return 1;
insert_reg_value(key, name, v2, data, size);
free(c);
return 0;
}

475
libs/winloader/resource.c Normal file
View file

@ -0,0 +1,475 @@
/*
* Resources
*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Alexandre Julliard
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <wine/winbase.h>
#include <wine/windef.h>
#include <wine/winuser.h>
#include <wine/heap.h>
#include <wine/module.h>
#include <wine/debugtools.h>
#include <wine/winerror.h>
#define CP_ACP 0
WORD WINE_LanguageId=0x409;//english
#define HRSRC_MAP_BLOCKSIZE 16
typedef struct _HRSRC_ELEM
{
HANDLE hRsrc;
WORD type;
} HRSRC_ELEM;
typedef struct _HRSRC_MAP
{
int nAlloc;
int nUsed;
HRSRC_ELEM *elem;
} HRSRC_MAP;
static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type,
LPCSTR name, WORD lang, int unicode)
{
HRSRC hRsrc = 0;
LPWSTR typeStr, nameStr;
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
if(!wm)
return 0;
/* 32-bit PE module */
if ( HIWORD( type ) && (!unicode))
typeStr = HEAP_strdupAtoW( GetProcessHeap(), 0, type );
else
typeStr = (LPWSTR)type;
if ( HIWORD( name ) && (!unicode))
nameStr = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
else
nameStr = (LPWSTR)name;
hRsrc = PE_FindResourceExW( wm, nameStr, typeStr, lang );
if ( HIWORD( type ) && (!unicode))
HeapFree( GetProcessHeap(), 0, typeStr );
if ( HIWORD( name ) && (!unicode))
HeapFree( GetProcessHeap(), 0, nameStr );
return hRsrc;
}
/**********************************************************************
* RES_FindResource
*/
static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type,
LPCSTR name, WORD lang, int unicode )
{
HRSRC hRsrc;
// __TRY
// {
hRsrc = RES_FindResource2(hModule, type, name, lang, unicode);
// }
// __EXCEPT(page_fault)
// {
// WARN("page fault\n");
// SetLastError(ERROR_INVALID_PARAMETER);
// return 0;
// }
// __ENDTRY
return hRsrc;
}
/**********************************************************************
* RES_SizeofResource
*/
static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc)
{
DWORD size = 0;
HRSRC hRsrc32;
// HMODULE16 hMod16 = MapHModuleLS( hModule );
// NE_MODULE *pModule = NE_GetPtr( hMod16 );
// WINE_MODREF *wm = pModule && pModule->module32?
// MODULE32_LookupHMODULE( pModule->module32 ) : NULL;
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
if ( !hModule || !hRsrc ) return 0;
/* 32-bit PE module */
/* If we got a 16-bit hRsrc, convert it */
// hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
if(!HIWORD(hRsrc))
{
printf("16-bit hRsrcs not supported\n");
return 0;
}
size = PE_SizeofResource( hModule, hRsrc );
return size;
}
/**********************************************************************
* RES_AccessResource
*/
static HFILE RES_AccessResource( HMODULE hModule, HRSRC hRsrc )
{
HFILE hFile = HFILE_ERROR;
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
if ( !hModule || !hRsrc ) return HFILE_ERROR;
/* 32-bit PE module */
FIXME("32-bit modules not yet supported.\n" );
hFile = HFILE_ERROR;
return hFile;
}
/**********************************************************************
* RES_LoadResource
*/
static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc)
{
HGLOBAL hMem = 0;
HRSRC hRsrc32;
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
if ( !hModule || !hRsrc ) return 0;
/* 32-bit PE module */
/* If we got a 16-bit hRsrc, convert it */
// hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
if(!HIWORD(hRsrc))
{
printf("16-bit hRsrcs not supported\n");
return 0;
}
hMem = PE_LoadResource( wm, hRsrc );
return hMem;
}
/**********************************************************************
* RES_LockResource
*/
static LPVOID RES_LockResource( HGLOBAL handle )
{
LPVOID bits = NULL;
TRACE("(%08x, %s)\n", handle, "PE" );
bits = (LPVOID)handle;
return bits;
}
/**********************************************************************
* RES_FreeResource
*/
static WIN_BOOL RES_FreeResource( HGLOBAL handle )
{
HGLOBAL retv = handle;
return (WIN_BOOL)retv;
}
/**********************************************************************
* FindResourceA (KERNEL32.128)
*/
HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type )
{
return RES_FindResource( hModule, type, name,
WINE_LanguageId, 0);
}
HANDLE WINAPI FindResourceW( HMODULE hModule, LPCWSTR name, LPCWSTR type )
{
return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
WINE_LanguageId, 1);
}
/**********************************************************************
* FindResourceExA (KERNEL32.129)
*/
HANDLE WINAPI FindResourceExA( HMODULE hModule,
LPCSTR type, LPCSTR name, WORD lang )
{
return RES_FindResource( hModule, type, name,
lang, 0 );
}
HANDLE WINAPI FindResourceExW( HMODULE hModule,
LPCWSTR type, LPCWSTR name, WORD lang )
{
return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
lang, 1 );
}
/**********************************************************************
* LockResource (KERNEL32.384)
*/
LPVOID WINAPI LockResource( HGLOBAL handle )
{
return RES_LockResource( handle );
}
/**********************************************************************
* FreeResource (KERNEL32.145)
*/
WIN_BOOL WINAPI FreeResource( HGLOBAL handle )
{
return RES_FreeResource( handle );
}
/**********************************************************************
* AccessResource (KERNEL32.64)
*/
INT WINAPI AccessResource( HMODULE hModule, HRSRC hRsrc )
{
return RES_AccessResource( hModule, hRsrc );
}
/**********************************************************************
* SizeofResource (KERNEL32.522)
*/
DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
{
return RES_SizeofResource( hModule, hRsrc );
}
/**********************************************************************
* LoadStringA (USER32.375)
*/
INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id,
LPSTR buffer, INT buflen )
{
INT retval;
INT wbuflen;
INT abuflen;
LPWSTR wbuf = NULL;
LPSTR abuf = NULL;
if ( buffer != NULL && buflen > 0 )
*buffer = 0;
wbuflen = LoadStringW(instance,resource_id,NULL,0);
if ( !wbuflen )
return 0;
wbuflen ++;
retval = 0;
wbuf = HeapAlloc( GetProcessHeap(), 0, wbuflen * sizeof(WCHAR) );
wbuflen = LoadStringW(instance,resource_id,wbuf,wbuflen);
if ( wbuflen > 0 )
{
abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,NULL,0,NULL,NULL);
if ( abuflen > 0 )
{
if ( buffer == NULL || buflen == 0 )
retval = abuflen;
else
{
abuf = HeapAlloc( GetProcessHeap(), 0, abuflen * sizeof(CHAR) );
abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,abuf,abuflen,NULL,NULL);
if ( abuflen > 0 )
{
abuflen = min(abuflen,buflen - 1);
memcpy( buffer, abuf, abuflen );
buffer[abuflen] = 0;
retval = abuflen;
}
HeapFree( GetProcessHeap(), 0, abuf );
}
}
}
HeapFree( GetProcessHeap(), 0, wbuf );
return retval;
}
/**********************************************************************
* LoadStringW (USER32.376)
*/
INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id,
LPWSTR buffer, INT buflen )
{
HGLOBAL hmem;
HRSRC hrsrc;
WCHAR *p;
int string_num;
int i;
if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */
resource_id = (UINT)(-((INT)resource_id));
TRACE("instance = %04x, id = %04x, buffer = %08x, "
"length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
/* Use bits 4 - 19 (incremented by 1) as resourceid, mask out
* 20 - 31. */
hrsrc = FindResourceW( instance, (LPCWSTR)(((resource_id>>4)&0xffff)+1),
RT_STRINGW );
if (!hrsrc) return 0;
hmem = LoadResource( instance, hrsrc );
if (!hmem) return 0;
p = LockResource(hmem);
string_num = resource_id & 0x000f;
for (i = 0; i < string_num; i++)
p += *p + 1;
TRACE("strlen = %d\n", (int)*p );
if (buffer == NULL) return *p;
i = min(buflen - 1, *p);
if (i > 0) {
memcpy(buffer, p + 1, i * sizeof (WCHAR));
buffer[i] = (WCHAR) 0;
} else {
if (buflen > 1) {
buffer[0] = (WCHAR) 0;
return 0;
}
#if 0
WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
#endif
}
TRACE("String loaded !\n");
return i;
}
/* Messages...used by FormatMessage32* (KERNEL32.something)
*
* They can be specified either directly or using a message ID and
* loading them from the resource.
*
* The resourcedata has following format:
* start:
* 0: DWORD nrofentries
* nrofentries * subentry:
* 0: DWORD firstentry
* 4: DWORD lastentry
* 8: DWORD offset from start to the stringentries
*
* (lastentry-firstentry) * stringentry:
* 0: WORD len (0 marks end)
* 2: WORD flags
* 4: CHAR[len-4]
* (stringentry i of a subentry refers to the ID 'firstentry+i')
*
* Yes, ANSI strings in win32 resources. Go figure.
*/
/**********************************************************************
* LoadMessageA (internal)
*/
INT WINAPI LoadMessageA( HMODULE instance, UINT id, WORD lang,
LPSTR buffer, INT buflen )
{
HGLOBAL hmem;
HRSRC hrsrc;
PMESSAGE_RESOURCE_DATA mrd;
PMESSAGE_RESOURCE_BLOCK mrb;
PMESSAGE_RESOURCE_ENTRY mre;
int i,slen;
TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen);
/*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
hrsrc = FindResourceExW(instance,RT_MESSAGELISTW,(LPWSTR)1,lang);
if (!hrsrc) return 0;
hmem = LoadResource( instance, hrsrc );
if (!hmem) return 0;
mrd = (PMESSAGE_RESOURCE_DATA)LockResource(hmem);
mre = NULL;
mrb = &(mrd->Blocks[0]);
for (i=mrd->NumberOfBlocks;i--;) {
if ((id>=mrb->LowId) && (id<=mrb->HighId)) {
mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mrd)+mrb->OffsetToEntries);
id -= mrb->LowId;
break;
}
mrb++;
}
if (!mre)
return 0;
for (i=id;i--;) {
if (!mre->Length)
return 0;
mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mre)+(mre->Length));
}
slen=mre->Length;
TRACE(" - strlen=%d\n",slen);
i = min(buflen - 1, slen);
if (buffer == NULL)
return slen;
if (i>0) {
lstrcpynA(buffer,(char*)mre->Text,i);
buffer[i]=0;
} else {
if (buflen>1) {
buffer[0]=0;
return 0;
}
}
if (buffer)
TRACE("'%s' copied !\n", buffer);
return i;
}
/**********************************************************************
* EnumResourceTypesA (KERNEL32.90)
*/
WIN_BOOL WINAPI EnumResourceTypesA( HMODULE hmodule,ENUMRESTYPEPROCA lpfun,
LONG lParam)
{
/* FIXME: move WINE_MODREF stuff here */
return PE_EnumResourceTypesA(hmodule,lpfun,lParam);
}
/**********************************************************************
* EnumResourceNamesA (KERNEL32.88)
*/
WIN_BOOL WINAPI EnumResourceNamesA( HMODULE hmodule, LPCSTR type,
ENUMRESNAMEPROCA lpfun, LONG lParam )
{
/* FIXME: move WINE_MODREF stuff here */
return PE_EnumResourceNamesA(hmodule,type,lpfun,lParam);
}
/**********************************************************************
* EnumResourceLanguagesA (KERNEL32.86)
*/
WIN_BOOL WINAPI EnumResourceLanguagesA( HMODULE hmodule, LPCSTR type,
LPCSTR name, ENUMRESLANGPROCA lpfun,
LONG lParam)
{
/* FIXME: move WINE_MODREF stuff here */
return PE_EnumResourceLanguagesA(hmodule,type,name,lpfun,lParam);
}
/**********************************************************************
* LoadResource (KERNEL32.370)
*/
HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc )
{
return RES_LoadResource( hModule, hRsrc);
}

363
libs/winloader/vfl.c Normal file
View file

@ -0,0 +1,363 @@
/*
* Copyright 1998 Marcus Meissner
*/
#include <stdio.h>
#include <string.h>
#include <wine/winbase.h>
#include <wine/windef.h>
#include <wine/winuser.h>
#include <wine/vfw.h>
#include <wine/winestring.h>
#include <wine/driver.h>
#include <avifmt.h>
#define FIXME_(X) printf
#define FIXME printf
long VFWAPI VideoForWindowsVersion(void);
long VFWAPIV ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits);
WIN_BOOL VFWAPI ICInfo(long fccType, long fccHandler, ICINFO * lpicinfo);
LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo, long cb);
HIC VFWAPI ICOpen(long fccType, long fccHandler, UINT wMode);
HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode, void* lpfnHandler);
LRESULT VFWAPI ICClose(HIC hic);
LRESULT VFWAPI ICSendMessage(HIC hic, unsigned int msg, long dw1, long dw2);
HIC VFWAPI ICLocate(long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, short wFlags);
#define OpenDriverA DrvOpen
extern HDRVR VFWAPI DrvOpen(long);
typedef struct {
unsigned int uDriverSignature;
void* hDriverModule;
void* DriverProc;
long dwDriverID;
} DRVR;
/***********************************************************************
* VideoForWindowsVersion [MSVFW.2][MSVIDEO.2]
* Returns the version in major.minor form.
* In Windows95 this returns 0x040003b6 (4.950)
*/
long VideoForWindowsVersion(void) {
return 0x040003B6; /* 4.950 */
}
/* system.ini: [drivers] */
/***********************************************************************
* ICInfo [MSVFW.33]
* Get information about an installable compressor. Return TRUE if there
* is one.
*/
int VFWAPI
ICInfo(
long fccType, /* [in] type of compressor ('vidc') */
long fccHandler, /* [in] <n>th compressor */
ICINFO *lpicinfo /* [out] information about compressor */
) {
char type[5],buf[2000];
memcpy(type,&fccType,4);type[4]=0;
TRACE("(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
/* does OpenDriver/CloseDriver */
lpicinfo->dwSize = sizeof(ICINFO);
lpicinfo->fccType = fccType;
lpicinfo->dwFlags = 0;
/*
if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,2000,"system.ini")) {
char *s = buf;
while (*s) {
if (!lstrncmpiA(type,s,4)) {
if(!fccHandler--) {
lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
return TRUE;
}
}
s=s+lstrlenA(s)+1;
}
}
*/
return TRUE;
}
/***********************************************************************
* ICOpen [MSVFW.37]
* Opens an installable compressor. Return special handle.
*/
HIC VFWAPI
ICOpen(long fccType,long fccHandler,unsigned int wMode) {
char type[5],handler[5],codecname[20];
ICOPEN icopen;
HDRVR hdrv;
WINE_HIC *whic;
memcpy(type,&fccType,4);type[4]=0;
memcpy(handler,&fccHandler,4);handler[4]=0;
TRACE("(%s,%s,0x%08lx)\n",type,handler,(long)wMode);
sprintf(codecname,"%s.%s",type,handler);
/* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
* same layout as ICOPEN
*/
icopen.fccType = fccType;
icopen.fccHandler = fccHandler;
icopen.dwSize = sizeof(ICOPEN);
icopen.dwFlags = wMode;
/* FIXME: do we need to fill out the rest too? */
// hdrv=OpenDriverA(codecname,"drivers32",(long)&icopen);
hdrv=OpenDriverA((long)&icopen);
/*
if (!hdrv) {
if (!strcasecmp(type,"vids")) {
sprintf(codecname,"vidc.%s",handler);
fccType = mmioFOURCC('v','i','d','c');
}
// hdrv=OpenDriverA(codecname,"drivers32",(long)&icopen);
hdrv=OpenDriverA((long)&icopen);
*/
if (!hdrv)
return 0;
// }
whic = (WINE_HIC*)my_mreq(sizeof(WINE_HIC), 0);
whic->hdrv = hdrv;
whic->driverproc= ((DRVR*)hdrv)->DriverProc;
// whic->private = ICSendMessage((HIC)whic,DRV_OPEN,0,(long)&icopen);
whic->private = ((DRVR*)hdrv)->dwDriverID;
return (HIC)whic;
}
/***********************************************************************
* ICOpenFunction [MSVFW.38]
*/
HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode,
void* lpfnHandler) {
char type[5],handler[5];
HIC hic;
WINE_HIC *whic;
memcpy(type,&fccType,4);type[4]=0;
memcpy(handler,&fccHandler,4);handler[4]=0;
FIXME("(%s,%s,%d,%p), stub!\n",type,handler,wMode,lpfnHandler);
hic = ICOpen(fccType,fccHandler,wMode);
if (!hic)
return hic;
whic = (WINE_HIC*)hic;
whic->driverproc = lpfnHandler;
return hic;
}
/***********************************************************************
* ICGetInfo [MSVFW.30]
*/
LRESULT VFWAPI
ICGetInfo(HIC hic,ICINFO *picinfo,long cb) {
LRESULT ret;
TRACE("(0x%08lx,%p,%ld)\n",(long)hic,picinfo,cb);
ret = ICSendMessage(hic,ICM_GETINFO,(long)picinfo,cb);
TRACE(" -> 0x%08lx\n",ret);
return ret;
}
/***********************************************************************
* ICLocate [MSVFW.35]
*/
HIC VFWAPI
ICLocate(
long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn,
LPBITMAPINFOHEADER lpbiOut, short wMode
) {
char type[5],handler[5];
HIC hic;
long querymsg;
switch (wMode) {
case ICMODE_FASTCOMPRESS:
case ICMODE_COMPRESS:
querymsg = ICM_COMPRESS_QUERY;
break;
case ICMODE_DECOMPRESS:
case ICMODE_FASTDECOMPRESS:
querymsg = ICM_DECOMPRESS_QUERY;
break;
case ICMODE_DRAW:
querymsg = ICM_DRAW_QUERY;
break;
default:
FIXME("Unknown mode (%d)\n",wMode);
return 0;
}
/* Easy case: handler/type match, we just fire a query and return */
hic = ICOpen(fccType,fccHandler,wMode);
if (hic) {
if (!ICSendMessage(hic,querymsg,(long)lpbiIn,(long)lpbiOut))
return hic;
ICClose(hic);
}
type[4]='\0';memcpy(type,&fccType,4);
handler[4]='\0';memcpy(handler,&fccHandler,4);
if (fccType==streamtypeVIDEO) {
hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
if (hic)
return hic;
}
FIXME("(%s,%s,%p,%p,0x%04x),unhandled!\n",type,handler,lpbiIn,lpbiOut,wMode);
return 0;
}
/***********************************************************************
* ICCompress [MSVFW.23]
*/
long VFWAPIV
ICCompress(
HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpData,
LPBITMAPINFOHEADER lpbiInput,void* lpBits,long* lpckid,
long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality,
LPBITMAPINFOHEADER lpbiPrev,void* lpPrev
) {
ICCOMPRESS iccmp;
iccmp.dwFlags = dwFlags;
iccmp.lpbiOutput = lpbiOutput;
iccmp.lpOutput = lpData;
iccmp.lpbiInput = lpbiInput;
iccmp.lpInput = lpBits;
iccmp.lpckid = lpckid;
iccmp.lpdwFlags = lpdwFlags;
iccmp.lFrameNum = lFrameNum;
iccmp.dwFrameSize = dwFrameSize;
iccmp.dwQuality = dwQuality;
iccmp.lpbiPrev = lpbiPrev;
iccmp.lpPrev = lpPrev;
return ICSendMessage(hic,ICM_COMPRESS,(long)&iccmp,sizeof(iccmp));
}
/***********************************************************************
* ICDecompress [MSVFW.26]
*/
long VFWAPIV
ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits) {
ICDECOMPRESS icd;
icd.dwFlags = dwFlags;
icd.lpbiInput = lpbiFormat;
icd.lpInput = lpData;
icd.lpbiOutput = lpbi;
icd.lpOutput = lpBits;
icd.ckid = 0;
return ICSendMessage(hic,ICM_DECOMPRESS,(long)&icd,sizeof(icd));
}
/***********************************************************************
* ICSendMessage [MSVFW.40]
*/
LRESULT VFWAPI
ICSendMessage(HIC hic,unsigned int msg,long lParam1,long lParam2) {
LRESULT ret;
WINE_HIC *whic = (WINE_HIC*)hic;
#define XX(x) case x: TRACE("(0x%08lx,"#x",0x%08lx,0x%08lx)\n",(long)hic,lParam1,lParam2);break;
/*
switch (msg) {
XX(ICM_ABOUT)
XX(ICM_GETINFO)
XX(ICM_COMPRESS_FRAMES_INFO)
XX(ICM_COMPRESS_GET_FORMAT)
XX(ICM_COMPRESS_GET_SIZE)
XX(ICM_COMPRESS_QUERY)
XX(ICM_COMPRESS_BEGIN)
XX(ICM_COMPRESS)
XX(ICM_COMPRESS_END)
XX(ICM_DECOMPRESS_GET_FORMAT)
XX(ICM_DECOMPRESS_QUERY)
XX(ICM_DECOMPRESS_BEGIN)
XX(ICM_DECOMPRESS)
XX(ICM_DECOMPRESS_END)
XX(ICM_DECOMPRESS_SET_PALETTE)
XX(ICM_DECOMPRESS_GET_PALETTE)
XX(ICM_DRAW_QUERY)
XX(ICM_DRAW_BEGIN)
XX(ICM_DRAW_GET_PALETTE)
XX(ICM_DRAW_START)
XX(ICM_DRAW_STOP)
XX(ICM_DRAW_END)
XX(ICM_DRAW_GETTIME)
XX(ICM_DRAW)
XX(ICM_DRAW_WINDOW)
XX(ICM_DRAW_SETTIME)
XX(ICM_DRAW_REALIZE)
XX(ICM_DRAW_FLUSH)
XX(ICM_DRAW_RENDERBUFFER)
XX(ICM_DRAW_START_PLAY)
XX(ICM_DRAW_STOP_PLAY)
XX(ICM_DRAW_SUGGESTFORMAT)
XX(ICM_DRAW_CHANGEPALETTE)
XX(ICM_GETBUFFERSWANTED)
XX(ICM_GETDEFAULTKEYFRAMERATE)
XX(ICM_DECOMPRESSEX_BEGIN)
XX(ICM_DECOMPRESSEX_QUERY)
XX(ICM_DECOMPRESSEX)
XX(ICM_DECOMPRESSEX_END)
XX(ICM_SET_STATUS_PROC)
default:
FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx)\n",(long)hic,(long)msg,lParam1,lParam2);
}
*/
// if (whic->driverproc) {
// FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx), calling %p\n",(long)hic,(long)msg,lParam1,lParam2,whic->driverproc);
#define STORE_ALL \
__asm__ ( \
"push %%ebx\n\t" \
"push %%ecx\n\t" \
"push %%edx\n\t" \
"push %%esi\n\t" \
"push %%edi\n\t"::)
#define REST_ALL \
__asm__ ( \
"pop %%edi\n\t" \
"pop %%esi\n\t" \
"pop %%edx\n\t" \
"pop %%ecx\n\t" \
"pop %%ebx\n\t"::)
// printf("private=%x\n", whic->private);
STORE_ALL;
ret = whic->driverproc(whic->private,1,msg,lParam1,lParam2);
REST_ALL;
// } else
// ret = SendDriverMessage(whic->hdrv,msg,lParam1,lParam2);
// TRACE(" -> 0x%08lx\n",ret);
return ret;
}
/***********************************************************************
* ICClose [MSVFW.22]
*/
LRESULT VFWAPI ICClose(HIC hic) {
WINE_HIC *whic = (WINE_HIC*)hic;
TRACE("(%d).\n",hic);
/* FIXME: correct? */
// CloseDriver(whic->hdrv,0,0);
DrvClose(whic->hdrv);
//#warning FIXME: DrvClose
my_release(whic);
return 0;
}
int VFWAPI ICDoSomething()
{
}