Sign in to follow this  
Followers 0

DllCall help please.

4 posts in this topic

Hi, I am struggling to get a function in a .dll file to work, I have had a good look about here & I have looked at similar functions and how they are called in other peoples working scrips (Martins CommMG), no matter what I try I cant get this .dll to return any information. The .dll allows you to return specific information / serial numbers from the PC, I want to use it so I can keep specific information on PC's in a file for my own records, It would be useful here to people if they wish to lock software to a certain PC. If anyone can please help me return some useful data from the .dll I think I could workout how to get the rest.

Here is a list of functions for the .dll


Functions exported by this DLL:


Version 1.4a

CubicDesign 2012
All rights reserved

Programming languages supported:
C, C++, VB, FoxPro, VBA, .Net, etc
Delphi programmers click this



// OSMemType
MemoryLoad = 1; // Total memory used in percents (%)
TotalPhys = 2; // Total physical memory in bytes
AvailPhys = 3; // Available physical memory (bytes)
TotalPageFile = 4; // Total page file in (bytes)
AvailPageFile = 5; // Available page file (bytes)
TotalVirtual = 6; // Total virtual memory in bytes
AvailVirtual = 7; // Available virtual memory (bytes)

// ProcMemType
WorkingSetSize =1; //- the current working set size, in bytes.
PageFaultCount =2; //- the number of page faults.
PeakWorkingSetSize =3; //- the peak working set size, in bytes.
QuotaPeakPagedPoolUsage =4; //- The peak paged pool usage, in bytes.
QuotaPagedPoolUsage =5; //- The current paged pool usage, in bytes.
QuotaPeakNonPagedPoolUsg =6; //- The peak nonpaged pool usage, in bytes.
QuotaNonPagedPoolUsg =7; //- The current nonpaged pool usage, in bytes.
PagefileUsage =8; //- The current space allocated for the pagefile, in bytes. Those pages may or may not be in memory.
PeakPagefileUsage =9; //- The peak space allocated for the pagefile, in bytes.

// CPU
function GetCPUSpeed : Double;
function CPUFamily : String; // Get cpu identifier from the windows registry
function GetCpuTheoreticSpeed: int; // Get cpu speed (in MHz)
function IsCPUIDAvailable : Boolean;
function GetCPUID (CoreMask: Word): String; // Get the ID of the specified logical CPU. For CoreMask parameter see this page.
function GetCpuIdNow : String; // Get the ID of the first available logical CPU
function GetCPUCount : int; // The number of LOGICAL processors in the current group
function IsIntel64BitCPU : Boolean; // Detects IA64 processors
function GetCPUVendor : String; // New GetCPUVendor function. Reported to work with D7 and D2009.

// RAM
function MemStatWindows (OSMemType : Byte): LongInt; // in Bytes. Limited by the capacity of the OS (32bits OSs will report max 2GB)
function MemStatWindows_KB (OSMemType : Byte): String; // in KB
function MemStatWindows_MB (OSMemType : Byte): String; // in MB
function MemStatCurrProc (ProcMemType: Byte= 1): LongInt; // Returns data about the memory used of the current process
function MemStatPeak: LongInt; // Peak memory used by current program

// RAM - Advanced stuff
function GetPageSize: LongInt; // The page size and the granularity of page protection and commitment. This is the page size used by the VirtualAlloc function.
function GetMemGranularity: int; // Granularity with which virtual memory is allocated (in KB)
function GetLowAddr: LongInt; // Lowest RAM memory address accessible to applications (this is the RAM address, not virtual memory address)
function GetHiAddr: LongInt; // Lowest RAM memory address accessible to applications

// HDD
function GetPartitionID (Partition : string): String; // Get the ID of the specified patition. Example of parameter: 'C:'
function GetIDESerialNumber(DriveNumber: Byte): String; // Get the unique ID of the harddrive. DriveNumber parameters can have values from 0 to 7. Number 0 corresponds to the first physic drive. UAC details

// BIOS (NEW!)
function BiosDate: string;
function BiosVersion: string; // Could be something like: TOSQCI - 6040000 Ver 1.00PARTTBL. TOS is comming from Toshiba Q is comming from product series (Qosmio)
function BiosProductID: string; // Manufacturer product (laptop, PC) ID - Could be something like: Toshiba_PQX33U-01G00H
function BiosVideo: string;

// Utils
function BinToInt(Value: String): int;
function CoreNumber2CoreMask(CoreNo: int): int; // Details
function GetDllVersion: Double;
function GetDllVersion: Double;

