Merging MinGW changes
This commit is contained in:
parent
ad39fa8cb0
commit
4ad1e6fedb
|
@ -1,3 +1,3 @@
|
||||||
|
|
||||||
Main test.exe : test.c ;
|
Main test.exe : test.c ;
|
||||||
|
|
||||||
|
|
|
@ -1,91 +1,91 @@
|
||||||
/*
|
/*
|
||||||
* A test which demonstrates the use of opendir and related functions
|
* A test which demonstrates the use of opendir and related functions
|
||||||
* declared in dirent.h.
|
* declared in dirent.h.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char* argv[])
|
main (int argc, char* argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct dirent* de;
|
struct dirent* de;
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
long lPos;
|
long lPos;
|
||||||
|
|
||||||
if (argc == 2)
|
if (argc == 2)
|
||||||
{
|
{
|
||||||
printf ("Opening directory \"%s\"\n", argv[1]);
|
printf ("Opening directory \"%s\"\n", argv[1]);
|
||||||
dir = opendir(argv[1]);
|
dir = opendir(argv[1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("Opening \".\"\n");
|
printf ("Opening \".\"\n");
|
||||||
dir = opendir(".");
|
dir = opendir(".");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dir)
|
if (!dir)
|
||||||
{
|
{
|
||||||
printf ("Directory open failed!\n");
|
printf ("Directory open failed!\n");
|
||||||
if (errno)
|
if (errno)
|
||||||
{
|
{
|
||||||
printf ("Error : %s\n", strerror(errno));
|
printf ("Error : %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
lPos = -1;
|
lPos = -1;
|
||||||
|
|
||||||
while (de = readdir (dir))
|
while (de = readdir (dir))
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
printf ("%d : \"%s\" (tell %ld)\n", i, de->d_name,
|
printf ("%d : \"%s\" (tell %ld)\n", i, de->d_name,
|
||||||
telldir(dir));
|
telldir(dir));
|
||||||
|
|
||||||
if (i == 3)
|
if (i == 3)
|
||||||
{
|
{
|
||||||
printf ("We will seek here later.\n");
|
printf ("We will seek here later.\n");
|
||||||
lPos = telldir (dir);
|
lPos = telldir (dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Rewind directory.\n");
|
printf ("Rewind directory.\n");
|
||||||
rewinddir (dir);
|
rewinddir (dir);
|
||||||
|
|
||||||
if (de = readdir (dir))
|
if (de = readdir (dir))
|
||||||
{
|
{
|
||||||
printf ("First entry : \"%s\"\n", de->d_name);
|
printf ("First entry : \"%s\"\n", de->d_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("Empty directory.\n");
|
printf ("Empty directory.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lPos != -1)
|
if (lPos != -1)
|
||||||
{
|
{
|
||||||
printf ("Seeking to fourth entry.\n");
|
printf ("Seeking to fourth entry.\n");
|
||||||
seekdir (dir, lPos);
|
seekdir (dir, lPos);
|
||||||
|
|
||||||
if (de = readdir (dir))
|
if (de = readdir (dir))
|
||||||
{
|
{
|
||||||
printf ("Fourth entry : \"%s\"\n", de->d_name);
|
printf ("Fourth entry : \"%s\"\n", de->d_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("No fourth entry.\n");
|
printf ("No fourth entry.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("Seek position is past end of directory.\n");
|
printf ("Seek position is past end of directory.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Closing directory.\n");
|
printf ("Closing directory.\n");
|
||||||
closedir (dir);
|
closedir (dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
/*
|
/*
|
||||||
* Source code of the functions inside our test DLL. Note that DllMain is
|
* Source code of the functions inside our test DLL. Note that DllMain is
|
||||||
* not required (it will be provided by the stub in libmingw32.a).
|
* not required (it will be provided by the stub in libmingw32.a).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int Add (int x, int y)
|
int Add (int x, int y)
|
||||||
{
|
{
|
||||||
printf ("In add!\nx = %d\ny = %d\n", x, y);
|
printf ("In add!\nx = %d\ny = %d\n", x, y);
|
||||||
return (x + y);
|
return (x + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double __attribute__((stdcall)) Sub (double x, double y)
|
double __attribute__((stdcall)) Sub (double x, double y)
|
||||||
{
|
{
|
||||||
printf ("In sub!\nx = %f\ny = %f\n", x, y);
|
printf ("In sub!\nx = %f\ny = %f\n", x, y);
|
||||||
return (x - y);
|
return (x - y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
EXPORTS
|
EXPORTS
|
||||||
Add
|
Add
|
||||||
Sub@16
|
Sub@16
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
|
|
||||||
int Add (int x, int y);
|
int Add (int x, int y);
|
||||||
double __attribute__((stdcall)) Sub (double x, double y);
|
double __attribute__((stdcall)) Sub (double x, double y);
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "dll.h"
|
#include "dll.h"
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
double dk;
|
double dk;
|
||||||
|
|
||||||
i = 10;
|
i = 10;
|
||||||
j = 13;
|
j = 13;
|
||||||
|
|
||||||
k = Add(i, j);
|
k = Add(i, j);
|
||||||
|
|
||||||
printf ("%d + %d = %d\n", i, j, k);
|
printf ("%d + %d = %d\n", i, j, k);
|
||||||
|
|
||||||
dk = Sub(i, j);
|
dk = Sub(i, j);
|
||||||
|
|
||||||
printf ("%d - %d = %f\n", i, j, dk);
|
printf ("%d - %d = %f\n", i, j, dk);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
In add!
|
In add!
|
||||||
x = 10
|
x = 10
|
||||||
y = 13
|
y = 13
|
||||||
10 + 13 = 23
|
10 + 13 = 23
|
||||||
In sub!
|
In sub!
|
||||||
x = 10
|
x = 10
|
||||||
y = 13
|
y = 13
|
||||||
10 - 13 = -3
|
10 - 13 = -3
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
ExportedFromExe ()
|
ExportedFromExe ()
|
||||||
{
|
{
|
||||||
printf ("This output produced by ExportedFromExe.\n");
|
printf ("This output produced by ExportedFromExe.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
printf ("Hello, world\n");
|
printf ("Hello, world\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
EXPORTS
|
EXPORTS
|
||||||
ExportedFromExe
|
ExportedFromExe
|
||||||
|
|
|
@ -1,40 +1,40 @@
|
||||||
/*
|
/*
|
||||||
* This version attempts to load dll.dll dynamically, get the address of the
|
* This version attempts to load dll.dll dynamically, get the address of the
|
||||||
* Add function, and then call it.
|
* Add function, and then call it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
int (*Add)(int x, int y);
|
int (*Add)(int x, int y);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
HINSTANCE hDll;
|
HINSTANCE hDll;
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
|
|
||||||
hDll = LoadLibrary ("dll.dll");
|
hDll = LoadLibrary ("dll.dll");
|
||||||
if (!hDll)
|
if (!hDll)
|
||||||
{
|
{
|
||||||
printf ("Error %d loading dll.\n", GetLastError());
|
printf ("Error %d loading dll.\n", GetLastError());
|
||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(Add = GetProcAddress (hDll, "Add")))
|
if (!(Add = GetProcAddress (hDll, "Add")))
|
||||||
{
|
{
|
||||||
printf ("Error %d getting Add function.\n", GetLastError());
|
printf ("Error %d getting Add function.\n", GetLastError());
|
||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 10;
|
i = 10;
|
||||||
j = 13;
|
j = 13;
|
||||||
|
|
||||||
k = Add(i, j);
|
k = Add(i, j);
|
||||||
|
|
||||||
printf ("i %d, j %d, k %d\n", i, j, k);
|
printf ("i %d, j %d, k %d\n", i, j, k);
|
||||||
|
|
||||||
FreeLibrary (hDll);
|
FreeLibrary (hDll);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,47 +1,47 @@
|
||||||
/*
|
/*
|
||||||
* This program attempts to load expexe.exe dynamically, get the address of the
|
* This program attempts to load expexe.exe dynamically, get the address of the
|
||||||
* ExportedFromExe function, and then call it.
|
* ExportedFromExe function, and then call it.
|
||||||
*
|
*
|
||||||
* This example DOES NOT WORK! I don't know exactly what can be done, but
|
* This example DOES NOT WORK! I don't know exactly what can be done, but
|
||||||
* it simply seems that LoadLibrary refuses to load executables.
|
* it simply seems that LoadLibrary refuses to load executables.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
int (*ExportedFromExe)();
|
int (*ExportedFromExe)();
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
HINSTANCE hDll;
|
HINSTANCE hDll;
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
|
|
||||||
hDll = LoadLibrary ("expexe.exe");
|
hDll = LoadLibrary ("expexe.exe");
|
||||||
if (!hDll)
|
if (!hDll)
|
||||||
{
|
{
|
||||||
printf ("Error %d loading exe.\n", GetLastError());
|
printf ("Error %d loading exe.\n", GetLastError());
|
||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(ExportedFromExe = GetProcAddress (hDll, "ExportedFromExe")))
|
if (!(ExportedFromExe = GetProcAddress (hDll, "ExportedFromExe")))
|
||||||
{
|
{
|
||||||
printf ("Error %d getting ExportedFromExe function.\n",
|
printf ("Error %d getting ExportedFromExe function.\n",
|
||||||
GetLastError());
|
GetLastError());
|
||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ExportedFromExe ();
|
ExportedFromExe ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: Unlike a DLL the exe doesn't have an entry point which
|
/* NOTE: Unlike a DLL the exe doesn't have an entry point which
|
||||||
* initializes global objects and adds __do_global_dtors to
|
* initializes global objects and adds __do_global_dtors to
|
||||||
* the atexit list. Thus it should be safe(?) to free the
|
* the atexit list. Thus it should be safe(?) to free the
|
||||||
* library. Of course, this also makes it unsafe to use
|
* library. Of course, this also makes it unsafe to use
|
||||||
* executables at all in this manner.
|
* executables at all in this manner.
|
||||||
*/
|
*/
|
||||||
FreeLibrary (hDll);
|
FreeLibrary (hDll);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,39 +1,39 @@
|
||||||
This directory contains two examples of building DLLs. The exe.c and dll.c
|
This directory contains two examples of building DLLs. The exe.c and dll.c
|
||||||
files are used to build a very simple example DLL with a function that
|
files are used to build a very simple example DLL with a function that
|
||||||
adds two numbers together (and prints some text at the same time). The
|
adds two numbers together (and prints some text at the same time). The
|
||||||
exe.c program links to the DLL and prints the results of the function
|
exe.c program links to the DLL and prints the results of the function
|
||||||
call.
|
call.
|
||||||
|
|
||||||
The C++ example "silly" is more interesting because it involves a DLL which
|
The C++ example "silly" is more interesting because it involves a DLL which
|
||||||
contains the code for a C++ class. The CSilly class has all of its code in
|
contains the code for a C++ class. The CSilly class has all of its code in
|
||||||
the sillydll.cpp source file, which is used to build the silly.dll. The
|
the sillydll.cpp source file, which is used to build the silly.dll. The
|
||||||
silly.cpp source code builds the main silly.exe executable which makes a
|
silly.cpp source code builds the main silly.exe executable which makes a
|
||||||
dynamic instance of the object and calls its member functions.
|
dynamic instance of the object and calls its member functions.
|
||||||
|
|
||||||
The C++ silly.def file was generated by doing a nm of sillydll.o after it
|
The C++ silly.def file was generated by doing a nm of sillydll.o after it
|
||||||
was generated and then getting the symbol names from that. Removing the
|
was generated and then getting the symbol names from that. Removing the
|
||||||
leading underscore produces the appropriate name to include in the EXPORTS
|
leading underscore produces the appropriate name to include in the EXPORTS
|
||||||
section. Notice there are a few weird functions.
|
section. Notice there are a few weird functions.
|
||||||
|
|
||||||
Since there are now several different versions of the GNU compiler capable
|
Since there are now several different versions of the GNU compiler capable
|
||||||
of doing this, and they each seem to have different requirements for exports
|
of doing this, and they each seem to have different requirements for exports
|
||||||
for classes, it has gotten kind of messy. The silly.def file here is for
|
for classes, it has gotten kind of messy. The silly.def file here is for
|
||||||
use with the native Mingw32 build of the EGCS version of GCC. The silly.def.old
|
use with the native Mingw32 build of the EGCS version of GCC. The silly.def.old
|
||||||
file was the def file I used when I was using Jan-Jaap's Mingw32 native port
|
file was the def file I used when I was using Jan-Jaap's Mingw32 native port
|
||||||
of GCC. The Cygnus version is different again, if I recall correctly, but I
|
of GCC. The Cygnus version is different again, if I recall correctly, but I
|
||||||
don't have it hanging around anymore.
|
don't have it hanging around anymore.
|
||||||
|
|
||||||
The jamfile builds all the components from the raw sources.
|
The jamfile builds all the components from the raw sources.
|
||||||
|
|
||||||
The expected output of exe.exe and silly.exe are in the files exe.exp
|
The expected output of exe.exe and silly.exe are in the files exe.exp
|
||||||
and silly.exp.
|
and silly.exp.
|
||||||
|
|
||||||
|
|
||||||
The source code in this directory is in the PUBLIC DOMAIN and can be
|
The source code in this directory is in the PUBLIC DOMAIN and can be
|
||||||
used or abused as you see fit. There is NO WARRANTY for this code,
|
used or abused as you see fit. There is NO WARRANTY for this code,
|
||||||
including (but not limited to) implied warranties of MERCHANTABILITY
|
including (but not limited to) implied warranties of MERCHANTABILITY
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE.
|
or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
|
Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
|
||||||
|
|
||||||
|
|
|
@ -1,55 +1,55 @@
|
||||||
//
|
//
|
||||||
// C++ test of a dll which contains a C++ class.
|
// C++ test of a dll which contains a C++ class.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
// Interface of class.
|
// Interface of class.
|
||||||
#include "silly.h"
|
#include "silly.h"
|
||||||
|
|
||||||
#ifdef DERIVED_TEST
|
#ifdef DERIVED_TEST
|
||||||
// Here is a derived class too.
|
// Here is a derived class too.
|
||||||
class CMoreSilly : public CSilly
|
class CMoreSilly : public CSilly
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMoreSilly (char* szNewName) : CSilly (szNewName) {};
|
CMoreSilly (char* szNewName) : CSilly (szNewName) {};
|
||||||
~CMoreSilly ();
|
~CMoreSilly ();
|
||||||
|
|
||||||
WhatsYourName();
|
WhatsYourName();
|
||||||
};
|
};
|
||||||
|
|
||||||
CMoreSilly::
|
CMoreSilly::
|
||||||
~CMoreSilly ()
|
~CMoreSilly ()
|
||||||
{
|
{
|
||||||
printf ("In CMoreSilly \"%s\" destructor!\n", szName);
|
printf ("In CMoreSilly \"%s\" destructor!\n", szName);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMoreSilly::
|
CMoreSilly::
|
||||||
WhatsYourName ()
|
WhatsYourName ()
|
||||||
{
|
{
|
||||||
printf ("I'm more silly and my name is \"%s\"\n", szName);
|
printf ("I'm more silly and my name is \"%s\"\n", szName);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
CSilly* psilly = new CSilly("silly");
|
CSilly* psilly = new CSilly("silly");
|
||||||
|
|
||||||
psilly->WhatsYourName();
|
psilly->WhatsYourName();
|
||||||
psilly->Poke(); // Poke him, he should say "Ouch!"
|
psilly->Poke(); // Poke him, he should say "Ouch!"
|
||||||
psilly->Stab(4); // Stab him four times he should say "Ugh!!!!"
|
psilly->Stab(4); // Stab him four times he should say "Ugh!!!!"
|
||||||
|
|
||||||
delete psilly;
|
delete psilly;
|
||||||
|
|
||||||
#ifdef DERIVED_TEST
|
#ifdef DERIVED_TEST
|
||||||
psilly = new CMoreSilly("more silly");
|
psilly = new CMoreSilly("more silly");
|
||||||
psilly->WhatsYourName();
|
psilly->WhatsYourName();
|
||||||
psilly->Stab(5);
|
psilly->Stab(5);
|
||||||
delete psilly;
|
delete psilly;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
EXPORTS
|
EXPORTS
|
||||||
DllMain@12
|
DllMain@12
|
||||||
Poke__6CSilly
|
Poke__6CSilly
|
||||||
Stab__6CSillyi
|
Stab__6CSillyi
|
||||||
WhatsYourName__6CSilly
|
WhatsYourName__6CSilly
|
||||||
_$_6CSilly
|
_$_6CSilly
|
||||||
__6CSilly
|
__6CSilly
|
||||||
__6CSillyPc
|
__6CSillyPc
|
||||||
__tf6CSilly
|
__tf6CSilly
|
||||||
__ti6CSilly
|
__ti6CSilly
|
||||||
_vt$6CSilly
|
_vt$6CSilly
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
I'm silly.
|
I'm silly.
|
||||||
Ouch!
|
Ouch!
|
||||||
Ugh!!!!
|
Ugh!!!!
|
||||||
In CSilly destructor.
|
In CSilly destructor.
|
||||||
I'm more silly and my name is "more silly"
|
I'm more silly and my name is "more silly"
|
||||||
Ugh!!!!!
|
Ugh!!!!!
|
||||||
In CMoreSilly "more silly" destructor!
|
In CMoreSilly "more silly" destructor!
|
||||||
In CSilly destructor.
|
In CSilly destructor.
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
|
|
||||||
#define DERIVED_TEST 1
|
#define DERIVED_TEST 1
|
||||||
|
|
||||||
class CSilly
|
class CSilly
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
char* szName;
|
char* szName;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CSilly();
|
CSilly();
|
||||||
CSilly(char* szName);
|
CSilly(char* szName);
|
||||||
#ifdef DERIVED_TEST
|
#ifdef DERIVED_TEST
|
||||||
virtual ~CSilly();
|
virtual ~CSilly();
|
||||||
#else
|
#else
|
||||||
~CSilly();
|
~CSilly();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Poke ();
|
Poke ();
|
||||||
Stab (int nTimes);
|
Stab (int nTimes);
|
||||||
#ifdef DERIVED_TEST
|
#ifdef DERIVED_TEST
|
||||||
virtual WhatsYourName ();
|
virtual WhatsYourName ();
|
||||||
#else
|
#else
|
||||||
WhatsYourName ();
|
WhatsYourName ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,107 +1,107 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define STREAMS_VERSION
|
#define STREAMS_VERSION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(STREAMS_VERSION)
|
#if defined(STREAMS_VERSION)
|
||||||
#include <iostream.h>
|
#include <iostream.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "silly.h"
|
#include "silly.h"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSilly::
|
CSilly::
|
||||||
CSilly()
|
CSilly()
|
||||||
{
|
{
|
||||||
szName = NULL;
|
szName = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSilly::
|
CSilly::
|
||||||
CSilly(char* new_szName)
|
CSilly(char* new_szName)
|
||||||
{
|
{
|
||||||
szName = new char[strlen(new_szName)+1];
|
szName = new char[strlen(new_szName)+1];
|
||||||
|
|
||||||
if (szName)
|
if (szName)
|
||||||
{
|
{
|
||||||
strcpy (szName, new_szName);
|
strcpy (szName, new_szName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CSilly::
|
CSilly::
|
||||||
~CSilly()
|
~CSilly()
|
||||||
{
|
{
|
||||||
printf ("In CSilly destructor.\n");
|
printf ("In CSilly destructor.\n");
|
||||||
if (szName)
|
if (szName)
|
||||||
{
|
{
|
||||||
delete szName;
|
delete szName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CSilly::
|
CSilly::
|
||||||
Poke ()
|
Poke ()
|
||||||
{
|
{
|
||||||
#ifndef STREAMS_VERSION
|
#ifndef STREAMS_VERSION
|
||||||
printf ("Ouch!\n");
|
printf ("Ouch!\n");
|
||||||
#else
|
#else
|
||||||
cout << "Ouch!" << endl;
|
cout << "Ouch!" << endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CSilly::
|
CSilly::
|
||||||
Stab (int nTimes)
|
Stab (int nTimes)
|
||||||
{
|
{
|
||||||
#ifndef STREAMS_VERSION
|
#ifndef STREAMS_VERSION
|
||||||
printf ("Ugh");
|
printf ("Ugh");
|
||||||
#else
|
#else
|
||||||
cout << "Ugh";
|
cout << "Ugh";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < nTimes; i++)
|
for (i = 0; i < nTimes; i++)
|
||||||
{
|
{
|
||||||
#ifndef STREAMS_VERSION
|
#ifndef STREAMS_VERSION
|
||||||
putchar('!');
|
putchar('!');
|
||||||
#else
|
#else
|
||||||
cout << '!' ;
|
cout << '!' ;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef STREAMS_VERSION
|
#ifndef STREAMS_VERSION
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
#else
|
#else
|
||||||
cout << endl;
|
cout << endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CSilly::
|
CSilly::
|
||||||
WhatsYourName ()
|
WhatsYourName ()
|
||||||
{
|
{
|
||||||
if (szName)
|
if (szName)
|
||||||
{
|
{
|
||||||
#ifndef STREAMS_VERSION
|
#ifndef STREAMS_VERSION
|
||||||
printf ("I'm %s.\n", szName);
|
printf ("I'm %s.\n", szName);
|
||||||
#else
|
#else
|
||||||
cout << "I'm " << szName << "." << endl;
|
cout << "I'm " << szName << "." << endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifndef STREAMS_VERSION
|
#ifndef STREAMS_VERSION
|
||||||
printf ("I have no name.\n");
|
printf ("I have no name.\n");
|
||||||
#else
|
#else
|
||||||
cout << "I have no name." << endl;
|
cout << "I have no name." << endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,57 +1,57 @@
|
||||||
/*
|
/*
|
||||||
* An example showing how you can obtain the UNIX-ish file number from a
|
* An example showing how you can obtain the UNIX-ish file number from a
|
||||||
* FILE* and in turn how you can get the Win32 HANDLE of the file from
|
* FILE* and in turn how you can get the Win32 HANDLE of the file from
|
||||||
* the file number.
|
* the file number.
|
||||||
*
|
*
|
||||||
* This code is in the PUBLIC DOMAIN and has NO WARRANTY.
|
* This code is in the PUBLIC DOMAIN and has NO WARRANTY.
|
||||||
*
|
*
|
||||||
* Colin Peters <colin@fu.is.saga-u.ac.jp>
|
* Colin Peters <colin@fu.is.saga-u.ac.jp>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char* argv[])
|
main (int argc, char* argv[])
|
||||||
{
|
{
|
||||||
char* szFileName;
|
char* szFileName;
|
||||||
FILE* fileIn;
|
FILE* fileIn;
|
||||||
int fnIn;
|
int fnIn;
|
||||||
HANDLE hFileIn;
|
HANDLE hFileIn;
|
||||||
char caBuf[81];
|
char caBuf[81];
|
||||||
int nRead;
|
int nRead;
|
||||||
|
|
||||||
if (argc >= 2)
|
if (argc >= 2)
|
||||||
{
|
{
|
||||||
szFileName = argv[1];
|
szFileName = argv[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
szFileName = "junk.txt";
|
szFileName = "junk.txt";
|
||||||
}
|
}
|
||||||
|
|
||||||
fileIn = fopen (szFileName, "r");
|
fileIn = fopen (szFileName, "r");
|
||||||
|
|
||||||
if (!fileIn)
|
if (!fileIn)
|
||||||
{
|
{
|
||||||
printf ("Could not open %s for reading\n", szFileName);
|
printf ("Could not open %s for reading\n", szFileName);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fnIn = fileno (fileIn);
|
fnIn = fileno (fileIn);
|
||||||
hFileIn = (HANDLE) _get_osfhandle (fnIn);
|
hFileIn = (HANDLE) _get_osfhandle (fnIn);
|
||||||
|
|
||||||
printf ("OS file handle %d\n", (int) hFileIn);
|
printf ("OS file handle %d\n", (int) hFileIn);
|
||||||
|
|
||||||
ReadFile (hFileIn, caBuf, 80, &nRead, NULL);
|
ReadFile (hFileIn, caBuf, 80, &nRead, NULL);
|
||||||
|
|
||||||
printf ("Read %d bytes using ReadFile.\n", nRead);
|
printf ("Read %d bytes using ReadFile.\n", nRead);
|
||||||
|
|
||||||
caBuf[nRead] = '\0';
|
caBuf[nRead] = '\0';
|
||||||
|
|
||||||
printf ("\"%s\"\n", caBuf);
|
printf ("\"%s\"\n", caBuf);
|
||||||
|
|
||||||
fclose (fileIn);
|
fclose (fileIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
|
|
||||||
Main filehand.exe : filehand.c ;
|
Main filehand.exe : filehand.c ;
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
This is a test file.
|
This is a test file.
|
||||||
|
|
|
@ -1,290 +1,290 @@
|
||||||
/*
|
/*
|
||||||
* fixargv.c
|
* fixargv.c
|
||||||
*
|
*
|
||||||
* A special function which "fixes" an argv array by replacing arguments
|
* A special function which "fixes" an argv array by replacing arguments
|
||||||
* that need quoting with quoted versions.
|
* that need quoting with quoted versions.
|
||||||
*
|
*
|
||||||
* NOTE: In order to be reasonably consistent there is some misuse of the
|
* NOTE: In order to be reasonably consistent there is some misuse of the
|
||||||
* const keyword here-- which leads to compilation warnings. These
|
* const keyword here-- which leads to compilation warnings. These
|
||||||
* should be ok to ignore.
|
* should be ok to ignore.
|
||||||
*
|
*
|
||||||
* This is a sample distributed as part of the Mingw32 package.
|
* This is a sample distributed as part of the Mingw32 package.
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
|
* Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS NOT COPYRIGHTED
|
* THIS SOFTWARE IS NOT COPYRIGHTED
|
||||||
*
|
*
|
||||||
* This source code is offered for use in the public domain. You may
|
* This source code is offered for use in the public domain. You may
|
||||||
* use, modify or distribute it freely.
|
* use, modify or distribute it freely.
|
||||||
*
|
*
|
||||||
* This code is distributed in the hope that it will be useful but
|
* This code is distributed in the hope that it will be useful but
|
||||||
* WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
|
* WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
|
||||||
* DISCLAMED. This includes but is not limited to warrenties of
|
* DISCLAMED. This includes but is not limited to warrenties of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
*
|
*
|
||||||
* $Revision$
|
* $Revision$
|
||||||
* $Author$
|
* $Author$
|
||||||
* $Date$
|
* $Date$
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "fixargv.h"
|
#include "fixargv.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This takes a single string and fixes it, enclosing it in quotes if it
|
* This takes a single string and fixes it, enclosing it in quotes if it
|
||||||
* contains any spaces and/or escaping the quotes it contains.
|
* contains any spaces and/or escaping the quotes it contains.
|
||||||
*/
|
*/
|
||||||
char*
|
char*
|
||||||
fix_arg (const char* szArg)
|
fix_arg (const char* szArg)
|
||||||
{
|
{
|
||||||
int nQuoteAll; /* Does the whole arg need quoting? */
|
int nQuoteAll; /* Does the whole arg need quoting? */
|
||||||
int nBkSlRun; /* How may backslashes in a row? */
|
int nBkSlRun; /* How may backslashes in a row? */
|
||||||
char* sz;
|
char* sz;
|
||||||
char* szNew;
|
char* szNew;
|
||||||
size_t sizeLen;
|
size_t sizeLen;
|
||||||
|
|
||||||
nQuoteAll = 0;
|
nQuoteAll = 0;
|
||||||
nBkSlRun = 0;
|
nBkSlRun = 0;
|
||||||
sz = szArg;
|
sz = szArg;
|
||||||
sizeLen = 1;
|
sizeLen = 1;
|
||||||
|
|
||||||
/* First we figure out how much bigger the new string has to be
|
/* First we figure out how much bigger the new string has to be
|
||||||
* than the old one. */
|
* than the old one. */
|
||||||
while (*sz != '\0')
|
while (*sz != '\0')
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Arguments containing whitespace of wildcards will be
|
* Arguments containing whitespace of wildcards will be
|
||||||
* quoted to preserve tokenization and/or those special
|
* quoted to preserve tokenization and/or those special
|
||||||
* characters (i.e. wildcarding will NOT be done at the
|
* characters (i.e. wildcarding will NOT be done at the
|
||||||
* other end-- they will get the * and ? characters as is).
|
* other end-- they will get the * and ? characters as is).
|
||||||
* TODO: Is this the best way? Do we want to enable wildcards?
|
* TODO: Is this the best way? Do we want to enable wildcards?
|
||||||
* If so, when?
|
* If so, when?
|
||||||
*/
|
*/
|
||||||
if (!nQuoteAll &&
|
if (!nQuoteAll &&
|
||||||
(*sz == ' ' || *sz == '\t' || *sz == '*' || *sz == '?'))
|
(*sz == ' ' || *sz == '\t' || *sz == '*' || *sz == '?'))
|
||||||
{
|
{
|
||||||
nQuoteAll = 1;
|
nQuoteAll = 1;
|
||||||
}
|
}
|
||||||
else if (*sz == '\\')
|
else if (*sz == '\\')
|
||||||
{
|
{
|
||||||
nBkSlRun++;
|
nBkSlRun++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (*sz == '\"')
|
if (*sz == '\"')
|
||||||
{
|
{
|
||||||
sizeLen += nBkSlRun + 1;
|
sizeLen += nBkSlRun + 1;
|
||||||
}
|
}
|
||||||
nBkSlRun = 0;
|
nBkSlRun = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sizeLen++;
|
sizeLen++;
|
||||||
sz++;
|
sz++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nQuoteAll)
|
if (nQuoteAll)
|
||||||
{
|
{
|
||||||
sizeLen += 2;
|
sizeLen += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make a new string big enough.
|
* Make a new string big enough.
|
||||||
*/
|
*/
|
||||||
szNew = (char*) malloc (sizeLen);
|
szNew = (char*) malloc (sizeLen);
|
||||||
if (!szNew)
|
if (!szNew)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sz = szNew;
|
sz = szNew;
|
||||||
|
|
||||||
/* First enclosing quote for fully quoted args. */
|
/* First enclosing quote for fully quoted args. */
|
||||||
if (nQuoteAll)
|
if (nQuoteAll)
|
||||||
{
|
{
|
||||||
*sz = '\"';
|
*sz = '\"';
|
||||||
sz++;
|
sz++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Go through the string putting backslashes in front of quotes,
|
* Go through the string putting backslashes in front of quotes,
|
||||||
* and doubling all backslashes immediately in front of quotes.
|
* and doubling all backslashes immediately in front of quotes.
|
||||||
*/
|
*/
|
||||||
nBkSlRun = 0;
|
nBkSlRun = 0;
|
||||||
while (*szArg != '\0')
|
while (*szArg != '\0')
|
||||||
{
|
{
|
||||||
if (*szArg == '\\')
|
if (*szArg == '\\')
|
||||||
{
|
{
|
||||||
nBkSlRun++;
|
nBkSlRun++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (*szArg == '\"')
|
if (*szArg == '\"')
|
||||||
{
|
{
|
||||||
while (nBkSlRun > 0)
|
while (nBkSlRun > 0)
|
||||||
{
|
{
|
||||||
*sz = '\\';
|
*sz = '\\';
|
||||||
sz++;
|
sz++;
|
||||||
nBkSlRun--;
|
nBkSlRun--;
|
||||||
}
|
}
|
||||||
*sz = '\\';
|
*sz = '\\';
|
||||||
sz++;
|
sz++;
|
||||||
}
|
}
|
||||||
nBkSlRun = 0;
|
nBkSlRun = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*sz = *szArg;
|
*sz = *szArg;
|
||||||
sz++;
|
sz++;
|
||||||
szArg++;
|
szArg++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Closing quote for fully quoted args. */
|
/* Closing quote for fully quoted args. */
|
||||||
if (nQuoteAll)
|
if (nQuoteAll)
|
||||||
{
|
{
|
||||||
*sz = '\"';
|
*sz = '\"';
|
||||||
sz++;
|
sz++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*sz = '\0';
|
*sz = '\0';
|
||||||
return szNew;
|
return szNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Takes argc and argv and returns a new argv with escaped members. Pass
|
* Takes argc and argv and returns a new argv with escaped members. Pass
|
||||||
* this fixed argv (along with the old one) to free_fixed_argv after
|
* this fixed argv (along with the old one) to free_fixed_argv after
|
||||||
* you finish with it. Pass in an argc of -1 and make sure the argv vector
|
* you finish with it. Pass in an argc of -1 and make sure the argv vector
|
||||||
* ends with a null pointer to have fix_argv count the arguments for you.
|
* ends with a null pointer to have fix_argv count the arguments for you.
|
||||||
*/
|
*/
|
||||||
char* const*
|
char* const*
|
||||||
fix_argv (int argc, char* const* szaArgv)
|
fix_argv (int argc, char* const* szaArgv)
|
||||||
{
|
{
|
||||||
char** szaNew;
|
char** szaNew;
|
||||||
char* sz;
|
char* sz;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!szaArgv)
|
if (!szaArgv)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Count the arguments if asked.
|
* Count the arguments if asked.
|
||||||
*/
|
*/
|
||||||
if (argc == -1)
|
if (argc == -1)
|
||||||
{
|
{
|
||||||
for (i = 0; szaArgv[i]; i++)
|
for (i = 0; szaArgv[i]; i++)
|
||||||
;
|
;
|
||||||
|
|
||||||
argc = i;
|
argc = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there are no args or only one arg then do no escaping.
|
* If there are no args or only one arg then do no escaping.
|
||||||
*/
|
*/
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
return szaArgv;
|
return szaArgv;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 1, szaNew = NULL; i < argc; i++)
|
for (i = 1, szaNew = NULL; i < argc; i++)
|
||||||
{
|
{
|
||||||
sz = szaArgv[i];
|
sz = szaArgv[i];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If an argument needs fixing, then fix it.
|
* If an argument needs fixing, then fix it.
|
||||||
*/
|
*/
|
||||||
if (strpbrk (sz, "\" \t*?"))
|
if (strpbrk (sz, "\" \t*?"))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If we haven't created a new argv list already
|
* If we haven't created a new argv list already
|
||||||
* then make one.
|
* then make one.
|
||||||
*/
|
*/
|
||||||
if (!szaNew)
|
if (!szaNew)
|
||||||
{
|
{
|
||||||
szaNew = (char**) malloc ((argc + 1) *
|
szaNew = (char**) malloc ((argc + 1) *
|
||||||
sizeof (char*));
|
sizeof (char*));
|
||||||
if (!szaNew)
|
if (!szaNew)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy previous args from old to new.
|
* Copy previous args from old to new.
|
||||||
*/
|
*/
|
||||||
memcpy (szaNew, szaArgv, sizeof(char*) * i);
|
memcpy (szaNew, szaArgv, sizeof(char*) * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now do the fixing.
|
* Now do the fixing.
|
||||||
*/
|
*/
|
||||||
szaNew[i] = fix_arg (sz);
|
szaNew[i] = fix_arg (sz);
|
||||||
if (!szaNew[i])
|
if (!szaNew[i])
|
||||||
{
|
{
|
||||||
/* Fixing failed, free up and return error. */
|
/* Fixing failed, free up and return error. */
|
||||||
free_fixed_argv (szaNew, szaArgv);
|
free_fixed_argv (szaNew, szaArgv);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (szaNew)
|
else if (szaNew)
|
||||||
{
|
{
|
||||||
szaNew[i] = sz;
|
szaNew[i] = sz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (szaNew)
|
if (szaNew)
|
||||||
{
|
{
|
||||||
/* If we have created a new argv list then we might as well
|
/* If we have created a new argv list then we might as well
|
||||||
* terminate it nicely. (And we depend on it in
|
* terminate it nicely. (And we depend on it in
|
||||||
* free_fixed_argv.) */
|
* free_fixed_argv.) */
|
||||||
szaNew[argc] = NULL;
|
szaNew[argc] = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* If we didn't create a new argv list then return the
|
/* If we didn't create a new argv list then return the
|
||||||
* original. */
|
* original. */
|
||||||
return szaArgv;
|
return szaArgv;
|
||||||
}
|
}
|
||||||
|
|
||||||
return szaNew;
|
return szaNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
free_fixed_argv (char* const* szaFixed, char* const* szaOld)
|
free_fixed_argv (char* const* szaFixed, char* const* szaOld)
|
||||||
{
|
{
|
||||||
char* const* sza;
|
char* const* sza;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for error conditions. Also note that if no corrections
|
* Check for error conditions. Also note that if no corrections
|
||||||
* were required the fixed argv will actually be the same as
|
* were required the fixed argv will actually be the same as
|
||||||
* the old one, and we don't need to do anything.
|
* the old one, and we don't need to do anything.
|
||||||
*/
|
*/
|
||||||
if (!szaFixed || !szaOld || szaFixed == szaOld)
|
if (!szaFixed || !szaOld || szaFixed == szaOld)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Go through all members of the argv list. If any of the
|
* Go through all members of the argv list. If any of the
|
||||||
* members in the fixed list are different from the old
|
* members in the fixed list are different from the old
|
||||||
* list we free those members.
|
* list we free those members.
|
||||||
* NOTE: The first member is never modified, so we don't need to
|
* NOTE: The first member is never modified, so we don't need to
|
||||||
* check.
|
* check.
|
||||||
*/
|
*/
|
||||||
sza = szaFixed + 1;
|
sza = szaFixed + 1;
|
||||||
szaOld++;
|
szaOld++;
|
||||||
while (*sza)
|
while (*sza)
|
||||||
{
|
{
|
||||||
if (*sza != *szaOld)
|
if (*sza != *szaOld)
|
||||||
{
|
{
|
||||||
free (*sza);
|
free (*sza);
|
||||||
}
|
}
|
||||||
sza++;
|
sza++;
|
||||||
szaOld++;
|
szaOld++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we can free the array of char pointers itself.
|
* Now we can free the array of char pointers itself.
|
||||||
*/
|
*/
|
||||||
free (szaFixed);
|
free (szaFixed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
/*
|
/*
|
||||||
* fixargv.h
|
* fixargv.h
|
||||||
*
|
*
|
||||||
* Prototypes of utility functions for 'properly' escaping argv vectors.
|
* Prototypes of utility functions for 'properly' escaping argv vectors.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS NOT COPYRIGHTED
|
* THIS SOFTWARE IS NOT COPYRIGHTED
|
||||||
*
|
*
|
||||||
* This source code is offered for use in the public domain. You may
|
* This source code is offered for use in the public domain. You may
|
||||||
* use, modify or distribute it freely.
|
* use, modify or distribute it freely.
|
||||||
*
|
*
|
||||||
* $Revision$
|
* $Revision$
|
||||||
* $Author$
|
* $Author$
|
||||||
* $Date$
|
* $Date$
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _FIXARGV_H_
|
#ifndef _FIXARGV_H_
|
||||||
#define _FIXARGV_H_
|
#define _FIXARGV_H_
|
||||||
|
|
||||||
char* fix_arg (const char* szArg);
|
char* fix_arg (const char* szArg);
|
||||||
char* const* fix_argv (int argc, char* const* szaArgv);
|
char* const* fix_argv (int argc, char* const* szaArgv);
|
||||||
void free_fixed_argv (char* const* szaFixed, char* const* szaOld);
|
void free_fixed_argv (char* const* szaFixed, char* const* szaOld);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,85 +1,85 @@
|
||||||
|
|
||||||
This code is a utility function I was considering adding to Mingw32. The
|
This code is a utility function I was considering adding to Mingw32. The
|
||||||
Microsoft versions of argc, argv construction use quotes and backslashes
|
Microsoft versions of argc, argv construction use quotes and backslashes
|
||||||
to allow the user to pass arguments containing spaces (or quotes) to
|
to allow the user to pass arguments containing spaces (or quotes) to
|
||||||
programs they invoke. The rules are
|
programs they invoke. The rules are
|
||||||
|
|
||||||
- Arguments containing spaces must be enclosed in quotes.
|
- Arguments containing spaces must be enclosed in quotes.
|
||||||
- A quote can be passed by preceeding it with a backslash.
|
- A quote can be passed by preceeding it with a backslash.
|
||||||
- Backslashes immediately preceeding a quote must be doubled to avoid
|
- Backslashes immediately preceeding a quote must be doubled to avoid
|
||||||
escaping the quote.
|
escaping the quote.
|
||||||
|
|
||||||
Thus an argument like:
|
Thus an argument like:
|
||||||
|
|
||||||
-D="Foo Bar\\"
|
-D="Foo Bar\\"
|
||||||
|
|
||||||
needs to be mangled as:
|
needs to be mangled as:
|
||||||
|
|
||||||
"-D\"Foo Bar\\\\\""
|
"-D\"Foo Bar\\\\\""
|
||||||
|
|
||||||
in order to get to the program as what was intended above.
|
in order to get to the program as what was intended above.
|
||||||
|
|
||||||
The fix_argv set of functions is meant to be used with spawnv and the
|
The fix_argv set of functions is meant to be used with spawnv and the
|
||||||
like to allow a program to set up an argv array for the spawned program
|
like to allow a program to set up an argv array for the spawned program
|
||||||
and have that array duplicated *exactly* in the spawned program, no
|
and have that array duplicated *exactly* in the spawned program, no
|
||||||
matter what it contains (it also quotes 'globbing' characters like *
|
matter what it contains (it also quotes 'globbing' characters like *
|
||||||
and ?, so it does not matter if the destination has globbing turned on
|
and ?, so it does not matter if the destination has globbing turned on
|
||||||
or not; it might be a reasonable extension to allow a flag to allow
|
or not; it might be a reasonable extension to allow a flag to allow
|
||||||
globbing characters to pass through unmolested, but they would still
|
globbing characters to pass through unmolested, but they would still
|
||||||
be quoted if the string contained whitespace).
|
be quoted if the string contained whitespace).
|
||||||
|
|
||||||
The reason for writing this came up because of problems with arguments
|
The reason for writing this came up because of problems with arguments
|
||||||
like -DBLAH="Foo Bar" to GCC (define BLAH as a preprocessor constant
|
like -DBLAH="Foo Bar" to GCC (define BLAH as a preprocessor constant
|
||||||
being the string "Foo Bar", including the quotes). Because GCC simply
|
being the string "Foo Bar", including the quotes). Because GCC simply
|
||||||
passes the argument directly to CPP (the preprocessor) it had to be
|
passes the argument directly to CPP (the preprocessor) it had to be
|
||||||
escaped *twice*:
|
escaped *twice*:
|
||||||
|
|
||||||
"-DBLAH=\"\\\"Foo Bar\\\"\""
|
"-DBLAH=\"\\\"Foo Bar\\\"\""
|
||||||
|
|
||||||
This would reach GCC as
|
This would reach GCC as
|
||||||
|
|
||||||
-DBLAH="\"Foo Bar\""
|
-DBLAH="\"Foo Bar\""
|
||||||
|
|
||||||
And that would reach CPP as the desired
|
And that would reach CPP as the desired
|
||||||
|
|
||||||
-DBLAH="Foo Bar"
|
-DBLAH="Foo Bar"
|
||||||
|
|
||||||
One level of quoting and escaping is to be expected (although MS's
|
One level of quoting and escaping is to be expected (although MS's
|
||||||
standard is, arguably, not very good), but forcing the user to know
|
standard is, arguably, not very good), but forcing the user to know
|
||||||
how many different programs the argument is going to pass through,
|
how many different programs the argument is going to pass through,
|
||||||
and perform double quoting and escaping, seems unreasonable. If
|
and perform double quoting and escaping, seems unreasonable. If
|
||||||
GCC and friends all used fix_argv (they use their own version of
|
GCC and friends all used fix_argv (they use their own version of
|
||||||
it now) then the original argument could be
|
it now) then the original argument could be
|
||||||
|
|
||||||
"-DBLAH=\"Foo Bar\""
|
"-DBLAH=\"Foo Bar\""
|
||||||
|
|
||||||
And that would work fine, no matter how many different tools it
|
And that would work fine, no matter how many different tools it
|
||||||
passed through.
|
passed through.
|
||||||
|
|
||||||
The only basic limitation with this code is that it assumes that all
|
The only basic limitation with this code is that it assumes that all
|
||||||
the spawned programs use Microsoft-type escaping when interpreting
|
the spawned programs use Microsoft-type escaping when interpreting
|
||||||
their command line. Most programs on Win32 machines do (anything
|
their command line. Most programs on Win32 machines do (anything
|
||||||
compiled with Mingw32 will).
|
compiled with Mingw32 will).
|
||||||
|
|
||||||
For now, this code has been relegated to 'sample' status. If you want
|
For now, this code has been relegated to 'sample' status. If you want
|
||||||
to use it, feel free (it is public domain after all).
|
to use it, feel free (it is public domain after all).
|
||||||
|
|
||||||
Colin.
|
Colin.
|
||||||
|
|
||||||
P.S. Just out of interest you might try writing your own little program
|
P.S. Just out of interest you might try writing your own little program
|
||||||
to look at the interaction of wildcards and quotes. Use the glob.exe
|
to look at the interaction of wildcards and quotes. Use the glob.exe
|
||||||
program in ../globbing and see what it does with
|
program in ../globbing and see what it does with
|
||||||
|
|
||||||
glob "foo*.txt"
|
glob "foo*.txt"
|
||||||
|
|
||||||
even if there are files foo.txt and foobar.txt in the same directory.
|
even if there are files foo.txt and foobar.txt in the same directory.
|
||||||
|
|
||||||
Note that
|
Note that
|
||||||
|
|
||||||
del "My *.txt"
|
del "My *.txt"
|
||||||
|
|
||||||
works (i.e. it deletes all files starting with My<space>). This could
|
works (i.e. it deletes all files starting with My<space>). This could
|
||||||
not be done unless del does globbing *after* processing escapes and
|
not be done unless del does globbing *after* processing escapes and
|
||||||
quotes, which is not the way it seems to work normally (again see
|
quotes, which is not the way it seems to work normally (again see
|
||||||
the glob example).
|
the glob example).
|
||||||
|
|
||||||
|
|
|
@ -1,46 +1,46 @@
|
||||||
/*
|
/*
|
||||||
* A sample program demonstrating how to use _CRT_fmode to change the default
|
* A sample program demonstrating how to use _CRT_fmode to change the default
|
||||||
* file opening mode to binary AND change stdin, stdout and stderr. Redirect
|
* file opening mode to binary AND change stdin, stdout and stderr. Redirect
|
||||||
* stdout to a file from the command line to see the difference.
|
* stdout to a file from the command line to see the difference.
|
||||||
*
|
*
|
||||||
* Also try directing a file into stdin. If you type into stdin you will get
|
* Also try directing a file into stdin. If you type into stdin you will get
|
||||||
* \r\n at the end of every line... unlike UNIX. But at least if you
|
* \r\n at the end of every line... unlike UNIX. But at least if you
|
||||||
* redirect a file in you will get exactly the characters in the file as input.
|
* redirect a file in you will get exactly the characters in the file as input.
|
||||||
*
|
*
|
||||||
* THIS CODE IS IN THE PUBLIC DOMAIN.
|
* THIS CODE IS IN THE PUBLIC DOMAIN.
|
||||||
*
|
*
|
||||||
* Colin Peters <colin@fu.is.saga-u.ac.jp>
|
* Colin Peters <colin@fu.is.saga-u.ac.jp>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
unsigned int _CRT_fmode = _O_BINARY;
|
unsigned int _CRT_fmode = _O_BINARY;
|
||||||
|
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
char* sz = "This is line one.\nThis is line two.\n";
|
char* sz = "This is line one.\nThis is line two.\n";
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
printf (sz);
|
printf (sz);
|
||||||
|
|
||||||
/* Note how this fopen does NOT indicate "wb" to open the file in
|
/* Note how this fopen does NOT indicate "wb" to open the file in
|
||||||
* binary mode. */
|
* binary mode. */
|
||||||
fp = fopen ("all.out", "w");
|
fp = fopen ("all.out", "w");
|
||||||
|
|
||||||
fprintf (fp, sz);
|
fprintf (fp, sz);
|
||||||
|
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
|
|
||||||
if (_isatty (_fileno(stdin)))
|
if (_isatty (_fileno(stdin)))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Waiting for input, press Ctrl-Z to finish.\n");
|
fprintf (stderr, "Waiting for input, press Ctrl-Z to finish.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((c = fgetc(stdin)) != EOF)
|
while ((c = fgetc(stdin)) != EOF)
|
||||||
{
|
{
|
||||||
printf ("\'%c\' %02X\n", (char) c, c);
|
printf ("\'%c\' %02X\n", (char) c, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
Main test.exe : test.c ;
|
Main test.exe : test.c ;
|
||||||
|
|
||||||
Main all.exe : all.c ;
|
Main all.exe : all.c ;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
These two demos show how _fmode and _CRT_fmode can be used to modify the
|
These two demos show how _fmode and _CRT_fmode can be used to modify the
|
||||||
default file opening mode (text vs. binary) and/or the mode of the standard
|
default file opening mode (text vs. binary) and/or the mode of the standard
|
||||||
file handles.
|
file handles.
|
||||||
|
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
/*
|
/*
|
||||||
* A sample program demonstrating how to use fmode to change the default
|
* A sample program demonstrating how to use fmode to change the default
|
||||||
* file opening mode to binary. NOTE: Does not change stdin, stdout or
|
* file opening mode to binary. NOTE: Does not change stdin, stdout or
|
||||||
* stderr.
|
* stderr.
|
||||||
*
|
*
|
||||||
* THIS CODE IS IN THE PUBLIC DOMAIN.
|
* THIS CODE IS IN THE PUBLIC DOMAIN.
|
||||||
*
|
*
|
||||||
* Colin Peters <colin@fu.is.saga-u.ac.jp>
|
* Colin Peters <colin@fu.is.saga-u.ac.jp>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h> /* Required to get _fmode and _O_BINARY */
|
#include <fcntl.h> /* Required to get _fmode and _O_BINARY */
|
||||||
|
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
char* sz = "This is line one.\nThis is line two.\n";
|
char* sz = "This is line one.\nThis is line two.\n";
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
|
|
||||||
_fmode = _O_BINARY;
|
_fmode = _O_BINARY;
|
||||||
|
|
||||||
printf (sz);
|
printf (sz);
|
||||||
|
|
||||||
/* Note how this fopen does NOT indicate "wb" to open the file in
|
/* Note how this fopen does NOT indicate "wb" to open the file in
|
||||||
* binary mode. */
|
* binary mode. */
|
||||||
fp = fopen ("test.out", "w");
|
fp = fopen ("test.out", "w");
|
||||||
|
|
||||||
fprintf (fp, sz);
|
fprintf (fp, sz);
|
||||||
|
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#
|
#
|
||||||
# A simple example which prints a message on a selected printer. This won't
|
# A simple example which prints a message on a selected printer. This won't
|
||||||
# work right unless you make PRINTDLG a packed structure!
|
# work right unless you make PRINTDLG a packed structure!
|
||||||
#
|
#
|
||||||
|
|
||||||
Main prntest.exe : prntest.c ;
|
Main prntest.exe : prntest.c ;
|
||||||
|
|
||||||
Gui prntest.exe ;
|
Gui prntest.exe ;
|
||||||
|
|
||||||
|
|
|
@ -1,65 +1,65 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
PRINTDLG pd;
|
PRINTDLG pd;
|
||||||
DOCINFO di;
|
DOCINFO di;
|
||||||
char* szMessage;
|
char* szMessage;
|
||||||
|
|
||||||
memset (&pd, 0, sizeof(PRINTDLG));
|
memset (&pd, 0, sizeof(PRINTDLG));
|
||||||
memset (&di, 0, sizeof(DOCINFO));
|
memset (&di, 0, sizeof(DOCINFO));
|
||||||
|
|
||||||
di.cbSize = sizeof(DOCINFO);
|
di.cbSize = sizeof(DOCINFO);
|
||||||
di.lpszDocName = "Test";
|
di.lpszDocName = "Test";
|
||||||
|
|
||||||
pd.lStructSize = sizeof(PRINTDLG);
|
pd.lStructSize = sizeof(PRINTDLG);
|
||||||
pd.Flags = PD_PAGENUMS | PD_RETURNDC;
|
pd.Flags = PD_PAGENUMS | PD_RETURNDC;
|
||||||
pd.nFromPage = 1;
|
pd.nFromPage = 1;
|
||||||
pd.nToPage = 1;
|
pd.nToPage = 1;
|
||||||
pd.nMinPage = 1;
|
pd.nMinPage = 1;
|
||||||
pd.nMaxPage = 1;
|
pd.nMaxPage = 1;
|
||||||
|
|
||||||
szMessage = 0;
|
szMessage = 0;
|
||||||
|
|
||||||
if (PrintDlg (&pd))
|
if (PrintDlg (&pd))
|
||||||
{
|
{
|
||||||
if (pd.hDC)
|
if (pd.hDC)
|
||||||
{
|
{
|
||||||
if (StartDoc (pd.hDC, &di) != SP_ERROR)
|
if (StartDoc (pd.hDC, &di) != SP_ERROR)
|
||||||
{
|
{
|
||||||
StartPage (pd.hDC);
|
StartPage (pd.hDC);
|
||||||
|
|
||||||
TextOut (pd.hDC, 0, 0, "Hello, printer!", 15);
|
TextOut (pd.hDC, 0, 0, "Hello, printer!", 15);
|
||||||
|
|
||||||
EndPage (pd.hDC);
|
EndPage (pd.hDC);
|
||||||
|
|
||||||
EndDoc (pd.hDC);
|
EndDoc (pd.hDC);
|
||||||
|
|
||||||
szMessage = "Printed.";
|
szMessage = "Printed.";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
szMessage = "Could not start document.";
|
szMessage = "Could not start document.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
szMessage = "Could not create device context.";
|
szMessage = "Could not create device context.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
szMessage = "Canceled or printer could not be setup.";
|
szMessage = "Canceled or printer could not be setup.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (szMessage)
|
if (szMessage)
|
||||||
{
|
{
|
||||||
MessageBox (NULL, szMessage, "Print Test", MB_OK);
|
MessageBox (NULL, szMessage, "Print Test", MB_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,112 +1,112 @@
|
||||||
int
|
int
|
||||||
__except_handler3(
|
__except_handler3(
|
||||||
struct _EXCEPTION_RECORD* pExceptionRecord,
|
struct _EXCEPTION_RECORD* pExceptionRecord,
|
||||||
struct EXCEPTION_REGISTRATION* pRegistrationFrame,
|
struct EXCEPTION_REGISTRATION* pRegistrationFrame,
|
||||||
struct _CONTEXT* pContextRecord,
|
struct _CONTEXT* pContextRecord,
|
||||||
void* pDispatcherContext
|
void* pDispatcherContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
LONG filterFuncRet;
|
LONG filterFuncRet;
|
||||||
LONG trylevel;
|
LONG trylevel;
|
||||||
EXCEPTION_POINTERS exceptPtrs;
|
EXCEPTION_POINTERS exceptPtrs;
|
||||||
PSCOPETABLE pScopeTable;
|
PSCOPETABLE pScopeTable;
|
||||||
|
|
||||||
|
|
||||||
CLD // Clear the direction flag (make no assumptions!)
|
CLD // Clear the direction flag (make no assumptions!)
|
||||||
|
|
||||||
// if neither the EXCEPTION_UNWINDING nor EXCEPTION_EXIT_UNWIND bit
|
// if neither the EXCEPTION_UNWINDING nor EXCEPTION_EXIT_UNWIND bit
|
||||||
// is set... This is true the first time through the handler (the
|
// is set... This is true the first time through the handler (the
|
||||||
// non-unwinding case)
|
// non-unwinding case)
|
||||||
|
|
||||||
if ( ! (pExceptionRecord->ExceptionFlags
|
if ( ! (pExceptionRecord->ExceptionFlags
|
||||||
& (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)
|
& (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)
|
||||||
) )
|
) )
|
||||||
{
|
{
|
||||||
// Build the EXCEPTION_POINTERS structure on the stack
|
// Build the EXCEPTION_POINTERS structure on the stack
|
||||||
exceptPtrs.ExceptionRecord = pExceptionRecord;
|
exceptPtrs.ExceptionRecord = pExceptionRecord;
|
||||||
exceptPtrs.ContextRecord = pContextRecord;
|
exceptPtrs.ContextRecord = pContextRecord;
|
||||||
|
|
||||||
// Put the pointer to the EXCEPTION_POINTERS 4 bytes below the
|
// Put the pointer to the EXCEPTION_POINTERS 4 bytes below the
|
||||||
// establisher frame. See ASM code for GetExceptionInformation
|
// establisher frame. See ASM code for GetExceptionInformation
|
||||||
*(PDWORD)((PBYTE)pRegistrationFrame - 4) = &exceptPtrs;
|
*(PDWORD)((PBYTE)pRegistrationFrame - 4) = &exceptPtrs;
|
||||||
|
|
||||||
// Get initial "trylevel" value
|
// Get initial "trylevel" value
|
||||||
trylevel = pRegistrationFrame->trylevel
|
trylevel = pRegistrationFrame->trylevel
|
||||||
|
|
||||||
// Get a pointer to the scopetable array
|
// Get a pointer to the scopetable array
|
||||||
scopeTable = pRegistrationFrame->scopetable;
|
scopeTable = pRegistrationFrame->scopetable;
|
||||||
|
|
||||||
search_for_handler:
|
search_for_handler:
|
||||||
if ( pRegistrationFrame->trylevel != TRYLEVEL_NONE )
|
if ( pRegistrationFrame->trylevel != TRYLEVEL_NONE )
|
||||||
{
|
{
|
||||||
if ( pRegistrationFrame->scopetable[trylevel].lpfnFilter )
|
if ( pRegistrationFrame->scopetable[trylevel].lpfnFilter )
|
||||||
{
|
{
|
||||||
|
|
||||||
PUSH EBP // Save this frame EBP
|
PUSH EBP // Save this frame EBP
|
||||||
|
|
||||||
// !!!Very Important!!! Switch to original EBP. This is
|
// !!!Very Important!!! Switch to original EBP. This is
|
||||||
// what allows all locals in the frame to have the same
|
// what allows all locals in the frame to have the same
|
||||||
// value as before the exception occurred.
|
// value as before the exception occurred.
|
||||||
|
|
||||||
EBP = &pRegistrationFrame->_ebp
|
EBP = &pRegistrationFrame->_ebp
|
||||||
|
|
||||||
// Call the filter function
|
// Call the filter function
|
||||||
filterFuncRet = scopetable[trylevel].lpfnFilter();
|
filterFuncRet = scopetable[trylevel].lpfnFilter();
|
||||||
|
|
||||||
POP EBP // Restore handler frame EBP
|
POP EBP // Restore handler frame EBP
|
||||||
|
|
||||||
if ( filterFuncRet != EXCEPTION_CONTINUE_SEARCH )
|
if ( filterFuncRet != EXCEPTION_CONTINUE_SEARCH )
|
||||||
{
|
{
|
||||||
if ( filterFuncRet < 0 ) // EXCEPTION_CONTINUE_EXECUTION
|
if ( filterFuncRet < 0 ) // EXCEPTION_CONTINUE_EXECUTION
|
||||||
return ExceptionContinueExecution;
|
return ExceptionContinueExecution;
|
||||||
|
|
||||||
// If we get here, EXCEPTION_EXECUTE_HANDLER was specified
|
// If we get here, EXCEPTION_EXECUTE_HANDLER was specified
|
||||||
scopetable == pRegistrationFrame->scopetable
|
scopetable == pRegistrationFrame->scopetable
|
||||||
|
|
||||||
// Does the actual OS cleanup of registration frames
|
// Does the actual OS cleanup of registration frames
|
||||||
// Causes this function to recurse
|
// Causes this function to recurse
|
||||||
__global_unwind2( pRegistrationFrame );
|
__global_unwind2( pRegistrationFrame );
|
||||||
|
|
||||||
|
|
||||||
// Once we get here, everything is all cleaned up, except
|
// Once we get here, everything is all cleaned up, except
|
||||||
// for the last frame, where we'll continue execution
|
// for the last frame, where we'll continue execution
|
||||||
EBP = &pRegistrationFrame->_ebp
|
EBP = &pRegistrationFrame->_ebp
|
||||||
|
|
||||||
__local_unwind2( pRegistrationFrame, trylevel );
|
__local_unwind2( pRegistrationFrame, trylevel );
|
||||||
|
|
||||||
// NLG == "non-local-goto" (setjmp/longjmp stuff)
|
// NLG == "non-local-goto" (setjmp/longjmp stuff)
|
||||||
__NLG_Notify( 1 ); // EAX == scopetable->lpfnHandler
|
__NLG_Notify( 1 ); // EAX == scopetable->lpfnHandler
|
||||||
|
|
||||||
// Set the current trylevel to whatever SCOPETABLE entry
|
// Set the current trylevel to whatever SCOPETABLE entry
|
||||||
// was being used when a handler was found
|
// was being used when a handler was found
|
||||||
pRegistrationFrame->trylevel = scopetable->previousTryLevel;
|
pRegistrationFrame->trylevel = scopetable->previousTryLevel;
|
||||||
|
|
||||||
// Call the _except {} block. Never returns.
|
// Call the _except {} block. Never returns.
|
||||||
pRegistrationFrame->scopetable[trylevel].lpfnHandler();
|
pRegistrationFrame->scopetable[trylevel].lpfnHandler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scopeTable = pRegistrationFrame->scopetable;
|
scopeTable = pRegistrationFrame->scopetable;
|
||||||
trylevel = scopeTable->previousTryLevel
|
trylevel = scopeTable->previousTryLevel
|
||||||
|
|
||||||
goto search_for_handler;
|
goto search_for_handler;
|
||||||
}
|
}
|
||||||
else // trylevel == TRYLEVEL_NONE
|
else // trylevel == TRYLEVEL_NONE
|
||||||
{
|
{
|
||||||
retvalue == DISPOSITION_CONTINUE_SEARCH;
|
retvalue == DISPOSITION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // EXCEPTION_UNWINDING or EXCEPTION_EXIT_UNWIND flags are set
|
else // EXCEPTION_UNWINDING or EXCEPTION_EXIT_UNWIND flags are set
|
||||||
{
|
{
|
||||||
PUSH EBP // Save EBP
|
PUSH EBP // Save EBP
|
||||||
|
|
||||||
EBP = pRegistrationFrame->_ebp // Set EBP for __local_unwind2
|
EBP = pRegistrationFrame->_ebp // Set EBP for __local_unwind2
|
||||||
|
|
||||||
__local_unwind2( pRegistrationFrame, TRYLEVEL_NONE )
|
__local_unwind2( pRegistrationFrame, TRYLEVEL_NONE )
|
||||||
|
|
||||||
POP EBP // Restore EBP
|
POP EBP // Restore EBP
|
||||||
|
|
||||||
retvalue == DISPOSITION_CONTINUE_SEARCH;
|
retvalue == DISPOSITION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,68 +1,68 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <excpt.h>
|
#include <excpt.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "exutil.h"
|
#include "exutil.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
WalkExceptionHandlers ()
|
WalkExceptionHandlers ()
|
||||||
{
|
{
|
||||||
PEXCEPTION_REGISTRATION_RECORD p;
|
PEXCEPTION_REGISTRATION_RECORD p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
__asm__("movl %%fs:0,%%eax;movl %%eax,%0" : "=g" (p) : : "%eax");
|
__asm__("movl %%fs:0,%%eax;movl %%eax,%0" : "=g" (p) : : "%eax");
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (p != (PEXCEPTION_REGISTRATION_RECORD) -1 && p)
|
while (p != (PEXCEPTION_REGISTRATION_RECORD) -1 && p)
|
||||||
{
|
{
|
||||||
printf ("Registration %d at %08x : ", i, p);
|
printf ("Registration %d at %08x : ", i, p);
|
||||||
printf ("Handler = %08x ", p->handler);
|
printf ("Handler = %08x ", p->handler);
|
||||||
printf ("Next Registration = %08x\n", p->prev);
|
printf ("Next Registration = %08x\n", p->prev);
|
||||||
p = p->prev;
|
p = p->prev;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
printf ("End of exception handler list.\n");
|
printf ("End of exception handler list.\n");
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DumpExceptionRecord (struct _EXCEPTION_RECORD* pExRec)
|
DumpExceptionRecord (struct _EXCEPTION_RECORD* pExRec)
|
||||||
{
|
{
|
||||||
printf ("Exception: Code = %08x Flags %08x", pExRec->ExceptionCode,
|
printf ("Exception: Code = %08x Flags %08x", pExRec->ExceptionCode,
|
||||||
pExRec->ExceptionFlags);
|
pExRec->ExceptionFlags);
|
||||||
|
|
||||||
if (pExRec->ExceptionFlags)
|
if (pExRec->ExceptionFlags)
|
||||||
{
|
{
|
||||||
printf (" ( ");
|
printf (" ( ");
|
||||||
if (pExRec->ExceptionFlags & EH_NONCONTINUABLE)
|
if (pExRec->ExceptionFlags & EH_NONCONTINUABLE)
|
||||||
{
|
{
|
||||||
printf ("EH_NONCONTINUABLE ");
|
printf ("EH_NONCONTINUABLE ");
|
||||||
}
|
}
|
||||||
if (pExRec->ExceptionFlags & EH_UNWINDING)
|
if (pExRec->ExceptionFlags & EH_UNWINDING)
|
||||||
{
|
{
|
||||||
printf ("EH_UNWINDING ");
|
printf ("EH_UNWINDING ");
|
||||||
}
|
}
|
||||||
if (pExRec->ExceptionFlags & EH_EXIT_UNWIND)
|
if (pExRec->ExceptionFlags & EH_EXIT_UNWIND)
|
||||||
{
|
{
|
||||||
printf ("EH_EXIT_UNWIND ");
|
printf ("EH_EXIT_UNWIND ");
|
||||||
}
|
}
|
||||||
if (pExRec->ExceptionFlags & EH_STACK_INVALID)
|
if (pExRec->ExceptionFlags & EH_STACK_INVALID)
|
||||||
{
|
{
|
||||||
printf ("EH_STACK_INVALID ");
|
printf ("EH_STACK_INVALID ");
|
||||||
}
|
}
|
||||||
if (pExRec->ExceptionFlags & EH_NESTED_CALL)
|
if (pExRec->ExceptionFlags & EH_NESTED_CALL)
|
||||||
{
|
{
|
||||||
printf ("EH_NESTED_CALL ");
|
printf ("EH_NESTED_CALL ");
|
||||||
}
|
}
|
||||||
printf (")\n");
|
printf (")\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
EXPORTS
|
EXPORTS
|
||||||
WalkExceptionHandlers
|
WalkExceptionHandlers
|
||||||
DumpExceptionRecord
|
DumpExceptionRecord
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
/*
|
/*
|
||||||
* Definitions of some internal stuff for exception handling, including
|
* Definitions of some internal stuff for exception handling, including
|
||||||
* a version of the all-important EXCEPTION_REGISTRATION_RECORD.
|
* a version of the all-important EXCEPTION_REGISTRATION_RECORD.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _EXUTIL_H_
|
#ifndef _EXUTIL_H_
|
||||||
#define _EXUTIL_H_
|
#define _EXUTIL_H_
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <excpt.h>
|
#include <excpt.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void WalkExceptionHandlers ();
|
void WalkExceptionHandlers ();
|
||||||
void DumpExceptionRecord (struct _EXCEPTION_RECORD* pExRec);
|
void DumpExceptionRecord (struct _EXCEPTION_RECORD* pExRec);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
|
|
||||||
Dll exutil.dll : exutil.c ;
|
Dll exutil.dll : exutil.c ;
|
||||||
|
|
||||||
ImportLib libexutil.a : exutil.def ;
|
ImportLib libexutil.a : exutil.def ;
|
||||||
|
|
||||||
Main sehtest.exe : sehtest.c ;
|
Main sehtest.exe : sehtest.c ;
|
||||||
|
|
||||||
Main sehfix.exe : sehfix.c ;
|
Main sehfix.exe : sehfix.c ;
|
||||||
|
|
||||||
Main sehsub.exe : sehsub.c ;
|
Main sehsub.exe : sehsub.c ;
|
||||||
|
|
||||||
LinkLibraries sehtest.exe sehfix.exe sehsub.exe : libexutil.a ;
|
LinkLibraries sehtest.exe sehfix.exe sehsub.exe : libexutil.a ;
|
||||||
|
|
||||||
|
|
|
@ -1,60 +1,60 @@
|
||||||
/*
|
/*
|
||||||
* sehfix.c
|
* sehfix.c
|
||||||
*
|
*
|
||||||
* A test program involving an exception handler that fixes the exception
|
* A test program involving an exception handler that fixes the exception
|
||||||
* causing condition.
|
* causing condition.
|
||||||
*
|
*
|
||||||
* In this code we install an exception handler my_handler and then a piece
|
* In this code we install an exception handler my_handler and then a piece
|
||||||
* of inline assembly attempts to write at the address marked in eax, after
|
* of inline assembly attempts to write at the address marked in eax, after
|
||||||
* setting eax to 10. This should produce an exception. The handler then
|
* setting eax to 10. This should produce an exception. The handler then
|
||||||
* changes the eax register of the exception context to be the address of
|
* changes the eax register of the exception context to be the address of
|
||||||
* a static variable and restarts the code. This should allow everything
|
* a static variable and restarts the code. This should allow everything
|
||||||
* to continue.
|
* to continue.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <excpt.h>
|
#include <excpt.h>
|
||||||
|
|
||||||
#include "exutil.h"
|
#include "exutil.h"
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
EXCEPTION_DISPOSITION
|
EXCEPTION_DISPOSITION
|
||||||
my_handler (
|
my_handler (
|
||||||
struct _EXCEPTION_RECORD* pExceptionRec,
|
struct _EXCEPTION_RECORD* pExceptionRec,
|
||||||
void* pEstablisherFrame,
|
void* pEstablisherFrame,
|
||||||
struct _CONTEXT* pContextRecord,
|
struct _CONTEXT* pContextRecord,
|
||||||
void* pDispatcherContext
|
void* pDispatcherContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
printf ("In my exception handler!\n");
|
printf ("In my exception handler!\n");
|
||||||
DumpExceptionRecord (pExceptionRec);
|
DumpExceptionRecord (pExceptionRec);
|
||||||
pContextRecord->Eax = (DWORD) &x;
|
pContextRecord->Eax = (DWORD) &x;
|
||||||
return ExceptionContinueExecution;
|
return ExceptionContinueExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
x = 2;
|
x = 2;
|
||||||
|
|
||||||
printf ("x = %d\n", x);
|
printf ("x = %d\n", x);
|
||||||
|
|
||||||
WalkExceptionHandlers();
|
WalkExceptionHandlers();
|
||||||
|
|
||||||
__try1(my_handler)
|
__try1(my_handler)
|
||||||
|
|
||||||
WalkExceptionHandlers();
|
WalkExceptionHandlers();
|
||||||
|
|
||||||
/* This assembly code should produce an exception. */
|
/* This assembly code should produce an exception. */
|
||||||
__asm__("movl $10,%%eax;movl $1,(%%eax);" : : : "%eax");
|
__asm__("movl $10,%%eax;movl $1,(%%eax);" : : : "%eax");
|
||||||
|
|
||||||
__except1
|
__except1
|
||||||
|
|
||||||
WalkExceptionHandlers();
|
WalkExceptionHandlers();
|
||||||
|
|
||||||
printf ("x = %d\n", x);
|
printf ("x = %d\n", x);
|
||||||
|
|
||||||
printf ("Finished!\n");
|
printf ("Finished!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
/*
|
/*
|
||||||
* sehsub.c
|
* sehsub.c
|
||||||
*
|
*
|
||||||
* In an attempt to see what might be going on inside CRTDLL, this program
|
* In an attempt to see what might be going on inside CRTDLL, this program
|
||||||
* walks the exception list after creating a new thread with _beginthread.
|
* walks the exception list after creating a new thread with _beginthread.
|
||||||
*
|
*
|
||||||
* It turns out that _beginthread DOES install an exception handler, as
|
* It turns out that _beginthread DOES install an exception handler, as
|
||||||
* expected, but this handler is NOT exported by CRTDLL (it is certainly
|
* expected, but this handler is NOT exported by CRTDLL (it is certainly
|
||||||
* not _except_handler2 or _XcptFilter)... an odd and unpleasant turn of
|
* not _except_handler2 or _XcptFilter)... an odd and unpleasant turn of
|
||||||
* events.
|
* events.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <excpt.h>
|
#include <excpt.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
|
||||||
#include "exutil.h"
|
#include "exutil.h"
|
||||||
|
|
||||||
extern void* __imp__except_handler3;
|
extern void* __imp__except_handler3;
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
my_thread (void * p)
|
my_thread (void * p)
|
||||||
{
|
{
|
||||||
printf ("In my thread.\n");
|
printf ("In my thread.\n");
|
||||||
WalkExceptionHandlers();
|
WalkExceptionHandlers();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
unsigned long h;
|
unsigned long h;
|
||||||
unsigned id;
|
unsigned id;
|
||||||
printf ("In main.\n");
|
printf ("In main.\n");
|
||||||
WalkExceptionHandlers();
|
WalkExceptionHandlers();
|
||||||
|
|
||||||
printf ("Except_handler3 %08x\n", __imp__except_handler3);
|
printf ("Except_handler3 %08x\n", __imp__except_handler3);
|
||||||
h = _beginthreadex (NULL, 0, my_thread, NULL, 0, &id);
|
h = _beginthreadex (NULL, 0, my_thread, NULL, 0, &id);
|
||||||
|
|
||||||
WaitForSingleObject ((HANDLE) h, INFINITE);
|
WaitForSingleObject ((HANDLE) h, INFINITE);
|
||||||
CloseHandle ((HANDLE) h);
|
CloseHandle ((HANDLE) h);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,72 +1,72 @@
|
||||||
/*
|
/*
|
||||||
* This file tests some of the basics of structured exception handling as
|
* This file tests some of the basics of structured exception handling as
|
||||||
* implemented in excpt.h and the Windows API header files.
|
* implemented in excpt.h and the Windows API header files.
|
||||||
*
|
*
|
||||||
* The program installs two exception handlers, then attempts to write to
|
* The program installs two exception handlers, then attempts to write to
|
||||||
* a pointer to an invalid address. This causes an exception which passes
|
* a pointer to an invalid address. This causes an exception which passes
|
||||||
* through the exception handlers and on to the default system exception
|
* through the exception handlers and on to the default system exception
|
||||||
* handler. That handler brings up the dialog box all Windows users know
|
* handler. That handler brings up the dialog box all Windows users know
|
||||||
* and love, and then the program is terminated.
|
* and love, and then the program is terminated.
|
||||||
*
|
*
|
||||||
* You might note that after the initial run up through our exception frames
|
* You might note that after the initial run up through our exception frames
|
||||||
* we get a second run up through them with the exception code
|
* we get a second run up through them with the exception code
|
||||||
* STATUS_INVALID_DISPOSITION and the code EH_UNWINDING. This seems normal
|
* STATUS_INVALID_DISPOSITION and the code EH_UNWINDING. This seems normal
|
||||||
* except that the code got changed from the previous STATUS_ACCESS_VIOLATION.
|
* except that the code got changed from the previous STATUS_ACCESS_VIOLATION.
|
||||||
* I don't understand that bit particularly.
|
* I don't understand that bit particularly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <excpt.h>
|
#include <excpt.h>
|
||||||
|
|
||||||
#include "exutil.h"
|
#include "exutil.h"
|
||||||
|
|
||||||
EXCEPTION_DISPOSITION
|
EXCEPTION_DISPOSITION
|
||||||
my_handler (
|
my_handler (
|
||||||
struct _EXCEPTION_RECORD* pExceptionRec,
|
struct _EXCEPTION_RECORD* pExceptionRec,
|
||||||
void* pEstablisherFrame,
|
void* pEstablisherFrame,
|
||||||
struct _CONTEXT* pContextRecord,
|
struct _CONTEXT* pContextRecord,
|
||||||
void* pDispatcherContext
|
void* pDispatcherContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
printf ("In my exception handler!\n");
|
printf ("In my exception handler!\n");
|
||||||
DumpExceptionRecord (pExceptionRec);
|
DumpExceptionRecord (pExceptionRec);
|
||||||
return ExceptionContinueSearch;
|
return ExceptionContinueSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXCEPTION_DISPOSITION
|
EXCEPTION_DISPOSITION
|
||||||
my_handler2 (
|
my_handler2 (
|
||||||
struct _EXCEPTION_RECORD* pExceptionRec,
|
struct _EXCEPTION_RECORD* pExceptionRec,
|
||||||
void* pEstablisherFrame,
|
void* pEstablisherFrame,
|
||||||
struct _CONTEXT* pContextRecord,
|
struct _CONTEXT* pContextRecord,
|
||||||
void* pDispatcherContext
|
void* pDispatcherContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
printf ("In top exception handler!\n");
|
printf ("In top exception handler!\n");
|
||||||
DumpExceptionRecord (pExceptionRec);
|
DumpExceptionRecord (pExceptionRec);
|
||||||
return ExceptionContinueSearch;
|
return ExceptionContinueSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
char* x;
|
char* x;
|
||||||
|
|
||||||
printf ("my_handler2 = %08x\n", my_handler2);
|
printf ("my_handler2 = %08x\n", my_handler2);
|
||||||
printf ("my_handler = %08x\n", my_handler);
|
printf ("my_handler = %08x\n", my_handler);
|
||||||
|
|
||||||
WalkExceptionHandlers();
|
WalkExceptionHandlers();
|
||||||
|
|
||||||
__try1(my_handler2)
|
__try1(my_handler2)
|
||||||
x = (char*) 10;
|
x = (char*) 10;
|
||||||
|
|
||||||
WalkExceptionHandlers();
|
WalkExceptionHandlers();
|
||||||
|
|
||||||
__try1(my_handler)
|
__try1(my_handler)
|
||||||
|
|
||||||
WalkExceptionHandlers();
|
WalkExceptionHandlers();
|
||||||
|
|
||||||
*x = 1;
|
*x = 1;
|
||||||
__except1
|
__except1
|
||||||
__except1
|
__except1
|
||||||
printf ("Finished!\n");
|
printf ("Finished!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
||||||
{
|
{
|
||||||
switch (dwReason)
|
switch (dwReason)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
printf ("DLL Attached.\n");
|
printf ("DLL Attached.\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
printf ("DLL Detached.\n");
|
printf ("DLL Detached.\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
printf ("DLL Thread Attached.\n");
|
printf ("DLL Thread Attached.\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
printf ("DLL Thread Detached.\n");
|
printf ("DLL Thread Detached.\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Test ()
|
Test ()
|
||||||
{
|
{
|
||||||
printf ("Test Function called!\n");
|
printf ("Test Function called!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,44 +1,44 @@
|
||||||
//
|
//
|
||||||
// This is a C++ version of the code in dll.c. NOTE that you need to put
|
// This is a C++ version of the code in dll.c. NOTE that you need to put
|
||||||
// extern "C" { ... } around DllMain or it will not be called when your
|
// extern "C" { ... } around DllMain or it will not be called when your
|
||||||
// Dll starts up! (It will get name mangled as a C++ function and the C
|
// Dll starts up! (It will get name mangled as a C++ function and the C
|
||||||
// default version in libmingw32.a will get called instead.)
|
// default version in libmingw32.a will get called instead.)
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
||||||
{
|
{
|
||||||
switch (dwReason)
|
switch (dwReason)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
cout << "Dll Attached" << endl ;
|
cout << "Dll Attached" << endl ;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
cout << "Dll Detached" << endl ;
|
cout << "Dll Detached" << endl ;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
printf ("DLL Thread Attached.\n");
|
printf ("DLL Thread Attached.\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
printf ("DLL Thread Detached.\n");
|
printf ("DLL Thread Detached.\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Test ()
|
Test ()
|
||||||
{
|
{
|
||||||
printf ("Test Function called!\n");
|
printf ("Test Function called!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
EXPORTS
|
EXPORTS
|
||||||
Test
|
Test
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
extern void Test();
|
extern void Test();
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
printf ("Program started.\n");
|
printf ("Program started.\n");
|
||||||
Test ();
|
Test ();
|
||||||
printf ("Program ends.\n");
|
printf ("Program ends.\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
|
|
||||||
Dll dll.dll : dll.c ;
|
Dll dll.dll : dll.c ;
|
||||||
|
|
||||||
ImportLib libdll.a : dll.def ;
|
ImportLib libdll.a : dll.def ;
|
||||||
|
|
||||||
|
|
||||||
Main exe.exe : exe.c ;
|
Main exe.exe : exe.c ;
|
||||||
|
|
||||||
LinkLibraries exe.exe : libdll.a ;
|
LinkLibraries exe.exe : libdll.a ;
|
||||||
|
|
||||||
DEPENDS exe.exe : dll.dll ;
|
DEPENDS exe.exe : dll.dll ;
|
||||||
|
|
||||||
LINKFLAGS on exe.exe = $(LINKFLAGS) -L. ;
|
LINKFLAGS on exe.exe = $(LINKFLAGS) -L. ;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#
|
#
|
||||||
# A very simple example with which you can test your compiler/jam setup.
|
# A very simple example with which you can test your compiler/jam setup.
|
||||||
# Also an interesting example of a hybrid console/GUI application.
|
# Also an interesting example of a hybrid console/GUI application.
|
||||||
#
|
#
|
||||||
|
|
||||||
Main test.exe : test.c ;
|
Main test.exe : test.c ;
|
||||||
|
|
||||||
GuiLibs test.exe ;
|
GuiLibs test.exe ;
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
/*
|
/*
|
||||||
* This source code is in the PUBLIC DOMAIN and has NO WARRANTY.
|
* This source code is in the PUBLIC DOMAIN and has NO WARRANTY.
|
||||||
*
|
*
|
||||||
* Colin Peters <colin@bird.fu.is.saga-u.ac.jp>, April 15, 1997.
|
* Colin Peters <colin@bird.fu.is.saga-u.ac.jp>, April 15, 1997.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int STDCALL
|
int STDCALL
|
||||||
WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
|
WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
|
||||||
{
|
{
|
||||||
char text[80];
|
char text[80];
|
||||||
|
|
||||||
printf ("Enter message box text:");
|
printf ("Enter message box text:");
|
||||||
fgets(text, 80, stdin);
|
fgets(text, 80, stdin);
|
||||||
MessageBox (NULL, text, "Test", MB_OK);
|
MessageBox (NULL, text, "Test", MB_OK);
|
||||||
printf ("\nHello after message box.\n");
|
printf ("\nHello after message box.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#
|
#
|
||||||
# A example of Win32 GUI programming in C.
|
# A example of Win32 GUI programming in C.
|
||||||
#
|
#
|
||||||
|
|
||||||
Main test.exe : test.c ;
|
Main test.exe : test.c ;
|
||||||
|
|
||||||
Gui test.exe ;
|
Gui test.exe ;
|
||||||
|
|
||||||
|
|
|
@ -1,212 +1,212 @@
|
||||||
/*
|
/*
|
||||||
* A basic example of Win32 programming in C.
|
* A basic example of Win32 programming in C.
|
||||||
*
|
*
|
||||||
* This source code is in the PUBLIC DOMAIN and has NO WARRANTY.
|
* This source code is in the PUBLIC DOMAIN and has NO WARRANTY.
|
||||||
*
|
*
|
||||||
* Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
|
* Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the window function for the main window. Whenever a message is
|
* This is the window function for the main window. Whenever a message is
|
||||||
* dispatched using DispatchMessage (or sent with SendMessage) this function
|
* dispatched using DispatchMessage (or sent with SendMessage) this function
|
||||||
* gets called with the contents of the message.
|
* gets called with the contents of the message.
|
||||||
*/
|
*/
|
||||||
LRESULT CALLBACK
|
LRESULT CALLBACK
|
||||||
MainWndProc (HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
|
MainWndProc (HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
/* The window handle for the "Click Me" button. */
|
/* The window handle for the "Click Me" button. */
|
||||||
static HWND hwndButton = 0;
|
static HWND hwndButton = 0;
|
||||||
static int cx, cy; /* Height and width of our button. */
|
static int cx, cy; /* Height and width of our button. */
|
||||||
|
|
||||||
HDC hdc; /* A device context used for drawing */
|
HDC hdc; /* A device context used for drawing */
|
||||||
PAINTSTRUCT ps; /* Also used during window drawing */
|
PAINTSTRUCT ps; /* Also used during window drawing */
|
||||||
RECT rc; /* A rectangle used during drawing */
|
RECT rc; /* A rectangle used during drawing */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform processing based on what kind of message we got.
|
* Perform processing based on what kind of message we got.
|
||||||
*/
|
*/
|
||||||
switch (nMsg)
|
switch (nMsg)
|
||||||
{
|
{
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
{
|
{
|
||||||
/* The window is being created. Create our button
|
/* The window is being created. Create our button
|
||||||
* window now. */
|
* window now. */
|
||||||
TEXTMETRIC tm;
|
TEXTMETRIC tm;
|
||||||
|
|
||||||
/* First we use the system fixed font size to choose
|
/* First we use the system fixed font size to choose
|
||||||
* a nice button size. */
|
* a nice button size. */
|
||||||
hdc = GetDC (hwnd);
|
hdc = GetDC (hwnd);
|
||||||
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
|
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
|
||||||
GetTextMetrics (hdc, &tm);
|
GetTextMetrics (hdc, &tm);
|
||||||
cx = tm.tmAveCharWidth * 30;
|
cx = tm.tmAveCharWidth * 30;
|
||||||
cy = (tm.tmHeight + tm.tmExternalLeading) * 2;
|
cy = (tm.tmHeight + tm.tmExternalLeading) * 2;
|
||||||
ReleaseDC (hwnd, hdc);
|
ReleaseDC (hwnd, hdc);
|
||||||
|
|
||||||
/* Now create the button */
|
/* Now create the button */
|
||||||
hwndButton = CreateWindow (
|
hwndButton = CreateWindow (
|
||||||
"button", /* Builtin button class */
|
"button", /* Builtin button class */
|
||||||
"Click Here",
|
"Click Here",
|
||||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
|
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
|
||||||
0, 0, cx, cy,
|
0, 0, cx, cy,
|
||||||
hwnd, /* Parent is this window. */
|
hwnd, /* Parent is this window. */
|
||||||
(HMENU) 1, /* Control ID: 1 */
|
(HMENU) 1, /* Control ID: 1 */
|
||||||
((LPCREATESTRUCT) lParam)->hInstance,
|
((LPCREATESTRUCT) lParam)->hInstance,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
/* The window is being destroyed, close the application
|
/* The window is being destroyed, close the application
|
||||||
* (the child button gets destroyed automatically). */
|
* (the child button gets destroyed automatically). */
|
||||||
PostQuitMessage (0);
|
PostQuitMessage (0);
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
/* The window needs to be painted (redrawn). */
|
/* The window needs to be painted (redrawn). */
|
||||||
hdc = BeginPaint (hwnd, &ps);
|
hdc = BeginPaint (hwnd, &ps);
|
||||||
GetClientRect (hwnd, &rc);
|
GetClientRect (hwnd, &rc);
|
||||||
|
|
||||||
/* Draw "Hello, World" in the middle of the upper
|
/* Draw "Hello, World" in the middle of the upper
|
||||||
* half of the window. */
|
* half of the window. */
|
||||||
rc.bottom = rc.bottom / 2;
|
rc.bottom = rc.bottom / 2;
|
||||||
DrawText (hdc, "Hello, World", -1, &rc,
|
DrawText (hdc, "Hello, World", -1, &rc,
|
||||||
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
|
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
|
||||||
|
|
||||||
EndPaint (hwnd, &ps);
|
EndPaint (hwnd, &ps);
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
/* The window size is changing. If the button exists
|
/* The window size is changing. If the button exists
|
||||||
* then place it in the center of the bottom half of
|
* then place it in the center of the bottom half of
|
||||||
* the window. */
|
* the window. */
|
||||||
if (hwndButton &&
|
if (hwndButton &&
|
||||||
(wParam == SIZEFULLSCREEN ||
|
(wParam == SIZEFULLSCREEN ||
|
||||||
wParam == SIZENORMAL)
|
wParam == SIZENORMAL)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
rc.left = (LOWORD(lParam) - cx) / 2;
|
rc.left = (LOWORD(lParam) - cx) / 2;
|
||||||
rc.top = HIWORD(lParam) * 3 / 4 - cy / 2;
|
rc.top = HIWORD(lParam) * 3 / 4 - cy / 2;
|
||||||
MoveWindow (
|
MoveWindow (
|
||||||
hwndButton,
|
hwndButton,
|
||||||
rc.left, rc.top, cx, cy, TRUE);
|
rc.left, rc.top, cx, cy, TRUE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
/* Check the control ID, notification code and
|
/* Check the control ID, notification code and
|
||||||
* control handle to see if this is a button click
|
* control handle to see if this is a button click
|
||||||
* message from our child button. */
|
* message from our child button. */
|
||||||
if (LOWORD(wParam) == 1 &&
|
if (LOWORD(wParam) == 1 &&
|
||||||
HIWORD(wParam) == BN_CLICKED &&
|
HIWORD(wParam) == BN_CLICKED &&
|
||||||
(HWND) lParam == hwndButton)
|
(HWND) lParam == hwndButton)
|
||||||
{
|
{
|
||||||
/* Our button was clicked. Close the window. */
|
/* Our button was clicked. Close the window. */
|
||||||
DestroyWindow (hwnd);
|
DestroyWindow (hwnd);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we don't handle a message completely we hand it to the system
|
/* If we don't handle a message completely we hand it to the system
|
||||||
* provided default window function. */
|
* provided default window function. */
|
||||||
return DefWindowProc (hwnd, nMsg, wParam, lParam);
|
return DefWindowProc (hwnd, nMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int STDCALL
|
int STDCALL
|
||||||
WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
|
WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
|
||||||
{
|
{
|
||||||
HWND hwndMain; /* Handle for the main window. */
|
HWND hwndMain; /* Handle for the main window. */
|
||||||
MSG msg; /* A Win32 message structure. */
|
MSG msg; /* A Win32 message structure. */
|
||||||
WNDCLASSEX wndclass; /* A window class structure. */
|
WNDCLASSEX wndclass; /* A window class structure. */
|
||||||
char* szMainWndClass = "WinTestWin";
|
char* szMainWndClass = "WinTestWin";
|
||||||
/* The name of the main window class */
|
/* The name of the main window class */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First we create a window class for our main window.
|
* First we create a window class for our main window.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Initialize the entire structure to zero. */
|
/* Initialize the entire structure to zero. */
|
||||||
memset (&wndclass, 0, sizeof(WNDCLASSEX));
|
memset (&wndclass, 0, sizeof(WNDCLASSEX));
|
||||||
|
|
||||||
/* This class is called WinTestWin */
|
/* This class is called WinTestWin */
|
||||||
wndclass.lpszClassName = szMainWndClass;
|
wndclass.lpszClassName = szMainWndClass;
|
||||||
|
|
||||||
/* cbSize gives the size of the structure for extensibility. */
|
/* cbSize gives the size of the structure for extensibility. */
|
||||||
wndclass.cbSize = sizeof(WNDCLASSEX);
|
wndclass.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
|
||||||
/* All windows of this class redraw when resized. */
|
/* All windows of this class redraw when resized. */
|
||||||
wndclass.style = CS_HREDRAW | CS_VREDRAW;
|
wndclass.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
|
|
||||||
/* All windows of this class use the MainWndProc window function. */
|
/* All windows of this class use the MainWndProc window function. */
|
||||||
wndclass.lpfnWndProc = MainWndProc;
|
wndclass.lpfnWndProc = MainWndProc;
|
||||||
|
|
||||||
/* This class is used with the current program instance. */
|
/* This class is used with the current program instance. */
|
||||||
wndclass.hInstance = hInst;
|
wndclass.hInstance = hInst;
|
||||||
|
|
||||||
/* Use standard application icon and arrow cursor provided by the OS */
|
/* Use standard application icon and arrow cursor provided by the OS */
|
||||||
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
|
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
|
||||||
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
|
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
|
||||||
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
|
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
|
||||||
|
|
||||||
/* Color the background white */
|
/* Color the background white */
|
||||||
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
|
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now register the window class for use.
|
* Now register the window class for use.
|
||||||
*/
|
*/
|
||||||
RegisterClassEx (&wndclass);
|
RegisterClassEx (&wndclass);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create our main window using that window class.
|
* Create our main window using that window class.
|
||||||
*/
|
*/
|
||||||
hwndMain = CreateWindow (
|
hwndMain = CreateWindow (
|
||||||
szMainWndClass, /* Class name */
|
szMainWndClass, /* Class name */
|
||||||
"Hello", /* Caption */
|
"Hello", /* Caption */
|
||||||
WS_OVERLAPPEDWINDOW, /* Style */
|
WS_OVERLAPPEDWINDOW, /* Style */
|
||||||
CW_USEDEFAULT, /* Initial x (use default) */
|
CW_USEDEFAULT, /* Initial x (use default) */
|
||||||
CW_USEDEFAULT, /* Initial y (use default) */
|
CW_USEDEFAULT, /* Initial y (use default) */
|
||||||
CW_USEDEFAULT, /* Initial x size (use default) */
|
CW_USEDEFAULT, /* Initial x size (use default) */
|
||||||
CW_USEDEFAULT, /* Initial y size (use default) */
|
CW_USEDEFAULT, /* Initial y size (use default) */
|
||||||
NULL, /* No parent window */
|
NULL, /* No parent window */
|
||||||
NULL, /* No menu */
|
NULL, /* No menu */
|
||||||
hInst, /* This program instance */
|
hInst, /* This program instance */
|
||||||
NULL /* Creation parameters */
|
NULL /* Creation parameters */
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display the window which we just created (using the nShow
|
* Display the window which we just created (using the nShow
|
||||||
* passed by the OS, which allows for start minimized and that
|
* passed by the OS, which allows for start minimized and that
|
||||||
* sort of thing).
|
* sort of thing).
|
||||||
*/
|
*/
|
||||||
ShowWindow (hwndMain, nShow);
|
ShowWindow (hwndMain, nShow);
|
||||||
UpdateWindow (hwndMain);
|
UpdateWindow (hwndMain);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The main message loop. All messages being sent to the windows
|
* The main message loop. All messages being sent to the windows
|
||||||
* of the application (or at least the primary thread) are retrieved
|
* of the application (or at least the primary thread) are retrieved
|
||||||
* by the GetMessage call, then translated (mainly for keyboard
|
* by the GetMessage call, then translated (mainly for keyboard
|
||||||
* messages) and dispatched to the appropriate window procedure.
|
* messages) and dispatched to the appropriate window procedure.
|
||||||
* This is the simplest kind of message loop. More complex loops
|
* This is the simplest kind of message loop. More complex loops
|
||||||
* are required for idle processing or handling modeless dialog
|
* are required for idle processing or handling modeless dialog
|
||||||
* boxes. When one of the windows calls PostQuitMessage GetMessage
|
* boxes. When one of the windows calls PostQuitMessage GetMessage
|
||||||
* will return zero and the wParam of the message will be filled
|
* will return zero and the wParam of the message will be filled
|
||||||
* with the argument to PostQuitMessage. The loop will end and
|
* with the argument to PostQuitMessage. The loop will end and
|
||||||
* the application will close.
|
* the application will close.
|
||||||
*/
|
*/
|
||||||
while (GetMessage (&msg, NULL, 0, 0))
|
while (GetMessage (&msg, NULL, 0, 0))
|
||||||
{
|
{
|
||||||
TranslateMessage (&msg);
|
TranslateMessage (&msg);
|
||||||
DispatchMessage (&msg);
|
DispatchMessage (&msg);
|
||||||
}
|
}
|
||||||
return msg.wParam;
|
return msg.wParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue