RtlStringCbCopyW Does copy only first char of the string why? - unicode-string

I have problem in copying string from on type to another. code which have problem I have given below.
DbgPrint("Value of ProcessName =%wZ \n",&ProcessName);
//The Type of ProcessName is UNICODE_STRING
RtlStringCbCopyW(myBuffer,((MAX_PATH+90)*sizeof(WCHAR)),ProcessName.Buffer);
//try to copy from ProcessName.Buffer to myBuffer
DbgPrint("Value of MyBuffer =%s \n",MyBuffer);
//The Type of MyBuffer is Array of WCHAR
DbgPrint("Value of ProcessName.Buffer =%s \n",ProcessName.Buffer);
Output:-
Value of ProcesssName =\Device\HarddiskVolume1\Windows\explorer.exe
Value of MyBuffer =\
Value of ProcesssName.Buffer =\
why it is happening ?

your problem here in invalid format %s in DbgPrint - you need use %S instead. strings in your case copied correct, you only incorrect displayed it - %s assumed ansi string at stop after first \0 byte (in first WCHAR symbol). however in general case use RtlStringCbCopyW is error - because UNICODE_STRING can be not null-terminated and can containing null characters. need use RtlCopyUnicodeString. and finally this not related to driver minifilter and kernel-mode only to unicode-string

Related

Is there any easy way to replace %20 by a space in a CString?

I need to replace some %20 by spaces and got compile errors which i do not understand:
CString str = _T("foo%20bar");
str.Replace('%20',' '); // C4305 argument: truncation from 'int' to 'wchar_t'
str.Replace(_T('%20'),_T(' ')); // C4305 argument: truncation from 'int' to 'wchar_t'
str.Replace(_T("%20"),_T(" ")); // C2664 'int ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::Replace(const wchar_t *,const wchar_t *)': cannot convert argument 1 from 'const char [4]' to 'wchar_t'
What is wrong?
The CString::Replace() method takes null-terminated string pointers as input, not individual characters. Your string literals need to use " instead of ', eg:
CString str = _T("foo%20bar");
str.Replace(_T("%20"), _T(" "));
Note that matches your last example, which you say is also erroring. The only way that can fail with the error message you have shown is if you have a misconfiguration in your project, where UNICODE is defined 1 but _UNICODE is not defined 2.
1: as evident by CString being mapped to CStringT<wchar_t>.
2: as evident by the compiler saying _T("%20") is a const char[] rather than a const wchar_t[].
CString uses TCHAR from the Win32 API, not _TCHAR from the C runtime library. Usually they are interchangeable, but not so in your situation. So, you need to either fix your project's configuration so that _UNICODE is also defined, or else use the Win32 TEXT() macro to match CString's use of TCHAR:
CString str = TEXT("foo%20bar");
str.Replace(TEXT("%20"), TEXT(" "));
Or, simply stop using TCHAR-based APIs altogether (TCHAR dates back to the days of Win9x/ME when Microsoft was pushing everyone to start migrating their code to Unicode), and really should not be used in modern coding if you can avoid it. Just use wchar_t strings directly instead, eg:
CStringW str = L"foo%20bar";
str.Replace(L"%20", L" ");
The last one should have worked, except that you seem to have a wide CString in a project without the UNICODE and/or _UNICODE macro defined.
In this combination, the _T() macro isn't giving you a compatible string literal. But L"whatever" will.
str.Replace(L"%20", L" ");
Notice that this does what you asked, but is not adequate for URL unescaping. You should convert all %xx sequences.
%20 may be formatted string like %d. and Replace function return replaced String and str is not replaced.
try like: str = str.Replace(_T("%%20"), _T(" "));
or
try like: str = str.Replace(_T("%20"),_T(" "));
Extra Info
If you look at this Format specification syntax: printf and wprintf functions article you will see the following clarification:
A basic conversion specification contains only the percent sign and a type character. For example, %s specifies a string conversion. To print a percent-sign character, use %%. ...

Without null char in second argument for strcpy() function is returning unexpected result. Why?

#include<stdio.h>
#include <string.h>
int main()
{
char a[5];
char b[2]="12";
strcpy(a,b);
printf("%s\n",a);
}
There is no null char in string b that is why the output is not as expected.output : 12#
Why the output is coming like this only?
Your program has undefined behavior.
Your array b contains { '1', '2' }. As you say, there is no null character in the array -- which means it doesn't contain a string.
strcpy's second argument must be a pointer to a string. You gave it a char* value that is not a pointer to a string.
In practice, strcpy will probably continue copying characters from the memory following b. That memory contains arbitrary garbage -- and even the attempt to access it has undefined behavior.
In a sense, you're lucky that you got output that is visibly garbage. If there had happened to be a null character immediately following your array in memory, and if your program didn't blow up trying to access it, it could have just printed 12, and you might not have known that your program is buggy.
If you want to correct your program, you can change
char b[2] = "12";
to
char b[] = "12";
The compiler will figure out how big b needs to be to hold the string (including the required terminating null character).
strcpy keeps copying until it hits a null character (byte with value 0x00). It copies whatever it encounters on the way. In your case, memory after the array b happens to contain a byte with value 0x40 ('#') and then a byte with value 0x00.

