// http://stackoverflow.com/questions/13463375/memory-corruption #include #include #include #include static inline QString LAT1(const char *str, const int len = -1) { return QString::fromLatin1(str, len); } template static inline QByteArray createByteArray(const T *from, const int numElements) { return QByteArray(reinterpret_cast(from), sizeof(T) * numElements); } /* // This one uses types and functions directly from . // (Static linking.) #define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include QByteArray fingerprintStatic() { const DWORD kMaxPath = 260 + 1; // MAX_PATH + 1 wchar_t path[kMaxPath] = {0}; wchar_t name[kMaxPath] = {0}; wchar_t fileSystem[kMaxPath] = {0}; DWORD serial = 0; DWORD maximumComponentLength = 0; DWORD fileSystemFlags = 0; QDir::toNativeSeparators(QDir::rootPath()).toWCharArray(path); if (FAILED(GetVolumeInformationW(path, name, kMaxPath, &serial, &maximumComponentLength, &fileSystemFlags, fileSystem, kMaxPath))) { qWarning("GetVolumeInformationW() failed: %u", static_cast(GetLastError())); return QByteArray(); } return createByteArray(fileSystem, wcslen(fileSystem)); } */ // This one resolves functions from Kernel32.dll dynamically and uses standard types. // (Dynamic linking.) QByteArray fingerprintDynamic() { const uint32_t kMaxPath = 260 + 1; // MAX_PATH + 1 wchar_t path[kMaxPath] = {0}; wchar_t name[kMaxPath] = {0}; wchar_t fileSystem[kMaxPath] = {0}; uint32_t serial = 0; uint32_t maximumComponentLength = 0; uint32_t fileSystemFlags = 0; QLibrary kernel32("kernel32"); typedef uint32_t (*fnGetLastError)(void); typedef bool (*fnGetVolumeInformationW)(const wchar_t*, wchar_t*, uint32_t, uint32_t*, uint32_t*, uint32_t*, wchar_t*, uint32_t); fnGetVolumeInformationW GetVolumeInformationW = reinterpret_cast(kernel32.resolve("GetVolumeInformationW")); fnGetLastError GetLastError = reinterpret_cast(kernel32.resolve("GetLastError")); if (!GetVolumeInformationW) { qWarning(LAT1("GetVolumeInformationW() not resolved: %1").arg(kernel32.errorString()).toLatin1().constData()); return QByteArray(); } else if (!GetLastError) { qWarning(LAT1("GetLastError() not resolved: %1").arg(kernel32.errorString()).toLatin1().constData()); return QByteArray(); } QDir::toNativeSeparators(QDir::rootPath()).toWCharArray(path); bool apiCall = GetVolumeInformationW(path, name, kMaxPath, &serial, &maximumComponentLength, &fileSystemFlags, fileSystem, kMaxPath); if (!apiCall) qWarning(LAT1("GetVolumeInformationW() failed: %1").arg(GetLastError()).toLatin1().constData()); // At this point, fileSystem is correct and contains // L"NTFS" // ONLY HAPPENS IN DEBUG MODE // // After this call memory becomes corrupted. wcslen() is not a problem. // And createByteArray<>() is ok too, I believe. //size_t len; // But if I change stack a bit (like uncomment this line), // result will be correct, so I guess it's related to memory offset. return createByteArray(fileSystem, wcslen(fileSystem)); // return createByteArray(path, wcslen(path)) + // createByteArray(name, wcslen(name)) + // createByteArray(fileSystem, wcslen(fileSystem)) + // createByteArray(&serial, 1) + // createByteArray(&maximumComponentLength, 1) + // createByteArray(&fileSystemFlags, 1); } void print(const QByteArray &bytes) { qDebug() << QString::fromWCharArray(reinterpret_cast(bytes.constData())); qDebug() << bytes.size() << "bytes" << bytes.toHex(); qDebug() << ""; } int main(int, char**) { // qDebug() << "static"; // print(fingerprintStatic()); qDebug() << "dynamic"; print(fingerprintDynamic()); return 0; }