what does BuildCommDCB actually do? - c++

I've just started doing some Win32 programming and I'm confused on the function:
BOOL BuildCommDCB(LPCTSTR szSettings, LPDCB lpDCB);
The description of the LPDCB struct states that "it points to the DCB structure in which the control settings information is
returned". But my question is how is the DCB structure returned when the return value is a BOOL?

LPDCB is a pointer to a structure you provide(1), and BuildCommDCB() will populate that structure, as well as returning a success indicator.
It's no different to the function:
int setTo13AndReturn42 (int *pInt) {
*pInt = 13;
return 42;
}
which, when called with:
int i1 = -1;
int i2 = setTo13AndReturn42 (&i1);
printf ("%d %d\n", i1, i2);
will output:
13 42
(1) From the earliest days of Windows when we had to suffer with the bizarre x86 {tiny, small, medium, large, huge, gargantuan} (or whatever they were actually called) memory models, LP stood for long pointer.

With the Windows API you can usually tell what something is by looking at the variable name and type. The function:
BOOL BuildCommDCB (LPCTSTR szSettings, LPDCB lpDCB);
Has the types and arguments:
LPCTSTR aka a Long Pointer to C-style (Type) STRing. The type is really a TCHAR* which if you have UNICODE defined1 eventually is of the type wchar_t*. The variable name gives you an additional hint (sz or string, zero-terminated). A Unicode string would be LPCWSTR.
LPDCB which stands for Long Pointer to DCB. In the header which defines it, the type is defined as DCB* (Again the variable name re-inforces that.)
So the function takes a string, and a pointer to a structure, (think of this as a form of passing by reference), and returns a BOOL2 to tell you whether it was successful. If it wasn't successful, then the values in the DCB have not been set, and you shouldn't use them.
The rules are not always followed, but they are often enough that you can translate the API types into C types without too much effort.
For example if I tell you that a HMODULE is a module handle, you should know what a HDEVICE3 is.
As always the best place for information about what a function does, and what is expected of it's parameters is MSDN. The documentation says that the lpDCB parameter is,
A pointer to a DCB structure that receives the information.
To use this knowledge with the example function:
DCB dcb;
if (BuildCommDCB(L"Settings", &dcb))
{
// dcb is valid.
}
else
{
// dcb is uninitialized garbage
}
References:
Windows Types
BuildCommDCB at MSDN
1You do have unicode defined, right?
2A word of warning, BOOL is not bool
3A handle to a device of course.

As per this, the second parameter is _Inout_ LPDCB lpDCB, which is a pointer. This situation is like any other pass by pointer/reference case, where information is returned out of function using a reference

Related

What does CString::GetBuffer() with no size parameter do?

