Toni6 wrote:You are right, my bad PROCESSENTRY32 is properly aligned in (x86, x64).
Good.
Anyway, I was thinking about parsing whole Windows SDK headers last week. I already tried different
approaches over the years, but my conclusion is I need to write at least a full C++ preprocessor and
maybe a full C++ parser to be 100 percent correct for all possible cases.
Last night I checked out Boost::Wave and Boost::Spirit projects, as I think it could be helpful.
My idea is to parse the full SDK headers with different flags (like #define UNICODE, different WINVER etc.) and
extract all information I can get from it. This will be tons of data, so I think it would be best the parser
puts all extracted info into a huge database. Structures, constants, function declarations, define/macro's, etc.
You then could search the database or write generators for different languages (PureBasic, DaniloBasic

).
It's a huge task IMO, so I think it will take a while (it is not my most important project atm).
I did not look at your approach yet. Do you also parse header files, or do you extract structures by hand?
You can get some preprocessed output from VC++ compiler. Here is one way:
Save this as "WindowsHeaders.h":
Code: Select all
#ifndef _HEADER_WINDOWSHEADERS_
#define _HEADER_WINDOWSHEADERS_
/*
Visual C++ no longer supports targeting Windows 95, Windows 98, Windows ME, or Windows NT.
If your WINVER or _WIN32_WINNT macros are assigned to one of these versions of Windows,
you must modify the macros.
When you upgrade a project that was created by using an earlier version of Visual C++,
you may see compilation errors related to the WINVER or _WIN32_WINNT macros if they
are assigned to a version of Windows that is no longer supported.
#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
This targets the Windows 2000 operating system.
Other valid values include 0x0501 for Windows XP,
0x0502 for Windows Server 2003,
0x0600 for Windows Vista,
and 0x0601 for Windows 7.
*/
/*
An application must add the following lines to use the generic functions
and compile for Unicode.
Note that both the Tchar.h and Wchar.h files are required,
and that the leading underscore on the _UNICODE variable is also required.
This nomenclature is specific to the standard C library.
"UNICODE" rendered without the underscore is for the Microsoft Windows runtimes.
*/
#ifdef UNICODE
#define _UNICODE
#endif
#include <tchar.h>
#include <wchar.h>
#define WINVER 0x0601
#define _WIN32_WINNT 0x0601
#pragma message("Compiling included headers - this should happen just once per project.\n")
//#pragma once
/************************************************************************/
/* C++ Headers */
/************************************************************************/
/*
#include <iostream>
#include <limits>
#include <cstdio>
#include <cstdlib>
#include <conio.h>
#include <iomanip>
#include <cmath>
#include <fstream>
#include <cstring>
using namespace std;
*/
/************************************************************************/
/* Windows Headers */
/************************************************************************/
#include <windows.h> // the main windows headers
#include <windowsx.h> // a lot of cool macros
#include <WinUser.h>
#include <WinNT.h>
#include <Richedit.h>
#include <RichOle.h>
#include <CommCtrl.h>
#include <TlHelp32.h>
#include <LMaccess.h>
#include <IPExport.h>
#include <Dbt.h>
#include <ShlObj.h>
#include <Shlwapi.h>
#include <SetupAPI.h>
#include <winhttp.h>
//#include <ws2def.h>
//#include <winsock2.h> // - WinSock (Windows Sockets), version 2
//#include <Ws2tcpip.h>
//#include <Wspiapi.h>
//#include <ShellAPI.h>
// http://en.wikipedia.org/wiki/Windows.h
// windows.h may include any of the following header files:
//#if 0
#include <excpt.h> // – Exception handling
#include <stdarg.h> // – variable-argument functions (standard C header)
#include <windef.h> // – various macros and types
#include <winnt.h> // – various macros and types (for Windows NT)
#include <basetsd.h> // – various types
#include <guiddef.h> // – the GUID type
#include <ctype.h> // – character classification (standard C header)
#include <string.h> // – strings and buffers (standard C header)
#include <winbase.h> // – kernel32.dll: kernel services
#include <winerror.h> // – Windows error codes
#include <wingdi.h> // – GDI (Graphics Device Interface)
#include <winuser.h> // – user32.dll: user services
#include <winnls.h> // – NLS (Native Language Support)
#include <wincon.h> // – console services
#include <winver.h> // – version information
#include <winreg.h> // – Windows registry
#include <winnetwk.h> // – WNet (Windows Networking)
#include <winsvc.h> // – Windows services and the SCM (Service Control Manager)
#include <imm.h> // – IME (Input Method Editor)
//#endif
// Extra includes
//#if 0
#include <cderr.h> // – CommDlgExtendedError function error codes
#include <commdlg.h> // – Common Dialog Boxes
#include <dde.h> // – DDE (Dynamic Data Exchange)
#include <ddeml.h> // – DDE Management Library
#include <dlgs.h> // – various constants for Common Dialog Boxes
#include <lzexpand.h> // – LZ (Lempel-Ziv) compression/decompression
#include <mmsystem.h> // – Windows Multimedia
#include <nb30.h> // – NetBIOS
#include <rpc.h> // – RPC (Remote procedure call)
#include <shellapi.h> // – Windows Shell API
#include <wincrypt.h> // – Cryptographic API
#include <winperf.h> // – Performance monitoring
//#include <winresrc.h> // – used in resources
//#include <winsock.h> // – Winsock (Windows Sockets), version 1.1
#include <winspool.h> // – Print Spooler
//#endif
// OLE and COM
#include <ole2.h> // – OLE (Object Linking and Embedding)
#include <objbase.h> // – COM (Component Object Model)
#include <oleauto.h> // – OLE Automation
#include <olectl.h> // –
//#include <olectlid.h> // – various GUID definitions
// Danilo
#include <scrnsave.h>
#include <gdiplus.h>
#include <wininet.h>
#endif
File main.cpp
Code: Select all
#include "WindowsHeaders.h"
#include <stdio.h>
int main() {
// Demonstrates functionality of __FUNCTION__, __FUNCDNAME__, and __FUNCSIG__ macros
{
printf("Function name: %s\n", __FUNCTION__);
printf("Decorated function name: %s\n", __FUNCDNAME__);
printf("Function signature: %s\n", __FUNCSIG__);
// Sample Output// -------------------------------------------------// Function name: exampleFunction// Decorated function name: ?exampleFunction@@YAXXZ// Function signature: void __cdecl exampleFunction(void)
}
return 0;
}
(main.cpp does nothing useful, it can be empty main() function, but it is required to #include "WindowsHeaders.h")
File COMPILE.bat
Code: Select all
@echo off
@CALL d:\VS2010\VC\vcvarsall.bat x86
@REM /P preprocess to file
@REM /EP do not display include file #line numbers
@REM /C preserve comments
@REM /Fi output filename of preprocessed file
@REM /TC all files are C source files
@REM /TP all files are C++ source files
@REM /FR generate .sbr for bscmake
@REM /Od no optimizations
@REM /Ob0 disables inline expansion
@REM /showIncludes
@cl /YcWindowsHeaders.h /Ob0 /FR /TP /nologo /Od main.cpp
@cl /YcWindowsHeaders.h /Ob0 /TC /P /EP /C /MP /nologo /Od /Fipreprocessed_C_32.cpp main.cpp
@cl /YcWindowsHeaders.h /Ob0 /TP /P /EP /C /MP /nologo /Od /Fipreprocessed_CPP_32.cpp main.cpp
@cl /YcWindowsHeaders.h /Ob0 /TC /P /EP /C /MP /nologo /Od /DUNICODE /Fipreprocessed_C_32_Unicode.cpp main.cpp
@cl /YcWindowsHeaders.h /Ob0 /TP /P /EP /C /MP /nologo /Od /DUNICODE /Fipreprocessed_CPP_32_Unicode.cpp main.cpp
@bscmake /n /v /nologo /Iu main.sbr
REM @main.exe
@pause
(change PATH to your vcvarsall.bat before running!)
Now run COMPILE.bat, you get 4 very huge preprocessed files (round about 6MB each).
Here is count_structs.pb
Code: Select all
Global NewList lines.s()
Procedure.s CountStructs(file.s)
ClearList( lines() )
If ReadFile(0,file)
While Not Eof(0)
line.s = Trim(ReadString(0))
If Left(line,2)="//"
Continue
EndIf
commentBegin = FindString(line,"/*")
If commentBegin And FindString(line,"struct ")>commentBegin
inComment = #True
commentEnd = FindString(line,"*/",commentBegin)
If commentEnd
inComment = #False
EndIf
ElseIf inComment=#True And FindString(line,"*/")
inComment=#False
EndIf
If inComment=#False
sFind = FindString(line,"struct ")
commentFound = FindString(line,"//")
If sFind And (commentFound=0 Or commentFound>sFind)
;Debug line
found + 1
EndIf
EndIf
Wend
CloseFile(0)
Else
ProcedureReturn "can not open file "+file
EndIf
ProcedureReturn "found "+Str(found)+ " structs in "+file
EndProcedure
Debug CountStructs("preprocessed_C_32.cpp")
Debug CountStructs("preprocessed_C_32_Unicode.cpp")
Debug CountStructs("preprocessed_CPP_32.cpp")
Debug CountStructs("preprocessed_CPP_32_Unicode.cpp")
Output:
Code: Select all
found 5022 structs in preprocessed_C_32.cpp
found 5022 structs in preprocessed_C_32_Unicode.cpp
found 3838 structs in preprocessed_CPP_32.cpp
found 3838 structs in preprocessed_CPP_32_Unicode.cpp
Make a copy of COMPILE.bat and change it to use x64 compiler and output to files with "_64" in file name.
Maybe it helps you to get started. You could write a tool to extract all structures and constants + enumerations
from the preprocessed headers.
If you put
mcpp.exe (mcpp -- a portable C preprocessor) in the same directory,
you can use this small .BAT to get a preprocessed file from mcpp:
Code: Select all
@echo off
@CALL d:\VS2010\VC\vcvarsall.bat x86
mcpp.exe WindowsHeaders.h -P -j -o mcpp_out.h
@pause
EDIT: changed count_structs.pb and output for it.