Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a WCHAR null terminated

Tags:

visual-c++

I've got this

WCHAR fileName[1];

as a returned value from a function (it's a sys 32 function so I am not able to change the returned type). I need to make fileName to be null terminated so I am trying to append '\0' to it, but nothing seems to work.

Once I get a null terminated WCHAR I will need to pass it to another sys 32 function so I need it to stay as WCHAR.

Could anyone give me any suggestion please?

================================================

Thanks a lot for all your help. Looks like my problem has to do with more than missing a null terminated string.

//This works:

WCHAR szPath1[50] = L"\\Invalid2.txt.txt";
    dwResult = FbwfCommitFile(szDrive, pPath1); //Successful

//This does not:

std::wstring l_fn(L"\\");  
    //Because Cache_detail->fileName is \Invalid2.txt.txt and I need two
l_fn.append(Cache_detail->fileName);
l_fn += L""; //To ensure null terminated
fprintf(output, "l_fn.c_str: %ls\n", l_fn.c_str()); //Prints "\\Invalid2.txt.txt"

    iCommitErr = FbwfCommitFile(L"C:", (WCHAR*)l_fn.c_str()); //Unsuccessful

//Then when I do a comparison on these two they are unequal.

int iCompareResult = l_fn.compare(pPath1);  // returns -1

So I need to figure out how these two ended up to be different.

Thanks a lot!

like image 379
WBun Avatar asked Nov 27 '09 00:11

WBun


2 Answers

Since you mentioned fbwffindfirst/fbwffindnext in a comment, you're talking about the file name returned in FbwfCacheDetail. So from the fileNameLength field you know length for the fileName in bytes. The length of fileName in WCHAR's is fileNameLength/sizeof(WCHAR). So the simple answer is that you can set

fileName[fileNameLength/sizeof(WCHAR)+1] = L'\0'

Now this is important you need to make sure that the buffer you send for the cacheDetail parameter into fbwffindfirst/fbwffindnext is sizeof(WCHAR) bytes larger than you need, the above code snippet may run outside the bounds of your array. So for the size parameter of fbwffindfirst/fbwffindnext pass in the buffer size - sizeof(WCHAR).

For example this:

// *** Caution: This example has no error checking, nor has it been compiled ***
ULONG error;
ULONG size;
FbwfCacheDetail *cacheDetail;

// Make an intial call to find how big of a buffer we need
size = 0;
error = FbwfFindFirst(volume, NULL, &size);
if (error == ERROR_MORE_DATA) {
    // Allocate more than we need
    cacheDetail = (FbwfCacheDetail*)malloc(size + sizeof(WCHAR));
    // Don't tell this call about the bytes we allocated for the null
    error = FbwfFindFirstFile(volume, cacheDetail, &size);
    cacheDetail->fileName[cacheDetail->fileNameLength/sizeof(WCHAR)+1] = L"\0";

    // ... Use fileName as a null terminated string ...

    // Have to free what we allocate
    free(cacheDetail);
}

Of course you'll have to change a good bit to fit in with your code (plus you'll have to call fbwffindnext as well)

If you are interested in why the FbwfCacheDetail struct ends with a WCHAR[1] field, see this blog post. It's a pretty common pattern in the Windows API.

like image 78
shf301 Avatar answered Oct 22 '22 09:10

shf301


Use L'\0', not '\0'.

like image 4
Mark Byers Avatar answered Oct 22 '22 10:10

Mark Byers