News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

How to Call StringCchCat in Win64 Assembly?

Started by wanker742126, October 30, 2024, 07:30:05 PM

Previous topic - Next topic

wanker742126

Hello everyone,

I'm currently writing a program in Win64 assembly language with the intention of using the StringCchCat function to concatenate two strings. However, I'm encountering the following error during compilation:
tststr.obj : error LNK2019: unresolved external symbol StringCchCat referenced in function main 
tststr.exe : fatal error LNK1120: 1 unresolved externals
It seems like StringCchCat cannot be located. I would like to ask:
    Do I need to manually link to a specific .lib file?
    Are there any particular settings required for using this function in assembly?
Thank you very much for any advice!

My source is tststr.asm:
INCLUDE \masm64\include64\masm64rt.inc

StringCchCat PROTO :QWORD,:DWORD,:QWORD

.DATA
hInst   DQ      ?
szTitle DB      "Test StringCb"
str1    DB      "I learn ",40h DUP (0)
str2    DB      "assembly language.",0

.CODE
main    PROC
        invoke  StringCchCat,ADDR str1,SIZEOF str1,ADDR str2
        invoke  MessageBox,0,ADDR str1,ADDR szTitle,MB_OK
        call    ExitProcess
main    ENDP
END


HSE

You can search in /include64 files.

Probably equate of import is vc_StringCchCat.
Equations in Assembly: SmplMath

TimoVJL

It's a C macro:
STRSAFEAPI
    StringCchCatA(
            _Inout_updates_(cchDest) _Always_(_Post_z_) STRSAFE_LPSTR pszDest,
            _In_ size_t cchDest,
            _In_ STRSAFE_LPCSTR pszSrc)
{
    HRESULT hr;
    size_t cchDestLength;

    hr = StringValidateDestAndLengthA(pszDest,
            cchDest,
            &cchDestLength,
            STRSAFE_MAX_CCH);

    if (SUCCEEDED(hr))
    {
        hr = StringCopyWorkerA(pszDest + cchDestLength,
                cchDest - cchDestLength,
                NULL,
                pszSrc,
                STRSAFE_MAX_LENGTH);
    }

    return hr;
}
Worker functions are in strsafe.lib
pFile Data Description Value
00000044 00000019 Number of Symbols
00000048 000006B2 Offset to Header StringVPrintf_lWorkerA
0000004C 000006B2 Offset to Header StringVPrintf_lWorkerW
00000050 00003E08 Offset to Header ??_C@_00CNPNBAHC@?$AA@
00000054 00003E08 Offset to Header ??_C@_11LOCGONAA@?$AA?$AA@
00000058 00003E08 Offset to Header StringCopyWorkerA
0000005C 00003E08 Offset to Header StringCopyWorkerW
00000060 00003E08 Offset to Header StringExHandleFillBehindNullA
00000064 00003E08 Offset to Header StringExHandleFillBehindNullW
00000068 00003E08 Offset to Header StringExHandleOtherFlagsA
0000006C 00003E08 Offset to Header StringExHandleOtherFlagsW
00000070 00003E08 Offset to Header StringExValidateDestA
00000074 00003E08 Offset to Header StringExValidateDestAndLengthA
00000078 00003E08 Offset to Header StringExValidateDestAndLengthW
0000007C 00003E08 Offset to Header StringExValidateDestW
00000080 00003E08 Offset to Header StringExValidateSrcA
00000084 00003E08 Offset to Header StringExValidateSrcW
00000088 00003E08 Offset to Header StringLengthWorkerA
0000008C 00003E08 Offset to Header StringLengthWorkerW
00000090 00003E08 Offset to Header StringVPrintfWorkerA
00000094 00003E08 Offset to Header StringVPrintfWorkerW
00000098 00003E08 Offset to Header StringValidateDestA
0000009C 00003E08 Offset to Header StringValidateDestAndLengthA
000000A0 00003E08 Offset to Header StringValidateDestAndLengthW
000000A4 00003E08 Offset to Header StringValidateDestW
000000A8 00003E08 Offset to Header UnalignedStringLengthWorkerW
May the source be with you