Problems assigning char string to char array

I have already read all prior answers regarding my problem. However, I'm not a very bright coder to am unable to grasp it. Could someone please look into my problem.
I am trying to write a CSV file using entries from a 2D array. string.h has already been included in main().
void create_marks_csv(int rout[][20],float p[][20],float c[][20],int n)
{
system("cls");
char str1[100],str2[100],str3[100];
printf("\nEnter filename for routing matrix: ");
gets(str1);
printf("\n Creating %s.csv file",str1);
FILE *fp;
int i,j;
str1=strcat(str1,".csv");
str1=strcat("C:\\Users\\Neil\\Documents\\Trust CSV Logs\\",str1) ;
fp=fopen(str1,"w+");
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j)
fprintf(fp,"X");
else
fprintf(fp,"%d",rout[i][j]);
}
fprintf(fp,"\n");
}
fclose(fp);
printf("\nFile created: %s",str1);
system("cls");
}
The warnings and errors are as follows:
5 20 C:\Users\Neil\Documents\main.c [Warning] extra tokens at end of #include directive [enabled by default]
C:\Users\Neil\Documents\main.c In function 'create_marks_csv':
168 6 C:\Users\Neil\Documents\main.c [Error] incompatible types when assigning to type 'char[100]' from type 'char *'
169 6 C:\Users\Neil\Documents\main.c [Error] incompatible types when assigning to type 'char[100]' from type 'char *'
28 C:\Users\Neil\Documents\Makefile.win recipe for target 'main.o' failed
Every time you write str1 =, you are telling the compiler to change str1 so that it points to whatever location in memory is found on the right-hand side of the = sign. But you declared char str1[100], which means that str1, interpreted as a pointer, can only point to the start of the block of 100 characters at the location where this declaration allocated them. So it makes no sense to write str1 =.
Passing a C string constant as the first argument of strcat is likely to be a disaster, although the compiler seems not to mind. The first argument of strcat should be a character buffer big enough to hold the results of the concatenation. In order to concatenate something onto the end of a constant string, you can allocate a buffer big enough, then copy the constant string to it, then call strcat.
In general you can probably do whatever you need to do without using the return value of strcat, that is, no need to ever write strcat on the right-hand side of =.
It is advisable to use fgets instead of gets because then you can protect against the possibility that you will get too much input to fit in your allocated character buffer. If you allocate 100 characters in your largest buffer, you can only afford to accept 95 characters minus the length of the string "C:\\Users\\Neil\\Documents\\Trust CSV Logs\\". (The other 5 characters are required to hold the string ".csv" and the terminating null character).
I saw also that you declare str2 and str3 but I didn't see where you used either of them. It looks like you don't need both of them, but you might find it convenient to use str2 as the buffer for your last concatenation of strings.

Go - Comparing strings/byte slices input by the user

I am getting input from the user, however when I try to compare it later on to a string literal it does not work. That is just a test though.
I would like to set it up so that when a blank line is entered (just hitting the enter/return key) the program exits. I don't understand why the strings are not comparing because when I print it, it comes out identical.
in := bufio.NewReader(os.Stdin);
input, err := in.ReadBytes('\n');
if err != nil {
fmt.Println("Error: ", err)
}
if string(input) == "example" {
os.Exit(0)
}
string vs []byte
string definition:
string is the set of all strings of 8-bit bytes, conventionally but not necessarily representing UTF-8-encoded text. A string may be empty, but not nil. Values of string type are immutable.
byte definition:
byte is an alias for uint8 and is equivalent to uint8 in all ways. It is used, by convention, to distinguish byte values from 8-bit unsigned integer values.
What does it mean?
[]byte is a byte slice. slice can be empty.
string elements are unicode characters, which can have more then 1 byte.
string elements keep a meaning of data (encoding), []bytes not.
equality operator is defined for string type but not for slice type.
As you see they are two different types with different properties.
There is a great blog post explaining different string related types [1]
Regards the issue you have in your code snippet.
Bear in mind that in.ReadBytes(char) returns a byte slice with char inclusively. So in your code input ends with '\n'. If you want your code to work in desired way then try this:
if string(input) == "example\n" { // or "example\r\n" when on windows
os.Exit(0)
}
Also make sure that your terminal code page is the same as your .go source file. Be aware about different end-line styles (Windows uses "\r\n"), Standard go compiler uses utf8 internally.
[1] Comparison of Go data types for string processing.

what is string strName<>?

I have seen code like this:
struct failed_login_res {
string errorMsg<>;
unsigned int error;
};
What does the <> at the end mean? How is it different from normal declaration like string errorMsg?
Correction: this is for RPC stub, not C++ and I can confirm that it does compile. The question is then still valid.
From a quick googling, I came across this PDF.
Section 6.9 is as follows:
Strings: C has no built-in string type, but instead uses the null-terminated “char *” convention. In XDR language, strings are declared using the “string” keyword, and compiled into “char *”s in the output header file. The maximum size contained in the angle brackets specifies the maximum number of characters allowed in the strings (not counting the NULL character). The maximum size may be left off, indicating a string of arbitrary length.
Examples:
string name<32>; --> char *name;
string longname<>; --> char *longname;

Resources