Perhaps I'm going insane, but I have tried every search combination I can think of, and I can't find a definition for CString::GetBuffer() with no parameters. Every reference I look up describes CString::GetBuffer( int ), where the int parameter passed in is the max buffer length. The definition in the header is for CSimpleStringT::GetBuffer(). That gave me the following link, which at least acknowledges the existence of the parameterless version, but offers no description of its behavior.
https://msdn.microsoft.com/en-us/library/sddk80xf.aspx#csimplestringt__getbuffer
I'm looking at existing C++ (Visual Studio) code that I don't want to change if I don't have to, but I need to know the expected behavior of CString::GetBuffer(). I'd appreciate it if someone could explain it or point me to some documentation on it.
Although the msdn documentation doesn't really say what GetBuffer without a parameter does, the MFC source code reveals the answer:
return( m_pszData );
So it just returns a pointer to the underlying character buffer. (It also checks to see if the internal data is shared and forks/copies it first).
The code is in atlsimpstr.h
Complete function:
PXSTR GetBuffer()
{
CStringData* pData = GetData();
if( pData->IsShared() )
{
Fork( pData->nDataLength );
}
return( m_pszData );
}
tl;dr
Call CString::GetString().
This is asking the wrong question for the wrong reasons. Just to get it out of the way, here is the answer from the documentation:
Return Value
An PXSTR pointer to the object's (null-terminated) character buffer.
This is true for both overloads, with and without an explicit length argument. When calling the overload taking a length argument, the internal buffer may get resized to accommodate for increased storage requirements, prior to returning a pointer to that buffer.
From this comment, it becomes apparent, that the question is asking for the wrong thing altogether. To learn why, you need to understand what the purpose of the GetBuffer() family of class members is: To temporarily disable enforcement of CString's class invariants1 for modification, until establishing them again by calling one of the ReleaseBuffer() members. The primary use case for this is to interface with C code (like the Windows API).
The important information is:
GetBuffer() should only be called, if you plan to directly modify the contents of the stored character sequence.
Every call to GetBuffer() must be matched with a call to ReleaseBuffer(), before using any other CString class member2. Note in particular, that operator PCXSTR() and the destructor are class members.
As long as you follow that protocol, the controlled character sequence will always be null-terminated.
Given your actual use case (Log.Print("%s\n", myCstring.GetBuffer())), none of the previous really applies. Since you do not plan to actually modify the string contents, you should access the immutable CString interface (e.g. GetString() or operator PCXSTR()) instead. This requires const-correct function signatures (TCHAR const* vs. TCHAR*). Failing that, use a const_cast if you can ensure, that the callee will not mutate the buffer.
There are several benefits to this:
It is semantically correct. If all you want is a view into the character string, you do not need a pointer to a mutable buffer.
There are no superfluous copies of the contents. CString implements copy-on-write semantics. Requesting a mutable buffer necessitates copying the contents for shared instances, even if you are going to throw that copy away immediately after evaluating the current expression.
The immutable interface cannot fail. No exceptions are thrown when calling operator PXCSTR() or GetString().
1 The relevant invariants are: 1 The controlled sequence of characters is always null-terminated. 2 GetLength() returns the count of characters in the controlled sequence, excluding the null terminator.
2 It is only strictly required to call one of the ReleaseBuffer() implementations, if the contents were changed. This is often not immediately obvious from looking at the source code, so always calling ReleaseBuffer() is the safe option.
Documentation is inconclusive. Looking at ATL sources available here (https://github.com/dblock/msiext/blob/d8898d0c84965622868b1763958b68e19fd49ba8/externals/WinDDK/7600.16385.1/inc/atl71/atlsimpstr.h - I do not claim to know if they are official or not) it looks like GetBuffer() without arguments returns the current buffer, cloning it before if it is shared.
On the other hand, GetBuffer(int) with size is going to check (through the call to PrepareWrite and possibly PrepareWrite2) if the current buffer size is greater than requested, and if it is not, it will allocate the new buffer - thus matching MSDN description.
On a side note, PrepareWrite seems to become quite creative in how it checks for two conditions:
PXSTR PrepareWrite( __in int nLength )
{
CStringData* pOldData = GetData();
int nShared = 1-pOldData->nRefs; // nShared < 0 means true, >= 0 means false
int nTooShort = pOldData->nAllocLength-nLength; // nTooShort < 0 means true, >= 0 means false
if( (nShared|nTooShort) < 0 ) // If either sign bit is set (i.e. either is less than zero), we need to copy data
{
PrepareWrite2( nLength );
}
return( m_pszData );
}
Windows API functions often require the input of a character buffer of a certain length. Then use the GetBuffer(int) version. The following code snippet illustrates this and the difference between GetBuffer() and GetString() and the importance of calling ReleaseBuffer() after calling GetBuffer():
CStringW FullName;
if(::GetModuleFileNameW(nullptr,FullName.GetBuffer(MAX_PATH), MAX_PATH) <= 0)
return 0; //GetBuffer() returns PXSTR
FullName.ReleaseBuffer(); //Don't forget!
FullName = L"Path and Name: " + FullName;
std::wcout << FullName.GetString() << L"\n"; //GetString() returns PCXSTR

FindFirstFile cout problems

I need to find files with certain extentions, for example *.doc, *.docx
First, i'm looking for all files
lstrcat(szPath, L"*");
hFind = FindFirstFile(szPath, &fdFindData);
Then, i compare founded file with extention i need
PCWSTR str1 = L".doc";
if(NULL != StrStr(fdFindData.cFileName,str1)) {
FoundFileFunction(fdFindData.cFileName);
}
And then I got problem with cout
VOID FoundFileFunction(HANDLE hFile)
{
std::cout<<hFile;
}
This is output:
009AE50000
009AEB0000
009AEBBB00
and so on. What's the problem?
WIN32_FIND_DATA::cFileName is a TCHAR[MAX_PATH], not a HANDLE.
I don't know why you wrote HANDLE, as that's not uttered on the documentation page even once.
Your function is trying to print out the C-string filename as if it were a HANDLE, which is a different kind of pointer to a TCHAR*. It doesn't know to take the pointer as a TCHAR* so it doesn't know you want it to format the output as a string. It can only know to print the address represented by the pointer.
Your function FoundFileFunction should take a TCHAR*.
The problem would have been automatically detected had you used STRICT mode. If (for example) NO_STRICT is defined then HANDLE is an alias for void* which, per the rules of the language, can be initialised implicitly from a TCHAR*. You should always compile with STRICT defined: that would have changed the types not to be implicitly convertible to one another, and you would have received a compilation error for your mistake.
Furthermore, if your program is using Unicode, then TCHAR is not char but wchar_t, so you need to use not std::cout but std::wcout.

How much consistency is there with WinAPI functions that have string out parameters?

I have recently begun to write in C on Windows and have been trying to be careful with the different ways that string buffers are handled. For instance, GetWindowText() takes an int nMaxCount of the maximum number of characters, including null. GetModuleFileName() takes a DWORD nSize of the size of the buffer, in TCHARs (I assume this also includes null). Even though these are worded differently and one takes a DWORD while the other takes an int (why the difference in types?), the behavior is identical, correct?
Both return the length of the string that is copied, not including the null, so I should be able to call either of them repeatedly, doubling the buffer size until the returned length is less than the buffer size passed in, like this:
DWORD buf_size = 1024;
DWORD return_val;
wchar_t *full_path = malloc(buf_size * sizeof(wchar_t));
// double the buffer until it's big enough
while ((return_val = GetModuleFileNameW(NULL, full_path, buf_size)) == buf_size) {
buf_size *= 2;
full_path = realloc(full_path, buf_size * sizeof(wchar_t));
}
if (!return_val) {
fprintf(stderr, "Error in GetModuleFileNameW()\n");
return NULL;
}
Do all of the Windows API functions with string [out] parameters work in the same way? Are there any individual functions or groups of functions that behave differently? (for instance, functions that take the size of the buffer in bytes instead of characters, or that take a maximum string length not including the null character or that return a different value than these two)
Actually, I just noticed that the return value of these two is not entirely consistent: GetModuleFileName() returns 0 when it errors; GetWindowText() will return 0 whenever there is an empty string for the window text, which I think I saw quite frequently when I was enumerating windows...
One reason I want to understand it in detail is because in some cases (GetModuleFileName() on WinXP, for instance), an off-by-one error in my code will result in a string that is not null-terminated.
By and large the majority of the Win32 API functions that return strings do so in a consistent manner. GetWindowText is a good choice for a canonical such function. However, there are exceptions, and I don't think anyone has ever compiled a comprehensive list.
The bottom line here is that you need to consult the documentation carefully every single time you write code to call a Win32 API function. Not only regarding the treatment of string output values, but all parameters. And all return values. And error handling. There is variation in style across the API, and even variation within related groups of functions.

UINT64 in Native WMI provider doesn't return data on certain systems

I have created a native WMI provider following This tutorial on MSDN. My MOF for the class looks similar to this:
[dynamic, provider("CacheProvider")]
class Cache
{
[key]
String Path;
uint32 Type;
uint64 MaxSize;
uint64 Size;
boolean Enabled;
};
All the data is returned correctly except the uint64 values. I have read that for uint64 values you need to actually provide the data as a BSTR. It does work on 99% of the machines I have tried it on. This is how I am accomplishing that.
v.vt = VT_BSTR;
v.bstrVal = ToLongLongString(MaxSize);
sc = (*pNewInst)->Put(L"MaxSize", 0, &v, 0);
VariantClear(&v);
The ToLongLongString function looks like this.
bstr_t ToLongLongString(LONGLONG llValue)
{
wchar_t szValue[21];
SecureZeroMemory(szValue, sizeof(szValue));
swprintf_s(szValue, L"%lld", llValue);
bstr_t bstrFormat(szValue);
return bstrFormat;
}
I have validated that the string being returned by this function is formatted correctly. It just appears that it is not making it through the WMI system for whatever reason. The only machine I do not seeing it working on is a 2012 R2 server.
From here:
http://msdn.microsoft.com/en-us/library/aa393262(v=vs.85).aspx
Note When querying for property values with a uint64 or sint64 data type in a scripting language like VBScript, WMI returns string values. Unexpected results can occur when comparing these values, because comparing strings returns different results than comparing numbers. For example, "10000000000" is less than "9" when comparing strings, and 9 is less than 10000000000 when comparing numbers. To avoid confusion you should use the CDbl method in VBScript when properties of type uint64 or sint64 are retrieved from WMI.
Can you try using CDBL ?
The problem was due to how I was assigning the BSTR.
Since ToLongLongString returns a bstr_t, it passes the BSTR value to the variant. Since I never detached the BSTR from the bstr_t the BSTR was being released once the bstr_t went out of scope.
Calling Detach fixed the issue.

C++ WriteProcessMemory Without Variables

I want to do WriteProcessMemory In C++ using Dword or Int, without storing it in a Variable i found one way to do this but i can only do it with bytes. does anyone know how to do this??
this one works using bytes.
WriteProcessMemory(hProcess, (void*)(BasePointer + 0x728),"\x90\x90", 4, NULL);
Thanks for the help everyone i made a function and its working really good
void WriteMemory(DWORD Address,DWORD NewValue, int NewValueSize)
{
WriteProcessMemory(hProcess, (void*)Address, (void*)&NewValue, NewValueSize, NULL);
}
int main()
{
srand(time(0));
GetProcess();
WriteMemory((BasePointer + 0x6F8),2+rand()%65500,2);
CloseHandle(hProcess);
return 0;
}
The reason your code "works" with bytes is that you're using a string literal. A string literal is an array of char, and an array of char automatically converts to a pointer to the first element if the context calls for it, as it does when you try to pass one as the third argument of WriteProcessMemory.
You can write any value you want as a string literal, including a four-byte DWord, as long as you're willing to express it one byte at a time. For example, "\x70\x71\x72\x73". On Windows, that's equivalent to a pointer to the DWord value 0x73727170. You probably won't want to do that, though; expressing numbers like that is tedious.
C++ doesn't offer any facility for having literal arrays of non-char type. There's just not much demand for it. Demand for literal char arrays is high because everyone deals with text, so we want easy ways of expressing it in our code. Although everyone also works with numbers, we rarely have need to express blobs of numerical data in our code, especially not mid-expression.
You haven't given a practical problem to be solved by your question. You're just asking whether something is possible to do. I'm sorry to be the bearer of bad news, but the answer is that what you're asking for cannot be done in C++. You'll just have to do like everyone else and declare a variable. Variables are cheap; feel free to use them whenever the need arises. Nonetheless, you've been shown ways to keep your code concise by using subroutines. Macros can also help shorten your code, if that's your goal.
Please also note that the string literal in your code is an array of three characters — the two between quotation marks, plus the nul character the compiler automatically includes at the end of all string literals. You're telling the function that you've provided a pointer to a block of four bytes, which is false. the fourth byte that the function writes into the other process will have an unspecified value.
Put the data into an array, and have a small loop get each item from the array, write it to the target process, then move to the next:
struct data {
DWORD offset;
DWORD length;
char data[256];
};
data items[] = {
{0x728, 4, "\x90\x90"},
// ...
};
for (int i=0; i<elements(items); i++)
WriteProcessMemory(hProcess, (void *)(BasePointer + items[i].offset), items[i].data, items[i].length, NULL);