wanker742126

Thank you, HSE and TimoVJL, for your response.
I couldn't find strsafe.lib in masm64\lib64. Where can I download it?

stoo23

QuoteI couldn't find strsafe.lib in masm64\lib64
No neither could I,.. I have searched our server and We do Not have a copy of it anywhere,... Should We ???  :undecided:
It certainly Isn't in the copies of MASM64 or the SDK ??

TimoVJL

Quote from: wanker742126 on October 30, 2024, 11:41:12 PMThank you, HSE and TimoVJL, for your response.
I couldn't find strsafe.lib in masm64\lib64. Where can I download it?
from Windows SDK
May the source be with you

stoo23

Quotefrom Windows SDK
Yeah ??? ... Which Windows SDK Timo ???

It's NOT anywhere in the copy of MASM64 We have on the server ??

zedd151

Quote from: stoo23 on October 31, 2024, 12:20:29 AM
QuoteI couldn't find strsafe.lib in masm64\lib64
No neither could I,.. I have searched our server and We do Not have a copy of it anywhere,... Should We ??? 
Stoo, the Windows SDK (software development kit) is a Microsoft product, which has a set of its own libraries (*.lib files). Hence are a separate entity from the Masm64 SDK that we offer. I don't think we should duplicate it within the Masm64 SDK.

This is another example of why it is difficult for some users to use Visual Studio with Masm32 SDK and/or Masm64 SDK.
They have the impression that Masm64 SDK has libraries and include files that it simply does not, but are either in the Visual Studio package or in one of the Microsoft Windows SDK's. (Microsoft products)

I do agree however that the Masm64 SDK is missing some include files (*.inc) that it should have - plus some incomplete or erroneous include files, which should not be confused with Microsofts own include files (*.h) which either the Visual Studio package or one of the Windows SDK packages does have.

 :smiley:
:azn:

C3

Quote from: stoo23 on October 31, 2024, 12:51:39 AM
Quotefrom Windows SDK
Yeah ??? ... Which Windows SDK Timo ???

It's NOT anywhere in the copy of MASM64 We have on the server ??

Google gives this: Microsoft Windows SDK

Also included in Microsoft Visual Studio, one reason to use, for me.

Quote from: zedd151 on October 31, 2024, 01:00:26 AM
QuoteI do agree however that the Masm64 SDK is missing some include files (*.inc) that it should have - plus some incomplete or erroneous include files, which should not be confused with Microsofts own include files (*.h) which either the Visual Studio package or one of the Windows SDK packages does have.

Thats what is really needed. I just add stuff from Microsoft headers (*.h) to include files (*.inc) when I need something what is not already there.

stoo23

Thanks for the Above link and info' guys  :thumbsup:
I'll try and Place that Windows resource somewhere usefully appropriate  :wink2:  :thumbsup:  Perhaps in the Reference section  :smiley:

QuoteStoo, the Windows SDK (software development kit) is a Microsoft product, which has a set of its own libraries (*.lib files). Hence are a separate entity from the Masm64 SDK that we offer. I don't think we should duplicate it within the Masm64 SDK.
Yep understood, I was just commenting on the fact that We did not have a copy of that file Anywhere on our server, OR in the Files I have locally from Hutch.

As suggested, thanks for the info'  :azn:

HSE

Don't pay attention to files names, just search function name.
Equations in Assembly: SmplMath

BugCatcher


TimoVJL

Quote from: BugCatcher on October 31, 2024, 03:56:45 AMstrsafe.h
MS documents don't always tell whole truth, so we had to give additional info.
May the source be with you

Vortex

#13
Hello wanker742126,

