...Not shure if this is a right place to put the thread in, but anyway,

Imagine that You have a memory layout (I'll call it a structure), and at the end of this
layout You have two or more strings, each with length undefined.
However You also have two corresponding fields inside the same structure telling You the length of each string.
Suppose that these fields can be filled in by your program at run-time.


STRTESTSTRUCT STRUC
str1_len WORD ?
str2_len WORD ?
str1 BYTE str1_len dup (?) ;<--Sure, This gives A2006 'undefined symbol' error
str2 BYTE (STRTESTSTRUCT.str2_len) dup (?) ;<--A2006 too
STRTESTSTRUCT ENDS

The question is: How to put the right number of symbols (dup) into each string, knowing these
lengths from upper fileds of the structure? The offset of second string is undefined, lengths of both strings
are undefined too.

Thanks for reading ;-)
Posted on 2002-10-21 06:16:46 by Andycar
Hi, Andy!

Labels inside STRUCs

It's not exact solution but hope helps you.
Posted on 2002-10-21 06:43:34 by Four-F
That you want to do is very similar to UNICODE_STRING structure.
Try this. Not exactly what you want but may be it suits to your need.
.386

.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

COUNTED_STRING STRUC
str_len WORD ?
pstr LPVOID ?
COUNTED_STRING ENDS

DefineCS MACRO lbl, str:REQ
local dum
dum db str, 0
lbl COUNTED_STRING {(sizeof dum), offset dum}
ENDM

.data
DefineCS sname1, "String2"
DefineCS sname2, "String4"

.code
start:
invoke MessageBox, NULL, sname1.pstr, NULL, MB_OK
invoke MessageBox, NULL, sname2.pstr, NULL, MB_OK
ret
end start


And you'll have:
.data:00403000 szString2       db 'String2', 0

.data:00403008 dw 8
.data:0040300A lpszString2 dd offset szString2
.data:0040300E szString4 db 'String4', 0
.data:00403016 dw 8
.data:00403018 lpszString2 dd offset szString4
Posted on 2002-10-21 08:08:45 by Four-F

That you want to do is very similar to UNICODE_STRING structure.
Try this. Not exactly what you want but may be it suits to your need.


Privet, tezka ;-)

Thanks for quick replies.
I think, the last solution is almost exactly what i need.
Thanks, man ;-)
Posted on 2002-10-21 09:09:10 by Andycar
Another solution: :)
STRTESTSTRUCT MACRO nme:REQ, string1:REQ, string2:REQ

LOCAL s1, s2

s1 = @SizeStr(string1) - 1
s2 = @SizeStr(string2) - 1

s_&nme STRUCT
str1_len WORD ?
str2_len WORD ?
str1 BYTE s1 dup (0)
str2 BYTE s2 dup (0)
s_&nme ENDS

nme s_&nme {s1,s2,string1,string2}
ENDM


_DATA SEGMENT
STRTESTSTRUCT TestName, "String 1", "String 2"
_DATA ENDS
Now you can access TestName structure using the names you originally suggested!

TestName.str1_len
TestName.str2_len
TestName.str1
TestName.str2
Posted on 2002-10-21 22:05:48 by bitRAKE
I recalled that one time i had similar problem. Solution rof me was here (thanx bitRAKE for the tip):

have trouble to define offset.

I guess it exactly what you want.
Assemble code-snippet below and load it to disassembler and you'll understand how it works.
Important here is that you can place $DefineCS macro in arbitrary location in your code.
But after linking you'll get consolidate arrays of COUNTED_STRING structures and array of strings.


.386

.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

_DATA$B SEGMENT
_DATA$B ENDS

_DATA$A SEGMENT
_DATA$A ENDS

STR_COUNTER = 0

COUNTED_STRING STRUC
str_len DWORD ?
pstr LPVOID ?
COUNTED_STRING ENDS

$DefineCS MACRO str:REQ
local str_cur

STR_COUNTER = STR_COUNTER + 1

_DATA$B SEGMENT
str_cur TEXTEQU @CatStr(<str_>, %(STR_COUNTER))
str_cur db str, 0
_DATA$B ENDS

_DATA$A SEGMENT
IF STR_COUNTER EQ 1
StrArray label BYTE
ENDIF
dd sizeof str_cur
dd offset str_cur
_DATA$A ENDS

EXITM <offset str_cur>
ENDM

.code
start:
invoke MessageBox, NULL, $DefineCS("Imagine"), NULL, MB_OK
invoke MessageBox, NULL, $DefineCS("that"), NULL, MB_OK
invoke MessageBox, NULL, $DefineCS("You"), NULL, MB_OK
invoke MessageBox, NULL, $DefineCS("have"), NULL, MB_OK
invoke MessageBox, NULL, $DefineCS("a"), NULL, MB_OK
invoke MessageBox, NULL, $DefineCS("memory"), NULL, MB_OK
invoke MessageBox, NULL, $DefineCS("layout"), NULL, MB_OK

lea eax, StrArray[(sizeof COUNTED_STRING)*5]
.if [COUNTED_STRING PTR [eax]].str_len < 100h
invoke MessageBox, NULL, (COUNTED_STRING PTR [eax]).pstr, NULL, MB_OK
.endif

ret
end start
Posted on 2002-10-22 09:27:13 by Four-F
Thanks bitRAKE and Four-F for your solutions!

I had a closer look and it appeared that bitRAKE's solution
is exactly what I need.
Thanks for your help, this board is the best!
Posted on 2002-10-22 13:41:48 by Andycar