Checking if a DLL is 32-bit or 64-bit?

Windows specific forum
ozzie
Enthusiast
Enthusiast
Posts: 429
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Checking if a DLL is 32-bit or 64-bit?

Post by ozzie »

In my program a user may browse for and select a VST Plugin DLL. However, I can't find any way that my program can check that the user has chosen a 32-bit DLL if they are running the 32-bit version of my program, and similarly for 64-bit. The closest I've come to a solution is in this Stackoverflow topic (see the info under 'Gory Details'), but converting that to PureBasic is a bit beyond me. Any suggestions for a PB solution?
User avatar
RSBasic
Moderator
Moderator
Posts: 1218
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: Checking if a DLL is 32-bit or 64-bit?

Post by RSBasic »

Code: Select all

EnableExplicit

;Define lpApplicationName$ = "C:\...\Datei.exe"
Define lpApplicationName$ = ProgramFilename()
Define lpBinaryType

#SCS_32BIT_BINARY = 0
#SCS_64BIT_BINARY = 6
#SCS_DOS_BINARY = 1
#SCS_OS216_BINARY = 5
#SCS_PIF_BINARY = 3
#SCS_POSIX_BINARY = 4
#SCS_WOW_BINARY = 2

GetBinaryType_(@lpApplicationName$,@lpBinaryType)

Select lpBinaryType
  Case #SCS_32BIT_BINARY
    MessageRequester("","A 32-bit Windows-based application.",0)
  Case #SCS_64BIT_BINARY
    MessageRequester("","A 64-bit Windows-based application.",0)
  Case #SCS_DOS_BINARY
    MessageRequester("","An MS-DOS-based application.",0)
  Case #SCS_OS216_BINARY
    MessageRequester("","A 16-bit OS/2-based application.",0)
  Case #SCS_PIF_BINARY
    MessageRequester("","A PIF file that executes an MS-DOS-based application.",0)
  Case #SCS_POSIX_BINARY
    MessageRequester("","A POSIX-based application.",0)
  Case #SCS_WOW_BINARY
    MessageRequester("","A 16-bit Windows-based application.",0)
EndSelect
Image
Image
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Checking if a DLL is 32-bit or 64-bit?

Post by Mijikai »

Optional :D

Code: Select all

EnableExplicit

;CheckPE()
;PB v.5.62

Procedure.i CheckPE(FileHandle.i)
  Protected IDH.IMAGE_DOS_HEADER
  Protected INH.IMAGE_NT_HEADERS
  Protected Position.i
  Protected Result.i
  If IsFile(FileHandle) 
    Position = Loc(FileHandle)
    FileSeek(FileHandle,#Null,#PB_Absolute)
    If ReadData(FileHandle,@IDH,SizeOf(IMAGE_DOS_HEADER)) = SizeOf(IMAGE_DOS_HEADER)
      If IDH\e_magic = $5A4D
        If (IDH\e_lfanew - 8) < Lof(FileHandle)
          FileSeek(FileHandle,IDH\e_lfanew,#PB_Absolute)
          If ReadData(FileHandle,@INH,SizeOf(IMAGE_NT_HEADERS)) = SizeOf(IMAGE_NT_HEADERS)
            If INH\Signature = $4550
              Select (INH\FileHeader\Machine & $FFFF);Helles Code!
                Case $014C
                  Result = 32
                Case $8664
                  Result = 64
              EndSelect
            EndIf
          EndIf
        EndIf
      EndIf
    EndIf
    FileSeek(FileHandle,Position,#PB_Absolute)
  EndIf
  ProcedureReturn Result
EndProcedure

If ReadFile(0,"XYZ.dll");<- change!
  Debug CheckPE(0)
  CloseFile(0)
EndIf
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Checking if a DLL is 32-bit or 64-bit?

Post by skywalk »

Thanks Mijikai, works for dll and exe. 8)
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Checking if a DLL is 32-bit or 64-bit?

Post by RASHAD »

Thanks RSBasic & Mijikai

Code: Select all

#SCS_64BIT_BINARY = 6
Define IDH.IMAGE_DOS_HEADER,INH.IMAGE_NT_HEADERS ,lpBinaryType

;***********************************************************************************
;Define lpApplicationName$ = "e:\projects\stuff rashad\for_test\freak-dll-x64.exe"
Define lpApplicationName$ = "c:\7-Zip\7-zip32.dll"
;Define lpApplicationName$ = "c:\7-Zip\7-zip.dll"
;Define lpApplicationName$ = "e:\projects\stuff rashad\for_test\freak-dll-test.pb"

hFile = CreateFile_(@lpApplicationName$, #GENERIC_READ, #FILE_SHARE_READ, 0, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL, 0)
hFileMap = CreateFileMapping_(hFile, 0, #PAGE_READONLY, 0, 0, 0)
PMapView = MapViewOfFile_(hFileMap, #FILE_MAP_READ, 0, 0, 0)
CopyMemory(PMapView, @IDH,SizeOf(IMAGE_DOS_HEADER))
If IDH\e_magic = $5A4D And GetBinaryType_(@lpApplicationName$,@lpBinaryType) = 1  
  Select lpBinaryType
    Case #SCS_32BIT_BINARY
      MessageRequester("","A 32-bit Windows-based application.",0)
    Case #SCS_64BIT_BINARY
      MessageRequester("","A 64-bit Windows-based application.",0)
    Case #SCS_DOS_BINARY
      MessageRequester("","An MS-DOS-based application.",0)
    Case #SCS_OS216_BINARY
      MessageRequester("","A 16-bit OS/2-based application.",0)
    Case #SCS_PIF_BINARY
      MessageRequester("","A PIF file that executes an MS-DOS-based application.",0)
    Case #SCS_POSIX_BINARY
      MessageRequester("","A POSIX-based application.",0)
    Case #SCS_WOW_BINARY
      MessageRequester("","A 16-bit Windows-based application.",0)
  EndSelect
ElseIf IDH\e_magic = $5A4D And GetBinaryType_(@lpApplicationName$,@lpBinaryType) = 0
  CopyMemory(PMapView+IDH\e_lfanew, @INH,SizeOf(IMAGE_NT_HEADERS))
  If INH\Signature = $4550
    Select INH\OptionalHeader\Magic
      Case $10B
        MessageRequester("","A "+Str(32)+"-bit Windows DLL.",0)
      Case $20B
        MessageRequester("","A "+Str(64)+"-bit Windows DLL.",0)
    EndSelect
  EndIf
Else
  MessageRequester("Error","Not a Windows DLL or EXE",0)
EndIf
CloseHandle_(hFile)
CloseHandle_(hFileMap)
UnmapViewOfFile_(PMapView)
Edit : Modified
Last edited by RASHAD on Tue Dec 11, 2018 5:32 am, edited 1 time in total.
Egypt my love
ozzie
Enthusiast
Enthusiast
Posts: 429
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: Checking if a DLL is 32-bit or 64-bit?

Post by ozzie »

Brilliant! Many thanks, everyone. Works great!
Post Reply