Using msdelta.dll with rundll32 from command promp? - patch

I'd like to use the CreateDelta function in msdelta.dll via rundll32.
Is this possible? I cannot figure out the proper syntax.
Any help would be great.
Thanks.

No. rundll32 requires a very specific function signature (void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)).
The CreateDelta signature is very different:
BOOL WINAPI CreateDeltaW(
DELTA_FILE_TYPE FileTypeSet,
DELTA_FLAG_TYPE SetFlags,
DELTA_FLAG_TYPE ResetFlags,
LPCWSTR lpSourceName,
LPCWSTR lpTargetName,
LPCWSTR lpSourceOptionsName,
LPCWSTR lpTargetOptionsName,
DELTA_INPUT GlobalOptions,
const FILETIME *lpTargetFileTime,
ALG_ID HashAlgId,
LPCWSTR lpDeltaName
);
As these two do not match, they cannot be used together.
See also:
http://blogs.msdn.com/b/oldnewthing/archive/2011/09/09/10208136.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2013/01/04/10382242.aspx

Related

c - Array of pointer to functions, having different number of arguments

I am making a simple scheduler that executes functions contained in a FIFO queue.
Those functions have a same return type int, but have different number of int arguments.
I tried to implement it this way, but it does not seem to work. The compiler forbids conversion between int(*)() , int(*)(int), int(*)(int, int), or to any of those sort. (Arduino Sketch compiler)
Is there a way to solve this problem, or could you recommend a better way around? Thanks!
My code:
typedef int (*fnptr)(); // Tried this!
int foo(int var) {
return 0;
}
int main() {
fnptr fp = &foo; // error: invalid conversion from
// 'int (*)(int)' to 'int (*)()'
// [-fpermissive]
return 0;
}
You can cast:
fnptr fp = reinterpret_cast<fnptr>(foo);
The ()s are the "function call operator", adding them makes no sense at all in this situation, it changes the expression from "take the address of this function" to "take the address of this function's return value".
Note that aboev I don't even include the &, this is because the name of a function acts pretty much like a function pointer so it's already an address.

How to 'steal' data from QByteArray without copy

Is it possible to take pointer to QByteArray's internal T* data and destroy QByteArray itself so that the pointer remains unreleased? I would like to use it in the something similar to the following scenario:
const char* File::readAllBytes(const String& path, u64& outCount) {
QFile file(*static_cast<QString*>(path.internal()));
outCount = static_cast<u64>(file.size());
if (!file.open(QIODevice::ReadOnly)) gException("Failed to open file");
const QByteArray array = file.readAll();
return array.steal();
}
No, you can't steal QByteArray's pointer unless it has been constructed with QByteArray::fromRawData, which is not the case. However you can create char array manually and read data from file to it using QFile::read(char * data, qint64 maxSize). You will then decide where to pass the pointer and when to delete[] it.
Note that this is not considered good practice. You should use managed allocations whenever you can, and Qt provides enough to cover most of possible use cases. You should not do this unless you're trying to do something really low-level.
Note that many of Qt classes, including QString and QByteArray, use copy-on-write strategy, so you generally should not be afraid of copying them and passing them to another context.
No, but you can easily sidestep the problem by not using QByteArray:
const char* File::readAllBytes(const String& path, u64& outCount) {
QFile file(*static_cast<QString*>(path.internal()));
if (!file.open(QIODevice::ReadOnly)) return nullptr;
auto N = file.bytesAvailable();
char *data = malloc(N);
outCount = file.read(data, N);
return data;
}
The solution above also assumes that the consumer of your data is aware of the need to free the data.
Alas, the manual memory management called for with such an API is a bad idea. If you wish not to use Qt classes in your API, you should be using std::vector<char> instead:
std::vector<char> File::readAllBytes(const String& path) {
std::vector<char> result;
QFile file(*static_cast<QString*>(path.internal()));
if (!file.open(QIODevice::ReadOnly)) return result;
result.resize(file.bytesAvailable());
auto count = file.read(result.data(), result.size());
result.resize(count);
return result;
}
I smell that String is some sort of a framework-independent string wrapper. Perhaps you could settle on std::u16string to carry the same UTF16 data as QString would.

