GoAsm; Easy Code IDE; ECGo header
Hello everybody!
I want to use the StringCB... functions (e.g. StringCbLengthW) defined in Strsave.h, but the linker quits with:
Error!
The following symbol was not defined in the object file or files:-
StringCbLengthW
My question is, it is necessary to download the whole PSDK to get the Strsave.lib or is there another solution? E.g. linking against a specific *.dll?
Thank you
traphunter
I'm not sure if I ever installed the SDK on this machine here, but the libraries are there.
Have you checked C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib\strsafe.lib ?
Besides, Masm32 has \Masm32\include\ntstrsafe.inc, but my puter says "The program can't start because ntstrsafe.dll is missing" ::)
Apart from that: Using lstrcpyn etc with some caution is the better choice. These "safe" functions are very slow...
yes, I've checked my machine, I didn't have the libraries. I would like to use these functions in a none time critical task, where I didn't have the control over the input string.
Quote from: traphunter on November 30, 2013, 02:11:26 AM... where I didn't have the control over the input string.
Safe and fast:
include \masm32\include\masm32rt.inc
.data
dest db 50 dup(?)
afterdest db "Don't trash me please...", 0
.code
somestring db "Hello, this is a simple string intended for testing string algos. It has 100 characters without zero", 0
.code
start:
mov esi, offset somestring
mov edi, offset dest
.if len(esi)>=sizeof dest
mov eax, sizeof dest
.endif
invoke lstrcpyn, edi, esi, eax
MsgBox 0, edi, offset afterdest, MB_OK
exit
end start
;)
yes, thank you, but I often try to use existing resources. Really, I would like to know, how to link these windows functions without downloading the whole SDK for getting the strsave.lib.
that's a strange one :redface:
according to msdn, it should be in coredll.dll, and is supported xp sp2 or better
i also found references on the web to ntstrsafe.dll and strsafe.dll
i am running xp sp3, and i don't find any of those dll's on my machine - lol
Pelle's C has coredll.lib <------------------------- this one is under WinCE
masm32 has ntstrsafe.inc and ntstrsafe.lib
hmmm - it may be in MSVCRT
checking......
http://www.masmforum.com/board/index.php?topic=18010.msg151770#msg151770 (http://www.masmforum.com/board/index.php?topic=18010.msg151770#msg151770)
quote from Edgar....
QuoteThe string safe functions are not exported by any library, they are inline code in the SDK headers (Strsafe.h) so they would need to be rewritten from scratch for MASM. However in Windows 8 I noticed that a few of them are available in kernel32.dll as exports.
http://www.masmforum.com/board/index.php?topic=18010.msg151826#msg151826 (http://www.masmforum.com/board/index.php?topic=18010.msg151826#msg151826)
i agree with the last 3 posts in that thread from Hutch, Jochen, and Greg
string-safe functions are a "compiler thing"
in assembly language, the program should be designed so that buffer over-flows don't occur :t
i.e., if you need a string-safe function, you're doing it wrong - lol
Ah, thank you very much, in strsave.h are c++ inline functions. I won't use the strsave.lib anymore. ;)
BTW: The question is not whether I need a function, the question is, it's better to reuse or to write code by yourself? The answer: it varies ;)
with best regards
traphunter
in assembly language, we might simply create a temp buffer on the stack
that way, you know the buffer is large enough to accomodate the string
thus, the function is never required
i hope that's a little clearer
If the stringlength is unknown and unpredictable due to streaminput, I can't locate enough memory anywhere, whether what coding language is used. Now I will use the lstr... functions with own coded wrapper.
I only wanted to know a way to use these StringC... functions. I've searched for that, here in this forum and elsewhere, but maybe with wrong phrases. Due to your hints I know much more than before. Thank you very much! :)
Judging from it not containing a DLL name but containing at least one object module name, the strsafe.lib from my 2003 PSDK is apparently a static library.
;==============================================================================
include \masm32\include\masm32rt.inc
includelib strsafe.lib
;==============================================================================
StringCbLengthA proto :DWORD,:DWORD,:DWORD
; _In_ LPCTSTR psz,
; _In_ size_t cbMax,
; _Out_ size_t *pcb
;==============================================================================
.data
slength dd 0
string db "my other brother darryl",0
.code
;==============================================================================
;==============================================================================
start:
;==============================================================================
invoke StringCbLengthA, ADDR string, 24, ADDR slength
printf("%d\t%d\n\n",eax,slength)
inkey
exit
;==============================================================================
end start
0 23
And from strsafe.h:
#define S_OK ((HRESULT)0x00000000L)
I get Unresolved external symbol '_StringCbLengthA@12'. from my C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib\strsafe.lib of 30.09.2009...
As Dave wrote, it's a 'compiler thing' - here is its definition from strsafe.h:
STRSAFEAPI
StringCbCopyNA(
__out_bcount(cbDest) STRSAFE_LPSTR pszDest,
__in size_t cbDest,
__in_bcount(cbToCopy) STRSAFE_PCNZCH pszSrc,
__in size_t cbToCopy)
{
HRESULT hr;
size_t cchDest = cbDest / sizeof(char);
hr = StringValidateDestA(pszDest, cchDest, STRSAFE_MAX_CCH);
if (SUCCEEDED(hr))
{
size_t cchToCopy = cbToCopy / sizeof(char);
if (cchToCopy > STRSAFE_MAX_LENGTH)
{
hr = STRSAFE_E_INVALID_PARAMETER;
*pszDest = '\0';
}
else
{
hr = StringCopyWorkerA(pszDest,
cchDest,
NULL,
pszSrc,
cchToCopy);
}
}
return hr;
}
By the way, we discussed all that already one year ago (http://masm32.com/board/index.php?topic=812.0).
ahhhh, Michael - the PSDK has the static library :t
don't know how i missed that one (i probably searched for ntstrsafe.lib)
the LIB in the masm32 package is undoubtedly an import library - with no DLL to import from :P
Quote from: dedndave on November 30, 2013, 10:11:47 PM
ahhhh, Michael - the PSDK has the static library :t
See reply #1. But it doesn't help much, at least with my machines, because the exe complains about the missing ntdll :(
However, StringCbLengthA works:
Intel(R) Celeron(R) M CPU 420 @ 1.60GHz (SSE3)
3948 cycles for 100 * MasmBasic Len
30580 cycles for 100 * StringCbLengthA
3936 cycles for 100 * MasmBasic Len
30588 cycles for 100 * StringCbLengthA
3936 cycles for 100 * MasmBasic Len
30676 cycles for 100 * StringCbLengthA
MichaelW's example with POAsm:.386
.model FLAT, c
option casemap:none
;==============================================================================
;include \masm32\include\masm32rt.inc
includelib kernel32.lib
includelib msvcrt.lib
includelib strsafe.lib
;==============================================================================
StringCbLengthA proto stdcall :DWORD,:DWORD,:DWORD
; _In_ LPCTSTR psz,
; _In_ size_t cbMax,
; _Out_ size_t *pcb
;==============================================================================
ExitProcess proto stdcall :DWORD
printf proto C :DWORD,:VARARG
.data
slength dd 0
string db "my other brother darryl",0
fmt db "%d",9,"%d",13,10,0
.code
;==============================================================================
;==============================================================================
start:
;==============================================================================
invoke StringCbLengthA, ADDR string, 24, ADDR slength
invoke printf,addr fmt,eax,slength
invoke ExitProcess,0
;==============================================================================
end start
LIBRARY msvcrt.dll
EXPORTS
printf
3948 cycles for 100 * MasmBasic Len
30580 cycles for 100 * StringCbLengthA
3936 cycles for 100 * MasmBasic Len
30588 cycles for 100 * StringCbLengthA
3936 cycles for 100 * MasmBasic Len
30676 cycles for 100 * StringCbLengthA
not very "zippy" - lol
(http://i5.photobucket.com/albums/y188/MsPurrl/Fictional%20Characters/Zippy.jpg)
Quote from: jj2007 on November 30, 2013, 02:49:12 PM
I get Unresolved external symbol '_StringCbLengthA@12'. from my C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib\strsafe.lib of 30.09.2009...
Using the Microsoft Visual C++ Toolkit 2003 compiler it works fine for me, whether the function is inlined or linked in from the library. The attachment includes the EXE and assembly ouput for both.
Doing a dump of the EXEs I see that they both contain the name mscoree.dll. The description from the DLL properties is:
Microsoft .NET Runtime Execution Engine
Makes me wonder how portable the EXEs are...
It looks like all of the EXEs I built with that compiler contain the name, apparently associated with CorExitProcess.
Thanks, Michael :t
Test_Inline.asm:
; Line 5165
lea ecx, DWORD PTR _cchLength$[ebp]
push ecx
mov edx, DWORD PTR _cchMax$[ebp]
push edx
mov eax, DWORD PTR _psz$[ebp]
push eax
call _StringLengthWorkerA@12
It's a mystery how they can release into the wild an algo that is eight times slower than a reasonable handcrafted one doing exactly the same ::)
Well, almost exactly. Just for fun:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
StringCbLengthA proto :DWORD,:DWORD,:DWORD
includelib strsafestatic.lib
Init tc
Let esi=FileRead$("\Masm32\include\Windows.inc") ; get a source text
invoke VirtualAlloc, 0, 4096, MEM_COMMIT, PAGE_READWRITE ; create a 4k buffer
xchg eax, edi
pushad
mov ecx, 4096
rep movsb ; copy
popad
Print Str$("Len=%i\twith MasmBasic Len\n", Len(edi))
push eax
invoke StringCbLengthA, edi, 4096, esp
pop ecx
Print Str$("Len=%i \twith StringCbLengthA\n", ecx)
Print Str$("Len=%i\twith Masm32 len\n", len(edi))
Exit
TryCatchEnd
end start
Output:
Len=4096 with MasmBasic Len
Len=0 with StringCbLengthA
The instruction at "0040149A" referred to the memory location...
And of course, StringCbLengthA reports "The operation completed successfully" - what else would you expect from such a "safe" function? ;)
Print Str$("Len=%i\twith MasmBasic Len\n", Len(edi))
change this line the value of edi?
I don't use masm, therefore I can't test it.
in most cases....
EAX, ECX, EDX are volatile
EBX, EBP, ESI, EDI are preserved
QuoteAnd of course, StringCbLengthA reports "The operation completed successfully"...
In my test it failed.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#define STRSAFE_LIB
#include <strsafe.h>
int main (void)
{
int res;
size_t slen;
char *p = VirtualAlloc(0,4096,MEM_COMMIT,PAGE_READWRITE);
FILE *stream = fopen( "\\masm32\\include\\windows.inc", "r");
printf("read: %d\n",fread(p,1,4096,stream));
res = StringCbLength(p,4096,&slen);
switch(res)
{
case S_OK:
printf("S_OK\n");
break;
case STRSAFE_E_INSUFFICIENT_BUFFER:
printf("STRSAFE_E_INSUFFICIENT_BUFFER\n");
break;
case STRSAFE_E_INVALID_PARAMETER:
printf("STRSAFE_E_INVALID_PARAMETER\n");
break;
case STRSAFE_E_END_OF_FILE:
printf("STRSAFE_E_END_OF_FILE\n");
break;
}
printf("length: %d\n\n",slen);
// For StringCbLength the cbMax parameter must specify the maximum
// number of bytes allowed, including the null terminator, so to
// correct this problem overwrite the last byte with a null.
p[4095] = 0;
res = StringCbLength(p,4096,&slen);
switch(res)
{
case S_OK:
printf("S_OK\n");
break;
case STRSAFE_E_INSUFFICIENT_BUFFER:
printf("STRSAFE_E_INSUFFICIENT_BUFFER\n");
break;
case STRSAFE_E_INVALID_PARAMETER:
printf("STRSAFE_E_INVALID_PARAMETER\n");
break;
case STRSAFE_E_END_OF_FILE:
printf("STRSAFE_E_END_OF_FILE\n");
break;
}
printf("length: %d\n\n",slen);
fclose(stream);
getch();
return 0;
}
read: 4096
STRSAFE_E_INVALID_PARAMETER
length: 0
S_OK
length: 4095
Quote from: MichaelW on December 02, 2013, 03:34:21 AM
QuoteAnd of course, StringCbLengthA reports "The operation completed successfully"...
In my test it failed.
I am wrong and you are right, Michael. While GetLastError reports "The operation completed successfully", StringCbLengthA returns indeed STRSAFE_E_INVALID_PARAMETER (80070057h).
Quote from: traphunter on December 02, 2013, 12:43:55 AM
Print Str$("Len=%i\twith MasmBasic Len\n", Len(edi))
change this line the value of edi?
As Dave already wrote, edi is one of the non-volatile registers. See "register gets trashed (http://www.webalice.it/jj2006/Masm32_Tips_Tricks_and_Traps.htm)".
In this specific case, only eax and edx get changed, because all MasmBasic macros preserve ecx.