Page 1 of 1

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

Posted: Mon Dec 10, 2018 12:32 pm
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?

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

Posted: Mon Dec 10, 2018 1:03 pm
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

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

Posted: Mon Dec 10, 2018 1:15 pm
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

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

Posted: Mon Dec 10, 2018 4:50 pm
by skywalk
Thanks Mijikai, works for dll and exe. 8)

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

Posted: Mon Dec 10, 2018 9:20 pm
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

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

Posted: Mon Dec 10, 2018 11:08 pm
by ozzie
Brilliant! Many thanks, everyone. Works great!