You don't have to download a lot of files to obtain the header file strsafe.h, it comes with Pelles C :

\PellesC\Include\strsafe.h
STRSAFEAPI StringCchCatA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
{
    size_t cchDestLength;
    HRESULT hr = _StringValidateDestAndLengthA(pszDest, cchDest, &cchDestLength, STRSAFE_MAX_CCH);
    if (SUCCEEDED(hr)) {
        hr = _StringCopyWorkerA(pszDest + cchDestLength, cchDest - cchDestLength, NULL, pszSrc, STRSAFE_MAX_LENGTH);
    }
    return hr;
}

STRSAFEWORKERAPI _StringCopyWorkerA(STRSAFE_LPSTR pszDest, size_t cchDest, size_t * pcchNewDestLength, STRSAFE_PCNZCH pszSrc, size_t cchToCopy) {
    HRESULT hr = S_OK;
    size_t cchNewDestLength = 0;
    while (cchDest && cchToCopy && (*pszSrc != '\0')) {
        *pszDest++ = *pszSrc++;
        cchDest--;
        cchToCopy--;

        cchNewDestLength++;
    }
    if (cchDest == 0) {
        pszDest--;
        cchNewDestLength--;
        hr = STRSAFE_E_INSUFFICIENT_BUFFER;
    }
    *pszDest = '\0';
    if (pcchNewDestLength) {
        *pcchNewDestLength = cchNewDestLength;
    }
    return hr;
}

Obtaining Pelles C :

http://www.smorgasbordet.com/pellesc/download.htm

wanker742126

#14
Hi everyone, thanks for your help, I finally solved this problem.

I followed TimoVJL's advice and downloaded the Windows SDK from the link provided by C3, then installed it.

The strsafe.lib file was located in the
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.26100.0\um\x64 folder. However, it's not an import library, and I took quite a detour before realizing this.

Using DUMPBIN /ALL, I discovered that StringCchCatA was not present in the library. After reading the contents of strsafe.h provided by TimoVJL, Vortex and the file located at
C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared\strsafe.h, I realized StringCchCatA is not included in strsafe.lib. It's more like a macro, so I wrote one using assembly language syntax. Here's the source file :

INCLUDE \masm64\include64\masm64rt.inc
includelib "c:\Program Files (x86)\Windows Kits\10\Lib\10.0.26100.0\um\x64\strsafe.lib"
STRSAFE_MAX_CCH    EQU 2147483647
STRSAFE_MAX_LENGTH EQU STRSAFE_MAX_CCH-1
StringValidateDestAndLengthA PROTO :QWORD,:DWORD,:QWORD,:DWORD
StringCopyWorkerA            PROTO :QWORD,:DWORD,:DWORD,:QWORD,:DWORD
.DATA
hInst   DQ      ?
szTitle DB      "Test StringCchCat",0
str1    DB      "I learn ",40h DUP (0)
str2    DB      "assembly language.",0

.CODE
StringCchCatA PROC pszDest:QWORD,cchDest:DWORD,pszSrc:QWORD
        LOCAL   cchDestLength:DWORD
        invoke  StringValidateDestAndLengthA,pszDest,cchDest,ADDR cchDestLength,STRSAFE_MAX_CCH
        cmp     eax,0
        jl      exit
        sub     r10,r10
        mov     r10d,cchDestLength
        mov     rcx,pszDest
        add     rcx,r10
        mov     edx,cchDest
        sub     edx,cchDestLength
        invoke  StringCopyWorkerA,rcx,edx,0,pszSrc,STRSAFE_MAX_LENGTH
exit:   ret
StringCchCatA ENDP
main    PROC
        invoke  StringCchCatA,ADDR str1,SIZEOF str1,ADDR str2
        invoke  MessageBox,0,ADDR str1,ADDR szTitle,MB_OK
        call    ExitProcess
main    ENDP
END

Please give me some advice for improvement, thank you for your help.