All strings used in this DLL are LPSTR (PAnsiChar). Byte is 'unsigned char'.
The following functions are freely accessible (you don't need a to purchase the DLL in order to use them): ChangeByteOrder, IntToBin, CoreNumber2CoreMask, WindowsProductID, GetPageSize, GetMemGranularity, GetLowAddr, GetHiAddr, MemStatWindows, MemStatWindows_KB, MemStatWindows_MB, MemStatCurrProc, MemStatPeak, IsCPUIDAvailable, GetCpuTheoreticSpeed, GetCPUCount, IsIntel64BitCPU, GetDllVersion, ReleaseMemory


Here are some examples of code usage


Example for C Builder programmers

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
char* (__stdcall *GetIDESerialNumber)(BYTE);


void __fastcall TForm1::Button1Click(TObject *Sender)
if (DllInst == NULL) DllInst = LoadLibrary("HardwareIDExtractorC.dll");
if (DllInst)
GetIDESerialNumber = (char* (__stdcall*)(BYTE))GetProcAddress(DllInst, "GetIDESerialNumber");

//Now call the imported function
Edit1->Text = GetIDESerialNumber(0); // 0 = first IDE hard drive in your system

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
if ( DllInst ) FreeLibrary (DllInst);

Example in Visual Basic 5 programmers

In your BAS file write this:

Attribute VB_Name = "HardwareIDExtractor"
Public Declare Function GetIDESerialNumber
Lib "HardwareIDExtractorC.dll.DLL" (ByVal DriveNumber As Byte) As String

In your FRM file write something like this:

Begin VB.Form Form1
Your form code here...
bla bla bla...

Private Sub Command1_Click()
Dim DriveNumber As Byte
DriveNumber = 0
Text1.Text = GetIDESerialNumber(DriveNumber)
End Sub

Example in Visual FoxPro programmers

DECLARE STRING GetIDESerialNumber IN "HardwareIDExtractorC.dll" BYTE DriveNumber

Form1.Text1.Value = GetIDESerialNumber(0)

Example in C# (VS2005) programmers

namespace Project
public partial class Form1 : Form
public static extern String GetIDESerialNumber(byte DriveNumber);

public Form1()

private void button1_Click(object sender, EventArgs e)
textBox1.Text = GetIDESerialNumber(0);

Example in VB.NET (VS2008) programmers

Imports System.Runtime.InteropServices
Public Class Form1

Public Declare Function HardwareIDExtractorC
Lib "HardwareIDExtractorC.dll" (ByVal DriveNumber As Boolean) As String

Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
textBox1.Text = GetHardwareID(0)
End Sub

Public Sub New()
End Sub

Protected Overrides Sub Finalize()
End Sub

End Class

Example in Delphi/Lazarus/Free Pascal programmers


function CPUFamily: String; external 'HardwareIDExtractor.DLL';


procedure Button1ClickExecute(Sender: TObject);
Label1.Caption:= CPUFamily;

Demo application:
Source code (basic demo)
Source code (full demo)

Example in VBA programmers

Private Declare Function HardwareIDExtractorC
Lib "HardwareIDExtractorC.dll" (ByVal DriveNumber As Byte) As String

Private Sub CommandButton1_Click()
TextBox1.Text = GetIDESerialNumber(0)
End Sub

Example in Liberty Basic programmers

open "HardwareIDExtractorC.dll" for dll as #id
calldll #id, "GetCpuIdNow", Pointer as uLong

function GetIDESerialNumber$(DriveNumber)
calldll #HwIDex, "GetIDESerialNumber", DriveNumber as ushort, pointer as ulong
GetIDESerialNumber$ = winstring(pointer) call ReleaseMemory pointer
end function


The .dll file is available in a Delphi version, I chose the universal version (not sure if that was correct) however I have tried both and they both returned the same value which is incorrect.

I am trying to get the unique serial number of the hard drive, my example returns 0 when run, if I remove the (0) at the end of my GetIDESerialNumber(0) I get an info box that quotes "invalid drive!" so I think something is working? Here is the code I am running now:-

Local $resultHDDSN
Local $dll = DllOpen("HardwareIDExtractorC.dll")

$resultHDDSN = DllCall('HardwareIDExtractorC.dll', 'str', 'GetIDESerialNumber(0)')

ConsoleWrite('+_WinAPI_GetLastErrorMessage() = ' & _WinAPI_GetLastErrorMessage())
ConsoleWrite('+_WinAPI_GetLastError() = ' & _WinAPI_GetLastError() & @crlf)
If @error Then Exit

MsgBox(262144, "IDE drive 0 Serial Number", $resultHDDSN )


I have attached the .dll file I am using. Any help is greatly appreciated.

Share this post

Link to post
Share on other sites

#2 ·  Posted (edited)


You must use $resultHDDSN[0] as the result of a successfull DLL call...

#include <winapi.au3>

Local $resultHDDSN
Local $dll = DllOpen("HardwareIDExtractorC.dll")
ConsoleWrite("DllOpen with result: " & $dll & @CRLF)

$resultHDDSN = DllCall('HardwareIDExtractorC.dll', 'str', 'GetIDESerialNumber', "BYTE", 0)

ConsoleWrite("DllCall  @error: " & @error & @CRLF)

ConsoleWrite('+_WinAPI_GetLastErrorMessage() = ' & _WinAPI_GetLastErrorMessage())
ConsoleWrite('+_WinAPI_GetLastError() = ' & _WinAPI_GetLastError() & @crlf)
If @error Then Exit

ConsoleWrite("resultHDDSN =" & $resultHDDSN[0] & @CRLF)

Edited by Sundance
1 person likes this

Share this post

Link to post
Share on other sites

Thanks Sundance I had no idea the result was an array, I also now understand a little more! :thumbsup:

Share this post

Link to post
Share on other sites

Years ago i stepped into the same pitfall :shifty:

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • luckyluke
      By luckyluke
      Im trying to read the output from CMD using Dllcall, here is my code:
      #include <WinAPI.au3> #include <array.au3> Global Const $STD_OUTPUT_HANDLE = -11 Global Const $_CONSOLE_SCREEN_BUFFER_INFO = _ "struct;int dwSizeX;" & _ "short dwSizeY;" & _ "short dwCursorPositionX;" & _ "short dwCursorPositionY;" & _ "short wAttributes;" & _ "short Left;" & _ "short Top;" & _ "short Right;" & _ "short Bottom;" & _ "short dwMaximumWindowSizeX;" & _ "short dwMaximumWindowSizeY;endstruct" $pCmd = Run( "cmd.exe" ) Sleep(1000) $hCmd = WinGetHandle("") ConsoleWrite('handle:' & $hCmd & @CRLF) $aRet = DllCall("kernel32.dll", "int", "AttachConsole", "dword", $pCmd) ;_ArrayDisplay($aRet) If $aRet[0] <> 0 Then $vHandle_data='' $vHandle='' $vHandle_data = DllStructCreate($_CONSOLE_SCREEN_BUFFER_INFO) ; Screen Buffer structure $aRet1 = DllCall("kernel32.dll", "hwnd", "GetStdHandle", "dword", $STD_OUTPUT_HANDLE) if not @error Then $vHandle = $aRet1[0] $aRet = DllCall("kernel32.dll", "int", "GetConsoleScreenBufferInfo", "hwnd", $vHandle, _ "ptr", $vHandle_data) MsgBox(0, '1',DllStructGetData($vHandle_data, 'dwSizeX') & _WinAPI_GetLastErrorMessage()) EndIf It did not work, i got the message 'The handle is invalid'. Please help?
      Thank you in advance!
    • MazeM
      By MazeM
      here's another UDF for the serial port. It is very similar to CommAPI using kernel32.dll, but all code is packed into a single file without any dependencies, not even using WinAPI.au3. It differs from existing UDF that it doesn't allow a timeout when reading, instead it always returns immediately, either with the requested amount ob bytes read or with a failure status. And of course there is a function provided to query the amount of available bytes in the receive buffer. The reason behind this design decision: You can do 1000 other things in the main loop while checking from time to time if enough data bytes arrived. There's no point to block the program waiting for the serial port.
      It is currently a work-in-progress, as I didn't test all functions yet. The code was developed and tested on Windows 7 64 bit.  The ComUDF-Tests.au3 shows some tests and basic usage of the UDF. Maybe there's no reason to use this UDF, given the existence of the others UDFs, but I did it to get to know DllCall better - I use structs no only to pass but also to get data back (I don't use the array returned by DllCall to read that data, unless required). You're welcome to test it on older and newer Windows versions.
      Here's a list of the implemented functions:
      ; _ComListPorts ; _ComOpenPort ; _ComSetTimeouts ; _ComClosePort ; ; _ComSetBreak ; _ComClearBreak ; _ComGetInputcount ; _ComGetOutputcount ; _ComClearOutputBuffer ; _ComClearInputBuffer ; ; _ComSendByte ; _ComReadByte ; _ComSendBinary ; _ComReadBinary ; ; _ComSendChar ; _ComReadChar ; _ComSendCharArray ; _ComReadCharArray ; _ComSendString ; _ComReadString ; ; __ComClearCommError ; __PurgeComm Maze
    • astrionn
      By astrionn
      So I had this Idea of creating a tooltip which shows me my ping.
      That itself was made quickly and I thought too add a couple features.
      I want the tooltip background to be a different color depending on the ping. (good ping is green, medium ping is yellow,...)
      So how do I color in a tooltip? google brought me to this: 
      where in the comments I found this:
      $s = "LOW" ToolTip($s, 0, 0, "Battery Information");, $icon) $H_TOOLTIP1 = WinGetHandle($s) DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", $H_TOOLTIP1, "wstr", "", "wstr", "") DllCall("user32.dll", "int", "SendMessage", "hwnd", $H_TOOLTIP1, "int", 1043, "int", 2552550, "int", 0) Sleep(1000) Which I then used in my code with different color codes... Trial and Error brought me these that I wanted to use:
      The Problem is if I loop through my code it only sets the color for the 1st loop and then sticks to it.
      The real problem is tho that I don't exactly understand the dllcalls... And I guess that's why it isn't working
      So if someone would be so awesome to explain to me how they work, or at least can give me a list of these parameters then I would really appreciate that and learn something new
      Obviously a solution to my problem is awesome aswell ^^
      I run this under Windows 8.1
      There is my code in a paste.
    • Leo1906
      By Leo1906
      Hello Guys,
      once aggain I need your help on a DLL Topic
      I need to pass arguments to my function via a structure, because I am limited to only one argument that can be passed.
      But I don't think that thats so important.
      So here's my approach:
      C++ Code (just the important part):
      extern "C" { struct ParamStruct { const char* test1; const char* test2; const char* test3; int size; }; int testFunc(struct ParamStruct * params) { return params->size; } } And thats how I try to call the function using Autoit:
      Local $struct = "struct;char shapefile[128];char output[128];char filename[128];int size;endstruct" Local $tTest = DllStructCreate($struct) DllStructSetData($tTest, "test1", "Bla") DllStructSetData($tTest, "test2", "BlaBla") DllStructSetData($tTest, "test3", "BlaBlaBla") DllStructSetData($tTest, "size", 40) $dll = DLLOpen("myDLL.dll") $ret = DllCall($dll, "int:cdecl", "testFunc", "STRUCT*", DllStructGetPtr($tTest)) MsgBox(0, 0, $ret[0]) DllClose($dll) Just for testing I want the function to just return the integer value in the struct.
      But this aint working. I tested many things, but still I'm not able to get it running. I even don't know if the mistakes are in the C++ code or the Autoit code or both .. I'm not that skilled at C++ and also not that skilled at Autoit DLLCalls :-/
      I would really appreciate some help!
      Kind regards,
    • MagicSpark
      By MagicSpark
      can someone help me out with some DllCall in AU3.
      The relevant source of function and struct definition are as follows (in slightly modified form):
      typedef struct {     char    *host;     char    *key;     char    *value; } test_sender_value_t; /******************************************************************************  * Parameters: address   - [IN] server address                                *  *             port      - [IN] server port                                   *  *             source    - [IN] source IP, optional - can be NULL             *  *             values    - [IN] array of values to send                       *  *             count     - [IN] number of items in values array               *  *             result    - [OUT] the server response/error message, optional  *  *                                                                            *  * Return value: 0 - the values were sent successfully, result contains       *  *                         server response                                    *  *               -1 - an error occurred, result contains error message        *  *                                                                            *  ******************************************************************************/ TEST_API int test_sender_send_values(const char *address, unsigned short port, const char *source, const test_sender_value_t *values, int count, char **result);
      In AutoIt I use the following code to build the struct and call the dll:
      Global $struct = DllStructCreate("ptr ptrtostring1;ptr ptrtostring2;ptr ptrtostring3;") Global $string1 = DllStructCreate("char host[255];") DllStructSetData($string1, "host", "Test_Client") DllStructSetData($struct, "ptrtostring1", DllStructGetPtr($string1)) Global $string2 = DllStructCreate("char key[255];") DllStructSetData($string2, "key", "clientver") DllStructSetData($struct, "ptrtostring2", DllStructGetPtr($string2)) Global $string3 = DllStructCreate("char value[255];") DllStructSetData($string3, "value", "123456") DllStructSetData($struct, "ptrtostring3", DllStructGetPtr($string3)) Global $aCall = DllCall("C:\temp\test.dll", "int", "test_sender_send_values", _     "str", "", _     "int", 80, _     "str", "", _     "ptr", DllStructGetPtr($struct), _     "int", 1) If @error Then     ConsoleWrite("Error: " & @error & @CRLF)     exit 1 Else     ConsoleWrite("Success: " & $aCall[0] & @CRLF) EndIf
      If I ran the AU3-Script with SciTE I get the following output:
      !>12:00:00 AutoIt3.exe ended.rc:-1073741783 Can someone point me into the right direction. I must admit, that I'm very new to handling DLL-Calls and structs.
      But I've read down the forum threads and the AutoIt help.
      Thanks in advance.