ogloed Posted January 16, 2017 Share Posted January 16, 2017 Again, I'm struggling with DllCall(). So I have this MS C++ 6.0 compiled DLL and a manual for it. There's a function: Get information of disk arrays Declaration: VINT vr_get_array_info (VINT array_index, vr_array_info_t* pinfo); Description: Application can fetch the information of one specific disk array, which is located by index of all disk arrays in current system. Input parameters: VINT array_index : Index to all disk arrays in system, specify which disk array. vr_array_info_t *pinfo : 14 Pointer to a vr_array_info_t data structure to get the information Return value: VR_SUCCESS : Get the information successfully. VR_ERR_NOT_INITED : Raid lib hasn’t been initialized. VR_ERR_INVALID_INDEX : The input index is invalid. VR_ERR_INVALID_PARAM : Input parameter is invalid: the pointer is NULL. Here's what DLL Export Viewer says: Function Name : int __cdecl vr_get_array_info(int,struct _vr_array_info *) Here's what is this _vr_array_info: expandcollapse popuptypedef struct _vr_array_info { VWORD status; // current status of disk array VBYTE raidType;// same as Disk_Array.raidType, but value 0xFF means // a stand-alone disk. When it's a stand-alone disk, // only arDevices[0] and diskNum has meaning, and diskNum should // always be 1 . VBYTE diskNum;// count of valid arDevices[] members. // Note: disk array maybe incomplete, i.e. , some disk in the array maybe missing, // corresponding device ptr arDevices[i]->pRealDevice should be NULL. VDWORD capacityLow;// (Unit: sector) VDWORD capacityHigh;// (Unit: sector) // following 8 bytes define the real-capcity (in sector) of every disk in array VDWORD realCapacityLow; // (Unit: sector) VDWORD realCapacityHigh; // (Unit: sector) VDWORD stripeSize; // valid when raid is raid0, raid5 or raid01, in Kbytes VDWORD blockSize; // valid when raid is RAID5, in Kbytes VBOOL bNeedMigration; // the raid need migration // only valid when raid0/raid5/matrixRaid VBOOL bNeedInit; // the raid need initialization, only valid for RAID5 VBOOL bOptimized; // only for RAID5, this RAID5 access was optimized VBYTE systemDisk; /* does the devices within this disk array contain system files of current running OS ? the probably value are: VR_DEVICE_NOT_SYS_DISK VR_DEVICE_MAYBE_SYS_DISK VR_DEVICE_SYS_DISK they are defined in this file */ VWORD raid_index;// only raid index, no meaning with stand-alone disk VINT index; // all device index, including all raid and stand-alone disk } vr_array_info_t; Here's my code (function names are actually decorated, so): expandcollapse popupLocal $pTest $hDLL = DllOpen(@ScriptDir & "\drvInterface.dll") ;~ VINT vr_init (void); ConsoleWrite("vr_init..." & @CRLF) $sTest = DllCall($hDLL, "int:cdecl", "?vr_init@@YAHXZ") ;~ VINT vr_get_controller_num (VINT *pnumber); ConsoleWrite("vr_get_controller_num..." & @CRLF) $sTest = DllCall($hDLL, "int:cdecl", "?vr_get_controller_num@@YAHPAH@Z", "int*", "$pTest") $iControllerNumber = $sTest[1] ConsoleWrite("$iControllerNumber = " & $iControllerNumber & @CRLF) ;~ VINT vr_get_device_num (VINT *pnumber); ConsoleWrite("vr_get_device_num..." & @CRLF) $sTest = DllCall($hDLL, "int:cdecl", "?vr_get_device_num@@YAHPAH@Z", "int*", "$pTest") $iDeviceNumber = $sTest[1] ConsoleWrite("$iDeviceNumber = " & $iDeviceNumber & @CRLF) ;~ VINT vr_get_array_num (VINT only_raid, VINT *pnumber); ConsoleWrite("vr_get_array_num..." & @CRLF) $sTest = DllCall($hDLL, "int:cdecl", "?vr_get_array_num@@YAHHPAH@Z", "int", 0, "int*", "$pTest") $iArrayNumber = $sTest[2] ConsoleWrite("$iArrayNumber = " & $iArrayNumber & @CRLF) $vr_array_info = DllStructCreate("ushort status;byte raidType;byte diskNum;dword capacityLow;dword capacityHigh;dword stripeSize;dword blockSize;boolean bNeedMigration;boolean bNeedInit;boolean bOptimized;byte systemDisk;byte raid_index;int index") ;~ VINT vr_get_array_info (VINT array_index, vr_array_info_t* pinfo); ConsoleWrite("vr_get_array_info..." & @CRLF) $sTest = DllCall($hDLL, "int:cdecl", "?vr_get_array_info@@YAHHPAU_vr_array_info@@@Z", "int", 0, "struct*", $vr_array_info) ;~ void vr_exit (void); ConsoleWrite("vr_exit..." & @CRLF) $sTest = DllCall($hDLL, "none", "?vr_exit@@YAXXZ") DllClose($hDLL) Exit Everything works fine up to vr_get_array_info part. This is where I get a "memory cannot be 'read'" Windows error ("Instruction at 0x7c93a514 referenced memory at 0x00000000"). What am I doing wrong? Please help. drvInterface.dll ProgGuide.pdf Link to comment Share on other sites More sharing options...
Danp2 Posted January 17, 2017 Share Posted January 17, 2017 Looks like you got the structure definition wrong -- VDWORD realCapacityLow; // (Unit: sector) VDWORD realCapacityHigh; // (Unit: sector) is missing byte raid_index; also appears to be wrong. ogloed 1 Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
ogloed Posted January 17, 2017 Author Share Posted January 17, 2017 1 hour ago, Danp2 said: Looks like you got the structure definition wrong -- VDWORD realCapacityLow; // (Unit: sector) VDWORD realCapacityHigh; // (Unit: sector) is missing byte raid_index; also appears to be wrong. Well, thank you and "thank you" to authors of the DLL manual. For there's a little bit different picture: vr_array_info_t typedef struct _vr_array_info { VWORD status; VBYTE raidType; // value 0xFF means // a stand-alone disk. When it's a stand-alone disk, // only diskNum has meaning, and diskNum should // always be 1 . VBYTE diskNum;// count of valid disk members. VDWORD capacityLow;// (Unit: sector) VDWORD capacityHigh;// (Unit: sector) VDWORD stripeSize; // valid when raid is raid0 or raid01, in Kbytes VDWORD blockSize; // valid when raid is RAID5, in Kbytes VBOOL bNeedMigration; // the raid need migration // only valid when raid0/raid5/matrixRaid VBOOL bNeedInit; // the raid need initialization, only valid for RAID5 VBOOL bOptimized; // only for RAID5, this RAID5 access was optimized VBYTE systemDisk; /* does the devices within this disk array contain system files of current running OS ? The probably value are: VR_DEVICE_NOT_SYS_DISK VR_DEVICE_MAYBE_SYS_DISK VR_DEVICE_SYS_DISK they are defined in this file */ VBYTE raid_index;// only raid index, no meaning with stand-alone disk VINT index; // all device index, including all raid and stand-alone disk } vr_array_info_t; OK, so here's what I changed: $vr_array_info = DllStructCreate("ushort status;byte raidType;byte diskNum;dword capacityLow;dword capacityHigh;dword realCapacityLow;dword realCapacityHigh;dword stripeSize;dword blockSize;boolean bNeedMigration;boolean bNeedInit;boolean bOptimized;byte systemDisk;ushort raid_index;int index") Getting the same "memory cannot be 'read'", but now with "referenced memory at 0x00000004" and "referenced memory at 0x00000000" showing randomly. Link to comment Share on other sites More sharing options...
Danp2 Posted January 17, 2017 Share Posted January 17, 2017 Look at the bottom of page 3 in the manual. There they show the definition of the data types, which are different than what you are using. ogloed 1 Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
ogloed Posted January 17, 2017 Author Share Posted January 17, 2017 1 hour ago, Danp2 said: Look at the bottom of page 3 in the manual. There they show the definition of the data types, which are different than what you are using. IT WORKS, THANK YOU!!! I'm so happy now! Link to comment Share on other sites More sharing options...
ogloed Posted January 17, 2017 Author Share Posted January 17, 2017 Working piece of code: $vr_array_info = DllStructCreate("ushort status;ubyte raidType;ubyte diskNum;ulong capacityLow;ulong capacityHigh;ulong realCapacityLow;ulong realCapacityHigh;ulong stripeSize;ulong blockSize;int bNeedMigration;int bNeedInit;int bOptimized;ubyte systemDisk;ushort raid_index;int index") $sTest = DllCall($hDLL, "int:cdecl", "?vr_get_array_info@@YAHHPAU_vr_array_info@@@Z", "int", 0, "struct*", DllStructGetPtr($vr_array_info)) Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now