Page 1 of 1

PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 1:17 pm
by Toni6
This is a conversion project of the Microsoft Windows SDK - 7.1.

At the moment it's just a partial conversion, there's still many headers missing, but i plan to do several updates.
Feel free to submit any new structures, macros, issues, corrections, etc...

Don't forget to install the SDK before trying to use it, check the Readme.txt for more info.

GIT: https://github.com/ToniPB/PureBasic_Windows_SDK_7.1.git

Example:

Code: Select all

IncludePath #PB_WINDOWS_SDK_PATH + "\Includes"
XIncludeFile "TlHelp32.pbi"
IncludePath #PB_Compiler_FilePath

Procedure.l GetProcessPID(ProcName.s)
  Protected lppe.PROCESSENTRY32_
  Protected hSnap.i
  Protected Result.l
  Protected PID.l
  
  hSnap = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, 0)
  
  If hSnap
    lppe\dwSize = SizeOf(PROCESSENTRY32_)
    
    Result = Process32First_(hSnap, @lppe)
    While Result
      If UCase(PeekS(@lppe\szExeFile, #MAX_PATH)) = UCase(ProcName)
        PID = lppe\th32ProcessID
        Break
      EndIf

      Result = Process32Next_(hSnap, @lppe)
    Wend
    
    CloseHandle_(hSnap)
  EndIf
  
  ProcedureReturn PID
EndProcedure

Debug GetProcessPID("notepad.exe")

Re: PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 5:53 pm
by jassing
I'm missing the point of your project...

All I had to do was change the structure name to omit the trailing "_" and it compiled and ran w/o you include file...

Re: PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 6:19 pm
by Toni6
jassing wrote:I'm missing the point of your project...

All I had to do was change the structure name to omit the trailing "_" and it compiled and ran w/o you include file...
The point of my project is to provide an up-to-date and correct, windows sdk for PureBasic.
There are many structures included in the latest PureBasic that either have wrong alignment, wrong field names, missing, etc...

Edit: removed the my MODULEENTRY32_BAD.

Re: PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 6:47 pm
by IdeasVacuum
There are many structures included in the latest PureBasic that either have wrong alignment, wrong field names, missing, etc...
It's best that you report these so that Fred/Freak can edit them - that would imho be far better than adding a 3rd Party SDK.

Re: PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 6:54 pm
by Toni6
IdeasVacuum wrote:
There are many structures included in the latest PureBasic that either have wrong alignment, wrong field names, missing, etc...
It's best that you report these so that Fred/Freak can edit them - that would imho be far better than adding a 3rd Party SDK.
Some of my projects can't wait until Fred/Freak decides to add them for next version of pb, plus there's useful macros that purebasic doesn't include.

Re: PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 8:31 pm
by Denis
Toni6

it's really a good idea :D
I'll take a deeper look .

Re: PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 8:34 pm
by Danilo
Toni6 wrote:The point of my project is to provide an up-to-date and correct, windows sdk for PureBasic.

This is the default PROCESSENTRY32 structure in PureBasic 5.11 beta 1 (x86), which has the wrong structure alignment.

Code: Select all

Structure PROCESSENTRY32
  dwSize.l
  cntUsage.l
  th32ProcessID.l
  th32DefaultHeapID.i
  th32ModuleID.l
  cntThreads.l
  th32ParentProcessID.l
  pcPriClassBase.l
  dwFlags.l
  szExeFile.c[260]
EndStructure
This is the correct one:

Code: Select all

Structure PROCESSENTRY32_ Align #PB_Structure_AlignC
  dwSize.l
  cntUsage.l
  th32ProcessID.l         ;  this process
  th32DefaultHeapID.i
  th32ModuleID.l          ;  associated exe
  cntThreads.l
  th32ParentProcessID.l   ; this process's parent process
  pcPriClassBase.l        ; Base priority of process's threads
  dwFlags.l
  szExeFile.c[260]        ; Path
EndStructure
There are many structures included in the latest PureBasic that either have wrong alignment, wrong field names, missing, etc...
The structure is correct in PB 5.10. Same values if I compare your structure and the internal one with PB 5.10 x86 & x64:

Code: Select all

Structure PROCESSENTRY32_ Align #PB_Structure_AlignC
  dwSize.l
  cntUsage.l
  th32ProcessID.l         ;  this process
  th32DefaultHeapID.i
  th32ModuleID.l          ;  associated exe
  cntThreads.l
  th32ParentProcessID.l   ; this process's parent process
  pcPriClassBase.l        ; Base priority of process's threads
  dwFlags.l
  szExeFile.c[260]        ; Path
EndStructure

Debug SizeOf(PROCESSENTRY32)

With PROCESSENTRY32
    Debug OffsetOf( \dwSize )
    Debug OffsetOf( \cntUsage )
    Debug OffsetOf( \th32ProcessID )
    Debug OffsetOf( \th32DefaultHeapID )
    Debug OffsetOf( \th32ModuleID )
    Debug OffsetOf( \cntThreads )
    Debug OffsetOf( \th32ParentProcessID )
    Debug OffsetOf( \pcPriClassBase )
    Debug OffsetOf( \dwFlags )
    Debug OffsetOf( \szExeFile )
EndWith

Debug "----------"

Debug SizeOf(PROCESSENTRY32_)

With PROCESSENTRY32_
    Debug OffsetOf( \dwSize )
    Debug OffsetOf( \cntUsage )
    Debug OffsetOf( \th32ProcessID )
    Debug OffsetOf( \th32DefaultHeapID )
    Debug OffsetOf( \th32ModuleID )
    Debug OffsetOf( \cntThreads )
    Debug OffsetOf( \th32ParentProcessID )
    Debug OffsetOf( \pcPriClassBase )
    Debug OffsetOf( \dwFlags )
    Debug OffsetOf( \szExeFile )
EndWith
Does it give different results with 5.11 beta1?

Re: PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 8:59 pm
by Toni6
Danilo wrote:
Toni6 wrote:The point of my project is to provide an up-to-date and correct, windows sdk for PureBasic.

This is the default PROCESSENTRY32 structure in PureBasic 5.11 beta 1 (x86), which has the wrong structure alignment.

Code: Select all

Structure PROCESSENTRY32
  dwSize.l
  cntUsage.l
  th32ProcessID.l
  th32DefaultHeapID.i
  th32ModuleID.l
  cntThreads.l
  th32ParentProcessID.l
  pcPriClassBase.l
  dwFlags.l
  szExeFile.c[260]
EndStructure
This is the correct one:

Code: Select all

Structure PROCESSENTRY32_ Align #PB_Structure_AlignC
  dwSize.l
  cntUsage.l
  th32ProcessID.l         ;  this process
  th32DefaultHeapID.i
  th32ModuleID.l          ;  associated exe
  cntThreads.l
  th32ParentProcessID.l   ; this process's parent process
  pcPriClassBase.l        ; Base priority of process's threads
  dwFlags.l
  szExeFile.c[260]        ; Path
EndStructure
There are many structures included in the latest PureBasic that either have wrong alignment, wrong field names, missing, etc...
The structure is correct in PB 5.10. Same values if I compare your structure and the internal one with PB 5.10 x86 & x64:

Code: Select all

Structure PROCESSENTRY32_ Align #PB_Structure_AlignC
  dwSize.l
  cntUsage.l
  th32ProcessID.l         ;  this process
  th32DefaultHeapID.i
  th32ModuleID.l          ;  associated exe
  cntThreads.l
  th32ParentProcessID.l   ; this process's parent process
  pcPriClassBase.l        ; Base priority of process's threads
  dwFlags.l
  szExeFile.c[260]        ; Path
EndStructure

Debug SizeOf(PROCESSENTRY32)

With PROCESSENTRY32
    Debug OffsetOf( \dwSize )
    Debug OffsetOf( \cntUsage )
    Debug OffsetOf( \th32ProcessID )
    Debug OffsetOf( \th32DefaultHeapID )
    Debug OffsetOf( \th32ModuleID )
    Debug OffsetOf( \cntThreads )
    Debug OffsetOf( \th32ParentProcessID )
    Debug OffsetOf( \pcPriClassBase )
    Debug OffsetOf( \dwFlags )
    Debug OffsetOf( \szExeFile )
EndWith

Debug "----------"

Debug SizeOf(PROCESSENTRY32_)

With PROCESSENTRY32_
    Debug OffsetOf( \dwSize )
    Debug OffsetOf( \cntUsage )
    Debug OffsetOf( \th32ProcessID )
    Debug OffsetOf( \th32DefaultHeapID )
    Debug OffsetOf( \th32ModuleID )
    Debug OffsetOf( \cntThreads )
    Debug OffsetOf( \th32ParentProcessID )
    Debug OffsetOf( \pcPriClassBase )
    Debug OffsetOf( \dwFlags )
    Debug OffsetOf( \szExeFile )
EndWith
Does it give different results with 5.11 beta1?
You are right, my bad PROCESSENTRY32 is properly aligned in (x86, x64).

Edit: MODULEENTRY32 is not properly aligned in x64, changed example.

Re: PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 9:33 pm
by Danilo
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.

Re: PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 11:09 pm
by Danilo
Toni6 wrote:Edit: MODULEENTRY32 is not properly aligned in x64, changed example.
MODULEENTRY32 is also correct here. It is your own "_BAD" structure that is not correct.

Code: Select all

Structure MODULEENTRY32_BAD ; <- default pb
  dwSize.l
  th32ModuleID.l
  th32ProcessID.l
  GlblcntUsage.l
  ProccntUsage.l
  *modBaseAddr
  modBaseSize.l
  hModule.i
  szModule.c[256]
  szExePath.c[260]
EndStructure

Structure MODULEENTRY32_GOOD Align #PB_Structure_AlignC
  dwSize.l
  th32ModuleID.l
  th32ProcessID.l
  GlblcntUsage.l
  ProccntUsage.l
  *modBaseAddr
  modBaseSize.l
  hModule.i
  szModule.c[256]
  szExePath.c[260]
EndStructure

Debug "MODULEENTRY32:      "+SizeOf(MODULEENTRY32)      ; << correct structure by PB
Debug "MODULEENTRY32_BAD:  "+SizeOf(MODULEENTRY32_BAD)  ; << wrong   structure by Toni6
Debug "MODULEENTRY32_GOOD: "+SizeOf(MODULEENTRY32_GOOD) ; << correct structure by Toni6

Re: PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 11:34 pm
by Toni6
Danilo wrote:
Toni6 wrote:Edit: MODULEENTRY32 is not properly aligned in x64, changed example.
MODULEENTRY32 is also correct here. It is your own "_BAD" structure that is not correct.

Code: Select all

Structure MODULEENTRY32_BAD ; <- default pb
  dwSize.l
  th32ModuleID.l
  th32ProcessID.l
  GlblcntUsage.l
  ProccntUsage.l
  *modBaseAddr
  modBaseSize.l
  hModule.i
  szModule.c[256]
  szExePath.c[260]
EndStructure

Structure MODULEENTRY32_GOOD Align #PB_Structure_AlignC
  dwSize.l
  th32ModuleID.l
  th32ProcessID.l
  GlblcntUsage.l
  ProccntUsage.l
  *modBaseAddr
  modBaseSize.l
  hModule.i
  szModule.c[256]
  szExePath.c[260]
EndStructure

Debug "MODULEENTRY32:      "+SizeOf(MODULEENTRY32)      ; << correct structure by PB
Debug "MODULEENTRY32_BAD:  "+SizeOf(MODULEENTRY32_BAD)  ; << wrong   structure by Toni6
Debug "MODULEENTRY32_GOOD: "+SizeOf(MODULEENTRY32_GOOD) ; << correct structure by Toni6
You are right once again, i guess i was using an old MODULEENTRY32...
Still needs to be updated to "Align #PB_Structure_AlignC" instead of "PB_Alignment3"

Re: PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 11:37 pm
by Toni6
Danilo wrote:
Toni6 wrote:You are right, my bad PROCESSENTRY32 is properly aligned in (x86, x64).
I did not look at your approach yet. Do you also parse header files, or do you extract structures by hand?
I am using a mix of methods manually parse, regex replace, PB Header Converter and PB Interface Importer.

Re: PureBasic Windows SDK - 7.1

Posted: Sun Mar 03, 2013 11:53 pm
by Josh
Hi Toni,

please don't use such long quotes. Shorten the quotes to the minimum is needed to see the context.

Re: PureBasic Windows SDK - 7.1

Posted: Mon Mar 04, 2013 12:07 am
by Danilo
Toni6 wrote:I am using a mix of methods manually parse, regex replace, PB Header Converter and PB Interface Importer.
I see. PB Header Converter always hung here when I wanted to use for the Windows SDK, that's why I started the preprocessed header stuff.

Had a quick look at your project now. Looks good so far and will be very useful for all PB WinAPI developers! Same for DirectX SDK. Thank you!