Force compiler not to use .rodata section

Is there any way to force gcc to put
char* str = "Hello";
not in the .rodata without change this statement in
char str[] = "Hello!";
?
Ok, so better way to do this is modify the statement to char str[]. Thanks to all.
Why? Trying to change string literals leads to undefined behavior. It's evil. Consider this program:
"hello"[0] = 'y'; // Welcome to Undefined Behavior Land. Enjoy yor stay!
std::cout << "hello" << std::endl; // Could very will print "yello" now!
static char strbuf[] = "Hello";
char *str = strbuf;
How about using strdup if your platform has it, or implementing it yourself if it doesn't?
char *str = strdup("hello world");
This will allocate memory (at runtime) and copy the string literal into an appropriately sized chunk of memory which you can quite legitimately write to and modify later.
Don't forget to free() after use though.
You might be able to force GCC to put somethings in specific sections of your choosing using the __attribute__ ((section ("my_section"))) attribute, but you'll still have to modify the original source to do that so you'd be much better off doing it a "normal" way.

convert std::ostream to some array?

I have a legacy library that takes data from hardware and writes it to ostream.
The method looks like following :
int sensors(ostream*) const;
I am not skilled enough in Ancient Ways. How to convert this data to QByteArray? Or, at least, to char array of known size?
I would have solved it myself, but there is an additional problem: the data in ostream seem to be arbitrary length and have several arbitrary '\0' symbols, so you can't count on it being null-terminated.
I think this is what OrcunC was getting at:
std::stringstream s;
sensors( &s );
QByteArray( s.str().data(), (int) s.str().size() );
... but hopefully more clear :). See also std::stringstream and std::string for information on the classes/member functions used here. By the way, note that I am using str().data(), not str().c_str() -- I'm being really careful to handle those \0 characters, and I'm not assuming NULL termination.
I have not tried it, but you need something like this :
ostream s (ios::out | ios::binary);
//..Populate the stream
//Convert it to string. string can hold \0 values too.
string str = s.str ();
QByteArray ba (str.data (),str.size ());
You can subclass std::ostream and use an object of the subclass to collect the bytes into your QByteArray.
/**
* This helper class collects bytes that are passed to it
* into a QByteArray.
*
* After https://stackoverflow.com/a/19933011/316578
*/
class QByteArrayAppender : public std::ostream, public std::streambuf {
private:
QByteArray &m_byteArray;
public:
QByteArrayAppender(QByteArray &byteArray)
: std::ostream(this),
std::streambuf(),
m_byteArray(byteArray) {
}
int overflow(int c) {
m_byteArray.append(static_cast<char>(c));
return 0;
}
};
This avoids going via an std::string, which is an extra copy of the byte array.

Automatic conversion of stucture to pointer in function call

We have a pretty normal looking printf style function in our project, with the modification that the %g format means to print a GUID instead of the normal floating-point type. For our case, a GUID looks something like this:
struct guid {
uint32_t Data1;
uint16_t Data2;
uint16_t Data3;
uint8_t Data4[8];
};
In reality, the print function expects a pointer to the GUID to be passed, as opposed to the structure itself:
struct guid myGuid = { 0x867FD1E7, 0x9AA7, 0x472A, { 0xAA, 0x56, 0xF2, 0xDA, 0x66, 0x62, 0xCD, 0x4D } };
print("%g", &myGuid);
There are several places in the source base, however, where for some reason the entire guid is passed:
print("%g", myGuid);
This style of call seems to work fine with MSVC2003 - is there some ABI requirement that makes the compiler translate that function call style to actually pass a pointer behind the scenes? When porting this codebase to use clang/llvm, it certainly doesn't do the same thing.
Can somebody explain why the second version of the call works with MSVC? A pointer to the appropriate documentation would be much appreciated!
I think I found some clarification on MSDN:
Any argument that doesn’t fit in 8 bytes, or is not 1, 2, 4, or 8 bytes, must be passed by reference.
Looks like it's time to fix clang!

Resources